SSHConfigFunc: append the ssh auth ways

This commit is contained in:
Adrien Delorme 2018-08-22 17:03:25 +02:00
parent 41f6e0334d
commit 0ff7c1da87
1 changed files with 72 additions and 0 deletions

View File

@ -3,11 +3,17 @@ package communicator
import (
"errors"
"fmt"
"io/ioutil"
"net"
"os"
"time"
packerssh "github.com/hashicorp/packer/communicator/ssh"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/template/interpolate"
"github.com/masterzen/winrm"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
// Config is the common configuration that communicators allow within
@ -52,6 +58,72 @@ type Config struct {
WinRMTransportDecorator func() winrm.Transporter
}
// SSHConfigFunc returns a function that can be used for the SSH communicator
// config for connecting to the instance created over SSH using the private key
// or password.
func (c *Config) SSHConfigFunc() func(multistep.StateBag) (*ssh.ClientConfig, error) {
useAgent := c.SSHAgentAuth
username := c.SSHUsername
password := c.SSHPassword
return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
sshConfig := &ssh.ClientConfig{
User: username,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
if useAgent {
authSock := os.Getenv("SSH_AUTH_SOCK")
if authSock == "" {
return nil, fmt.Errorf("SSH_AUTH_SOCK is not set")
}
sshAgent, err := net.Dial("unix", authSock)
if err != nil {
return nil, fmt.Errorf("Cannot connect to SSH Agent socket %q: %s", authSock, err)
}
sshConfig.Auth = append(sshConfig.Auth, ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers))
}
var privateKeys [][]byte
if c.SSHPrivateKey != "" {
// key based auth
bytes, err := ioutil.ReadFile(c.SSHPrivateKey)
if err != nil {
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
}
privateKeys = append(privateKeys, bytes)
}
if iKey, hasKey := state.GetOk("privateKey"); hasKey {
privateKeys = append(privateKeys, []byte(iKey.(string)))
}
if iKey, hasKey := state.GetOk("ssh_private_key"); hasKey { // gcp key
privateKeys = append(privateKeys, []byte(iKey.(string)))
}
//this is what scaleway.sshConfig did
if iKey, hasKey := state.GetOk("private_key"); hasKey {
privateKeys = append(privateKeys, []byte(iKey.(string)))
}
for _, key := range privateKeys {
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
return nil, fmt.Errorf("Error setting up SSH config: %s", err)
}
sshConfig.Auth = append(sshConfig.Auth, ssh.PublicKeys(signer))
}
if password != "" {
sshConfig.Auth = append(sshConfig.Auth,
ssh.Password(password),
ssh.KeyboardInteractive(packerssh.PasswordKeyboardInteractive(password)),
)
}
return sshConfig, nil
}
}
// Port returns the port that will be used for access based on config.
func (c *Config) Port() int {
switch c.Type {