go.crypto/ssh: never send more data than maxpacket
RFC 4254 s5.2 is clear that a client must never send a data
packet larger than the value of maximum packet supplied by the
remote side during channel setup. The client was not honoring
this value, in fact it wasn't even recording it.
Thanks to Albert Strasheim for the bug report.
R=agl, fullung
CC=golang-dev
https://golang.org/cl/6448128
diff --git a/ssh/session_test.go b/ssh/session_test.go
index aaeae48..a5aafb1 100644
--- a/ssh/session_test.go
+++ b/ssh/session_test.go
@@ -9,6 +9,7 @@
import (
"bytes"
"io"
+ "io/ioutil"
"net"
"testing"
@@ -338,6 +339,26 @@
}
}
+// Verify that we never send a packet larger than maxpacket.
+func TestClientStdinRespectsMaxPacketSize(t *testing.T) {
+ conn := dial(discardHandler, t)
+ defer conn.Close()
+ session, err := conn.NewSession()
+ if err != nil {
+ t.Fatalf("Unable to request new session: %s", err)
+ }
+ defer session.Close()
+ if err := session.Shell(); err != nil {
+ t.Fatalf("Unable to execute command: %s", err)
+ }
+ // try to stuff 128k of data into a 32k hole.
+ const size = 128 * 1024
+ n, err := session.clientChan.stdin.Write(make([]byte, size))
+ if n != size || err != nil {
+ t.Fatalf("failed to write: %d, %v", n, err)
+ }
+}
+
type exitStatusMsg struct {
PeersId uint32
Request string
@@ -456,3 +477,13 @@
shell.ReadLine()
sendStatus(0, ch)
}
+
+func discardHandler(ch *serverChan) {
+ defer ch.Close()
+ // grow the window to avoid being fooled by
+ // the initial 1 << 14 window.
+ ch.sendWindowAdj(1024 * 1024)
+ shell := newServerShell(ch, "> ")
+ shell.ReadLine()
+ io.Copy(ioutil.Discard, ch.serverConn)
+}