crypto/ssh: Allow customization of the client version.
R=agl, golang-dev, dave
CC=golang-dev
https://golang.org/cl/13176044
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 @@
"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 (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 @@
// 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))
+}