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;
 }
-