mirror of https://github.com/hashicorp/packer
Conflicts: builder/amazon/common/ssh.go builder/digitalocean/ssh.go builder/googlecompute/ssh.go builder/openstack/ssh.go communicator/ssh/communicator_test.go communicator/ssh/keychain.go communicator/ssh/keychain_test.gopull/919/head
commit
e84e5e4f2c
@ -1,81 +0,0 @@
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"code.google.com/p/gosshold/ssh"
|
||||
"crypto"
|
||||
"crypto/dsa"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
// SimpleKeychain makes it easy to use private keys in order to connect
|
||||
// via SSH, since the interface exposed by Go isn't the easiest to use
|
||||
// right away.
|
||||
type SimpleKeychain struct {
|
||||
keys []interface{}
|
||||
}
|
||||
|
||||
// AddPEMKey adds a simple PEM encoded private key to the keychain.
|
||||
func (k *SimpleKeychain) AddPEMKey(key string) (err error) {
|
||||
block, _ := pem.Decode([]byte(key))
|
||||
if block == nil {
|
||||
return errors.New("no block in key")
|
||||
}
|
||||
|
||||
var rsakey interface{}
|
||||
rsakey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
rsakey, err = x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
k.keys = append(k.keys, rsakey)
|
||||
return
|
||||
}
|
||||
|
||||
// AddPEMKeyPassword adds a PEM encoded private key that is protected by
|
||||
// a password to the keychain.
|
||||
func (k *SimpleKeychain) AddPEMKeyPassword(key string, password string) (err error) {
|
||||
block, _ := pem.Decode([]byte(key))
|
||||
bytes, _ := x509.DecryptPEMBlock(block, []byte(password))
|
||||
rsakey, err := x509.ParsePKCS1PrivateKey(bytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
k.keys = append(k.keys, rsakey)
|
||||
return
|
||||
}
|
||||
|
||||
// Key method for ssh.ClientKeyring interface
|
||||
func (k *SimpleKeychain) Key(i int) (ssh.PublicKey, error) {
|
||||
if i < 0 || i >= len(k.keys) {
|
||||
return nil, nil
|
||||
}
|
||||
switch key := k.keys[i].(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return ssh.NewPublicKey(&key.PublicKey)
|
||||
case *dsa.PrivateKey:
|
||||
return ssh.NewPublicKey(&key.PublicKey)
|
||||
}
|
||||
panic("unknown key type")
|
||||
}
|
||||
|
||||
// Sign method for ssh.ClientKeyring interface
|
||||
func (k *SimpleKeychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) {
|
||||
hashFunc := crypto.SHA1
|
||||
h := hashFunc.New()
|
||||
h.Write(data)
|
||||
digest := h.Sum(nil)
|
||||
switch key := k.keys[i].(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return rsa.SignPKCS1v15(rand, key, hashFunc, digest)
|
||||
}
|
||||
return nil, errors.New("ssh: unknown key type")
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"code.google.com/p/gosshold/ssh"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const testPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBALdGZxkXDAjsYk10ihwU6Id2KeILz1TAJuoq4tOgDWxEEGeTrcld
|
||||
r/ZwVaFzjWzxaf6zQIJbfaSEAhqD5yo72+sCAwEAAQJBAK8PEVU23Wj8mV0QjwcJ
|
||||
tZ4GcTUYQL7cF4+ezTCE9a1NrGnCP2RuQkHEKxuTVrxXt+6OF15/1/fuXnxKjmJC
|
||||
nxkCIQDaXvPPBi0c7vAxGwNY9726x01/dNbHCE0CBtcotobxpwIhANbbQbh3JHVW
|
||||
2haQh4fAG5mhesZKAGcxTyv4mQ7uMSQdAiAj+4dzMpJWdSzQ+qGHlHMIBvVHLkqB
|
||||
y2VdEyF7DPCZewIhAI7GOI/6LDIFOvtPo6Bj2nNmyQ1HU6k/LRtNIXi4c9NJAiAr
|
||||
rrxx26itVhJmcvoUhOjwuzSlP2bE5VHAvkGB352YBg==
|
||||
-----END RSA PRIVATE KEY-----`
|
||||
|
||||
func TestAddPEMKey(t *testing.T) {
|
||||
k := &SimpleKeychain{}
|
||||
err := k.AddPEMKey(testPrivateKey)
|
||||
if err != nil {
|
||||
t.Fatalf("error while adding key: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSimpleKeyChain_ImplementsClientkeyring(t *testing.T) {
|
||||
var raw interface{}
|
||||
raw = &SimpleKeychain{}
|
||||
if _, ok := raw.(ssh.ClientKeyring); !ok {
|
||||
t.Fatal("SimpleKeychain is not a valid ssh.ClientKeyring")
|
||||
}
|
||||
}
|
||||
@ -1,32 +1,27 @@
|
||||
package ssh
|
||||
|
||||
import "log"
|
||||
import (
|
||||
"log"
|
||||
"code.google.com/p/go.crypto/ssh"
|
||||
)
|
||||
|
||||
// An implementation of ssh.ClientPassword so that you can use a static
|
||||
// string password for the password to ClientAuthPassword.
|
||||
type Password string
|
||||
|
||||
func (p Password) Password(user string) (string, error) {
|
||||
return string(p), nil
|
||||
}
|
||||
|
||||
// An implementation of ssh.ClientKeyboardInteractive that simply sends
|
||||
// An implementation of ssh.KeyboardInteractiveChallenge that simply sends
|
||||
// back the password for all questions. The questions are logged.
|
||||
type PasswordKeyboardInteractive string
|
||||
|
||||
func (p PasswordKeyboardInteractive) Challenge(user, instruction string, questions []string, echos []bool) ([]string, error) {
|
||||
log.Printf("Keyboard interactive challenge: ")
|
||||
log.Printf("-- User: %s", user)
|
||||
log.Printf("-- Instructions: %s", instruction)
|
||||
for i, question := range questions {
|
||||
log.Printf("-- Question %d: %s", i+1, question)
|
||||
func PasswordKeyboardInteractive (password string) (ssh.KeyboardInteractiveChallenge) {
|
||||
return func (user, instruction string, questions []string, echos []bool) ([]string, error) {
|
||||
log.Printf("Keyboard interactive challenge: ")
|
||||
log.Printf("-- User: %s", user)
|
||||
log.Printf("-- Instructions: %s", instruction)
|
||||
for i, question := range questions {
|
||||
log.Printf("-- Question %d: %s", i+1, question)
|
||||
}
|
||||
|
||||
// Just send the password back for all questions
|
||||
answers := make([]string, len(questions))
|
||||
for i, _ := range answers {
|
||||
answers[i] = string(password)
|
||||
}
|
||||
|
||||
return answers, nil
|
||||
}
|
||||
|
||||
// Just send the password back for all questions
|
||||
answers := make([]string, len(questions))
|
||||
for i, _ := range answers {
|
||||
answers[i] = string(p)
|
||||
}
|
||||
|
||||
return answers, nil
|
||||
}
|
||||
|
||||
Loading…
Reference in new issue