builder/null: Support SSH Agent Auth

This commit is contained in:
Rickard von Essen 2017-06-02 12:55:31 +02:00
parent 75a635a8e0
commit 2f8b02a6e1
No known key found for this signature in database
GPG Key ID: E0C0327388876CBA
3 changed files with 30 additions and 5 deletions

View File

@ -32,6 +32,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Config: &b.config.CommConfig,
Host: CommHost(b.config.CommConfig.Host()),
SSHConfig: SSHConfig(
b.config.CommConfig.SSHAgentAuth,
b.config.CommConfig.SSHUsername,
b.config.CommConfig.SSHPassword,
b.config.CommConfig.SSHPrivateKey),

View File

@ -41,14 +41,16 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
fmt.Errorf("a Username must be specified, please reference your communicator documentation"))
}
if c.CommConfig.Password() == "" && c.CommConfig.SSHPrivateKey == "" {
if !c.CommConfig.SSHAgentAuth && c.CommConfig.Password() == "" && c.CommConfig.SSHPrivateKey == "" {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("one authentication method must be specified, please reference your communicator documentation"))
}
if c.CommConfig.SSHPassword != "" && c.CommConfig.SSHPrivateKey != "" {
if (c.CommConfig.SSHAgentAuth &&
(c.CommConfig.SSHPassword != "" || c.CommConfig.SSHPrivateKey != "")) ||
(c.CommConfig.SSHPassword != "" && c.CommConfig.SSHPrivateKey != "") {
errs = packer.MultiErrorAppend(errs,
fmt.Errorf("only one of ssh_password and ssh_private_key_file must be specified"))
fmt.Errorf("only one of ssh_agent_auth, ssh_password, and ssh_private_key_file must be specified"))
}
if errs != nil && len(errs.Errors) > 0 {

View File

@ -2,10 +2,14 @@ package null
import (
"fmt"
"io/ioutil"
"net"
"os"
"github.com/hashicorp/packer/communicator/ssh"
"github.com/mitchellh/multistep"
gossh "golang.org/x/crypto/ssh"
"io/ioutil"
"golang.org/x/crypto/ssh/agent"
)
func CommHost(host string) func(multistep.StateBag) (string, error) {
@ -17,8 +21,26 @@ func CommHost(host string) func(multistep.StateBag) (string, error) {
// SSHConfig returns a function that can be used for the SSH communicator
// config for connecting to the specified host via SSH
// private_key_file has precedence over password!
func SSHConfig(username string, password string, privateKeyFile string) func(multistep.StateBag) (*gossh.ClientConfig, error) {
func SSHConfig(useAgent bool, username string, password string, privateKeyFile string) func(multistep.StateBag) (*gossh.ClientConfig, error) {
return func(state multistep.StateBag) (*gossh.ClientConfig, error) {
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)
}
return &gossh.ClientConfig{
User: username,
Auth: []gossh.AuthMethod{
gossh.PublicKeysCallback(agent.NewClient(sshAgent).Signers),
},
}, nil
}
if privateKeyFile != "" {
// key based auth