From c2c80b64c04ccb917376270f715718ec87bacb29 Mon Sep 17 00:00:00 2001 From: JP Sugarbroad Date: Tue, 27 Aug 2013 13:40:08 -0400 Subject: [PATCH] crypto/ssh: Allow customization of the client version. R=agl, golang-dev, dave CC=golang-dev https://golang.org/cl/13176044 --- ssh/client.go | 19 +++++++++++++++---- ssh/client_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 ssh/client_test.go diff --git a/ssh/client.go b/ssh/client.go index a97a0fb..b0919a9 100644 --- a/ssh/client.go +++ b/ssh/client.go @@ -16,8 +16,8 @@ import ( "sync" ) -// clientVersion is the fixed identification string that the client will use. -var clientVersion = []byte("SSH-2.0-Go\r\n") +// clientVersion is the default identification string that the client will use. +var clientVersion = []byte("SSH-2.0-Go") // ClientConn represents the client side of an SSH connection. type ClientConn struct { @@ -63,13 +63,20 @@ func clientWithAddress(c net.Conn, addr string, config *ClientConfig) (*ClientCo func (c *ClientConn) handshake() error { var magics handshakeMagics - if _, err := c.Write(clientVersion); err != nil { + var version []byte + if len(c.config.ClientVersion) > 0 { + version = []byte(c.config.ClientVersion) + } else { + version = clientVersion + } + magics.clientVersion = version + version = append(version, '\r', '\n') + if _, err := c.Write(version); err != nil { return err } if err := c.Flush(); err != nil { return err } - magics.clientVersion = clientVersion[:len(clientVersion)-2] // read remote server version version, err := readVersion(c) @@ -489,6 +496,10 @@ type ClientConfig struct { // Cryptographic-related configuration. Crypto CryptoConfig + + // The identification string that will be used for the connection. + // If empty, a reasonable default is used. + ClientVersion string } func (c *ClientConfig) rand() io.Reader { diff --git a/ssh/client_test.go b/ssh/client_test.go new file mode 100644 index 0000000..ec0405a --- /dev/null +++ b/ssh/client_test.go @@ -0,0 +1,34 @@ +package ssh + +import ( + "net" + "testing" +) + +func testClientVersion(t *testing.T, config *ClientConfig, expected string) { + clientConn, serverConn := net.Pipe() + receivedVersion := make(chan string, 1) + go func() { + version, err := readVersion(serverConn) + if err != nil { + receivedVersion <- "" + } else { + receivedVersion <- string(version) + } + serverConn.Close() + }() + Client(clientConn, config) + actual := <-receivedVersion + if actual != expected { + t.Fatalf("got %s; want %s", actual, expected) + } +} + +func TestCustomClientVersion(t *testing.T) { + version := "Test-Client-Version-0.0" + testClientVersion(t, &ClientConfig{ClientVersion: version}, version) +} + +func TestDefaultClientVersion(t *testing.T) { + testClientVersion(t, &ClientConfig{}, string(clientVersion)) +}