services/agent/internal/server: check for socket file path length
test/modules/shell: shorten the path to the dir holding agent sockets

A long socket path is rejected when trying to listen. The error is
murky, and it's not immediately clear to the client what's wrong. This
change adds an explicit check in the agent to ensure the socket path is
of an acceptable length, and return an informative error if not.

One of the places where the socket path occasionally ends up being too
long is in integration tests. This change shaves off ~20 characters to
help keep it short.

Change-Id: I60c25c9a14ad0f8c7e81c5f5a5abbc090ab7f7e2
diff --git a/services/agent/internal/server/server.go b/services/agent/internal/server/server.go
index a9ccc5c..cce84a9 100644
--- a/services/agent/internal/server/server.go
+++ b/services/agent/internal/server/server.go
@@ -339,6 +339,9 @@
 }
 
 func (m *keymgr) ServePrincipal(handle [agent.PrincipalHandleByteSize]byte, path string) error {
+	if maxLen := GetMaxSockPathLen(); len(path) > maxLen {
+		return fmt.Errorf("socket path (%s) exceeds maximum allowed socket path length (%d)", path, maxLen)
+	}
 	if _, err := m.readKey(handle); err != nil {
 		return err
 	}
diff --git a/services/agent/internal/server/sock_len.go b/services/agent/internal/server/sock_len.go
new file mode 100644
index 0000000..7706d58
--- /dev/null
+++ b/services/agent/internal/server/sock_len.go
@@ -0,0 +1,9 @@
+package server
+
+// #include <sys/un.h>
+import "C"
+
+func GetMaxSockPathLen() int {
+	var t C.struct_sockaddr_un
+	return len(t.sun_path)
+}
diff --git a/services/agent/internal/server/sock_len_darwin_test.go b/services/agent/internal/server/sock_len_darwin_test.go
new file mode 100644
index 0000000..ca8fc74
--- /dev/null
+++ b/services/agent/internal/server/sock_len_darwin_test.go
@@ -0,0 +1,11 @@
+package server
+
+import (
+	"testing"
+)
+
+func TestMaxSockPathLen(t *testing.T) {
+	if length := GetMaxSockPathLen(); length != 104 {
+		t.Errorf("Expected max socket path length to be 104 on darwin, got %d instead", length)
+	}
+}
diff --git a/services/agent/internal/server/sock_len_linux_test.go b/services/agent/internal/server/sock_len_linux_test.go
new file mode 100644
index 0000000..e592f12
--- /dev/null
+++ b/services/agent/internal/server/sock_len_linux_test.go
@@ -0,0 +1,11 @@
+package server
+
+import (
+	"testing"
+)
+
+func TestMaxSockPathLen(t *testing.T) {
+	if length := GetMaxSockPathLen(); length != 108 {
+		t.Errorf("Expected max socket path length to be 108 on linux, got %d instead", length)
+	}
+}
diff --git a/test/modules/shell.go b/test/modules/shell.go
index 4b3400e..c4dae02 100644
--- a/test/modules/shell.go
+++ b/test/modules/shell.go
@@ -229,7 +229,7 @@
 	sh.ctx = ctx
 	sh.logger = ctx
 
-	if sh.tempCredDir, err = ioutil.TempDir("", "shell_credentials-"); err != nil {
+	if sh.tempCredDir, err = ioutil.TempDir("", "sh_creds"); err != nil {
 		return nil, err
 	}
 	if sh.agent, err = keymgr.NewLocalAgent(sh.tempCredDir, nil); err != nil {
@@ -282,7 +282,7 @@
 	return fd, nil
 }
 
-// NewCustomCredentials creates a new Principal for StartWithOpts..
+// NewCustomCredentials creates a new Principal for StartWithOpts.
 // Returns nil if the shell is not managing principals.
 func (sh *Shell) NewCustomCredentials() (cred *CustomCredentials, err error) {
 	// Create child principal.
@@ -293,7 +293,7 @@
 	if err != nil {
 		return nil, err
 	}
-	dir, err := ioutil.TempDir(sh.tempCredDir, "agent")
+	dir, err := ioutil.TempDir(sh.tempCredDir, "a")
 	if err != nil {
 		return nil, err
 	}