This uses a copy of testenv.Command copied from the main repo, with light edits to allow the testenv helpers to build with Go 1.19. The testenv helper revealed an exec.Command leak in TestCertLogin, so we also fix that leak and simplify server cleanup using testing.T.Cleanup. For golang/go#60099. Fixes golang/go#60343. Change-Id: I7f79fcdb559498b987ee7689972ac53b83870aaf Reviewed-on: https://go-review.googlesource.com/c/crypto/+/496935 Auto-Submit: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org> Run-TryBot: Bryan Mills <bcmills@google.com>
78 lines
2.1 KiB
Go
78 lines
2.1 KiB
Go
// Copyright 2014 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
|
|
|
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)
|
|
|
|
// Use a key different from the default.
|
|
clientKey := testSigners["dsa"]
|
|
caAuthKey := testSigners["ecdsa"]
|
|
cert := &ssh.Certificate{
|
|
Key: clientKey.PublicKey(),
|
|
ValidPrincipals: []string{username()},
|
|
CertType: ssh.UserCert,
|
|
ValidBefore: ssh.CertTimeInfinity,
|
|
}
|
|
if err := cert.SignCert(rand.Reader, caAuthKey); err != nil {
|
|
t.Fatalf("SetSignature: %v", err)
|
|
}
|
|
|
|
certSigner, err := ssh.NewCertSigner(cert, clientKey)
|
|
if err != nil {
|
|
t.Fatalf("NewCertSigner: %v", err)
|
|
}
|
|
|
|
conf := &ssh.ClientConfig{
|
|
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))
|
|
|
|
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")
|
|
}
|
|
}
|
|
}
|
|
}
|