x/crypto/ssh: fix host certificate principal evaluation to check for hostname only
SSH host certificates are expected to contain hostnames only, not "host:port" format. This change allows Go clients to connect to OpenSSH servers that use host certificates. Note, this change will break any clients that use ssh.NewClientConn() with an `addr` that is not in `host:port` format (they will see a "missing port in address" error). Fixes bug 20273. Change-Id: I5a306c6b7b419a737e1f0f9c5ca8c585e21a45a4 Reviewed-on: https://go-review.googlesource.com/43475 Reviewed-by: Han-Wen Nienhuys <hanwen@google.com> Run-TryBot: Han-Wen Nienhuys <hanwen@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
committed by
Han-Wen Nienhuys
parent
6c586e17d9
commit
7e9105388e
+35
-6
@@ -7,12 +7,14 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
// Test both logging in with a cert, and also that the certificate presented by an OpenSSH host can be validated correctly
|
||||
func TestCertLogin(t *testing.T) {
|
||||
s := newServer(t)
|
||||
defer s.Shutdown()
|
||||
@@ -36,13 +38,40 @@ func TestCertLogin(t *testing.T) {
|
||||
}
|
||||
|
||||
conf := &ssh.ClientConfig{
|
||||
User: username(),
|
||||
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
|
||||
User: username(),
|
||||
HostKeyCallback: (&ssh.CertChecker{
|
||||
IsHostAuthority: func(pk ssh.PublicKey, addr string) bool {
|
||||
return bytes.Equal(pk.Marshal(), testPublicKeys["ca"].Marshal())
|
||||
},
|
||||
}).CheckHostKey,
|
||||
}
|
||||
conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner))
|
||||
client, err := s.TryDial(conf)
|
||||
if err != nil {
|
||||
t.Fatalf("TryDial: %v", err)
|
||||
|
||||
for _, test := range []struct {
|
||||
addr string
|
||||
succeed bool
|
||||
}{
|
||||
{addr: "host.example.com:22", succeed: true},
|
||||
{addr: "host.example.com:10000", succeed: true}, // non-standard port must be OK
|
||||
{addr: "host.example.com", succeed: false}, // port must be specified
|
||||
{addr: "host.ex4mple.com:22", succeed: false}, // wrong host
|
||||
} {
|
||||
client, err := s.TryDialWithAddr(conf, test.addr)
|
||||
|
||||
// Always close client if opened successfully
|
||||
if err == nil {
|
||||
client.Close()
|
||||
}
|
||||
|
||||
// Now evaluate whether the test failed or passed
|
||||
if test.succeed {
|
||||
if err != nil {
|
||||
t.Fatalf("TryDialWithAddr: %v", err)
|
||||
}
|
||||
} else {
|
||||
if err == nil {
|
||||
t.Fatalf("TryDialWithAddr, unexpected success")
|
||||
}
|
||||
}
|
||||
}
|
||||
client.Close()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user