github.com/deis/deis@v1.13.5-0.20170519182049-1d9e59fbdbfc/Godeps/_workspace/src/golang.org/x/crypto/ssh/test/session_test.go (about) 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 284 for _, ciph := range cipherOrder { 285 server := newServer(t) 286 defer server.Shutdown() 287 conf := clientConfig() 288 conf.Ciphers = []string{ciph} 289 // Don't fail if sshd doesnt have the cipher. 290 conf.Ciphers = append(conf.Ciphers, cipherOrder...) 291 conn, err := server.TryDial(conf) 292 if err == nil { 293 conn.Close() 294 } else { 295 t.Fatalf("failed for cipher %q", ciph) 296 } 297 } 298 } 299 300 func TestMACs(t *testing.T) { 301 var config ssh.Config 302 config.SetDefaults() 303 macOrder := config.MACs 304 305 for _, mac := range macOrder { 306 server := newServer(t) 307 defer server.Shutdown() 308 conf := clientConfig() 309 conf.MACs = []string{mac} 310 // Don't fail if sshd doesnt have the MAC. 311 conf.MACs = append(conf.MACs, macOrder...) 312 if conn, err := server.TryDial(conf); err == nil { 313 conn.Close() 314 } else { 315 t.Fatalf("failed for MAC %q", mac) 316 } 317 } 318 }