session_test.go 20 KB

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