func TestAgentForward(t *testing.T) { server := newServer(t) defer server.Shutdown() conn := server.Dial(clientConfig()) defer conn.Close() keyring := agent.NewKeyring() keyring.Add(testPrivateKeys["dsa"], nil, "") pub := testPublicKeys["dsa"] sess, err := conn.NewSession() if err != nil { t.Fatalf("NewSession: %v", err) } if err := agent.RequestAgentForwarding(sess); err != nil { t.Fatalf("RequestAgentForwarding: %v", err) } if err := agent.ForwardToAgent(conn, keyring); err != nil { t.Fatalf("SetupForwardKeyring: %v", err) } out, err := sess.CombinedOutput("ssh-add -L") if err != nil { t.Fatalf("running ssh-add: %v, out %s", err, out) } key, _, _, _, err := ssh.ParseAuthorizedKey(out) if err != nil { t.Fatalf("ParseAuthorizedKey(%q): %v", out, err) } if !bytes.Equal(key.Marshal(), pub.Marshal()) { t.Fatalf("got key %s, want %s", ssh.MarshalAuthorizedKey(key), ssh.MarshalAuthorizedKey(pub)) } }
// NewSSHAgent constructs a new SSHAgent using dialer to create ssh // connections. func NewSSHAgent(dialer Dialer) (*SSHAgent, error) { key, err := rsa.GenerateKey(rand.Reader, rsaKeySize) if err != nil { return nil, err } addedkey := agent.AddedKey{ PrivateKey: key, Comment: "core@default", } keyring := agent.NewKeyring() err = keyring.Add(addedkey) if err != nil { return nil, err } sockDir, err := ioutil.TempDir("", "mantle-ssh-") if err != nil { return nil, err } // Use a similar naming scheme to ssh-agent sockPath := fmt.Sprintf("%s/agent.%d", sockDir, os.Getpid()) sockAddr := &net.UnixAddr{Name: sockPath, Net: "unix"} listener, err := net.ListenUnix("unix", sockAddr) if err != nil { os.RemoveAll(sockDir) return nil, err } a := &SSHAgent{ Agent: keyring, Dialer: dialer, User: defaultUser, Socket: sockPath, sockDir: sockDir, listener: listener, } go func() { for { conn, err := listener.Accept() if err != nil { return } go agent.ServeAgent(a, conn) } }() return a, nil }