Fix the build problem by updating ssh package
This commit is contained in:
parent
dc21bf011a
commit
f087ce16dc
|
@ -1,12 +1,11 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gossh "code.google.com/p/go.crypto/ssh"
|
"code.google.com/p/go.crypto/ssh"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/goamz/ec2"
|
"github.com/mitchellh/goamz/ec2"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/communicator/ssh"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,19 +50,19 @@ func SSHAddress(e *ec2.EC2, port int) func(multistep.StateBag) (string, error) {
|
||||||
// SSHConfig returns a function that can be used for the SSH communicator
|
// SSHConfig returns a function that can be used for the SSH communicator
|
||||||
// config for connecting to the instance created over SSH using the generated
|
// config for connecting to the instance created over SSH using the generated
|
||||||
// private key.
|
// private key.
|
||||||
func SSHConfig(username string) func(multistep.StateBag) (*gossh.ClientConfig, error) {
|
func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) {
|
||||||
return func(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
|
||||||
privateKey := state.Get("privateKey").(string)
|
privateKey := state.Get("privateKey").(string)
|
||||||
|
|
||||||
keyring := new(ssh.SimpleKeychain)
|
signer, err := ssh.ParsePrivateKey([]byte(privateKey))
|
||||||
if err := keyring.AddPEMKey(privateKey); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &gossh.ClientConfig{
|
return &ssh.ClientConfig{
|
||||||
User: username,
|
User: username,
|
||||||
Auth: []gossh.ClientAuth{
|
Auth: []ssh.AuthMethod{
|
||||||
gossh.ClientAuthKeyring(keyring),
|
ssh.PublicKeys(signer),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package digitalocean
|
package digitalocean
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gossh "code.google.com/p/go.crypto/ssh"
|
"code.google.com/p/go.crypto/ssh"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/communicator/ssh"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func sshAddress(state multistep.StateBag) (string, error) {
|
func sshAddress(state multistep.StateBag) (string, error) {
|
||||||
|
@ -13,19 +12,19 @@ func sshAddress(state multistep.StateBag) (string, error) {
|
||||||
return fmt.Sprintf("%s:%d", ipAddress, config.SSHPort), nil
|
return fmt.Sprintf("%s:%d", ipAddress, config.SSHPort), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) {
|
||||||
config := state.Get("config").(config)
|
config := state.Get("config").(config)
|
||||||
privateKey := state.Get("privateKey").(string)
|
privateKey := state.Get("privateKey").(string)
|
||||||
|
|
||||||
keyring := new(ssh.SimpleKeychain)
|
signer, err := ssh.ParsePrivateKey([]byte(privateKey))
|
||||||
if err := keyring.AddPEMKey(privateKey); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &gossh.ClientConfig{
|
return &ssh.ClientConfig{
|
||||||
User: config.SSHUsername,
|
User: config.SSHUsername,
|
||||||
Auth: []gossh.ClientAuth{
|
Auth: []ssh.AuthMethod{
|
||||||
gossh.ClientAuthKeyring(keyring),
|
ssh.PublicKeys(signer),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,8 @@ package googlecompute
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"code.google.com/p/go.crypto/ssh"
|
||||||
gossh "code.google.com/p/go.crypto/ssh"
|
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/communicator/ssh"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// sshAddress returns the ssh address.
|
// sshAddress returns the ssh address.
|
||||||
|
@ -16,19 +14,19 @@ func sshAddress(state multistep.StateBag) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// sshConfig returns the ssh configuration.
|
// sshConfig returns the ssh configuration.
|
||||||
func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
func sshConfig(state multistep.StateBag) (*ssh.ClientConfig, error) {
|
||||||
config := state.Get("config").(*Config)
|
config := state.Get("config").(*Config)
|
||||||
privateKey := state.Get("ssh_private_key").(string)
|
privateKey := state.Get("ssh_private_key").(string)
|
||||||
|
|
||||||
keyring := new(ssh.SimpleKeychain)
|
signer, err := ssh.ParsePrivateKey([]byte(privateKey))
|
||||||
if err := keyring.AddPEMKey(privateKey); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sshConfig := &gossh.ClientConfig{
|
return &ssh.ClientConfig{
|
||||||
User: config.SSHUsername,
|
User: config.SSHUsername,
|
||||||
Auth: []gossh.ClientAuth{gossh.ClientAuthKeyring(keyring)},
|
Auth: []ssh.AuthMethod{
|
||||||
}
|
ssh.PublicKeys(signer),
|
||||||
|
},
|
||||||
return sshConfig, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
package openstack
|
package openstack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gossh "code.google.com/p/go.crypto/ssh"
|
"code.google.com/p/go.crypto/ssh"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
"github.com/mitchellh/packer/communicator/ssh"
|
|
||||||
"github.com/rackspace/gophercloud"
|
"github.com/rackspace/gophercloud"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -39,19 +38,19 @@ func SSHAddress(csp gophercloud.CloudServersProvider, port int) func(multistep.S
|
||||||
// SSHConfig returns a function that can be used for the SSH communicator
|
// SSHConfig returns a function that can be used for the SSH communicator
|
||||||
// config for connecting to the instance created over SSH using the generated
|
// config for connecting to the instance created over SSH using the generated
|
||||||
// private key.
|
// private key.
|
||||||
func SSHConfig(username string) func(multistep.StateBag) (*gossh.ClientConfig, error) {
|
func SSHConfig(username string) func(multistep.StateBag) (*ssh.ClientConfig, error) {
|
||||||
return func(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
|
||||||
privateKey := state.Get("privateKey").(string)
|
privateKey := state.Get("privateKey").(string)
|
||||||
|
|
||||||
keyring := new(ssh.SimpleKeychain)
|
signer, err := ssh.ParsePrivateKey([]byte(privateKey))
|
||||||
if err := keyring.AddPEMKey(privateKey); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &gossh.ClientConfig{
|
return &ssh.ClientConfig{
|
||||||
User: username,
|
User: username,
|
||||||
Auth: []gossh.ClientAuth{
|
Auth: []ssh.AuthMethod{
|
||||||
gossh.ClientAuthKeyring(keyring),
|
ssh.PublicKeys(signer),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,7 +338,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
if _, err := os.Stat(b.config.SSHKeyPath); err != nil {
|
if _, err := os.Stat(b.config.SSHKeyPath); err != nil {
|
||||||
errs = packer.MultiErrorAppend(
|
errs = packer.MultiErrorAppend(
|
||||||
errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
||||||
} else if _, err := sshKeyToKeyring(b.config.SSHKeyPath); err != nil {
|
} else if _, err := sshKeyToSigner(b.config.SSHKeyPath); err != nil {
|
||||||
errs = packer.MultiErrorAppend(
|
errs = packer.MultiErrorAppend(
|
||||||
errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,19 +17,19 @@ func sshAddress(state multistep.StateBag) (string, error) {
|
||||||
func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||||
config := state.Get("config").(*config)
|
config := state.Get("config").(*config)
|
||||||
|
|
||||||
auth := []gossh.ClientAuth{
|
auth := []gossh.AuthMethod{
|
||||||
gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)),
|
gossh.Password(config.SSHPassword),
|
||||||
gossh.ClientAuthKeyboardInteractive(
|
gossh.KeyboardInteractive(
|
||||||
ssh.PasswordKeyboardInteractive(config.SSHPassword)),
|
ssh.PasswordKeyboardInteractive(config.SSHPassword)),
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.SSHKeyPath != "" {
|
if config.SSHKeyPath != "" {
|
||||||
keyring, err := sshKeyToKeyring(config.SSHKeyPath)
|
signer, err := sshKeyToSigner(config.SSHKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
auth = append(auth, gossh.ClientAuthKeyring(keyring))
|
auth = append(auth, gossh.PublicKeys(signer))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &gossh.ClientConfig{
|
return &gossh.ClientConfig{
|
||||||
|
@ -38,7 +38,7 @@ func sshConfig(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func sshKeyToKeyring(path string) (gossh.ClientKeyring, error) {
|
func sshKeyToSigner(path string) (gossh.Signer, error) {
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -50,10 +50,10 @@ func sshKeyToKeyring(path string) (gossh.ClientKeyring, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
keyring := new(ssh.SimpleKeychain)
|
signer, err := gossh.ParsePrivateKey(keyBytes)
|
||||||
if err := keyring.AddPEMKey(string(keyBytes)); err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return keyring, nil
|
return signer, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,19 +16,19 @@ func SSHAddress(state multistep.StateBag) (string, error) {
|
||||||
|
|
||||||
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) {
|
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||||
return func(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
return func(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||||
auth := []gossh.ClientAuth{
|
auth := []gossh.AuthMethod{
|
||||||
gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)),
|
gossh.Password(config.SSHPassword),
|
||||||
gossh.ClientAuthKeyboardInteractive(
|
gossh.KeyboardInteractive(
|
||||||
ssh.PasswordKeyboardInteractive(config.SSHPassword)),
|
ssh.PasswordKeyboardInteractive(config.SSHPassword)),
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.SSHKeyPath != "" {
|
if config.SSHKeyPath != "" {
|
||||||
keyring, err := sshKeyToKeyring(config.SSHKeyPath)
|
signer, err := sshKeyToSigner(config.SSHKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
auth = append(auth, gossh.ClientAuthKeyring(keyring))
|
auth = append(auth, gossh.PublicKeys(signer))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &gossh.ClientConfig{
|
return &gossh.ClientConfig{
|
||||||
|
@ -38,7 +38,7 @@ func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*gossh.ClientConf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sshKeyToKeyring(path string) (gossh.ClientKeyring, error) {
|
func sshKeyToSigner(path string) (gossh.Signer, error) {
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -50,10 +50,10 @@ func sshKeyToKeyring(path string) (gossh.ClientKeyring, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
keyring := new(ssh.SimpleKeychain)
|
signer, err := gossh.ParsePrivateKey(keyBytes)
|
||||||
if err := keyring.AddPEMKey(string(keyBytes)); err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return keyring, nil
|
return signer, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ func (c *SSHConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||||
if c.SSHKeyPath != "" {
|
if c.SSHKeyPath != "" {
|
||||||
if _, err := os.Stat(c.SSHKeyPath); err != nil {
|
if _, err := os.Stat(c.SSHKeyPath); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
||||||
} else if _, err := sshKeyToKeyring(c.SSHKeyPath); err != nil {
|
} else if _, err := sshKeyToSigner(c.SSHKeyPath); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,19 +63,19 @@ func SSHAddressFunc(config *SSHConfig) func(multistep.StateBag) (string, error)
|
||||||
|
|
||||||
func SSHConfigFunc(config *SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) {
|
func SSHConfigFunc(config *SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||||
return func(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
return func(state multistep.StateBag) (*gossh.ClientConfig, error) {
|
||||||
auth := []gossh.ClientAuth{
|
auth := []gossh.AuthMethod{
|
||||||
gossh.ClientAuthPassword(ssh.Password(config.SSHPassword)),
|
gossh.Password(config.SSHPassword),
|
||||||
gossh.ClientAuthKeyboardInteractive(
|
gossh.KeyboardInteractive(
|
||||||
ssh.PasswordKeyboardInteractive(config.SSHPassword)),
|
ssh.PasswordKeyboardInteractive(config.SSHPassword)),
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.SSHKeyPath != "" {
|
if config.SSHKeyPath != "" {
|
||||||
keyring, err := sshKeyToKeyring(config.SSHKeyPath)
|
signer, err := sshKeyToSigner(config.SSHKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
auth = append(auth, gossh.ClientAuthKeyring(keyring))
|
auth = append(auth, gossh.PublicKeys(signer))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &gossh.ClientConfig{
|
return &gossh.ClientConfig{
|
||||||
|
@ -85,7 +85,7 @@ func SSHConfigFunc(config *SSHConfig) func(multistep.StateBag) (*gossh.ClientCon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sshKeyToKeyring(path string) (gossh.ClientKeyring, error) {
|
func sshKeyToSigner(path string) (gossh.Signer, error) {
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -97,10 +97,10 @@ func sshKeyToKeyring(path string) (gossh.ClientKeyring, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
keyring := new(ssh.SimpleKeychain)
|
signer, err := gossh.ParsePrivateKey(keyBytes)
|
||||||
if err := keyring.AddPEMKey(string(keyBytes)); err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return keyring, nil
|
return signer, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func (c *SSHConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||||
if c.SSHKeyPath != "" {
|
if c.SSHKeyPath != "" {
|
||||||
if _, err := os.Stat(c.SSHKeyPath); err != nil {
|
if _, err := os.Stat(c.SSHKeyPath); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
||||||
} else if _, err := sshKeyToKeyring(c.SSHKeyPath); err != nil {
|
} else if _, err := sshKeyToSigner(c.SSHKeyPath); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,9 +260,9 @@ func (d *ESX5Driver) datastorePath(path string) string {
|
||||||
func (d *ESX5Driver) connect() error {
|
func (d *ESX5Driver) connect() error {
|
||||||
address := fmt.Sprintf("%s:%d", d.Host, d.Port)
|
address := fmt.Sprintf("%s:%d", d.Host, d.Port)
|
||||||
|
|
||||||
auth := []gossh.ClientAuth{
|
auth := []gossh.AuthMethod{
|
||||||
gossh.ClientAuthPassword(ssh.Password(d.Password)),
|
gossh.Password(d.Password),
|
||||||
gossh.ClientAuthKeyboardInteractive(
|
gossh.KeyboardInteractive(
|
||||||
ssh.PasswordKeyboardInteractive(d.Password)),
|
ssh.PasswordKeyboardInteractive(d.Password)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ func (d *ESX5Driver) connect() error {
|
||||||
NoPty: true,
|
NoPty: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
comm, err := ssh.New(sshConfig)
|
comm, err := ssh.New(address, sshConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ func (s *StepConnectSSH) waitForSSH(state multistep.StateBag, cancel <-chan stru
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Attempting SSH connection...")
|
log.Println("Attempting SSH connection...")
|
||||||
comm, err = ssh.New(config)
|
comm, err = ssh.New(address, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("SSH handshake err: %s", err)
|
log.Printf("SSH handshake err: %s", err)
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type comm struct {
|
type comm struct {
|
||||||
client *ssh.ClientConn
|
client *ssh.Client
|
||||||
config *Config
|
config *Config
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
|
address string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is the structure used to configure the SSH communicator.
|
// Config is the structure used to configure the SSH communicator.
|
||||||
|
@ -39,10 +40,11 @@ type Config struct {
|
||||||
|
|
||||||
// Creates a new packer.Communicator implementation over SSH. This takes
|
// Creates a new packer.Communicator implementation over SSH. This takes
|
||||||
// an already existing TCP connection and SSH configuration.
|
// an already existing TCP connection and SSH configuration.
|
||||||
func New(config *Config) (result *comm, err error) {
|
func New(address string, config *Config) (result *comm, err error) {
|
||||||
// Establish an initial connection and connect
|
// Establish an initial connection and connect
|
||||||
result = &comm{
|
result = &comm{
|
||||||
config: config,
|
config: config,
|
||||||
|
address: address,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = result.reconnect(); err != nil {
|
if err = result.reconnect(); err != nil {
|
||||||
|
@ -253,10 +255,13 @@ func (c *comm) reconnect() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("handshaking with SSH")
|
log.Printf("handshaking with SSH")
|
||||||
c.client, err = ssh.Client(c.conn, c.config.SSHConfig)
|
sshConn, sshChan, req, err := ssh.NewClientConn(c.conn, c.address, c.config.SSHConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("handshake error: %s", err)
|
log.Printf("handshake error: %s", err)
|
||||||
}
|
}
|
||||||
|
if sshConn != nil {
|
||||||
|
c.client = ssh.NewClient(sshConn, sshChan, req)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ package ssh
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"code.google.com/p/go.crypto/ssh"
|
"code.google.com/p/go.crypto/ssh"
|
||||||
|
"fmt"
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -39,65 +40,57 @@ gqnBycHj6AhEycjda75cs+0zybZvN4x65KZHOGW/O/7OAWEcZP5TPb3zf9ned3Hl
|
||||||
NsZoFj52ponUM6+99A2CmezFCN16c4mbA//luWF+k3VVqR6BpkrhKw==
|
NsZoFj52ponUM6+99A2CmezFCN16c4mbA//luWF+k3VVqR6BpkrhKw==
|
||||||
-----END RSA PRIVATE KEY-----`
|
-----END RSA PRIVATE KEY-----`
|
||||||
|
|
||||||
// password implements the ClientPassword interface
|
|
||||||
type password string
|
|
||||||
|
|
||||||
func (p password) Password(user string) (string, error) {
|
|
||||||
return string(p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var serverConfig = &ssh.ServerConfig{
|
var serverConfig = &ssh.ServerConfig{
|
||||||
PasswordCallback: func(c *ssh.ServerConn, user, pass string) bool {
|
PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
|
||||||
return user == "user" && pass == "pass"
|
if c.User() == "user" && string(pass) == "pass" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("password rejected for %q", c.User())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// Set the private key of the server, required to accept connections
|
// Parse and set the private key of the server, required to accept connections
|
||||||
if err := serverConfig.SetRSAPrivateKey([]byte(testServerPrivateKey)); err != nil {
|
signer, err := ssh.ParsePrivateKey([]byte(testServerPrivateKey))
|
||||||
panic("unable to set private key: " + err.Error())
|
if err != nil {
|
||||||
|
panic("unable to parse private key: " + err.Error())
|
||||||
}
|
}
|
||||||
|
serverConfig.AddHostKey(signer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMockLineServer(t *testing.T) string {
|
func newMockLineServer(t *testing.T) string {
|
||||||
l, err := ssh.Listen("tcp", "127.0.0.1:0", serverConfig)
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to newMockAuthServer: %s", err)
|
t.Fatalf("Unable to listen for connection: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer l.Close()
|
defer l.Close()
|
||||||
c, err := l.Accept()
|
c, err := l.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unable to accept incoming connection: %v", err)
|
t.Errorf("Unable to accept incoming connection: %s", err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Handshake(); err != nil {
|
|
||||||
// not Errorf because this is expected to
|
|
||||||
// fail for some tests.
|
|
||||||
t.Logf("Handshaking error: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Log("Accepted SSH connection")
|
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
conn, chans, _, err := ssh.NewServerConn(c, serverConfig)
|
||||||
channel, err := c.Accept()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unable to accept a channel: %s", err)
|
t.Logf("Handshaking error: %v", err)
|
||||||
return
|
}
|
||||||
|
t.Log("Accepted SSH connection")
|
||||||
|
for newChannel := range chans {
|
||||||
|
channel, _, err := newChannel.Accept()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to accept channel.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just go in a loop now accepting things... we need to
|
|
||||||
// do this to handle packets for SSH.
|
|
||||||
go func() {
|
|
||||||
c.Accept()
|
|
||||||
}()
|
|
||||||
|
|
||||||
channel.Accept()
|
|
||||||
t.Log("Accepted channel")
|
t.Log("Accepted channel")
|
||||||
|
|
||||||
|
go func() {
|
||||||
defer channel.Close()
|
defer channel.Close()
|
||||||
|
conn.OpenChannel(newChannel.ChannelType(), nil)
|
||||||
}()
|
}()
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
return l.Addr().String()
|
return l.Addr().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,15 +105,16 @@ func TestCommIsCommunicator(t *testing.T) {
|
||||||
func TestNew_Invalid(t *testing.T) {
|
func TestNew_Invalid(t *testing.T) {
|
||||||
clientConfig := &ssh.ClientConfig{
|
clientConfig := &ssh.ClientConfig{
|
||||||
User: "user",
|
User: "user",
|
||||||
Auth: []ssh.ClientAuth{
|
Auth: []ssh.AuthMethod{
|
||||||
ssh.ClientAuthPassword(password("i-am-invalid")),
|
ssh.Password("i-am-invalid"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
address := newMockLineServer(t)
|
||||||
conn := func() (net.Conn, error) {
|
conn := func() (net.Conn, error) {
|
||||||
conn, err := net.Dial("tcp", newMockLineServer(t))
|
conn, err := net.Dial("tcp", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to dial to remote side: %s", err)
|
t.Errorf("Unable to accept incoming connection: %v", err)
|
||||||
}
|
}
|
||||||
return conn, err
|
return conn, err
|
||||||
}
|
}
|
||||||
|
@ -130,7 +124,7 @@ func TestNew_Invalid(t *testing.T) {
|
||||||
SSHConfig: clientConfig,
|
SSHConfig: clientConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := New(config)
|
_, err := New(address, config)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("should have had an error connecting")
|
t.Fatal("should have had an error connecting")
|
||||||
}
|
}
|
||||||
|
@ -139,13 +133,14 @@ func TestNew_Invalid(t *testing.T) {
|
||||||
func TestStart(t *testing.T) {
|
func TestStart(t *testing.T) {
|
||||||
clientConfig := &ssh.ClientConfig{
|
clientConfig := &ssh.ClientConfig{
|
||||||
User: "user",
|
User: "user",
|
||||||
Auth: []ssh.ClientAuth{
|
Auth: []ssh.AuthMethod{
|
||||||
ssh.ClientAuthPassword(password("pass")),
|
ssh.Password("pass"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
address := newMockLineServer(t)
|
||||||
conn := func() (net.Conn, error) {
|
conn := func() (net.Conn, error) {
|
||||||
conn, err := net.Dial("tcp", newMockLineServer(t))
|
conn, err := net.Dial("tcp", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to dial to remote side: %s", err)
|
t.Fatalf("unable to dial to remote side: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -157,7 +152,7 @@ func TestStart(t *testing.T) {
|
||||||
SSHConfig: clientConfig,
|
SSHConfig: clientConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := New(config)
|
client, err := New(address, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error connecting to SSH: %s", err)
|
t.Fatalf("error connecting to SSH: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
package ssh
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.crypto/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/go.crypto/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,20 +1,14 @@
|
||||||
package ssh
|
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
|
// An implementation of ssh.KeyboardInteractiveChallenge that simply sends
|
||||||
// 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
|
|
||||||
// back the password for all questions. The questions are logged.
|
// back the password for all questions. The questions are logged.
|
||||||
type PasswordKeyboardInteractive string
|
func PasswordKeyboardInteractive (password string) (ssh.KeyboardInteractiveChallenge) {
|
||||||
|
return func (user, instruction string, questions []string, echos []bool) ([]string, error) {
|
||||||
func (p PasswordKeyboardInteractive) Challenge(user, instruction string, questions []string, echos []bool) ([]string, error) {
|
|
||||||
log.Printf("Keyboard interactive challenge: ")
|
log.Printf("Keyboard interactive challenge: ")
|
||||||
log.Printf("-- User: %s", user)
|
log.Printf("-- User: %s", user)
|
||||||
log.Printf("-- Instructions: %s", instruction)
|
log.Printf("-- Instructions: %s", instruction)
|
||||||
|
@ -25,8 +19,9 @@ func (p PasswordKeyboardInteractive) Challenge(user, instruction string, questio
|
||||||
// Just send the password back for all questions
|
// Just send the password back for all questions
|
||||||
answers := make([]string, len(questions))
|
answers := make([]string, len(questions))
|
||||||
for i, _ := range answers {
|
for i, _ := range answers {
|
||||||
answers[i] = string(p)
|
answers[i] = string(password)
|
||||||
}
|
}
|
||||||
|
|
||||||
return answers, nil
|
return answers, nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,37 +6,17 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPassword_Impl(t *testing.T) {
|
|
||||||
var raw interface{}
|
|
||||||
raw = Password("foo")
|
|
||||||
if _, ok := raw.(ssh.ClientPassword); !ok {
|
|
||||||
t.Fatal("Password must implement ClientPassword")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPasswordPassword(t *testing.T) {
|
|
||||||
p := Password("foo")
|
|
||||||
result, err := p.Password("user")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err not nil: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if result != "foo" {
|
|
||||||
t.Fatalf("invalid password: %s", result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPasswordKeyboardInteractive_Impl(t *testing.T) {
|
func TestPasswordKeyboardInteractive_Impl(t *testing.T) {
|
||||||
var raw interface{}
|
var raw interface{}
|
||||||
raw = PasswordKeyboardInteractive("foo")
|
raw = PasswordKeyboardInteractive("foo")
|
||||||
if _, ok := raw.(ssh.ClientKeyboardInteractive); !ok {
|
if _, ok := raw.(ssh.KeyboardInteractiveChallenge); !ok {
|
||||||
t.Fatal("PasswordKeyboardInteractive must implement ClientKeyboardInteractive")
|
t.Fatal("PasswordKeyboardInteractive must implement KeyboardInteractiveChallenge")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPasswordKeybardInteractive_Challenge(t *testing.T) {
|
func TestPasswordKeybardInteractive_Challenge(t *testing.T) {
|
||||||
p := PasswordKeyboardInteractive("foo")
|
p := PasswordKeyboardInteractive("foo")
|
||||||
result, err := p.Challenge("foo", "bar", []string{"one", "two"}, nil)
|
result, err := p("foo", "bar", []string{"one", "two"}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err not nil: %s", err)
|
t.Fatalf("err not nil: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func testConn(t *testing.T) (net.Conn, net.Conn) {
|
func testConn(t *testing.T) (net.Conn, net.Conn) {
|
||||||
l, err := net.Listen("tcp", ":0")
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ func readStream(t *testing.T, s io.Reader) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMux(t *testing.T) (client *MuxConn, server *MuxConn) {
|
func testMux(t *testing.T) (client *MuxConn, server *MuxConn) {
|
||||||
l, err := net.Listen("tcp", ":0")
|
l, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue