1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
11 pseudorand "math/rand"
16 "golang.org/x/crypto/ssh"
19 func TestServer(t *testing.T) {
20 c1, c2, err := netPipe()
22 t.Fatalf("netPipe: %v", err)
26 client := NewClient(c1)
28 go ServeAgent(NewKeyring(), c2)
30 testAgentInterface(t, client, testPrivateKeys["rsa"], nil, 0)
33 func TestLockServer(t *testing.T) {
34 testLockAgent(NewKeyring(), t)
37 func TestSetupForwardAgent(t *testing.T) {
38 a, b, err := netPipe()
40 t.Fatalf("netPipe: %v", err)
46 _, socket, cleanup := startOpenSSHAgent(t)
49 serverConf := ssh.ServerConfig{
52 serverConf.AddHostKey(testSigners["rsa"])
53 incoming := make(chan *ssh.ServerConn, 1)
55 conn, _, _, err := ssh.NewServerConn(a, &serverConf)
57 t.Fatalf("Server: %v", err)
62 conf := ssh.ClientConfig{
63 HostKeyCallback: ssh.InsecureIgnoreHostKey(),
65 conn, chans, reqs, err := ssh.NewClientConn(b, "", &conf)
67 t.Fatalf("NewClientConn: %v", err)
69 client := ssh.NewClient(conn, chans, reqs)
71 if err := ForwardToRemote(client, socket); err != nil {
72 t.Fatalf("SetupForwardAgent: %v", err)
76 ch, reqs, err := server.OpenChannel(channelType, nil)
78 t.Fatalf("OpenChannel(%q): %v", channelType, err)
80 go ssh.DiscardRequests(reqs)
82 agentClient := NewClient(ch)
83 testAgentInterface(t, agentClient, testPrivateKeys["rsa"], nil, 0)
87 func TestV1ProtocolMessages(t *testing.T) {
88 c1, c2, err := netPipe()
90 t.Fatalf("netPipe: %v", err)
96 go ServeAgent(NewKeyring(), c2)
98 testV1ProtocolMessages(t, c.(*client))
101 func testV1ProtocolMessages(t *testing.T, c *client) {
102 reply, err := c.call([]byte{agentRequestV1Identities})
104 t.Fatalf("v1 request all failed: %v", err)
106 if msg, ok := reply.(*agentV1IdentityMsg); !ok || msg.Numkeys != 0 {
107 t.Fatalf("invalid request all response: %#v", reply)
110 reply, err = c.call([]byte{agentRemoveAllV1Identities})
112 t.Fatalf("v1 remove all failed: %v", err)
114 if _, ok := reply.(*successAgentMsg); !ok {
115 t.Fatalf("invalid remove all response: %#v", reply)
119 func verifyKey(sshAgent Agent) error {
120 keys, err := sshAgent.List()
122 return fmt.Errorf("listing keys: %v", err)
126 return fmt.Errorf("bad number of keys found. expected 1, got %d", len(keys))
129 buf := make([]byte, 128)
130 if _, err := rand.Read(buf); err != nil {
131 return fmt.Errorf("rand: %v", err)
134 sig, err := sshAgent.Sign(keys[0], buf)
136 return fmt.Errorf("sign: %v", err)
139 if err := keys[0].Verify(buf, sig); err != nil {
140 return fmt.Errorf("verify: %v", err)
145 func addKeyToAgent(key crypto.PrivateKey) error {
146 sshAgent := NewKeyring()
147 if err := sshAgent.Add(AddedKey{PrivateKey: key}); err != nil {
148 return fmt.Errorf("add: %v", err)
150 return verifyKey(sshAgent)
153 func TestKeyTypes(t *testing.T) {
154 for k, v := range testPrivateKeys {
155 if err := addKeyToAgent(v); err != nil {
156 t.Errorf("error adding key type %s, %v", k, err)
158 if err := addCertToAgentSock(v, nil); err != nil {
159 t.Errorf("error adding key type %s, %v", k, err)
164 func addCertToAgentSock(key crypto.PrivateKey, cert *ssh.Certificate) error {
165 a, b, err := netPipe()
169 agentServer := NewKeyring()
170 go ServeAgent(agentServer, a)
172 agentClient := NewClient(b)
173 if err := agentClient.Add(AddedKey{PrivateKey: key, Certificate: cert}); err != nil {
174 return fmt.Errorf("add: %v", err)
176 return verifyKey(agentClient)
179 func addCertToAgent(key crypto.PrivateKey, cert *ssh.Certificate) error {
180 sshAgent := NewKeyring()
181 if err := sshAgent.Add(AddedKey{PrivateKey: key, Certificate: cert}); err != nil {
182 return fmt.Errorf("add: %v", err)
184 return verifyKey(sshAgent)
187 func TestCertTypes(t *testing.T) {
188 for keyType, key := range testPublicKeys {
189 cert := &ssh.Certificate{
190 ValidPrincipals: []string{"gopher1"},
192 ValidBefore: ssh.CertTimeInfinity,
195 CertType: ssh.UserCert,
196 SignatureKey: testPublicKeys["rsa"],
197 Permissions: ssh.Permissions{
198 CriticalOptions: map[string]string{},
199 Extensions: map[string]string{},
202 if err := cert.SignCert(rand.Reader, testSigners["rsa"]); err != nil {
203 t.Fatalf("signcert: %v", err)
205 if err := addCertToAgent(testPrivateKeys[keyType], cert); err != nil {
208 if err := addCertToAgentSock(testPrivateKeys[keyType], cert); err != nil {
214 func TestParseConstraints(t *testing.T) {
216 var msg = constrainLifetimeAgentMsg{pseudorand.Uint32()}
217 lifetimeSecs, _, _, err := parseConstraints(ssh.Marshal(msg))
219 t.Fatalf("parseConstraints: %v", err)
221 if lifetimeSecs != msg.LifetimeSecs {
222 t.Errorf("got lifetime %v, want %v", lifetimeSecs, msg.LifetimeSecs)
225 // Test ConfirmBeforeUse
226 _, confirmBeforeUse, _, err := parseConstraints([]byte{agentConstrainConfirm})
230 if !confirmBeforeUse {
231 t.Error("got comfirmBeforeUse == false")
234 // Test ConstraintExtensions
236 var expect []ConstraintExtension
237 for i := 0; i < 10; i++ {
238 var ext = ConstraintExtension{
239 ExtensionName: fmt.Sprintf("name%d", i),
240 ExtensionDetails: []byte(fmt.Sprintf("details: %d", i)),
242 expect = append(expect, ext)
243 data = append(data, agentConstrainExtension)
244 data = append(data, ssh.Marshal(ext)...)
246 _, _, extensions, err := parseConstraints(data)
250 if !reflect.DeepEqual(expect, extensions) {
251 t.Errorf("got extension %v, want %v", extensions, expect)
254 // Test Unknown Constraint
255 _, _, _, err = parseConstraints([]byte{128})
256 if err == nil || !strings.Contains(err.Error(), "unknown constraint") {
257 t.Errorf("unexpected error: %v", err)