Merge pull request #4956 from rickard-von-essen/null-ssh-agent
builder/null: Support SSH Agent Auth
This commit is contained in:
commit
254bd95ad7
|
@ -32,6 +32,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
Config: &b.config.CommConfig,
|
Config: &b.config.CommConfig,
|
||||||
Host: CommHost(b.config.CommConfig.Host()),
|
Host: CommHost(b.config.CommConfig.Host()),
|
||||||
SSHConfig: SSHConfig(
|
SSHConfig: SSHConfig(
|
||||||
|
b.config.CommConfig.SSHAgentAuth,
|
||||||
b.config.CommConfig.SSHUsername,
|
b.config.CommConfig.SSHUsername,
|
||||||
b.config.CommConfig.SSHPassword,
|
b.config.CommConfig.SSHPassword,
|
||||||
b.config.CommConfig.SSHPrivateKey),
|
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"))
|
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,
|
errs = packer.MultiErrorAppend(errs,
|
||||||
fmt.Errorf("one authentication method must be specified, please reference your communicator documentation"))
|
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,
|
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 {
|
if errs != nil && len(errs.Errors) > 0 {
|
||||||
|
|
|
@ -2,10 +2,14 @@ package null
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/hashicorp/packer/communicator/ssh"
|
"github.com/hashicorp/packer/communicator/ssh"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
gossh "golang.org/x/crypto/ssh"
|
gossh "golang.org/x/crypto/ssh"
|
||||||
"io/ioutil"
|
"golang.org/x/crypto/ssh/agent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CommHost(host string) func(multistep.StateBag) (string, error) {
|
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
|
// SSHConfig returns a function that can be used for the SSH communicator
|
||||||
// config for connecting to the specified host via SSH
|
// config for connecting to the specified host via SSH
|
||||||
// private_key_file has precedence over password!
|
// 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) {
|
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 != "" {
|
if privateKeyFile != "" {
|
||||||
// key based auth
|
// key based auth
|
||||||
|
|
Loading…
Reference in New Issue