From b83c72fd5451ef78153f3c475e68efefd8b6e22e Mon Sep 17 00:00:00 2001 From: Adrien Delorme Date: Mon, 27 Aug 2018 15:58:00 +0200 Subject: [PATCH] more private keys in config --- builder/alicloud/ecs/step_attach_keypair.go | 16 ++++++------ builder/alicloud/ecs/step_config_key_pair.go | 9 ++++--- builder/azure/common/constants/stateBag.go | 1 - builder/azure/common/lin/step_create_cert.go | 3 ++- builder/digitalocean/step_create_ssh_key.go | 5 ++-- builder/oneandone/step_create_sshkey.go | 4 +-- builder/openstack/step_get_password.go | 2 +- builder/openstack/step_key_pair.go | 27 ++++++++++---------- builder/openstack/step_run_source_server.go | 6 ++--- builder/profitbricks/step_create_ssh_key.go | 4 +-- builder/scaleway/step_create_ssh_key.go | 17 ++++++------ helper/communicator/config.go | 6 +---- 12 files changed, 49 insertions(+), 51 deletions(-) diff --git a/builder/alicloud/ecs/step_attach_keypair.go b/builder/alicloud/ecs/step_attach_keypair.go index 9a565d144..828606555 100644 --- a/builder/alicloud/ecs/step_attach_keypair.go +++ b/builder/alicloud/ecs/step_attach_keypair.go @@ -16,15 +16,15 @@ type stepAttachKeyPair struct { } func (s *stepAttachKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { - keyPairName := state.Get("keyPair").(string) - if keyPairName == "" { - return multistep.ActionContinue - } ui := state.Get("ui").(packer.Ui) client := state.Get("client").(*ecs.Client) config := state.Get("config").(Config) instance := state.Get("instance").(*ecs.InstanceAttributesType) timeoutPoint := time.Now().Add(120 * time.Second) + keyPairName := config.Comm.SSHKeyPair + if keyPairName == "" { + return multistep.ActionContinue + } for { err := client.AttachKeyPair(&ecs.AttachKeyPairArgs{RegionId: common.Region(config.AlicloudRegion), KeyPairName: keyPairName, InstanceIds: "[\"" + instance.InstanceId + "\"]"}) @@ -51,14 +51,14 @@ func (s *stepAttachKeyPair) Run(_ context.Context, state multistep.StateBag) mul } func (s *stepAttachKeyPair) Cleanup(state multistep.StateBag) { - keyPairName := state.Get("keyPair").(string) - if keyPairName == "" { - return - } client := state.Get("client").(*ecs.Client) config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) instance := state.Get("instance").(*ecs.InstanceAttributesType) + keyPairName := config.Comm.SSHKeyPair + if keyPairName == "" { + return + } err := client.DetachKeyPair(&ecs.DetachKeyPairArgs{RegionId: common.Region(config.AlicloudRegion), KeyPairName: keyPairName, InstanceIds: "[\"" + instance.InstanceId + "\"]"}) diff --git a/builder/alicloud/ecs/step_config_key_pair.go b/builder/alicloud/ecs/step_config_key_pair.go index 5a1d4c91e..3efb2401f 100644 --- a/builder/alicloud/ecs/step_config_key_pair.go +++ b/builder/alicloud/ecs/step_config_key_pair.go @@ -27,6 +27,7 @@ type stepConfigAlicloudKeyPair struct { func (s *stepConfigAlicloudKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) + config := state.Get("config").(*Config) if s.PrivateKeyFile != "" { ui.Say("Using existing SSH private key") @@ -37,8 +38,8 @@ func (s *stepConfigAlicloudKeyPair) Run(_ context.Context, state multistep.State return multistep.ActionHalt } - state.Put("keyPair", s.KeyPairName) - state.Put("privateKey", string(privateKeyBytes)) + config.Comm.SSHKeyPair = s.KeyPairName + config.Comm.SSHPrivateKey = privateKeyBytes return multistep.ActionContinue } @@ -76,8 +77,8 @@ func (s *stepConfigAlicloudKeyPair) Run(_ context.Context, state multistep.State s.keyName = s.TemporaryKeyPairName // Set some state data for use in future steps - state.Put("keyPair", s.keyName) - state.Put("privateKey", keyResp.PrivateKeyBody) + config.Comm.SSHKeyPair = s.keyName + config.Comm.SSHPrivateKey = []byte(keyResp.PrivateKeyBody) // If we're in debug mode, output the private key to the working // directory. diff --git a/builder/azure/common/constants/stateBag.go b/builder/azure/common/constants/stateBag.go index e1fe8a66b..5c78912b1 100644 --- a/builder/azure/common/constants/stateBag.go +++ b/builder/azure/common/constants/stateBag.go @@ -5,7 +5,6 @@ const ( AuthorizedKey string = "authorizedKey" Certificate string = "certificate" Error string = "error" - PrivateKey string = "privateKey" SSHHost string = "sshHost" Thumbprint string = "thumbprint" Ui string = "ui" diff --git a/builder/azure/common/lin/step_create_cert.go b/builder/azure/common/lin/step_create_cert.go index da2cb5bf5..301dc2fbb 100644 --- a/builder/azure/common/lin/step_create_cert.go +++ b/builder/azure/common/lin/step_create_cert.go @@ -58,7 +58,8 @@ func (s *StepCreateCert) createCert(state multistep.StateBag) error { })) // Set the private key in the state bag for later - state.Put(constants.PrivateKey, privkey) + state.Put("privateKey", privkey) + log.Printf("createCert: Private key:\n%s", privkey) log.Println("createCert: Creating certificate...") diff --git a/builder/digitalocean/step_create_ssh_key.go b/builder/digitalocean/step_create_ssh_key.go index c03809ba2..e60a0edad 100644 --- a/builder/digitalocean/step_create_ssh_key.go +++ b/builder/digitalocean/step_create_ssh_key.go @@ -28,6 +28,7 @@ type stepCreateSSHKey struct { func (s *stepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { client := state.Get("client").(*godo.Client) ui := state.Get("ui").(packer.Ui) + c := state.Get("config").(*Config) ui.Say("Creating temporary ssh key for droplet...") @@ -41,8 +42,8 @@ func (s *stepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) mult Bytes: priv_der, } - // Set the private key in the statebag for later - state.Put("privateKey", string(pem.EncodeToMemory(&priv_blk))) + // Set the private key in the config for later + c.Comm.SSHPrivateKey = pem.EncodeToMemory(&priv_blk) // Marshal the public key into SSH compatible format // TODO properly handle the public key error diff --git a/builder/oneandone/step_create_sshkey.go b/builder/oneandone/step_create_sshkey.go index f03ece03a..5036e9b57 100644 --- a/builder/oneandone/step_create_sshkey.go +++ b/builder/oneandone/step_create_sshkey.go @@ -53,8 +53,8 @@ func (s *StepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) mult ui.Error(err.Error()) return multistep.ActionHalt } - state.Put("privateKey", string(pem.EncodeToMemory(&priv_blk))) - state.Put("publicKey", string(ssh.MarshalAuthorizedKey(pub))) + c.Comm.SSHPrivateKey = pem.EncodeToMemory(&priv_blk) + c.Comm.SSHPublicKey = ssh.MarshalAuthorizedKey(pub) } return multistep.ActionContinue } diff --git a/builder/openstack/step_get_password.go b/builder/openstack/step_get_password.go index 4b962db4b..1572fb7a6 100644 --- a/builder/openstack/step_get_password.go +++ b/builder/openstack/step_get_password.go @@ -49,7 +49,7 @@ func (s *StepGetPassword) Run(_ context.Context, state multistep.StateBag) multi server := state.Get("server").(*servers.Server) var password string - privateKey, err := ssh.ParseRawPrivateKey([]byte(state.Get("privateKey").(string))) + privateKey, err := ssh.ParseRawPrivateKey(s.Comm.SSHPrivateKey) if err != nil { err = fmt.Errorf("Error parsing private key: %s", err) state.Put("error", err) diff --git a/builder/openstack/step_key_pair.go b/builder/openstack/step_key_pair.go index c4eba5804..fb8ca958d 100644 --- a/builder/openstack/step_key_pair.go +++ b/builder/openstack/step_key_pair.go @@ -28,6 +28,7 @@ type StepKeyPair struct { func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) + config := state.Get("config").(Config) if s.PrivateKeyFile != "" { privateKeyBytes, err := ioutil.ReadFile(s.PrivateKeyFile) @@ -37,8 +38,8 @@ func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep return multistep.ActionHalt } - state.Put("keyPair", s.KeyPairName) - state.Put("privateKey", string(privateKeyBytes)) + config.Comm.SSHPrivateKey = privateKeyBytes + config.Comm.SSHKeyPair = s.KeyPairName return multistep.ActionContinue } @@ -50,18 +51,16 @@ func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep if s.SSHAgentAuth && s.KeyPairName != "" { ui.Say(fmt.Sprintf("Using SSH Agent for existing key pair %s", s.KeyPairName)) - state.Put("keyPair", s.KeyPairName) + config.Comm.SSHKeyPair = "" return multistep.ActionContinue } if s.TemporaryKeyPairName == "" { ui.Say("Not using temporary keypair") - state.Put("keyPair", "") + config.Comm.SSHKeyPair = "" return multistep.ActionContinue } - config := state.Get("config").(Config) - // We need the v2 compute client computeClient, err := config.computeV2Client() if err != nil { @@ -79,14 +78,14 @@ func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep return multistep.ActionHalt } - if keypair.PrivateKey == "" { + if len(keypair.PrivateKey) == 0 { state.Put("error", fmt.Errorf("The temporary keypair returned was blank")) return multistep.ActionHalt } ui.Say(fmt.Sprintf("Created temporary keypair: %s", s.TemporaryKeyPairName)) - keypair.PrivateKey = berToDer(keypair.PrivateKey, ui) + keypair.PrivateKey = string(berToDer([]byte(keypair.PrivateKey), ui)) // If we're in debug mode, output the private key to the working // directory. @@ -118,16 +117,16 @@ func (s *StepKeyPair) Run(_ context.Context, state multistep.StateBag) multistep s.doCleanup = true // Set some state data for use in future steps - state.Put("keyPair", s.TemporaryKeyPairName) - state.Put("privateKey", keypair.PrivateKey) + config.Comm.SSHKeyPair = s.TemporaryKeyPairName + config.Comm.SSHPrivateKey = []byte(keypair.PrivateKey) return multistep.ActionContinue } // Work around for https://github.com/hashicorp/packer/issues/2526 -func berToDer(ber string, ui packer.Ui) string { +func berToDer(ber []byte, ui packer.Ui) []byte { // Check if x/crypto/ssh can parse the key - _, err := ssh.ParsePrivateKey([]byte(ber)) + _, err := ssh.ParsePrivateKey(ber) if err == nil { return ber } @@ -145,7 +144,7 @@ func berToDer(ber string, ui packer.Ui) string { if err != nil { return ber } - ioutil.WriteFile(berKey.Name(), []byte(ber), os.ModeAppend) + ioutil.WriteFile(berKey.Name(), ber, os.ModeAppend) derKey, err := ioutil.TempFile("", "packer-der-privatekey-") defer os.Remove(derKey.Name()) if err != nil { @@ -164,7 +163,7 @@ func berToDer(ber string, ui packer.Ui) string { return ber } ui.Say("Successfully converted BER encoded SSH key to DER encoding.") - return string(der) + return der } func (s *StepKeyPair) Cleanup(state multistep.StateBag) { diff --git a/builder/openstack/step_run_source_server.go b/builder/openstack/step_run_source_server.go index 6bbb40eba..6f2b78c41 100644 --- a/builder/openstack/step_run_source_server.go +++ b/builder/openstack/step_run_source_server.go @@ -107,11 +107,11 @@ func (s *StepRunSourceServer) Run(_ context.Context, state multistep.StateBag) m } // Add keypair to the server create options. - keyName, hasKey := state.GetOk("keyPair") - if hasKey { + keyName := config.Comm.SSHKeyPair + if keyName != "" { serverOptsExt = keypairs.CreateOptsExt{ CreateOptsBuilder: serverOptsExt, - KeyName: keyName.(string), + KeyName: keyName, } } diff --git a/builder/profitbricks/step_create_ssh_key.go b/builder/profitbricks/step_create_ssh_key.go index 6e041a8e8..f9678c751 100644 --- a/builder/profitbricks/step_create_ssh_key.go +++ b/builder/profitbricks/step_create_ssh_key.go @@ -53,8 +53,8 @@ func (s *StepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) mult ui.Error(err.Error()) return multistep.ActionHalt } - state.Put("privateKey", string(pem.EncodeToMemory(&priv_blk))) - state.Put("publicKey", string(ssh.MarshalAuthorizedKey(pub))) + c.Comm.SSHPrivateKey = pem.EncodeToMemory(&priv_blk) + c.Comm.SSHPublicKey = ssh.MarshalAuthorizedKey(pub) } return multistep.ActionContinue } diff --git a/builder/scaleway/step_create_ssh_key.go b/builder/scaleway/step_create_ssh_key.go index 4272d9ff4..f2e92a0e6 100644 --- a/builder/scaleway/step_create_ssh_key.go +++ b/builder/scaleway/step_create_ssh_key.go @@ -1,6 +1,7 @@ package scaleway import ( + "bytes" "context" "crypto/rand" "crypto/rsa" @@ -11,7 +12,6 @@ import ( "log" "os" "runtime" - "strings" "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" @@ -26,6 +26,7 @@ type stepCreateSSHKey struct { func (s *stepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ui := state.Get("ui").(packer.Ui) + config := state.Get("config").(*Config) if s.PrivateKeyFile != "" { ui.Say("Using existing SSH private key") @@ -36,8 +37,8 @@ func (s *stepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) mult return multistep.ActionHalt } - state.Put("private_key", string(privateKeyBytes)) - state.Put("ssh_pubkey", "") + config.Comm.SSHPrivateKey = privateKeyBytes + config.Comm.SSHPublicKey = nil return multistep.ActionContinue } @@ -60,17 +61,17 @@ func (s *stepCreateSSHKey) Run(_ context.Context, state multistep.StateBag) mult Bytes: priv_der, } - // Set the private key in the statebag for later - state.Put("private_key", string(pem.EncodeToMemory(&priv_blk))) + // Set the private key in the config for later + config.Comm.SSHPrivateKey = pem.EncodeToMemory(&priv_blk) pub, _ := ssh.NewPublicKey(&priv.PublicKey) - pub_sshformat := string(ssh.MarshalAuthorizedKey(pub)) - pub_sshformat = strings.Replace(pub_sshformat, " ", "_", -1) + pub_sshformat := ssh.MarshalAuthorizedKey(pub) + pub_sshformat = bytes.Replace(pub_sshformat, []byte(" "), []byte("_"), -1) log.Printf("temporary ssh key created") // Remember some state for the future - state.Put("ssh_pubkey", string(pub_sshformat)) + config.Comm.SSHPublicKey = pub_sshformat // If we're in debug mode, output the private key to the working directory. if s.Debug { diff --git a/helper/communicator/config.go b/helper/communicator/config.go index 3d25f210c..fa208092d 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -28,6 +28,7 @@ type Config struct { SSHPassword string `mapstructure:"ssh_password"` SSHPublicKey []byte `mapstructure:"ssh_public_key"` SSHPrivateKey []byte `mapstructure:"ssh_private_key"` + SSHKeyPair string `mapstructure:"ssh_key_pair"` SSHPrivateKeyFile string `mapstructure:"ssh_private_key_file"` SSHPty bool `mapstructure:"ssh_pty"` SSHTimeout time.Duration `mapstructure:"ssh_timeout"` @@ -103,11 +104,6 @@ func (c *Config) SSHConfigFunc() func(multistep.StateBag) (*ssh.ClientConfig, er privateKeys = append(privateKeys, c.SSHPrivateKey) } - //scaleway key - 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 {