session_test.go 19 KB

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