add tests for signed host certs
This checks that we can verify host certificates signed by a CA
This commit is contained in:
parent
1e7fd1c4ea
commit
bdfa97dbdb
|
@ -52,21 +52,26 @@ gqnBycHj6AhEycjda75cs+0zybZvN4x65KZHOGW/O/7OAWEcZP5TPb3zf9ned3Hl
|
||||||
NsZoFj52ponUM6+99A2CmezFCN16c4mbA//luWF+k3VVqR6BpkrhKw==
|
NsZoFj52ponUM6+99A2CmezFCN16c4mbA//luWF+k3VVqR6BpkrhKw==
|
||||||
-----END RSA PRIVATE KEY-----`
|
-----END RSA PRIVATE KEY-----`
|
||||||
|
|
||||||
var serverConfig = &ssh.ServerConfig{
|
// this cert was signed by the key from testCAPublicKey
|
||||||
PasswordCallback: acceptUserPass("user", "pass"),
|
const testServerHostCert = `ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgvQ3Bs1ex7277b9q6I0fNaWsVEC16f+LcT8RLPSVMEVMAAAADAQABAAABAQDX2UZWxOohPmKI1hGCehjULCRsRNblyr5HOTm/+ROV/fVelJTvQdVaRtMREQKNph1czaAZxtv6zGmroa1d/UzeRWibJyqHHCE+/gKvpenhZP+OQXH3P4UXOl6h0YlaM4fovYfm5fUK+v0QN1Cn2338nfb+oEWe1jwbChQj/L/UxJOYyIW26l0w4M3Tri93eDIwpPCuVDy1kzppi7I4+y60uVRjsznHkXAwNi+c8NJ7JP8jDTOzcH40LKp54x3ZPtjNAWdEBOPQzuszkuhKzsNWpWuI4QAGywXIuPfU9uhqguE4qByqgz2SGQ3OvsUdW+L4OFgzaMPQPC+pks3o2acvAAAAAAAAAAAAAAACAAAAB2NhLXRlc3QAAAANAAAACTEyNy4wLjAuMQAAAABag0jkAAAAAHDcHtAAAAAAAAAAAAAAAAAAAAEXAAAAB3NzaC1yc2EAAAADAQABAAABAQCrozyZIhdEvalCn+eSzHH94cO9ykiywA13ntWI7mJcHBwYTeCYWG8E9zGXyp2iDOjCGudM0Tdt8o0OofKChk9Z/qiUN0G8y1kmaXBlBM3qA5R9NPpvMYMNkYLfX6ivtZCnqrsbzaoqN2Oc/7H2StHzJWh/XCGu9otQZA6vdv1oSmAsZOjw/xIGaGQqDUaLq21J280PP1qSbdJHf76iSHE+TWe3YpqV946JWM5tCh0DykZ10VznvxYpUjzhr07IN3tVKxOXbPnnU7lX6IaLIWgfzLqwSyheeux05c3JLF9iF4sFu8ou4hwQz1iuUTU1jxgwZP0w/bkXgFFs0949lW81AAABDwAAAAdzc2gtcnNhAAABAEyoiVkZ5z79nh3WSU5mU2U7e2BItnnEqsJIm9EN+35uG0yORSXmQoaa9mtli7G3r79tyqEJd/C95EdNvU/9TjaoDcbH8OHP+Ue9XSfUzBuQ6bGSXe6mlZlO7QJ1cIyWphFP3MkrweDSiJ+SpeXzLzZkiJ7zKv5czhBEyG/MujFgvikotL+eUNG42y2cgsesXSjENSBS3l11q55a+RM2QKt3W32im8CsSxrH6Mz6p4JXQNgsVvZRknLxNlWXULFB2HLTunPKzJNMTf6xZf66oivSBAXVIdNKhlVpAQ3dT/dW5K6J4aQF/hjWByyLprFwZ16cPDqvtalnTCpbRYelNbw=`
|
||||||
PublicKeyCallback: acceptPublicKey(testClientPublicKey),
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
const testCAPublicKey = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrozyZIhdEvalCn+eSzHH94cO9ykiywA13ntWI7mJcHBwYTeCYWG8E9zGXyp2iDOjCGudM0Tdt8o0OofKChk9Z/qiUN0G8y1kmaXBlBM3qA5R9NPpvMYMNkYLfX6ivtZCnqrsbzaoqN2Oc/7H2StHzJWh/XCGu9otQZA6vdv1oSmAsZOjw/xIGaGQqDUaLq21J280PP1qSbdJHf76iSHE+TWe3YpqV946JWM5tCh0DykZ10VznvxYpUjzhr07IN3tVKxOXbPnnU7lX6IaLIWgfzLqwSyheeux05c3JLF9iF4sFu8ou4hwQz1iuUTU1jxgwZP0w/bkXgFFs0949lW81`
|
||||||
// Parse and set the private key of the server, required to accept connections
|
|
||||||
signer, err := ssh.ParsePrivateKey([]byte(testServerPrivateKey))
|
func newMockLineServer(t *testing.T, signer ssh.Signer) string {
|
||||||
if err != nil {
|
serverConfig := &ssh.ServerConfig{
|
||||||
panic("unable to parse private key: " + err.Error())
|
PasswordCallback: acceptUserPass("user", "pass"),
|
||||||
|
PublicKeyCallback: acceptPublicKey(testClientPublicKey),
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if signer == nil {
|
||||||
|
signer, err = ssh.ParsePrivateKey([]byte(testServerPrivateKey))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to parse private key: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
serverConfig.AddHostKey(signer)
|
serverConfig.AddHostKey(signer)
|
||||||
}
|
|
||||||
|
|
||||||
func newMockLineServer(t *testing.T) string {
|
|
||||||
l, err := net.Listen("tcp", "127.0.0.1:0")
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unable to listen for connection: %s", err)
|
t.Fatalf("Unable to listen for connection: %s", err)
|
||||||
|
@ -113,7 +118,7 @@ func newMockLineServer(t *testing.T) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNew_Invalid(t *testing.T) {
|
func TestNew_Invalid(t *testing.T) {
|
||||||
address := newMockLineServer(t)
|
address := newMockLineServer(t, nil)
|
||||||
parts := strings.Split(address, ":")
|
parts := strings.Split(address, ":")
|
||||||
|
|
||||||
r := &terraform.InstanceState{
|
r := &terraform.InstanceState{
|
||||||
|
@ -141,7 +146,7 @@ func TestNew_Invalid(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStart(t *testing.T) {
|
func TestStart(t *testing.T) {
|
||||||
address := newMockLineServer(t)
|
address := newMockLineServer(t, nil)
|
||||||
parts := strings.Split(address, ":")
|
parts := strings.Split(address, ":")
|
||||||
|
|
||||||
r := &terraform.InstanceState{
|
r := &terraform.InstanceState{
|
||||||
|
@ -181,7 +186,7 @@ func TestHostKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
pubKey := fmt.Sprintf("ssh-rsa %s", base64.StdEncoding.EncodeToString(signer.PublicKey().Marshal()))
|
pubKey := fmt.Sprintf("ssh-rsa %s", base64.StdEncoding.EncodeToString(signer.PublicKey().Marshal()))
|
||||||
|
|
||||||
address := newMockLineServer(t)
|
address := newMockLineServer(t, nil)
|
||||||
host, p, _ := net.SplitHostPort(address)
|
host, p, _ := net.SplitHostPort(address)
|
||||||
port, _ := strconv.Atoi(p)
|
port, _ := strconv.Atoi(p)
|
||||||
|
|
||||||
|
@ -217,7 +222,7 @@ func TestHostKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check with the wrong HostKey
|
// now check with the wrong HostKey
|
||||||
address = newMockLineServer(t)
|
address = newMockLineServer(t, nil)
|
||||||
_, p, _ = net.SplitHostPort(address)
|
_, p, _ = net.SplitHostPort(address)
|
||||||
port, _ = strconv.Atoi(p)
|
port, _ = strconv.Atoi(p)
|
||||||
|
|
||||||
|
@ -238,7 +243,81 @@ func TestHostKey(t *testing.T) {
|
||||||
if err == nil || !strings.Contains(err.Error(), "mismatch") {
|
if err == nil || !strings.Contains(err.Error(), "mismatch") {
|
||||||
t.Fatalf("expected host key mismatch, got error:%v", err)
|
t.Fatalf("expected host key mismatch, got error:%v", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHostCert(t *testing.T) {
|
||||||
|
pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(testServerHostCert))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
signer, err := ssh.ParsePrivateKey([]byte(testServerPrivateKey))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
signer, err = ssh.NewCertSigner(pk.(*ssh.Certificate), signer)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
address := newMockLineServer(t, signer)
|
||||||
|
host, p, _ := net.SplitHostPort(address)
|
||||||
|
port, _ := strconv.Atoi(p)
|
||||||
|
|
||||||
|
connInfo := &connectionInfo{
|
||||||
|
User: "user",
|
||||||
|
Password: "pass",
|
||||||
|
Host: host,
|
||||||
|
HostKey: testCAPublicKey,
|
||||||
|
Port: port,
|
||||||
|
Timeout: "30s",
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := prepareSSHConfig(connInfo)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &Communicator{
|
||||||
|
connInfo: connInfo,
|
||||||
|
config: cfg,
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmd remote.Cmd
|
||||||
|
stdout := new(bytes.Buffer)
|
||||||
|
cmd.Command = "echo foo"
|
||||||
|
cmd.Stdout = stdout
|
||||||
|
|
||||||
|
if err := c.Start(&cmd); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := c.Disconnect(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check with the wrong HostKey
|
||||||
|
address = newMockLineServer(t, signer)
|
||||||
|
_, p, _ = net.SplitHostPort(address)
|
||||||
|
port, _ = strconv.Atoi(p)
|
||||||
|
|
||||||
|
connInfo.HostKey = testClientPublicKey
|
||||||
|
connInfo.Port = port
|
||||||
|
|
||||||
|
cfg, err = prepareSSHConfig(connInfo)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c = &Communicator{
|
||||||
|
connInfo: connInfo,
|
||||||
|
config: cfg,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.Start(&cmd)
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "authorities") {
|
||||||
|
t.Fatalf("expected host key mismatch, got error:%v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccUploadFile(t *testing.T) {
|
func TestAccUploadFile(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue