OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / crypto / ssh / test / session_test.go
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.
4
5 // +build !windows
6
7 package test
8
9 // Session functional tests.
10
11 import (
12         "bytes"
13         "errors"
14         "io"
15         "strings"
16         "testing"
17
18         "golang.org/x/crypto/ssh"
19 )
20
21 func TestRunCommandSuccess(t *testing.T) {
22         server := newServer(t)
23         defer server.Shutdown()
24         conn := server.Dial(clientConfig())
25         defer conn.Close()
26
27         session, err := conn.NewSession()
28         if err != nil {
29                 t.Fatalf("session failed: %v", err)
30         }
31         defer session.Close()
32         err = session.Run("true")
33         if err != nil {
34                 t.Fatalf("session failed: %v", err)
35         }
36 }
37
38 func TestHostKeyCheck(t *testing.T) {
39         server := newServer(t)
40         defer server.Shutdown()
41
42         conf := clientConfig()
43         hostDB := hostKeyDB()
44         conf.HostKeyCallback = hostDB.Check
45
46         // change the keys.
47         hostDB.keys[ssh.KeyAlgoRSA][25]++
48         hostDB.keys[ssh.KeyAlgoDSA][25]++
49         hostDB.keys[ssh.KeyAlgoECDSA256][25]++
50
51         conn, err := server.TryDial(conf)
52         if err == nil {
53                 conn.Close()
54                 t.Fatalf("dial should have failed.")
55         } else if !strings.Contains(err.Error(), "host key mismatch") {
56                 t.Fatalf("'host key mismatch' not found in %v", err)
57         }
58 }
59
60 func TestRunCommandStdin(t *testing.T) {
61         server := newServer(t)
62         defer server.Shutdown()
63         conn := server.Dial(clientConfig())
64         defer conn.Close()
65
66         session, err := conn.NewSession()
67         if err != nil {
68                 t.Fatalf("session failed: %v", err)
69         }
70         defer session.Close()
71
72         r, w := io.Pipe()
73         defer r.Close()
74         defer w.Close()
75         session.Stdin = r
76
77         err = session.Run("true")
78         if err != nil {
79                 t.Fatalf("session failed: %v", err)
80         }
81 }
82
83 func TestRunCommandStdinError(t *testing.T) {
84         server := newServer(t)
85         defer server.Shutdown()
86         conn := server.Dial(clientConfig())
87         defer conn.Close()
88
89         session, err := conn.NewSession()
90         if err != nil {
91                 t.Fatalf("session failed: %v", err)
92         }
93         defer session.Close()
94
95         r, w := io.Pipe()
96         defer r.Close()
97         session.Stdin = r
98         pipeErr := errors.New("closing write end of pipe")
99         w.CloseWithError(pipeErr)
100
101         err = session.Run("true")
102         if err != pipeErr {
103                 t.Fatalf("expected %v, found %v", pipeErr, err)
104         }
105 }
106
107 func TestRunCommandFailed(t *testing.T) {
108         server := newServer(t)
109         defer server.Shutdown()
110         conn := server.Dial(clientConfig())
111         defer conn.Close()
112
113         session, err := conn.NewSession()
114         if err != nil {
115                 t.Fatalf("session failed: %v", err)
116         }
117         defer session.Close()
118         err = session.Run(`bash -c "kill -9 $$"`)
119         if err == nil {
120                 t.Fatalf("session succeeded: %v", err)
121         }
122 }
123
124 func TestRunCommandWeClosed(t *testing.T) {
125         server := newServer(t)
126         defer server.Shutdown()
127         conn := server.Dial(clientConfig())
128         defer conn.Close()
129
130         session, err := conn.NewSession()
131         if err != nil {
132                 t.Fatalf("session failed: %v", err)
133         }
134         err = session.Shell()
135         if err != nil {
136                 t.Fatalf("shell failed: %v", err)
137         }
138         err = session.Close()
139         if err != nil {
140                 t.Fatalf("shell failed: %v", err)
141         }
142 }
143
144 func TestFuncLargeRead(t *testing.T) {
145         server := newServer(t)
146         defer server.Shutdown()
147         conn := server.Dial(clientConfig())
148         defer conn.Close()
149
150         session, err := conn.NewSession()
151         if err != nil {
152                 t.Fatalf("unable to create new session: %s", err)
153         }
154
155         stdout, err := session.StdoutPipe()
156         if err != nil {
157                 t.Fatalf("unable to acquire stdout pipe: %s", err)
158         }
159
160         err = session.Start("dd if=/dev/urandom bs=2048 count=1024")
161         if err != nil {
162                 t.Fatalf("unable to execute remote command: %s", err)
163         }
164
165         buf := new(bytes.Buffer)
166         n, err := io.Copy(buf, stdout)
167         if err != nil {
168                 t.Fatalf("error reading from remote stdout: %s", err)
169         }
170
171         if n != 2048*1024 {
172                 t.Fatalf("Expected %d bytes but read only %d from remote command", 2048, n)
173         }
174 }
175
176 func TestKeyChange(t *testing.T) {
177         server := newServer(t)
178         defer server.Shutdown()
179         conf := clientConfig()
180         hostDB := hostKeyDB()
181         conf.HostKeyCallback = hostDB.Check
182         conf.RekeyThreshold = 1024
183         conn := server.Dial(conf)
184         defer conn.Close()
185
186         for i := 0; i < 4; i++ {
187                 session, err := conn.NewSession()
188                 if err != nil {
189                         t.Fatalf("unable to create new session: %s", err)
190                 }
191
192                 stdout, err := session.StdoutPipe()
193                 if err != nil {
194                         t.Fatalf("unable to acquire stdout pipe: %s", err)
195                 }
196
197                 err = session.Start("dd if=/dev/urandom bs=1024 count=1")
198                 if err != nil {
199                         t.Fatalf("unable to execute remote command: %s", err)
200                 }
201                 buf := new(bytes.Buffer)
202                 n, err := io.Copy(buf, stdout)
203                 if err != nil {
204                         t.Fatalf("error reading from remote stdout: %s", err)
205                 }
206
207                 want := int64(1024)
208                 if n != want {
209                         t.Fatalf("Expected %d bytes but read only %d from remote command", want, n)
210                 }
211         }
212
213         if changes := hostDB.checkCount; changes < 4 {
214                 t.Errorf("got %d key changes, want 4", changes)
215         }
216 }
217
218 func TestInvalidTerminalMode(t *testing.T) {
219         server := newServer(t)
220         defer server.Shutdown()
221         conn := server.Dial(clientConfig())
222         defer conn.Close()
223
224         session, err := conn.NewSession()
225         if err != nil {
226                 t.Fatalf("session failed: %v", err)
227         }
228         defer session.Close()
229
230         if err = session.RequestPty("vt100", 80, 40, ssh.TerminalModes{255: 1984}); err == nil {
231                 t.Fatalf("req-pty failed: successful request with invalid mode")
232         }
233 }
234
235 func TestValidTerminalMode(t *testing.T) {
236         server := newServer(t)
237         defer server.Shutdown()
238         conn := server.Dial(clientConfig())
239         defer conn.Close()
240
241         session, err := conn.NewSession()
242         if err != nil {
243                 t.Fatalf("session failed: %v", err)
244         }
245         defer session.Close()
246
247         stdout, err := session.StdoutPipe()
248         if err != nil {
249                 t.Fatalf("unable to acquire stdout pipe: %s", err)
250         }
251
252         stdin, err := session.StdinPipe()
253         if err != nil {
254                 t.Fatalf("unable to acquire stdin pipe: %s", err)
255         }
256
257         tm := ssh.TerminalModes{ssh.ECHO: 0}
258         if err = session.RequestPty("xterm", 80, 40, tm); err != nil {
259                 t.Fatalf("req-pty failed: %s", err)
260         }
261
262         err = session.Shell()
263         if err != nil {
264                 t.Fatalf("session failed: %s", err)
265         }
266
267         stdin.Write([]byte("stty -a && exit\n"))
268
269         var buf bytes.Buffer
270         if _, err := io.Copy(&buf, stdout); err != nil {
271                 t.Fatalf("reading failed: %s", err)
272         }
273
274         if sttyOutput := buf.String(); !strings.Contains(sttyOutput, "-echo ") {
275                 t.Fatalf("terminal mode failure: expected -echo in stty output, got %s", sttyOutput)
276         }
277 }
278
279 func TestCiphers(t *testing.T) {
280         var config ssh.Config
281         config.SetDefaults()
282         cipherOrder := config.Ciphers
283         // These ciphers will not be tested when commented out in cipher.go it will
284         // fallback to the next available as per line 292.
285         cipherOrder = append(cipherOrder, "aes128-cbc", "3des-cbc")
286
287         for _, ciph := range cipherOrder {
288                 server := newServer(t)
289                 defer server.Shutdown()
290                 conf := clientConfig()
291                 conf.Ciphers = []string{ciph}
292                 // Don't fail if sshd doesn't have the cipher.
293                 conf.Ciphers = append(conf.Ciphers, cipherOrder...)
294                 conn, err := server.TryDial(conf)
295                 if err == nil {
296                         conn.Close()
297                 } else {
298                         t.Fatalf("failed for cipher %q", ciph)
299                 }
300         }
301 }
302
303 func TestMACs(t *testing.T) {
304         var config ssh.Config
305         config.SetDefaults()
306         macOrder := config.MACs
307
308         for _, mac := range macOrder {
309                 server := newServer(t)
310                 defer server.Shutdown()
311                 conf := clientConfig()
312                 conf.MACs = []string{mac}
313                 // Don't fail if sshd doesn't have the MAC.
314                 conf.MACs = append(conf.MACs, macOrder...)
315                 if conn, err := server.TryDial(conf); err == nil {
316                         conn.Close()
317                 } else {
318                         t.Fatalf("failed for MAC %q", mac)
319                 }
320         }
321 }
322
323 func TestKeyExchanges(t *testing.T) {
324         var config ssh.Config
325         config.SetDefaults()
326         kexOrder := config.KeyExchanges
327         for _, kex := range kexOrder {
328                 server := newServer(t)
329                 defer server.Shutdown()
330                 conf := clientConfig()
331                 // Don't fail if sshd doesn't have the kex.
332                 conf.KeyExchanges = append([]string{kex}, kexOrder...)
333                 conn, err := server.TryDial(conf)
334                 if err == nil {
335                         conn.Close()
336                 } else {
337                         t.Errorf("failed for kex %q", kex)
338                 }
339         }
340 }
341
342 func TestClientAuthAlgorithms(t *testing.T) {
343         for _, key := range []string{
344                 "rsa",
345                 "dsa",
346                 "ecdsa",
347                 "ed25519",
348         } {
349                 server := newServer(t)
350                 conf := clientConfig()
351                 conf.SetDefaults()
352                 conf.Auth = []ssh.AuthMethod{
353                         ssh.PublicKeys(testSigners[key]),
354                 }
355
356                 conn, err := server.TryDial(conf)
357                 if err == nil {
358                         conn.Close()
359                 } else {
360                         t.Errorf("failed for key %q", key)
361                 }
362
363                 server.Shutdown()
364         }
365 }