session_test.go 18 KB

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