session_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  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. crypto_rand "crypto/rand"
  9. "io"
  10. "io/ioutil"
  11. "math/rand"
  12. "net"
  13. "testing"
  14. "code.google.com/p/go.crypto/ssh/terminal"
  15. )
  16. type serverType func(*serverChan, *testing.T)
  17. // dial constructs a new test server and returns a *ClientConn.
  18. func dial(handler serverType, t *testing.T) *ClientConn {
  19. l, err := Listen("tcp", "127.0.0.1:0", serverConfig)
  20. if err != nil {
  21. t.Fatalf("unable to listen: %v", err)
  22. }
  23. go func() {
  24. defer l.Close()
  25. conn, err := l.Accept()
  26. if err != nil {
  27. t.Errorf("Unable to accept: %v", err)
  28. return
  29. }
  30. defer conn.Close()
  31. if err := conn.Handshake(); err != nil {
  32. t.Errorf("Unable to handshake: %v", err)
  33. return
  34. }
  35. done := make(chan struct{})
  36. for {
  37. ch, err := conn.Accept()
  38. if err == io.EOF || err == io.ErrUnexpectedEOF {
  39. return
  40. }
  41. // We sometimes get ECONNRESET rather than EOF.
  42. if _, ok := err.(*net.OpError); ok {
  43. return
  44. }
  45. if err != nil {
  46. t.Errorf("Unable to accept incoming channel request: %v", err)
  47. return
  48. }
  49. if ch.ChannelType() != "session" {
  50. ch.Reject(UnknownChannelType, "unknown channel type")
  51. continue
  52. }
  53. ch.Accept()
  54. go func() {
  55. defer close(done)
  56. handler(ch.(*serverChan), t)
  57. }()
  58. }
  59. }()
  60. config := &ClientConfig{
  61. User: "testuser",
  62. Auth: []ClientAuth{
  63. ClientAuthPassword(clientPassword),
  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 that a simple string is returned via the Output helper,
  129. // and that stderr is discarded.
  130. func TestSessionOutput(t *testing.T) {
  131. conn := dial(fixedOutputHandler, t)
  132. defer conn.Close()
  133. session, err := conn.NewSession()
  134. if err != nil {
  135. t.Fatalf("Unable to request new session: %v", err)
  136. }
  137. defer session.Close()
  138. buf, err := session.Output("") // cmd is ignored by fixedOutputHandler
  139. if err != nil {
  140. t.Error("Remote command did not exit cleanly:", err)
  141. }
  142. w := "this-is-stdout."
  143. g := string(buf)
  144. if g != w {
  145. t.Error("Remote command did not return expected string:")
  146. t.Logf("want %q", w)
  147. t.Logf("got %q", g)
  148. }
  149. }
  150. // Test that both stdout and stderr are returned
  151. // via the CombinedOutput helper.
  152. func TestSessionCombinedOutput(t *testing.T) {
  153. conn := dial(fixedOutputHandler, t)
  154. defer conn.Close()
  155. session, err := conn.NewSession()
  156. if err != nil {
  157. t.Fatalf("Unable to request new session: %v", err)
  158. }
  159. defer session.Close()
  160. buf, err := session.CombinedOutput("") // cmd is ignored by fixedOutputHandler
  161. if err != nil {
  162. t.Error("Remote command did not exit cleanly:", err)
  163. }
  164. const stdout = "this-is-stdout."
  165. const stderr = "this-is-stderr."
  166. g := string(buf)
  167. if g != stdout+stderr && g != stderr+stdout {
  168. t.Error("Remote command did not return expected string:")
  169. t.Logf("want %q, or %q", stdout+stderr, stderr+stdout)
  170. t.Logf("got %q", g)
  171. }
  172. }
  173. // Test non-0 exit status is returned correctly.
  174. func TestExitStatusNonZero(t *testing.T) {
  175. conn := dial(exitStatusNonZeroHandler, t)
  176. defer conn.Close()
  177. session, err := conn.NewSession()
  178. if err != nil {
  179. t.Fatalf("Unable to request new session: %v", err)
  180. }
  181. defer session.Close()
  182. if err := session.Shell(); err != nil {
  183. t.Fatalf("Unable to execute command: %v", err)
  184. }
  185. err = session.Wait()
  186. if err == nil {
  187. t.Fatalf("expected command to fail but it didn't")
  188. }
  189. e, ok := err.(*ExitError)
  190. if !ok {
  191. t.Fatalf("expected *ExitError but got %T", err)
  192. }
  193. if e.ExitStatus() != 15 {
  194. t.Fatalf("expected command to exit with 15 but got %v", e.ExitStatus())
  195. }
  196. }
  197. // Test 0 exit status is returned correctly.
  198. func TestExitStatusZero(t *testing.T) {
  199. conn := dial(exitStatusZeroHandler, t)
  200. defer conn.Close()
  201. session, err := conn.NewSession()
  202. if err != nil {
  203. t.Fatalf("Unable to request new session: %v", err)
  204. }
  205. defer session.Close()
  206. if err := session.Shell(); err != nil {
  207. t.Fatalf("Unable to execute command: %v", err)
  208. }
  209. err = session.Wait()
  210. if err != nil {
  211. t.Fatalf("expected nil but got %v", err)
  212. }
  213. }
  214. // Test exit signal and status are both returned correctly.
  215. func TestExitSignalAndStatus(t *testing.T) {
  216. conn := dial(exitSignalAndStatusHandler, t)
  217. defer conn.Close()
  218. session, err := conn.NewSession()
  219. if err != nil {
  220. t.Fatalf("Unable to request new session: %v", err)
  221. }
  222. defer session.Close()
  223. if err := session.Shell(); err != nil {
  224. t.Fatalf("Unable to execute command: %v", err)
  225. }
  226. err = session.Wait()
  227. if err == nil {
  228. t.Fatalf("expected command to fail but it didn't")
  229. }
  230. e, ok := err.(*ExitError)
  231. if !ok {
  232. t.Fatalf("expected *ExitError but got %T", err)
  233. }
  234. if e.Signal() != "TERM" || e.ExitStatus() != 15 {
  235. t.Fatalf("expected command to exit with signal TERM and status 15 but got signal %s and status %v", e.Signal(), e.ExitStatus())
  236. }
  237. }
  238. // Test exit signal and status are both returned correctly.
  239. func TestKnownExitSignalOnly(t *testing.T) {
  240. conn := dial(exitSignalHandler, t)
  241. defer conn.Close()
  242. session, err := conn.NewSession()
  243. if err != nil {
  244. t.Fatalf("Unable to request new session: %v", err)
  245. }
  246. defer session.Close()
  247. if err := session.Shell(); err != nil {
  248. t.Fatalf("Unable to execute command: %v", err)
  249. }
  250. err = session.Wait()
  251. if err == nil {
  252. t.Fatalf("expected command to fail but it didn't")
  253. }
  254. e, ok := err.(*ExitError)
  255. if !ok {
  256. t.Fatalf("expected *ExitError but got %T", err)
  257. }
  258. if e.Signal() != "TERM" || e.ExitStatus() != 143 {
  259. t.Fatalf("expected command to exit with signal TERM and status 143 but got signal %s and status %v", e.Signal(), e.ExitStatus())
  260. }
  261. }
  262. // Test exit signal and status are both returned correctly.
  263. func TestUnknownExitSignal(t *testing.T) {
  264. conn := dial(exitSignalUnknownHandler, t)
  265. defer conn.Close()
  266. session, err := conn.NewSession()
  267. if err != nil {
  268. t.Fatalf("Unable to request new session: %v", err)
  269. }
  270. defer session.Close()
  271. if err := session.Shell(); err != nil {
  272. t.Fatalf("Unable to execute command: %v", err)
  273. }
  274. err = session.Wait()
  275. if err == nil {
  276. t.Fatalf("expected command to fail but it didn't")
  277. }
  278. e, ok := err.(*ExitError)
  279. if !ok {
  280. t.Fatalf("expected *ExitError but got %T", err)
  281. }
  282. if e.Signal() != "SYS" || e.ExitStatus() != 128 {
  283. t.Fatalf("expected command to exit with signal SYS and status 128 but got signal %s and status %v", e.Signal(), e.ExitStatus())
  284. }
  285. }
  286. // Test WaitMsg is not returned if the channel closes abruptly.
  287. func TestExitWithoutStatusOrSignal(t *testing.T) {
  288. conn := dial(exitWithoutSignalOrStatus, t)
  289. defer conn.Close()
  290. session, err := conn.NewSession()
  291. if err != nil {
  292. t.Fatalf("Unable to request new session: %v", err)
  293. }
  294. defer session.Close()
  295. if err := session.Shell(); err != nil {
  296. t.Fatalf("Unable to execute command: %v", err)
  297. }
  298. err = session.Wait()
  299. if err == nil {
  300. t.Fatalf("expected command to fail but it didn't")
  301. }
  302. _, ok := err.(*ExitError)
  303. if ok {
  304. // you can't actually test for errors.errorString
  305. // because it's not exported.
  306. t.Fatalf("expected *errorString but got %T", err)
  307. }
  308. }
  309. func TestInvalidServerMessage(t *testing.T) {
  310. conn := dial(sendInvalidRecord, t)
  311. defer conn.Close()
  312. session, err := conn.NewSession()
  313. if err != nil {
  314. t.Fatalf("Unable to request new session: %v", err)
  315. }
  316. // Make sure that we closed all the clientChans when the connection
  317. // failed.
  318. session.wait()
  319. defer session.Close()
  320. }
  321. // In the wild some clients (and servers) send zero sized window updates.
  322. // Test that the client can continue after receiving a zero sized update.
  323. func TestClientZeroWindowAdjust(t *testing.T) {
  324. conn := dial(sendZeroWindowAdjust, t)
  325. defer conn.Close()
  326. session, err := conn.NewSession()
  327. if err != nil {
  328. t.Fatalf("Unable to request new session: %v", err)
  329. }
  330. defer session.Close()
  331. if err := session.Shell(); err != nil {
  332. t.Fatalf("Unable to execute command: %v", err)
  333. }
  334. err = session.Wait()
  335. if err != nil {
  336. t.Fatalf("expected nil but got %v", err)
  337. }
  338. }
  339. // In the wild some clients (and servers) send zero sized window updates.
  340. // Test that the server can continue after receiving a zero size update.
  341. func TestServerZeroWindowAdjust(t *testing.T) {
  342. conn := dial(exitStatusZeroHandler, t)
  343. defer conn.Close()
  344. session, err := conn.NewSession()
  345. if err != nil {
  346. t.Fatalf("Unable to request new session: %v", err)
  347. }
  348. defer session.Close()
  349. if err := session.Shell(); err != nil {
  350. t.Fatalf("Unable to execute command: %v", err)
  351. }
  352. // send a bogus zero sized window update
  353. session.clientChan.sendWindowAdj(0)
  354. err = session.Wait()
  355. if err != nil {
  356. t.Fatalf("expected nil but got %v", err)
  357. }
  358. }
  359. // Verify that the client never sends a packet larger than maxpacket.
  360. func TestClientStdinRespectsMaxPacketSize(t *testing.T) {
  361. conn := dial(discardHandler, t)
  362. defer conn.Close()
  363. session, err := conn.NewSession()
  364. if err != nil {
  365. t.Fatalf("failed to request new session: %v", err)
  366. }
  367. defer session.Close()
  368. stdin, err := session.StdinPipe()
  369. if err != nil {
  370. t.Fatalf("failed to obtain stdinpipe: %v", err)
  371. }
  372. const size = 100 * 1000
  373. for i := 0; i < 10; i++ {
  374. n, err := stdin.Write(make([]byte, size))
  375. if n != size || err != nil {
  376. t.Fatalf("failed to write: %d, %v", n, err)
  377. }
  378. }
  379. }
  380. // Verify that the client never accepts a packet larger than maxpacket.
  381. func TestServerStdoutRespectsMaxPacketSize(t *testing.T) {
  382. conn := dial(largeSendHandler, t)
  383. defer conn.Close()
  384. session, err := conn.NewSession()
  385. if err != nil {
  386. t.Fatalf("Unable to request new session: %v", err)
  387. }
  388. defer session.Close()
  389. out, err := session.StdoutPipe()
  390. if err != nil {
  391. t.Fatalf("Unable to connect to Stdout: %v", err)
  392. }
  393. if err := session.Shell(); err != nil {
  394. t.Fatalf("Unable to execute command: %v", err)
  395. }
  396. if _, err := ioutil.ReadAll(out); err != nil {
  397. t.Fatalf("failed to read: %v", err)
  398. }
  399. }
  400. func TestClientCannotSendAfterEOF(t *testing.T) {
  401. conn := dial(exitWithoutSignalOrStatus, t)
  402. defer conn.Close()
  403. session, err := conn.NewSession()
  404. if err != nil {
  405. t.Fatalf("Unable to request new session: %v", err)
  406. }
  407. defer session.Close()
  408. in, err := session.StdinPipe()
  409. if err != nil {
  410. t.Fatalf("Unable to connect channel stdin: %v", err)
  411. }
  412. if err := session.Shell(); err != nil {
  413. t.Fatalf("Unable to execute command: %v", err)
  414. }
  415. if err := in.Close(); err != nil {
  416. t.Fatalf("Unable to close stdin: %v", err)
  417. }
  418. if _, err := in.Write([]byte("foo")); err == nil {
  419. t.Fatalf("Session write should fail")
  420. }
  421. }
  422. func TestClientCannotSendAfterClose(t *testing.T) {
  423. conn := dial(exitWithoutSignalOrStatus, t)
  424. defer conn.Close()
  425. session, err := conn.NewSession()
  426. if err != nil {
  427. t.Fatalf("Unable to request new session: %v", err)
  428. }
  429. defer session.Close()
  430. in, err := session.StdinPipe()
  431. if err != nil {
  432. t.Fatalf("Unable to connect channel stdin: %v", err)
  433. }
  434. if err := session.Shell(); err != nil {
  435. t.Fatalf("Unable to execute command: %v", err)
  436. }
  437. // close underlying channel
  438. if err := session.channel.Close(); err != nil {
  439. t.Fatalf("Unable to close session: %v", err)
  440. }
  441. if _, err := in.Write([]byte("foo")); err == nil {
  442. t.Fatalf("Session write should fail")
  443. }
  444. }
  445. func TestClientCannotSendHugePacket(t *testing.T) {
  446. // client and server use the same transport write code so this
  447. // test suffices for both.
  448. conn := dial(shellHandler, t)
  449. defer conn.Close()
  450. if err := conn.transport.writePacket(make([]byte, maxPacket*2)); err == nil {
  451. t.Fatalf("huge packet write should fail")
  452. }
  453. }
  454. // windowTestBytes is the number of bytes that we'll send to the SSH server.
  455. const windowTestBytes = 16000 * 200
  456. // TestServerWindow writes random data to the server. The server is expected to echo
  457. // the same data back, which is compared against the original.
  458. func TestServerWindow(t *testing.T) {
  459. origBuf := bytes.NewBuffer(make([]byte, 0, windowTestBytes))
  460. io.CopyN(origBuf, crypto_rand.Reader, windowTestBytes)
  461. origBytes := origBuf.Bytes()
  462. conn := dial(echoHandler, t)
  463. defer conn.Close()
  464. session, err := conn.NewSession()
  465. if err != nil {
  466. t.Fatal(err)
  467. }
  468. defer session.Close()
  469. result := make(chan []byte)
  470. go func() {
  471. defer close(result)
  472. echoedBuf := bytes.NewBuffer(make([]byte, 0, windowTestBytes))
  473. serverStdout, err := session.StdoutPipe()
  474. if err != nil {
  475. t.Errorf("StdoutPipe failed: %v", err)
  476. return
  477. }
  478. n, err := copyNRandomly("stdout", echoedBuf, serverStdout, windowTestBytes)
  479. if err != nil && err != io.EOF {
  480. t.Errorf("Read only %d bytes from server, expected %d: %v", n, windowTestBytes, err)
  481. }
  482. result <- echoedBuf.Bytes()
  483. }()
  484. serverStdin, err := session.StdinPipe()
  485. if err != nil {
  486. t.Fatalf("StdinPipe failed: %v", err)
  487. }
  488. written, err := copyNRandomly("stdin", serverStdin, origBuf, windowTestBytes)
  489. if err != nil {
  490. t.Fatalf("falied to copy origBuf to serverStdin: %v", err)
  491. }
  492. if written != windowTestBytes {
  493. t.Fatalf("Wrote only %d of %d bytes to server", written, windowTestBytes)
  494. }
  495. echoedBytes := <-result
  496. if !bytes.Equal(origBytes, echoedBytes) {
  497. t.Fatalf("Echoed buffer differed from original, orig %d, echoed %d", len(origBytes), len(echoedBytes))
  498. }
  499. }
  500. // Verify the client can handle a keepalive packet from the server.
  501. func TestClientHandlesKeepalives(t *testing.T) {
  502. conn := dial(channelKeepaliveSender, t)
  503. defer conn.Close()
  504. session, err := conn.NewSession()
  505. if err != nil {
  506. t.Fatal(err)
  507. }
  508. defer session.Close()
  509. if err := session.Shell(); err != nil {
  510. t.Fatalf("Unable to execute command: %v", err)
  511. }
  512. err = session.Wait()
  513. if err != nil {
  514. t.Fatalf("expected nil but got: %v", err)
  515. }
  516. }
  517. type exitStatusMsg struct {
  518. PeersId uint32
  519. Request string
  520. WantReply bool
  521. Status uint32
  522. }
  523. type exitSignalMsg struct {
  524. PeersId uint32
  525. Request string
  526. WantReply bool
  527. Signal string
  528. CoreDumped bool
  529. Errmsg string
  530. Lang string
  531. }
  532. func newServerShell(ch *serverChan, prompt string) *ServerTerminal {
  533. term := terminal.NewTerminal(ch, prompt)
  534. return &ServerTerminal{
  535. Term: term,
  536. Channel: ch,
  537. }
  538. }
  539. func exitStatusZeroHandler(ch *serverChan, t *testing.T) {
  540. defer ch.Close()
  541. // this string is returned to stdout
  542. shell := newServerShell(ch, "> ")
  543. readLine(shell, t)
  544. sendStatus(0, ch, t)
  545. }
  546. func exitStatusNonZeroHandler(ch *serverChan, t *testing.T) {
  547. defer ch.Close()
  548. shell := newServerShell(ch, "> ")
  549. readLine(shell, t)
  550. sendStatus(15, ch, t)
  551. }
  552. func exitSignalAndStatusHandler(ch *serverChan, t *testing.T) {
  553. defer ch.Close()
  554. shell := newServerShell(ch, "> ")
  555. readLine(shell, t)
  556. sendStatus(15, ch, t)
  557. sendSignal("TERM", ch, t)
  558. }
  559. func exitSignalHandler(ch *serverChan, t *testing.T) {
  560. defer ch.Close()
  561. shell := newServerShell(ch, "> ")
  562. readLine(shell, t)
  563. sendSignal("TERM", ch, t)
  564. }
  565. func exitSignalUnknownHandler(ch *serverChan, t *testing.T) {
  566. defer ch.Close()
  567. shell := newServerShell(ch, "> ")
  568. readLine(shell, t)
  569. sendSignal("SYS", ch, t)
  570. }
  571. func exitWithoutSignalOrStatus(ch *serverChan, t *testing.T) {
  572. defer ch.Close()
  573. shell := newServerShell(ch, "> ")
  574. readLine(shell, t)
  575. }
  576. func shellHandler(ch *serverChan, t *testing.T) {
  577. defer ch.Close()
  578. // this string is returned to stdout
  579. shell := newServerShell(ch, "golang")
  580. readLine(shell, t)
  581. sendStatus(0, ch, t)
  582. }
  583. // Ignores the command, writes fixed strings to stderr and stdout.
  584. // Strings are "this-is-stdout." and "this-is-stderr.".
  585. func fixedOutputHandler(ch *serverChan, t *testing.T) {
  586. defer ch.Close()
  587. _, err := ch.Read(make([]byte, 0))
  588. if _, ok := err.(ChannelRequest); !ok {
  589. t.Fatalf("error: expected channel request, got: %#v", err)
  590. return
  591. }
  592. // ignore request, always send some text
  593. ch.AckRequest(true)
  594. _, err = io.WriteString(ch, "this-is-stdout.")
  595. if err != nil {
  596. t.Fatalf("error writing on server: %v", err)
  597. }
  598. _, err = io.WriteString(ch.Stderr(), "this-is-stderr.")
  599. if err != nil {
  600. t.Fatalf("error writing on server: %v", err)
  601. }
  602. sendStatus(0, ch, t)
  603. }
  604. func readLine(shell *ServerTerminal, t *testing.T) {
  605. if _, err := shell.ReadLine(); err != nil && err != io.EOF {
  606. t.Errorf("unable to read line: %v", err)
  607. }
  608. }
  609. func sendStatus(status uint32, ch *serverChan, t *testing.T) {
  610. msg := exitStatusMsg{
  611. PeersId: ch.remoteId,
  612. Request: "exit-status",
  613. WantReply: false,
  614. Status: status,
  615. }
  616. if err := ch.writePacket(marshal(msgChannelRequest, msg)); err != nil {
  617. t.Errorf("unable to send status: %v", err)
  618. }
  619. }
  620. func sendSignal(signal string, ch *serverChan, t *testing.T) {
  621. sig := exitSignalMsg{
  622. PeersId: ch.remoteId,
  623. Request: "exit-signal",
  624. WantReply: false,
  625. Signal: signal,
  626. CoreDumped: false,
  627. Errmsg: "Process terminated",
  628. Lang: "en-GB-oed",
  629. }
  630. if err := ch.writePacket(marshal(msgChannelRequest, sig)); err != nil {
  631. t.Errorf("unable to send signal: %v", err)
  632. }
  633. }
  634. func sendInvalidRecord(ch *serverChan, t *testing.T) {
  635. defer ch.Close()
  636. packet := make([]byte, 1+4+4+1)
  637. packet[0] = msgChannelData
  638. marshalUint32(packet[1:], 29348723 /* invalid channel id */)
  639. marshalUint32(packet[5:], 1)
  640. packet[9] = 42
  641. if err := ch.writePacket(packet); err != nil {
  642. t.Errorf("unable send invalid record: %v", err)
  643. }
  644. }
  645. func sendZeroWindowAdjust(ch *serverChan, t *testing.T) {
  646. defer ch.Close()
  647. // send a bogus zero sized window update
  648. ch.sendWindowAdj(0)
  649. shell := newServerShell(ch, "> ")
  650. readLine(shell, t)
  651. sendStatus(0, ch, t)
  652. }
  653. func discardHandler(ch *serverChan, t *testing.T) {
  654. defer ch.Close()
  655. // grow the window to avoid being fooled by
  656. // the initial 1 << 14 window.
  657. ch.sendWindowAdj(1024 * 1024)
  658. io.Copy(ioutil.Discard, ch)
  659. }
  660. func largeSendHandler(ch *serverChan, t *testing.T) {
  661. defer ch.Close()
  662. // grow the window to avoid being fooled by
  663. // the initial 1 << 14 window.
  664. ch.sendWindowAdj(1024 * 1024)
  665. shell := newServerShell(ch, "> ")
  666. readLine(shell, t)
  667. // try to send more than the 32k window
  668. // will allow
  669. if err := ch.writePacket(make([]byte, 128*1024)); err == nil {
  670. t.Errorf("wrote packet larger than 32k")
  671. }
  672. }
  673. func echoHandler(ch *serverChan, t *testing.T) {
  674. defer ch.Close()
  675. if n, err := copyNRandomly("echohandler", ch, ch, windowTestBytes); err != nil {
  676. t.Errorf("short write, wrote %d, expected %d: %v ", n, windowTestBytes, err)
  677. }
  678. }
  679. // copyNRandomly copies n bytes from src to dst. It uses a variable, and random,
  680. // buffer size to exercise more code paths.
  681. func copyNRandomly(title string, dst io.Writer, src io.Reader, n int) (int, error) {
  682. var (
  683. buf = make([]byte, 32*1024)
  684. written int
  685. remaining = n
  686. )
  687. for remaining > 0 {
  688. l := rand.Intn(1 << 15)
  689. if remaining < l {
  690. l = remaining
  691. }
  692. nr, er := src.Read(buf[:l])
  693. nw, ew := dst.Write(buf[:nr])
  694. remaining -= nw
  695. written += nw
  696. if ew != nil {
  697. return written, ew
  698. }
  699. if nr != nw {
  700. return written, io.ErrShortWrite
  701. }
  702. if er != nil && er != io.EOF {
  703. return written, er
  704. }
  705. }
  706. return written, nil
  707. }
  708. func channelKeepaliveSender(ch *serverChan, t *testing.T) {
  709. defer ch.Close()
  710. shell := newServerShell(ch, "> ")
  711. readLine(shell, t)
  712. msg := channelRequestMsg{
  713. PeersId: ch.remoteId,
  714. Request: "keepalive@openssh.com",
  715. WantReply: true,
  716. }
  717. if err := ch.writePacket(marshal(msgChannelRequest, msg)); err != nil {
  718. t.Errorf("unable to send channel keepalive request: %v", err)
  719. }
  720. sendStatus(0, ch, t)
  721. }