Change to use a unix socket instead of TCP.
This change makes Trousers use a unix domain socket instead of a TCP socket. This allows tcsd to start without waiting on the network.
Change-Id: Ic66830a03d35bbe503e9a91ca2ebbbd96924fb42
BUG=7892
TEST=install, test cryptohome tpm ownership, crypto, and status
Review URL: http://codereview.chromium.org/3958001
diff --git a/src/include/tcsd.h b/src/include/tcsd.h
index 1f72e05..e43ce05 100644
--- a/src/include/tcsd.h
+++ b/src/include/tcsd.h
@@ -159,4 +159,6 @@
struct sigaction tcsd_sa_int;
struct sigaction tcsd_sa_chld;
+#define TCSD_UNIX_SOCKET "/var/run/tcsd.socket"
+
#endif
diff --git a/src/tcs/rpc/tcstp/rpc.c b/src/tcs/rpc/tcstp/rpc.c
index ca1a4df..6a78840 100644
--- a/src/tcs/rpc/tcstp/rpc.c
+++ b/src/tcs/rpc/tcstp/rpc.c
@@ -516,50 +516,8 @@
int
access_control(struct tcsd_thread_data *thread_data)
{
- int i = 0;
- struct hostent *local_hostent = NULL;
- static char *localhostname = NULL;
- static int localhostname_len = 0;
-
- if (!localhostname) {
- if ((local_hostent = gethostbyname("localhost")) == NULL) {
- LogError("Error resolving localhost: %s", hstrerror(h_errno));
- return 1;
- }
-
- LogDebugFn("Cached local hostent:");
- LogDebugFn("h_name: %s", local_hostent->h_name);
- for (i = 0; local_hostent->h_aliases[i]; i++) {
- LogDebugFn("h_aliases[%d]: %s", i, local_hostent->h_aliases[i]);
- }
- LogDebugFn("h_addrtype: %s",
- (local_hostent->h_addrtype == AF_INET6 ? "AF_INET6" : "AF_INET"));
-
- localhostname_len = strlen(local_hostent->h_name);
- if ((localhostname = strdup(local_hostent->h_name)) == NULL) {
- LogError("malloc of %d bytes failed.", localhostname_len);
- return TCSERR(TSS_E_OUTOFMEMORY);
- }
- }
-
- /* if the request comes from localhost, or is in the accepted ops list,
- * approve it */
- if (!strncmp(thread_data->hostname, localhostname,
- MIN((size_t)localhostname_len, strlen(thread_data->hostname)))) {
- return 0;
- } else {
- while (tcsd_options.remote_ops[i]) {
- if ((UINT32)tcsd_options.remote_ops[i] == thread_data->comm.hdr.u.ordinal) {
- LogInfo("Accepted %s operation from %s",
- tcs_func_table[thread_data->comm.hdr.u.ordinal].name,
- thread_data->hostname);
- return 0;
- }
- i++;
- }
- }
-
- return 1;
+ // Unix domain socket, so just allow
+ return 0;
}
TSS_RESULT
diff --git a/src/tcsd/svrside.c b/src/tcsd/svrside.c
index 27c18bf..5945607 100644
--- a/src/tcsd/svrside.c
+++ b/src/tcsd/svrside.c
@@ -19,6 +19,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <netdb.h>
#include <pwd.h>
#if (defined (__OpenBSD__) || defined (__FreeBSD__))
@@ -211,11 +212,10 @@
int
main(int argc, char **argv)
{
- struct sockaddr_in serv_addr, client_addr;
+ struct sockaddr_un serv_addr, client_addr;
TSS_RESULT result;
int sd, newsd, c, option_index = 0;
unsigned client_len;
- char *hostname = NULL;
struct passwd *pwd;
struct hostent *client_hostent = NULL;
struct option long_options[] = {
@@ -245,29 +245,27 @@
if ((result = tcsd_startup()))
return (int)result;
- sd = socket(AF_INET, SOCK_STREAM, 0);
+ sd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sd < 0) {
LogError("Failed socket: %s", strerror(errno));
return -1;
}
memset(&serv_addr, 0, sizeof (serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(tcsd_options.port);
-
- /* If no remote_ops are defined, restrict connections to localhost
- * only at the socket. */
- if (tcsd_options.remote_ops[0] == 0)
- serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- else
- serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serv_addr.sun_family = AF_UNIX;
+ strcpy(serv_addr.sun_path, TCSD_UNIX_SOCKET);
+ unlink(serv_addr.sun_path);
c = 1;
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &c, sizeof(c));
- if (bind(sd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
+ if (bind(sd, (struct sockaddr *) &serv_addr,
+ strlen(serv_addr.sun_path) + sizeof (serv_addr.sun_family))
+ < 0) {
LogError("Failed bind: %s", strerror(errno));
return -1;
}
+ chmod(serv_addr.sun_path,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
#ifndef SOLARIS
pwd = getpwnam(TSS_USER_NAME);
if (pwd == NULL) {
@@ -314,24 +312,8 @@
}
LogDebug("accepted socket %i", newsd);
- if ((client_hostent = gethostbyaddr((char *) &client_addr.sin_addr,
- sizeof(client_addr.sin_addr),
- AF_INET)) == NULL) {
- char buf[16];
- uint32_t addr = htonl(client_addr.sin_addr.s_addr);
-
- snprintf(buf, 16, "%d.%d.%d.%d", (addr & 0xff000000) >> 24,
- (addr & 0x00ff0000) >> 16, (addr & 0x0000ff00) >> 8,
- addr & 0x000000ff);
-
- LogWarn("Host name for connecting IP %s could not be resolved", buf);
- hostname = strdup(buf);
- } else {
- hostname = strdup(client_hostent->h_name);
- }
-
- tcsd_thread_create(newsd, hostname);
- hostname = NULL;
+ // We're listening on a domain socket, so just use "localhost"
+ tcsd_thread_create(newsd, strdup("localhost"));
if (hup) {
if (reload_config() != TSS_SUCCESS)
LogError("Failed reloading config");
diff --git a/src/tspi/rpc/tcstp/rpc.c b/src/tspi/rpc/tcstp/rpc.c
index 963da1f..fd9b390 100644
--- a/src/tspi/rpc/tcstp/rpc.c
+++ b/src/tspi/rpc/tcstp/rpc.c
@@ -13,6 +13,7 @@
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
+#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
@@ -32,7 +33,6 @@
#include "obj.h"
#include "rpc_tcstp_tsp.h"
-
void
initData(struct tcsd_comm_data *comm, int parm_count)
{
@@ -345,10 +345,9 @@
BYTE *buffer;
TSS_RESULT result;
- struct sockaddr_in addr;
- struct hostent *hEnt = NULL;
+ struct sockaddr_un addr;
- sd = socket(PF_INET, SOCK_STREAM, 0);
+ sd = socket(PF_UNIX, SOCK_STREAM, 0);
if (sd == -1) {
LogError("socket: %s", strerror(errno));
result = TSPERR(TSS_E_COMM_FAILURE);
@@ -356,27 +355,11 @@
}
memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(get_port());
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, TCSD_UNIX_SOCKET);
- LogDebug("Sending TSP packet to host %s.", hte->hostname);
-
- /* try to resolve by hostname first */
- hEnt = gethostbyname((char *)hte->hostname);
- if (hEnt == NULL) {
- /* if by hostname fails, try by dot notation */
- if (inet_aton((char *)hte->hostname, &addr.sin_addr) == 0) {
- LogError("hostname %s does not resolve to a valid address.", hte->hostname);
- result = TSPERR(TSS_E_CONNECTION_FAILED);
- goto err_exit;
- }
- } else {
- memcpy(&addr.sin_addr, hEnt->h_addr_list[0], 4);
- }
-
- LogDebug("Connecting to %s", inet_ntoa(addr.sin_addr));
-
- if (connect(sd, (struct sockaddr *) &addr, sizeof (addr))) {
+ if (connect(sd, (struct sockaddr *) &addr,
+ strlen(addr.sun_path) + sizeof (addr.sun_family))) {
LogError("connect: %s", strerror(errno));
result = TSPERR(TSS_E_COMM_FAILURE);
goto err_exit;
@@ -511,4 +494,3 @@
return (short)port;
}
-