veyron/security/agent: Initial implementation using VC.
This is a bare bones implementation of an agent which stores the
identity's private key in a separate process. Currently it only
stores a single key for a single child process. Future versions will lift
these limitations.
The first attempt broke on linux because the socket addresses on Linux are
"@", which the endpoint parsing code doesn't support. This is fixed by
implementing custom names for unixfd Conn's.
Change-Id: I3122401767c8875fb88464fca2354fe201ab161d
diff --git a/security/agent/agentd/main.go b/security/agent/agentd/main.go
new file mode 100644
index 0000000..9538b1e
--- /dev/null
+++ b/security/agent/agentd/main.go
@@ -0,0 +1,63 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "os/exec"
+ "syscall"
+ "veyron/security/agent"
+ "veyron/security/agent/server"
+ "veyron2/rt"
+)
+
+func main() {
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, `Usage: %s [agent options] command command_args...
+
+Loads the identity specified in VEYRON_IDENTITY into memory, then
+starts the specified command with access to the identity via the
+agent protocol instead of directly reading from disk.
+
+`, os.Args[0])
+ flag.PrintDefaults()
+ }
+ // Load the identity specified in the environment
+ runtime := rt.Init()
+ log := runtime.Logger()
+
+ if len(flag.Args()) < 1 {
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ var err error
+ if err = os.Setenv(agent.EndpointVarName, agent.CreateAgentEndpoint(3)); err != nil {
+ log.Fatalf("setenv: %v", err)
+ }
+ if err = os.Setenv("VEYRON_IDENTITY", ""); err != nil {
+ log.Fatalf("setenv: %v", err)
+ }
+
+ // Start running our server.
+ var sock *os.File
+ if sock, err = server.RunAnonymousAgent(runtime, runtime.Identity()); err != nil {
+ log.Fatalf("RunAgent: %v", err)
+ }
+
+ // Now run the client and wait for it to finish.
+ cmd := exec.Command(flag.Args()[0], flag.Args()[1:]...)
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ cmd.ExtraFiles = []*os.File{sock}
+
+ err = cmd.Start()
+ if err != nil {
+ log.Fatalf("Error starting child: %v", err)
+ }
+ sock.Close()
+ cmd.Wait()
+ status := cmd.ProcessState.Sys().(syscall.WaitStatus)
+ os.Exit(status.ExitStatus())
+}