session_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. // Copyright 2011 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. package ssh
  5. // Session tests.
  6. import (
  7. "bytes"
  8. "io"
  9. "io/ioutil"
  10. "net"
  11. "testing"
  12. "code.google.com/p/go.crypto/ssh/terminal"
  13. )
  14. type serverType func(*serverChan, *testing.T)
  15. // dial constructs a new test server and returns a *ClientConn.
  16. func dial(handler serverType, t *testing.T) *ClientConn {
  17. pw := password("tiger")
  18. serverConfig.PasswordCallback = func(conn *ServerConn, user, pass string) bool {
  19. return user == "testuser" && pass == string(pw)
  20. }
  21. serverConfig.PublicKeyCallback = nil
  22. l, err := Listen("tcp", "127.0.0.1:0", serverConfig)
  23. if err != nil {
  24. t.Fatalf("unable to listen: %v", err)
  25. }
  26. go func() {
  27. defer l.Close()
  28. conn, err := l.Accept()
  29. if err != nil {
  30. t.Errorf("Unable to accept: %v", err)
  31. return
  32. }
  33. defer conn.Close()
  34. if err := conn.Handshake(); err != nil {
  35. t.Errorf("Unable to handshake: %v", err)
  36. return
  37. }
  38. for {
  39. ch, err := conn.Accept()
  40. if err == io.EOF {
  41. return
  42. }
  43. // We sometimes get ECONNRESET rather than EOF.
  44. if _, ok := err.(*net.OpError); ok {
  45. return
  46. }
  47. if err != nil {
  48. t.Errorf("Unable to accept incoming channel request: %v", err)
  49. return
  50. }
  51. if ch.ChannelType() != "session" {
  52. ch.Reject(UnknownChannelType, "unknown channel type")
  53. continue
  54. }
  55. ch.Accept()
  56. go handler(ch.(*serverChan), t)
  57. }
  58. t.Log("done")
  59. }()
  60. config := &ClientConfig{
  61. User: "testuser",
  62. Auth: []ClientAuth{
  63. ClientAuthPassword(pw),
  64. },
  65. }
  66. c, err := Dial("tcp", l.Addr().String(), config)
  67. if err != nil {
  68. t.Fatalf("unable to dial remote side: %v", err)
  69. }
  70. return c
  71. }
  72. // Test a simple string is returned to session.Stdout.
  73. func TestSessionShell(t *testing.T) {
  74. conn := dial(shellHandler, t)
  75. defer conn.Close()
  76. session, err := conn.NewSession()
  77. if err != nil {
  78. t.Fatalf("Unable to request new session: %v", err)
  79. }
  80. defer session.Close()
  81. stdout := new(bytes.Buffer)
  82. session.Stdout = stdout
  83. if err := session.Shell(); err != nil {
  84. t.Fatalf("Unable to execute command: %s", err)
  85. }
  86. if err := session.Wait(); err != nil {
  87. t.Fatalf("Remote command did not exit cleanly: %v", err)
  88. }
  89. actual := stdout.String()
  90. if actual != "golang" {
  91. t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual)
  92. }
  93. }
  94. // TODO(dfc) add support for Std{in,err}Pipe when the Server supports it.
  95. // Test a simple string is returned via StdoutPipe.
  96. func TestSessionStdoutPipe(t *testing.T) {
  97. conn := dial(shellHandler, t)
  98. defer conn.Close()
  99. session, err := conn.NewSession()
  100. if err != nil {
  101. t.Fatalf("Unable to request new session: %v", err)
  102. }
  103. defer session.Close()
  104. stdout, err := session.StdoutPipe()
  105. if err != nil {
  106. t.Fatalf("Unable to request StdoutPipe(): %v", err)
  107. }
  108. var buf bytes.Buffer
  109. if err := session.Shell(); err != nil {
  110. t.Fatalf("Unable to execute command: %v", err)
  111. }
  112. done := make(chan bool, 1)
  113. go func() {
  114. if _, err := io.Copy(&buf, stdout); err != nil {
  115. t.Errorf("Copy of stdout failed: %v", err)
  116. }
  117. done <- true
  118. }()
  119. if err := session.Wait(); err != nil {
  120. t.Fatalf("Remote command did not exit cleanly: %v", err)
  121. }
  122. <-done
  123. actual := buf.String()
  124. if actual != "golang" {
  125. t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual)
  126. }
  127. }
  128. // Test non-0 exit status is returned correctly.
  129. func TestExitStatusNonZero(t *testing.T) {
  130. conn := dial(exitStatusNonZeroHandler, t)
  131. defer conn.Close()
  132. session, err := conn.NewSession()
  133. if err != nil {
  134. t.Fatalf("Unable to request new session: %v", err)
  135. }
  136. defer session.Close()
  137. if err := session.Shell(); err != nil {
  138. t.Fatalf("Unable to execute command: %v", err)
  139. }
  140. err = session.Wait()
  141. if err == nil {
  142. t.Fatalf("expected command to fail but it didn't")
  143. }
  144. e, ok := err.(*ExitError)
  145. if !ok {
  146. t.Fatalf("expected *ExitError but got %T", err)
  147. }
  148. if e.ExitStatus() != 15 {
  149. t.Fatalf("expected command to exit with 15 but got %v", e.ExitStatus())
  150. }
  151. }
  152. // Test 0 exit status is returned correctly.
  153. func TestExitStatusZero(t *testing.T) {
  154. conn := dial(exitStatusZeroHandler, t)
  155. defer conn.Close()
  156. session, err := conn.NewSession()
  157. if err != nil {
  158. t.Fatalf("Unable to request new session: %v", err)
  159. }
  160. defer session.Close()
  161. if err := session.Shell(); err != nil {
  162. t.Fatalf("Unable to execute command: %v", err)
  163. }
  164. err = session.Wait()
  165. if err != nil {
  166. t.Fatalf("expected nil but got %v", err)
  167. }
  168. }
  169. // Test exit signal and status are both returned correctly.
  170. func TestExitSignalAndStatus(t *testing.T) {
  171. conn := dial(exitSignalAndStatusHandler, t)
  172. defer conn.Close()
  173. session, err := conn.NewSession()
  174. if err != nil {
  175. t.Fatalf("Unable to request new session: %v", err)
  176. }
  177. defer session.Close()
  178. if err := session.Shell(); err != nil {
  179. t.Fatalf("Unable to execute command: %v", err)
  180. }
  181. err = session.Wait()
  182. if err == nil {
  183. t.Fatalf("expected command to fail but it didn't")
  184. }
  185. e, ok := err.(*ExitError)
  186. if !ok {
  187. t.Fatalf("expected *ExitError but got %T", err)
  188. }
  189. if e.Signal() != "TERM" || e.ExitStatus() != 15 {
  190. t.Fatalf("expected command to exit with signal TERM and status 15 but got signal %s and status %v", e.Signal(), e.ExitStatus())
  191. }
  192. }
  193. // Test exit signal and status are both returned correctly.
  194. func TestKnownExitSignalOnly(t *testing.T) {
  195. conn := dial(exitSignalHandler, t)
  196. defer conn.Close()
  197. session, err := conn.NewSession()
  198. if err != nil {
  199. t.Fatalf("Unable to request new session: %v", err)
  200. }
  201. defer session.Close()
  202. if err := session.Shell(); err != nil {
  203. t.Fatalf("Unable to execute command: %v", err)
  204. }
  205. err = session.Wait()
  206. if err == nil {
  207. t.Fatalf("expected command to fail but it didn't")
  208. }
  209. e, ok := err.(*ExitError)
  210. if !ok {
  211. t.Fatalf("expected *ExitError but got %T", err)
  212. }
  213. if e.Signal() != "TERM" || e.ExitStatus() != 143 {
  214. t.Fatalf("expected command to exit with signal TERM and status 143 but got signal %s and status %v", e.Signal(), e.ExitStatus())
  215. }
  216. }
  217. // Test exit signal and status are both returned correctly.
  218. func TestUnknownExitSignal(t *testing.T) {
  219. conn := dial(exitSignalUnknownHandler, t)
  220. defer conn.Close()
  221. session, err := conn.NewSession()
  222. if err != nil {
  223. t.Fatalf("Unable to request new session: %v", err)
  224. }
  225. defer session.Close()
  226. if err := session.Shell(); err != nil {
  227. t.Fatalf("Unable to execute command: %v", err)
  228. }
  229. err = session.Wait()
  230. if err == nil {
  231. t.Fatalf("expected command to fail but it didn't")
  232. }
  233. e, ok := err.(*ExitError)
  234. if !ok {
  235. t.Fatalf("expected *ExitError but got %T", err)
  236. }
  237. if e.Signal() != "SYS" || e.ExitStatus() != 128 {
  238. t.Fatalf("expected command to exit with signal SYS and status 128 but got signal %s and status %v", e.Signal(), e.ExitStatus())
  239. }
  240. }
  241. // Test WaitMsg is not returned if the channel closes abruptly.
  242. func TestExitWithoutStatusOrSignal(t *testing.T) {
  243. conn := dial(exitWithoutSignalOrStatus, t)
  244. defer conn.Close()
  245. session, err := conn.NewSession()
  246. if err != nil {
  247. t.Fatalf("Unable to request new session: %v", err)
  248. }
  249. defer session.Close()
  250. if err := session.Shell(); err != nil {
  251. t.Fatalf("Unable to execute command: %v", err)
  252. }
  253. err = session.Wait()
  254. if err == nil {
  255. t.Fatalf("expected command to fail but it didn't")
  256. }
  257. _, ok := err.(*ExitError)
  258. if ok {
  259. // you can't actually test for errors.errorString
  260. // because it's not exported.
  261. t.Fatalf("expected *errorString but got %T", err)
  262. }
  263. }
  264. func TestInvalidServerMessage(t *testing.T) {
  265. conn := dial(sendInvalidRecord, t)
  266. defer conn.Close()
  267. session, err := conn.NewSession()
  268. if err != nil {
  269. t.Fatalf("Unable to request new session: %v", err)
  270. }
  271. // Make sure that we closed all the clientChans when the connection
  272. // failed.
  273. session.wait()
  274. defer session.Close()
  275. }
  276. // In the wild some clients (and servers) send zero sized window updates.
  277. // Test that the client can continue after receiving a zero sized update.
  278. func TestClientZeroWindowAdjust(t *testing.T) {
  279. conn := dial(sendZeroWindowAdjust, t)
  280. defer conn.Close()
  281. session, err := conn.NewSession()
  282. if err != nil {
  283. t.Fatalf("Unable to request new session: %v", err)
  284. }
  285. defer session.Close()
  286. if err := session.Shell(); err != nil {
  287. t.Fatalf("Unable to execute command: %v", err)
  288. }
  289. err = session.Wait()
  290. if err != nil {
  291. t.Fatalf("expected nil but got %v", err)
  292. }
  293. }
  294. // In the wild some clients (and servers) send zero sized window updates.
  295. // Test that the server can continue after receiving a zero size update.
  296. func TestServerZeroWindowAdjust(t *testing.T) {
  297. conn := dial(exitStatusZeroHandler, t)
  298. defer conn.Close()
  299. session, err := conn.NewSession()
  300. if err != nil {
  301. t.Fatalf("Unable to request new session: %v", err)
  302. }
  303. defer session.Close()
  304. if err := session.Shell(); err != nil {
  305. t.Fatalf("Unable to execute command: %v", err)
  306. }
  307. // send a bogus zero sized window update
  308. session.clientChan.sendWindowAdj(0)
  309. err = session.Wait()
  310. if err != nil {
  311. t.Fatalf("expected nil but got %v", err)
  312. }
  313. }
  314. // Verify that the client never sends a packet larger than maxpacket.
  315. func TestClientStdinRespectsMaxPacketSize(t *testing.T) {
  316. conn := dial(discardHandler, t)
  317. defer conn.Close()
  318. session, err := conn.NewSession()
  319. if err != nil {
  320. t.Fatalf("Unable to request new session: %v", err)
  321. }
  322. defer session.Close()
  323. if err := session.Shell(); err != nil {
  324. t.Fatalf("Unable to execute command: %v", err)
  325. }
  326. // try to stuff 128k of data into a 32k hole.
  327. const size = 128 * 1024
  328. n, err := session.clientChan.stdin.Write(make([]byte, size))
  329. if n != size || err != nil {
  330. t.Fatalf("failed to write: %d, %v", n, err)
  331. }
  332. }
  333. // Verify that the client never accepts a packet larger than maxpacket.
  334. func TestServerStdoutRespectsMaxPacketSize(t *testing.T) {
  335. conn := dial(largeSendHandler, t)
  336. defer conn.Close()
  337. session, err := conn.NewSession()
  338. if err != nil {
  339. t.Fatalf("Unable to request new session: %v", err)
  340. }
  341. defer session.Close()
  342. out, err := session.StdoutPipe()
  343. if err != nil {
  344. t.Fatalf("Unable to connect to Stdout: %v", err)
  345. }
  346. if err := session.Shell(); err != nil {
  347. t.Fatalf("Unable to execute command: %v", err)
  348. }
  349. if _, err := ioutil.ReadAll(out); err != nil {
  350. t.Fatalf("failed to read: %v", err)
  351. }
  352. }
  353. // TODO(dfc) currently writes succeed after Close()
  354. func testClientCannotSendAfterEOF(t *testing.T) {
  355. conn := dial(shellHandler, t)
  356. defer conn.Close()
  357. session, err := conn.NewSession()
  358. if err != nil {
  359. t.Fatalf("Unable to request new session: %v", err)
  360. }
  361. defer session.Close()
  362. in, err := session.StdinPipe()
  363. if err != nil {
  364. t.Fatalf("Unable to connect channel stdin: %v", err)
  365. }
  366. if err := session.Shell(); err != nil {
  367. t.Fatalf("Unable to execute command: %v", err)
  368. }
  369. if err := in.Close(); err != nil {
  370. t.Fatalf("Unable to close stdin: %v", err)
  371. }
  372. if _, err := in.Write([]byte("foo")); err == nil {
  373. t.Fatalf("Session write should fail")
  374. }
  375. }
  376. func TestClientCannotSendAfterClose(t *testing.T) {
  377. conn := dial(shellHandler, t)
  378. defer conn.Close()
  379. session, err := conn.NewSession()
  380. if err != nil {
  381. t.Fatalf("Unable to request new session: %v", err)
  382. }
  383. defer session.Close()
  384. in, err := session.StdinPipe()
  385. if err != nil {
  386. t.Fatalf("Unable to connect channel stdin: %v", err)
  387. }
  388. if err := session.Shell(); err != nil {
  389. t.Fatalf("Unable to execute command: %v", err)
  390. }
  391. // close underlying channel
  392. if err := session.channel.Close(); err != nil {
  393. t.Fatalf("Unable to close session: %v", err)
  394. }
  395. if _, err := in.Write([]byte("foo")); err == nil {
  396. t.Fatalf("Session write should fail")
  397. }
  398. }
  399. type exitStatusMsg struct {
  400. PeersId uint32
  401. Request string
  402. WantReply bool
  403. Status uint32
  404. }
  405. type exitSignalMsg struct {
  406. PeersId uint32
  407. Request string
  408. WantReply bool
  409. Signal string
  410. CoreDumped bool
  411. Errmsg string
  412. Lang string
  413. }
  414. func newServerShell(ch *serverChan, prompt string) *ServerTerminal {
  415. term := terminal.NewTerminal(ch, prompt)
  416. return &ServerTerminal{
  417. Term: term,
  418. Channel: ch,
  419. }
  420. }
  421. func exitStatusZeroHandler(ch *serverChan, t *testing.T) {
  422. defer ch.Close()
  423. // this string is returned to stdout
  424. shell := newServerShell(ch, "> ")
  425. shell.ReadLine()
  426. sendStatus(0, ch, t)
  427. }
  428. func exitStatusNonZeroHandler(ch *serverChan, t *testing.T) {
  429. defer ch.Close()
  430. shell := newServerShell(ch, "> ")
  431. shell.ReadLine()
  432. sendStatus(15, ch, t)
  433. }
  434. func exitSignalAndStatusHandler(ch *serverChan, t *testing.T) {
  435. defer ch.Close()
  436. shell := newServerShell(ch, "> ")
  437. shell.ReadLine()
  438. sendStatus(15, ch, t)
  439. sendSignal("TERM", ch, t)
  440. }
  441. func exitSignalHandler(ch *serverChan, t *testing.T) {
  442. defer ch.Close()
  443. shell := newServerShell(ch, "> ")
  444. shell.ReadLine()
  445. sendSignal("TERM", ch, t)
  446. }
  447. func exitSignalUnknownHandler(ch *serverChan, t *testing.T) {
  448. defer ch.Close()
  449. shell := newServerShell(ch, "> ")
  450. shell.ReadLine()
  451. sendSignal("SYS", ch, t)
  452. }
  453. func exitWithoutSignalOrStatus(ch *serverChan, t *testing.T) {
  454. defer ch.Close()
  455. shell := newServerShell(ch, "> ")
  456. shell.ReadLine()
  457. }
  458. func shellHandler(ch *serverChan, t *testing.T) {
  459. defer ch.Close()
  460. // this string is returned to stdout
  461. shell := newServerShell(ch, "golang")
  462. shell.ReadLine()
  463. sendStatus(0, ch, t)
  464. }
  465. func sendStatus(status uint32, ch *serverChan, t *testing.T) {
  466. msg := exitStatusMsg{
  467. PeersId: ch.remoteId,
  468. Request: "exit-status",
  469. WantReply: false,
  470. Status: status,
  471. }
  472. if err := ch.writePacket(marshal(msgChannelRequest, msg)); err != nil {
  473. t.Errorf("unable to send status: %v", err)
  474. }
  475. }
  476. func sendSignal(signal string, ch *serverChan, t *testing.T) {
  477. sig := exitSignalMsg{
  478. PeersId: ch.remoteId,
  479. Request: "exit-signal",
  480. WantReply: false,
  481. Signal: signal,
  482. CoreDumped: false,
  483. Errmsg: "Process terminated",
  484. Lang: "en-GB-oed",
  485. }
  486. if err := ch.writePacket(marshal(msgChannelRequest, sig)); err != nil {
  487. t.Errorf("unable to send signal: %v", err)
  488. }
  489. }
  490. func sendInvalidRecord(ch *serverChan, t *testing.T) {
  491. defer ch.Close()
  492. packet := make([]byte, 1+4+4+1)
  493. packet[0] = msgChannelData
  494. marshalUint32(packet[1:], 29348723 /* invalid channel id */)
  495. marshalUint32(packet[5:], 1)
  496. packet[9] = 42
  497. if err := ch.writePacket(packet); err != nil {
  498. t.Errorf("unable send invalid record: %v", err)
  499. }
  500. }
  501. func sendZeroWindowAdjust(ch *serverChan, t *testing.T) {
  502. defer ch.Close()
  503. // send a bogus zero sized window update
  504. ch.sendWindowAdj(0)
  505. shell := newServerShell(ch, "> ")
  506. shell.ReadLine()
  507. sendStatus(0, ch, t)
  508. }
  509. func discardHandler(ch *serverChan, t *testing.T) {
  510. defer ch.Close()
  511. // grow the window to avoid being fooled by
  512. // the initial 1 << 14 window.
  513. ch.sendWindowAdj(1024 * 1024)
  514. shell := newServerShell(ch, "> ")
  515. shell.ReadLine()
  516. io.Copy(ioutil.Discard, ch.serverConn)
  517. }
  518. func largeSendHandler(ch *serverChan, t *testing.T) {
  519. defer ch.Close()
  520. // grow the window to avoid being fooled by
  521. // the initial 1 << 14 window.
  522. ch.sendWindowAdj(1024 * 1024)
  523. shell := newServerShell(ch, "> ")
  524. shell.ReadLine()
  525. // try to send more than the 32k window
  526. // will allow
  527. if err := ch.writePacket(make([]byte, 128*1024)); err == nil {
  528. t.Errorf("wrote packet larger than 32k")
  529. }
  530. }