x/ssh: filter debug and ignore messages in transport.readPacket.
This prevents these messages from confusing higher layers of the
protocol.
Fixes #16927.
Change-Id: If18d8d02bdde3c0470e29a7280cd355d3e55ad78
Reviewed-on: https://go-review.googlesource.com/34959
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
diff --git a/ssh/handshake_test.go b/ssh/handshake_test.go
index da53d3a..4cf5368 100644
--- a/ssh/handshake_test.go
+++ b/ssh/handshake_test.go
@@ -9,6 +9,7 @@
"crypto/rand"
"errors"
"fmt"
+ "io"
"net"
"reflect"
"runtime"
@@ -58,14 +59,46 @@
return c1, c2, nil
}
-func handshakePair(clientConf *ClientConfig, addr string) (client *handshakeTransport, server *handshakeTransport, err error) {
+// noiseTransport inserts ignore messages to check that the read loop
+// and the key exchange filters out these messages.
+type noiseTransport struct {
+ keyingTransport
+}
+
+func (t *noiseTransport) writePacket(p []byte) error {
+ ignore := []byte{msgIgnore}
+ if err := t.keyingTransport.writePacket(ignore); err != nil {
+ return err
+ }
+ debug := []byte{msgDebug, 1, 2, 3}
+ if err := t.keyingTransport.writePacket(debug); err != nil {
+ return err
+ }
+
+ return t.keyingTransport.writePacket(p)
+}
+
+func addNoiseTransport(t keyingTransport) keyingTransport {
+ return &noiseTransport{t}
+}
+
+// handshakePair creates two handshakeTransports connected with each
+// other. If the noise argument is true, both transports will try to
+// confuse the other side by sending ignore and debug messages.
+func handshakePair(clientConf *ClientConfig, addr string, noise bool) (client *handshakeTransport, server *handshakeTransport, err error) {
a, b, err := netPipe()
if err != nil {
return nil, nil, err
}
- trC := newTransport(a, rand.Reader, true)
- trS := newTransport(b, rand.Reader, false)
+ var trC, trS keyingTransport
+
+ trC = newTransport(a, rand.Reader, true)
+ trS = newTransport(b, rand.Reader, false)
+ if noise {
+ trC = addNoiseTransport(trC)
+ trS = addNoiseTransport(trS)
+ }
clientConf.SetDefaults()
v := []byte("version")
@@ -85,7 +118,7 @@
t.Skip("see golang.org/issue/7237")
}
checker := &testChecker{}
- trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr")
+ trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr", true)
if err != nil {
t.Fatalf("handshakePair: %v", err)
}
@@ -93,7 +126,9 @@
defer trC.Close()
defer trS.Close()
+ clientDone := make(chan int, 0)
go func() {
+ defer close(clientDone)
// Client writes a bunch of stuff, and does a key
// change in the middle. This should not confuse the
// handshake in progress
@@ -115,8 +150,10 @@
// Server checks that client messages come in cleanly
i := 0
+ err = nil
for {
- p, err := trS.readPacket()
+ var p []byte
+ p, err = trS.readPacket()
if err != nil {
break
}
@@ -129,6 +166,10 @@
}
i++
}
+ <-clientDone
+ if err != nil && err != io.EOF {
+ t.Fatalf("server error: %v", err)
+ }
if i != 10 {
t.Errorf("received %d messages, want 10.", i)
}
@@ -143,11 +184,12 @@
if want != checker.calls[0] {
t.Errorf("got %q want %q for host key check", checker.calls[0], want)
}
+
}
func TestHandshakeError(t *testing.T) {
checker := &testChecker{}
- trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "bad")
+ trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "bad", false)
if err != nil {
t.Fatalf("handshakePair: %v", err)
}
@@ -186,7 +228,7 @@
func TestForceFirstKex(t *testing.T) {
checker := &testChecker{}
- trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr")
+ trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr", false)
if err != nil {
t.Fatalf("handshakePair: %v", err)
}
@@ -208,7 +250,7 @@
func TestHandshakeTwice(t *testing.T) {
checker := &testChecker{}
- trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr")
+ trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr", false)
if err != nil {
t.Fatalf("handshakePair: %v", err)
}
@@ -278,7 +320,7 @@
checker := &testChecker{}
clientConf := &ClientConfig{HostKeyCallback: checker.Check}
clientConf.RekeyThreshold = 500
- trC, trS, err := handshakePair(clientConf, "addr")
+ trC, trS, err := handshakePair(clientConf, "addr", false)
if err != nil {
t.Fatalf("handshakePair: %v", err)
}
@@ -326,7 +368,7 @@
}
clientConf.RekeyThreshold = 500
- trC, trS, err := handshakePair(clientConf, "addr")
+ trC, trS, err := handshakePair(clientConf, "addr", false)
if err != nil {
t.Fatalf("handshakePair: %v", err)
}
@@ -448,7 +490,7 @@
t.Skip("see golang.org/issue/7237")
}
checker := &testChecker{}
- trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr")
+ trC, trS, err := handshakePair(&ClientConfig{HostKeyCallback: checker.Check}, "addr", false)
if err != nil {
t.Fatalf("handshakePair: %v", err)
}