builder/null: Support SSH Agent Auth
This commit is contained in:
parent
75a635a8e0
commit
2f8b02a6e1
|
@ -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),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue