From 094c87e39585ceda07559882e9973070373a8d44 Mon Sep 17 00:00:00 2001 From: Stephen Fox Date: Thu, 28 Feb 2019 17:06:51 -0500 Subject: [PATCH] Remove 'SSHPublicKeyUrlEncoded', use 'urlquery' instead. Per code review feedback, the Go template library supports encoding variables in URL query format. Instead of exposing two different public key formats (unmodified string and a URL encoded string), just have the user apply the 'urlquery' modifier to their template. --- .../common/step_type_boot_command.go | 15 ++++----------- helper/communicator/config.go | 7 ------- helper/communicator/config_test.go | 18 ------------------ .../builders/_virtualbox-ssh-key-pair.html.md | 19 +++++++++---------- 4 files changed, 13 insertions(+), 46 deletions(-) diff --git a/builder/virtualbox/common/step_type_boot_command.go b/builder/virtualbox/common/step_type_boot_command.go index 6095505af..fb596cc82 100644 --- a/builder/virtualbox/common/step_type_boot_command.go +++ b/builder/virtualbox/common/step_type_boot_command.go @@ -27,12 +27,6 @@ type bootCommandTemplateData struct { // Name is the VM's name. Name string - // EncodedSSHPublicKey is the URL encoded SSH public key in - // OpenSSH authorized_keys format. This is safe for usage - // on the the kernel command line, or other places that split - // on whitespace. - EncodedSSHPublicKey string - // SSHPublicKey is the SSH public key in OpenSSH authorized_keys format. SSHPublicKey string } @@ -72,11 +66,10 @@ func (s *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) hostIP := "10.0.2.2" common.SetHTTPIP(hostIP) s.Ctx.Data = &bootCommandTemplateData{ - HTTPIP: hostIP, - HTTPPort: httpPort, - Name: s.VMName, - EncodedSSHPublicKey: s.Comm.SSHPublicKeyUrlEncoded(), - SSHPublicKey: string(s.Comm.SSHPublicKey), + HTTPIP: hostIP, + HTTPPort: httpPort, + Name: s.VMName, + SSHPublicKey: string(s.Comm.SSHPublicKey), } sendCodes := func(codes []string) error { diff --git a/helper/communicator/config.go b/helper/communicator/config.go index 75ac3b2b6..7d66254b5 100644 --- a/helper/communicator/config.go +++ b/helper/communicator/config.go @@ -5,7 +5,6 @@ import ( "fmt" "io/ioutil" "net" - "net/url" "os" "time" @@ -330,9 +329,3 @@ func (c *Config) prepareWinRM(ctx *interpolate.Context) []error { return errs } - -// SSHPublicKeyUrlEncoded returns a string representing the SSH public key -// encoded in URL format. -func (c *Config) SSHPublicKeyUrlEncoded() string { - return url.PathEscape(string(c.SSHPublicKey)) -} diff --git a/helper/communicator/config_test.go b/helper/communicator/config_test.go index 9f28c2be5..c5af24114 100644 --- a/helper/communicator/config_test.go +++ b/helper/communicator/config_test.go @@ -1,7 +1,6 @@ package communicator import ( - "net/url" "reflect" "testing" @@ -137,23 +136,6 @@ func TestConfig_winrm(t *testing.T) { } } -func TestConfig_SSHPublicKeyUrlEncoded(t *testing.T) { - c := &Config{ - SSHPublicKey: []byte("ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBADulbdHCjXhsH8wGtyLhhi3qVvX6M0tGgtousr/DzArwf2KX0L2Zm1OZfqMWFCrSVD743OFY60YL5CGsN9/PVQP7gApll5yTWyaQJu8lReptR5TMnUDn0u3mJN/QRT5Zs8qS5J5Q3WhXwaMF96kSuu+MwXrBnl8sK+bwxOKQtlKJXowcw==\n"), - } - - encoded := c.SSHPublicKeyUrlEncoded() - - decoded, err := url.PathUnescape(encoded) - if err != nil { - t.Fatal(err.Error()) - } - - if decoded != string(c.SSHPublicKey) { - t.Fatal("resulting public key does not match original public key") - } -} - func testContext(t *testing.T) *interpolate.Context { return nil } diff --git a/website/source/partials/builders/_virtualbox-ssh-key-pair.html.md b/website/source/partials/builders/_virtualbox-ssh-key-pair.html.md index f1f8c189c..62372174c 100644 --- a/website/source/partials/builders/_virtualbox-ssh-key-pair.html.md +++ b/website/source/partials/builders/_virtualbox-ssh-key-pair.html.md @@ -1,13 +1,10 @@ ### SSH key pair automation The VirtualBox builders can inject the current SSH key pair's public key into -the template using the following variables: +the template using the following variable: -- `SSHPublicKey` (*VirtualBox builders only*) - The SSH public key as a line - in OpenSSH authorized_keys format. -- `EncodedSSHPublicKey` (*VirtualBox builders only*) - The same as - `SSHPublicKey`, except it is URL encoded for usage in places - like the kernel command line. +- `SSHPublicKey` (*VirtualBox builders only*) - This is the SSH public key + as a line in OpenSSH authorized_keys format. When a private key is provided using `ssh_private_key_file`, the key's corresponding public key can be accessed using the above variables. @@ -16,17 +13,19 @@ If `ssh_password` and `ssh_private_key_file` are not specified, Packer will automatically generate en ephemeral key pair. The key pair's public key can be accessed using the template variables. -For example, the public key can be provided in the boot command: +For example, the public key can be provided in the boot command as a URL +encoded string by appending `| urlquery` to the variable: ```json { "type": "virtualbox-iso", "boot_command": [ - " text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg PACKER_USER={{ user `username` }} PACKER_AUTHORIZED_KEY={{ .EncodedSSHPublicKey }}" + " text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg PACKER_USER={{ user `username` }} PACKER_AUTHORIZED_KEY={{ .SSHPublicKey | urlquery }}" ] } ``` -The kickstart can then leverage those fields from the kernel command line: +A kickstart could then leverage those fields from the kernel command line by +decoding the URL-encoded public key: ``` %post @@ -43,8 +42,8 @@ do PACKER_USER="${x#*=}" ;; PACKER_AUTHORIZED_KEY=*) - encoded="${x#*=}" # URL decode $encoded into $PACKER_AUTHORIZED_KEY + encoded=$(echo "${x#*=}" | tr '+' ' ') printf -v PACKER_AUTHORIZED_KEY '%b' "${encoded//%/\\x}" ;; esac