Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(207)

Delta Between Two Patch Sets: ssh/agent/agent_test.go

Issue 38940043: code review 38940043: gosshnew/ssh/agent: move ssh-agent support into separat... (Closed)
Left Patch Set: Created 10 years, 3 months ago
Right Patch Set: diff -r bb1e8d449b04 https://hanwen%40google.com@code.google.com/p/gosshnew/ Created 10 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « ssh/agent/agent.go ('k') | ssh/client_auth.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2012 The Go Authors. All rights reserved. 1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package ssh 5 package agent
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "crypto/rsa"
10 "crypto/x509"
11 "encoding/pem"
9 "net" 12 "net"
10 "os" 13 "os"
11 "os/exec" 14 "os/exec"
12 "strconv" 15 "strconv"
13 "testing" 16 "testing"
17
18 "code.google.com/p/gosshnew/ssh"
14 ) 19 )
15 20
16 func startAgent(t *testing.T) (address string, cleanup func()) { 21 const rsaKeySerialized = `-----BEGIN RSA PRIVATE KEY-----
22 MIIBOwIBAAJBALdGZxkXDAjsYk10ihwU6Id2KeILz1TAJuoq4tOgDWxEEGeTrcld
23 r/ZwVaFzjWzxaf6zQIJbfaSEAhqD5yo72+sCAwEAAQJBAK8PEVU23Wj8mV0QjwcJ
24 tZ4GcTUYQL7cF4+ezTCE9a1NrGnCP2RuQkHEKxuTVrxXt+6OF15/1/fuXnxKjmJC
25 nxkCIQDaXvPPBi0c7vAxGwNY9726x01/dNbHCE0CBtcotobxpwIhANbbQbh3JHVW
26 2haQh4fAG5mhesZKAGcxTyv4mQ7uMSQdAiAj+4dzMpJWdSzQ+qGHlHMIBvVHLkqB
27 y2VdEyF7DPCZewIhAI7GOI/6LDIFOvtPo6Bj2nNmyQ1HU6k/LRtNIXi4c9NJAiAr
28 rrxx26itVhJmcvoUhOjwuzSlP2bE5VHAvkGB352YBg==
29 -----END RSA PRIVATE KEY-----`
30
31 var rsaKey ssh.Signer
32 var rawRSAKey *rsa.PrivateKey
33
34 func init() {
35 » block, _ := pem.Decode([]byte(rsaKeySerialized))
36 » if block == nil {
37 » » panic("ssh: no key found")
38 » }
39
40 » rawRSAKey, _ = x509.ParsePKCS1PrivateKey(block.Bytes)
41 » rsaKey, _ = ssh.NewSignerFromKey(rawRSAKey)
42 }
43
44 func startAgent(t *testing.T) (client *AgentClient, cleanup func()) {
17 bin, err := exec.LookPath("ssh-agent") 45 bin, err := exec.LookPath("ssh-agent")
18 if err != nil { 46 if err != nil {
19 t.Skip("could not find ssh-agent") 47 t.Skip("could not find ssh-agent")
20 } 48 }
21 49
22 cmd := exec.Command(bin, "-s") 50 cmd := exec.Command(bin, "-s")
23 out, err := cmd.Output() 51 out, err := cmd.Output()
24 if err != nil { 52 if err != nil {
25 t.Fatalf("cmd.Output: %v", err) 53 t.Fatalf("cmd.Output: %v", err)
26 } 54 }
27 55
28 /* Output looks like: 56 /* Output looks like:
29 57
30 SSH_AUTH_SOCK=/tmp/ssh-P65gpcqArqvH/agent.15541; export SSH_A UTH_SOCK; 58 SSH_AUTH_SOCK=/tmp/ssh-P65gpcqArqvH/agent.15541; export SSH_A UTH_SOCK;
31 SSH_AGENT_PID=15542; export SSH_AGENT_PID; 59 SSH_AGENT_PID=15542; export SSH_AGENT_PID;
32 echo Agent pid 15542; 60 echo Agent pid 15542;
33 */ 61 */
34 fields := bytes.Split(out, []byte(";")) 62 fields := bytes.Split(out, []byte(";"))
35 line := bytes.SplitN(fields[0], []byte("="), 2) 63 line := bytes.SplitN(fields[0], []byte("="), 2)
36 socket := line[1] 64 socket := line[1]
37 65
38 line = bytes.SplitN(fields[2], []byte("="), 2) 66 line = bytes.SplitN(fields[2], []byte("="), 2)
39 pidStr := line[1] 67 pidStr := line[1]
40 pid, err := strconv.Atoi(string(pidStr)) 68 pid, err := strconv.Atoi(string(pidStr))
41 if err != nil { 69 if err != nil {
42 t.Fatalf("Atoi(%q): %v", pidStr, err) 70 t.Fatalf("Atoi(%q): %v", pidStr, err)
43 } 71 }
44 » return string(socket), func() { 72
73 » conn, err := net.Dial("unix", string(socket))
74 » if err != nil {
75 » » t.Fatalf("net.Dial: %v", err)
76 » }
77
78 » ac := NewAgentClient(conn)
79 » return ac, func() {
45 proc, _ := os.FindProcess(pid) 80 proc, _ := os.FindProcess(pid)
46 if proc != nil { 81 if proc != nil {
47 proc.Kill() 82 proc.Kill()
48 } 83 }
84 ac.Close()
49 } 85 }
50 } 86 }
51 87
52 func TestAgent(t *testing.T) { 88 func TestAgent(t *testing.T) {
53 » socket, cleanup := startAgent(t) 89 » agent, cleanup := startAgent(t)
54 defer cleanup() 90 defer cleanup()
55 » conn, err := net.Dial("unix", socket) 91 » keys, err := agent.List()
56 » if err != nil {
57 » » t.Fatalf("net.Dial: %v", err)
58 » }
59 » defer conn.Close()
60
61 » ac := NewAgentClient(conn)
62 » keys, err := ac.RequestIdentities()
63 if err != nil { 92 if err != nil {
64 t.Fatalf("RequestIdentities: %v", err) 93 t.Fatalf("RequestIdentities: %v", err)
65 } 94 }
66 if len(keys) > 0 { 95 if len(keys) > 0 {
67 t.Errorf("got %d keys, want 0", len(keys)) 96 t.Errorf("got %d keys, want 0", len(keys))
68 } 97 }
69 » if err := ac.insert(rsaKey, "comment"); err != nil { 98 » if err := agent.Insert(rawRSAKey, "comment"); err != nil {
70 t.Fatalf("insert: %v", err) 99 t.Fatalf("insert: %v", err)
71 } 100 }
72 » if keys, _ := ac.RequestIdentities(); len(keys) != 1 || keys[0].Comment != "comment" { 101 » if keys, _ := agent.List(); len(keys) != 1 || keys[0].Comment != "commen t" {
73 t.Fatalf("got %v, want 1 key with comment `comment`", keys) 102 t.Fatalf("got %v, want 1 key with comment `comment`", keys)
74 } 103 }
75 data := []byte("hello") 104 data := []byte("hello")
76 » sigBytes, err := ac.SignRequest(rsaKey.PublicKey(), data) 105 » sigBytes, err := agent.Sign(rsaKey.PublicKey(), data)
77 if err != nil { 106 if err != nil {
78 » » t.Fatalf("SignRequest: %v", err) 107 » » t.Fatalf("Sign: %v", err)
79 } 108 }
80 » sig, _, ok := parseSignatureBody(sigBytes) 109
81 » if !ok { 110 » type Sig struct {
82 » » t.Fatalf("parseSignatureBody(%q) failed", sig) 111 » » Algo string
112 » » Blob []byte
83 } 113 }
114 sig := Sig{}
115 if err := ssh.Unmarshal(sigBytes, &sig); err != nil {
116 t.Fatalf("parseSignatureBody(%q) failed", sigBytes)
117 }
118
84 if !rsaKey.PublicKey().Verify(data, sig.Blob) { 119 if !rsaKey.PublicKey().Verify(data, sig.Blob) {
85 t.Fatalf("key signature does not validate") 120 t.Fatalf("key signature does not validate")
86 } 121 }
87 } 122 }
123
124 // netPipe is analogous to net.Pipe, but it uses a real net.Conn, and
125 // therefore is buffered (net.Pipe deadlocks if both sides start with
126 // a write.)
127 func netPipe() (net.Conn, net.Conn, error) {
128 listener, err := net.Listen("tcp", "127.0.0.1:0")
129 if err != nil {
130 return nil, nil, err
131 }
132 defer listener.Close()
133 c1, err := net.Dial("tcp", listener.Addr().String())
134 if err != nil {
135 return nil, nil, err
136 }
137
138 c2, err := listener.Accept()
139 if err != nil {
140 c1.Close()
141 return nil, nil, err
142 }
143
144 return c1, c2, nil
145 }
146
147 func TestAuth(t *testing.T) {
148 a, b, err := netPipe()
149 if err != nil {
150 t.Fatalf("netPipe: %v", err)
151 }
152
153 defer a.Close()
154 defer b.Close()
155
156 agent, cleanup := startAgent(t)
157 defer cleanup()
158
159 if err := agent.Insert(rawRSAKey, "comment"); err != nil {
160 t.Errorf("Insert: %v", err)
161 }
162
163 serverConf := ssh.ServerConfig{}
164 serverConf.AddHostKey(rsaKey)
165 serverConf.PublicKeyCallback = func(c ssh.ConnMetadata, algo string, pub key []byte) bool {
166 return bytes.Equal(pubkey, ssh.MarshalPublicKey(rsaKey.PublicKey ()))
167 }
168
169 go func() {
170 _, err := ssh.Server(a, &serverConf)
171 if err != nil {
172 t.Fatalf("Server: %v", err)
173 }
174 }()
175
176 conf := ssh.ClientConfig{}
177 conf.Auth = append(conf.Auth, ssh.ClientAuthKeyring(agent))
178 if _, err := ssh.Client(b, &conf); err != nil {
179 t.Fatalf("Client: %v", err)
180 }
181 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b