go.crypto/ssh: never negotiate unsupported ciphers

Fixes golang/go#4285.

Adding a new cipher that is supported by the remote end, but not supported by our client causes that cipher to be considered a valid candidate. This fails later in setupKeys when there is no cipherModes configuration.

In summary, unsupported ciphers cannot be willed into existence by adding them to the client config. This change enforces this.

R=golang-dev, agl
CC=golang-dev
https://golang.org/cl/6780047
This commit is contained in:
Dave Cheney
2012-10-30 18:13:59 +11:00
parent 2fccde5d00
commit 1582bf0781
6 changed files with 76 additions and 32 deletions
+6 -6
View File
@@ -20,7 +20,7 @@ import (
func TestRunCommandSuccess(t *testing.T) {
server := newServer(t)
defer server.Shutdown()
conn := server.Dial()
conn := server.Dial(clientConfig())
defer conn.Close()
session, err := conn.NewSession()
@@ -37,7 +37,7 @@ func TestRunCommandSuccess(t *testing.T) {
func TestRunCommandFailed(t *testing.T) {
server := newServer(t)
defer server.Shutdown()
conn := server.Dial()
conn := server.Dial(clientConfig())
defer conn.Close()
session, err := conn.NewSession()
@@ -54,7 +54,7 @@ func TestRunCommandFailed(t *testing.T) {
func TestRunCommandWeClosed(t *testing.T) {
server := newServer(t)
defer server.Shutdown()
conn := server.Dial()
conn := server.Dial(clientConfig())
defer conn.Close()
session, err := conn.NewSession()
@@ -74,7 +74,7 @@ func TestRunCommandWeClosed(t *testing.T) {
func TestFuncLargeRead(t *testing.T) {
server := newServer(t)
defer server.Shutdown()
conn := server.Dial()
conn := server.Dial(clientConfig())
defer conn.Close()
session, err := conn.NewSession()
@@ -106,7 +106,7 @@ func TestFuncLargeRead(t *testing.T) {
func TestInvalidTerminalMode(t *testing.T) {
server := newServer(t)
defer server.Shutdown()
conn := server.Dial()
conn := server.Dial(clientConfig())
defer conn.Close()
session, err := conn.NewSession()
@@ -123,7 +123,7 @@ func TestInvalidTerminalMode(t *testing.T) {
func TestValidTerminalMode(t *testing.T) {
server := newServer(t)
defer server.Shutdown()
conn := server.Dial()
conn := server.Dial(clientConfig())
defer conn.Close()
session, err := conn.NewSession()
+1 -1
View File
@@ -27,7 +27,7 @@ func TestTCPIPHTTPS(t *testing.T) {
func doTest(t *testing.T, url string) {
server := newServer(t)
defer server.Shutdown()
conn := server.Dial()
conn := server.Dial(clientConfig())
defer conn.Close()
tr := &http.Transport{
+30 -20
View File
@@ -9,6 +9,7 @@ package test
// functional test harness for unix.
import (
"bytes"
"crypto"
"crypto/dsa"
"crypto/rsa"
@@ -40,7 +41,7 @@ Pidfile {{.Dir}}/sshd.pid
KeyRegenerationInterval 3600
ServerKeyBits 768
SyslogFacility AUTH
LogLevel INFO
LogLevel DEBUG2
LoginGraceTime 120
PermitRootLogin no
StrictModes no
@@ -146,29 +147,13 @@ type server struct {
cleanup func() // executed during Shutdown
configfile string
cmd *exec.Cmd
output bytes.Buffer // holds stderr from sshd process
}
func (s *server) Dial() *ssh.ClientConn {
s.cmd = exec.Command("sshd", "-f", s.configfile, "-i")
stdin, err := s.cmd.StdinPipe()
if err != nil {
s.t.Fatal(err)
}
stdout, err := s.cmd.StdoutPipe()
if err != nil {
s.t.Fatal(err)
}
s.cmd.Stderr = os.Stderr
err = s.cmd.Start()
if err != nil {
s.Shutdown()
s.t.Fatal(err)
}
func clientConfig() *ssh.ClientConfig {
user, err := user.Current()
if err != nil {
s.Shutdown()
s.t.Fatal(err)
panic(err)
}
kc := new(keychain)
kc.keys = append(kc.keys, rsakey)
@@ -178,8 +163,29 @@ func (s *server) Dial() *ssh.ClientConn {
ssh.ClientAuthKeyring(kc),
},
}
return config
}
func (s *server) Dial(config *ssh.ClientConfig) *ssh.ClientConn {
s.cmd = exec.Command("sshd", "-f", s.configfile, "-i")
stdin, err := s.cmd.StdinPipe()
if err != nil {
s.t.Fatal(err)
}
stdout, err := s.cmd.StdoutPipe()
if err != nil {
s.t.Fatal(err)
}
s.cmd.Stderr = os.Stderr // &s.output
err = s.cmd.Start()
if err != nil {
s.t.FailNow()
s.Shutdown()
s.t.Fatal(err)
}
conn, err := ssh.Client(&client{stdin, stdout}, config)
if err != nil {
s.t.FailNow()
s.Shutdown()
s.t.Fatal(err)
}
@@ -190,6 +196,10 @@ func (s *server) Shutdown() {
if err := s.cmd.Process.Kill(); err != nil {
s.t.Error(err)
}
if s.t.Failed() {
// log any output from sshd process
s.t.Log(s.output.String())
}
s.cleanup()
}