Powershell uses UTF16Le for encodedCommand

This commit is contained in:
Taliesin Sisson 2016-07-24 14:44:07 +01:00
parent e36051d394
commit f38d787b0e
2 changed files with 43 additions and 39 deletions

View File

@ -2,33 +2,53 @@ package powershell
import ( import (
"encoding/base64" "encoding/base64"
"encoding/binary"
"unicode/utf16"
"unicode/utf8"
"golang.org/x/text/encoding/unicode" "golang.org/x/text/encoding/unicode"
) )
func powershellUtf8(message string) (string, error) { func convertUtf8ToUtf16LE(message string) (string, error) {
utf8 := unicode.UTF8 utf16le := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
utfEncoder := utf8.NewEncoder() utfEncoder := utf16le.NewEncoder()
utf8EncodedMessage, err := utfEncoder.String(message) ut16LeEncodedMessage, err := utfEncoder.String(message)
return utf8EncodedMessage, err return ut16LeEncodedMessage, err
}
// UTF16BytesToString converts UTF-16 encoded bytes, in big or little endian byte order,
// to a UTF-8 encoded string.
func UTF16BytesToString(b []byte, o binary.ByteOrder) string {
utf := make([]uint16, (len(b)+(2-1))/2)
for i := 0; i+(2-1) < len(b); i += 2 {
utf[i/2] = o.Uint16(b[i:])
}
if len(b)/2 < len(utf) {
utf[len(utf)-1] = utf8.RuneError
}
return string(utf16.Decode(utf))
} }
func powershellEncode(message string) (string, error) { func powershellEncode(message string) (string, error) {
utf8EncodedMessage, err := powershellUtf8(message) utf16LEEncodedMessage, err := convertUtf8ToUtf16LE(message)
if err != nil { if err != nil {
return "", err return "", err
} }
// Base64 encode the command // Base64 encode the command
input := []uint8(utf8EncodedMessage) input := []uint8(utf16LEEncodedMessage)
return base64.StdEncoding.EncodeToString(input), nil return base64.StdEncoding.EncodeToString(input), nil
} }
func powershellDecode(message string) (retour string, err error) { func powershellDecode(messageBase64 string) (retour string, err error) {
data, err := base64.StdEncoding.DecodeString(message) messageUtf16LeByteArray, err := base64.StdEncoding.DecodeString(messageBase64)
if err != nil { if err != nil {
return "", err return "", err
} }
return string(data), nil
message := UTF16BytesToString(messageUtf16LeByteArray, binary.LittleEndian)
return message, nil
} }

View File

@ -390,11 +390,7 @@ func TestProvisionerProvision_Inline(t *testing.T) {
} }
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode` expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode`
expectedCommandUtf8, err := powershellUtf8(expectedCommand) expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAEUAUgBfAFQAWQBQAEUAPQAiAGkAcwBvACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABfAE4AQQBNAEUAPQAiAHYAbQB3AGEAcgBlACIAOwAgACYAJwBjADoALwBXAGkAbgBkAG8AdwBzAC8AVABlAG0AcAAvAGkAbgBsAGkAbgBlAFMAYwByAGkAcAB0AC4AcABzADEAJwA7AGUAeABpAHQAIAAkAEwAYQBzAHQARQB4AGkAdABDAG8AZABlAA==`
if err != nil {
t.Fatal("should not have error when Utf 8 encoding")
}
expectedCommandBase64Encoded := `aWYgKFRlc3QtUGF0aCB2YXJpYWJsZTpnbG9iYWw6UHJvZ3Jlc3NQcmVmZXJlbmNlKXskUHJvZ3Jlc3NQcmVmZXJlbmNlPSdTaWxlbnRseUNvbnRpbnVlJ307JGVudjpQQUNLRVJfQlVJTERFUl9UWVBFPSJpc28iOyAkZW52OlBBQ0tFUl9CVUlMRF9OQU1FPSJ2bXdhcmUiOyAmJ2M6L1dpbmRvd3MvVGVtcC9pbmxpbmVTY3JpcHQucHMxJztleGl0ICRMYXN0RXhpdENvZGU=`
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand ` expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
@ -404,8 +400,8 @@ func TestProvisionerProvision_Inline(t *testing.T) {
t.Fatal("should not have error when base64 decoding") t.Fatal("should not have error when base64 decoding")
} }
if actualCommandDecoded != expectedCommandUtf8 { if actualCommandDecoded != expectedCommand {
t.Fatalf("Expected decoded:%s, %s, got %s", expectedCommandEncoded, expectedCommandUtf8, actualCommandDecoded) t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
} }
if comm.StartCmd.Command != expectedCommandEncoded { if comm.StartCmd.Command != expectedCommandEncoded {
@ -425,11 +421,7 @@ func TestProvisionerProvision_Inline(t *testing.T) {
} }
expectedCommand = `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR="BAZ"; $env:FOO="BAR"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode` expectedCommand = `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR="BAZ"; $env:FOO="BAR"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode`
expectedCommandUtf8, err = powershellUtf8(expectedCommand) expectedCommandBase64Encoded = `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AEIAQQBSAD0AIgBCAEEAWgAiADsAIAAkAGUAbgB2ADoARgBPAE8APQAiAEIAQQBSACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABFAFIAXwBUAFkAUABFAD0AIgBpAHMAbwAiADsAIAAkAGUAbgB2ADoAUABBAEMASwBFAFIAXwBCAFUASQBMAEQAXwBOAEEATQBFAD0AIgB2AG0AdwBhAHIAZQAiADsAIAAmACcAYwA6AC8AVwBpAG4AZABvAHcAcwAvAFQAZQBtAHAALwBpAG4AbABpAG4AZQBTAGMAcgBpAHAAdAAuAHAAcwAxACcAOwBlAHgAaQB0ACAAJABMAGEAcwB0AEUAeABpAHQAQwBvAGQAZQA=`
if err != nil {
t.Fatal("should not have error when Utf 8 encoding")
}
expectedCommandBase64Encoded = `aWYgKFRlc3QtUGF0aCB2YXJpYWJsZTpnbG9iYWw6UHJvZ3Jlc3NQcmVmZXJlbmNlKXskUHJvZ3Jlc3NQcmVmZXJlbmNlPSdTaWxlbnRseUNvbnRpbnVlJ307JGVudjpCQVI9IkJBWiI7ICRlbnY6Rk9PPSJCQVIiOyAkZW52OlBBQ0tFUl9CVUlMREVSX1RZUEU9ImlzbyI7ICRlbnY6UEFDS0VSX0JVSUxEX05BTUU9InZtd2FyZSI7ICYnYzovV2luZG93cy9UZW1wL2lubGluZVNjcmlwdC5wczEnO2V4aXQgJExhc3RFeGl0Q29kZQ==`
expectedCommandPrefix = `powershell -executionpolicy bypass -encodedCommand ` expectedCommandPrefix = `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded = expectedCommandPrefix + expectedCommandBase64Encoded expectedCommandEncoded = expectedCommandPrefix + expectedCommandBase64Encoded
@ -439,8 +431,8 @@ func TestProvisionerProvision_Inline(t *testing.T) {
t.Fatal("should not have error when base64 decoding") t.Fatal("should not have error when base64 decoding")
} }
if actualCommandDecoded != expectedCommandUtf8 { if actualCommandDecoded != expectedCommand {
t.Fatalf("Expected decoded: %s, got %s", expectedCommandUtf8, actualCommandDecoded) t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
} }
if comm.StartCmd.Command != expectedCommandEncoded { if comm.StartCmd.Command != expectedCommandEncoded {
@ -467,11 +459,7 @@ func TestProvisionerProvision_Scripts(t *testing.T) {
} }
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode` expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode`
expectedCommandUtf8, err := powershellUtf8(expectedCommand) expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAEUAUgBfAFQAWQBQAEUAPQAiAGYAbwBvAHQAeQBwAGUAIgA7ACAAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAF8ATgBBAE0ARQA9ACIAZgBvAG8AYgB1AGkAbABkACIAOwAgACYAJwBjADoALwBXAGkAbgBkAG8AdwBzAC8AVABlAG0AcAAvAHMAYwByAGkAcAB0AC4AcABzADEAJwA7AGUAeABpAHQAIAAkAEwAYQBzAHQARQB4AGkAdABDAG8AZABlAA==`
if err != nil {
t.Fatal("should not have error when Utf 8 encoding")
}
expectedCommandBase64Encoded := `aWYgKFRlc3QtUGF0aCB2YXJpYWJsZTpnbG9iYWw6UHJvZ3Jlc3NQcmVmZXJlbmNlKXskUHJvZ3Jlc3NQcmVmZXJlbmNlPSdTaWxlbnRseUNvbnRpbnVlJ307JGVudjpQQUNLRVJfQlVJTERFUl9UWVBFPSJmb290eXBlIjsgJGVudjpQQUNLRVJfQlVJTERfTkFNRT0iZm9vYnVpbGQiOyAmJ2M6L1dpbmRvd3MvVGVtcC9zY3JpcHQucHMxJztleGl0ICRMYXN0RXhpdENvZGU=`
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand ` expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
@ -481,8 +469,8 @@ func TestProvisionerProvision_Scripts(t *testing.T) {
t.Fatal("should not have error when base64 decoding") t.Fatal("should not have error when base64 decoding")
} }
if actualCommandDecoded != expectedCommandUtf8 { if actualCommandDecoded != expectedCommand {
t.Fatalf("Expected decoded: %s, got %s", expectedCommandUtf8, actualCommandDecoded) t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
} }
if comm.StartCmd.Command != expectedCommandEncoded { if comm.StartCmd.Command != expectedCommandEncoded {
@ -516,11 +504,7 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) {
} }
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR="BAZ"; $env:FOO="BAR"; $env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode` expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR="BAZ"; $env:FOO="BAR"; $env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode`
expectedCommandUtf8, err := powershellUtf8(expectedCommand) expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AEIAQQBSAD0AIgBCAEEAWgAiADsAIAAkAGUAbgB2ADoARgBPAE8APQAiAEIAQQBSACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABFAFIAXwBUAFkAUABFAD0AIgBmAG8AbwB0AHkAcABlACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABfAE4AQQBNAEUAPQAiAGYAbwBvAGIAdQBpAGwAZAAiADsAIAAmACcAYwA6AC8AVwBpAG4AZABvAHcAcwAvAFQAZQBtAHAALwBzAGMAcgBpAHAAdAAuAHAAcwAxACcAOwBlAHgAaQB0ACAAJABMAGEAcwB0AEUAeABpAHQAQwBvAGQAZQA=`
if err != nil {
t.Fatal("should not have error when Utf 8 encoding")
}
expectedCommandBase64Encoded := `aWYgKFRlc3QtUGF0aCB2YXJpYWJsZTpnbG9iYWw6UHJvZ3Jlc3NQcmVmZXJlbmNlKXskUHJvZ3Jlc3NQcmVmZXJlbmNlPSdTaWxlbnRseUNvbnRpbnVlJ307JGVudjpCQVI9IkJBWiI7ICRlbnY6Rk9PPSJCQVIiOyAkZW52OlBBQ0tFUl9CVUlMREVSX1RZUEU9ImZvb3R5cGUiOyAkZW52OlBBQ0tFUl9CVUlMRF9OQU1FPSJmb29idWlsZCI7ICYnYzovV2luZG93cy9UZW1wL3NjcmlwdC5wczEnO2V4aXQgJExhc3RFeGl0Q29kZQ==`
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand ` expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
@ -530,8 +514,8 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) {
t.Fatal("should not have error when base64 decoding") t.Fatal("should not have error when base64 decoding")
} }
if actualCommandDecoded != expectedCommandUtf8 { if actualCommandDecoded != expectedCommand {
t.Fatalf("Expected decoded: %s, got %s", expectedCommandUtf8, actualCommandDecoded) t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
} }
if comm.StartCmd.Command != expectedCommandEncoded { if comm.StartCmd.Command != expectedCommandEncoded {
@ -647,7 +631,7 @@ func TestProvision_createCommandText(t *testing.T) {
cmd, _ := p.createCommandText() cmd, _ := p.createCommandText()
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=""; $env:PACKER_BUILD_NAME=""; &'c:/Windows/Temp/script.ps1';exit $LastExitCode` expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=""; $env:PACKER_BUILD_NAME=""; &'c:/Windows/Temp/script.ps1';exit $LastExitCode`
expectedCommandBase64Encoded := `aWYgKFRlc3QtUGF0aCB2YXJpYWJsZTpnbG9iYWw6UHJvZ3Jlc3NQcmVmZXJlbmNlKXskUHJvZ3Jlc3NQcmVmZXJlbmNlPSdTaWxlbnRseUNvbnRpbnVlJ307JGVudjpQQUNLRVJfQlVJTERFUl9UWVBFPSIiOyAkZW52OlBBQ0tFUl9CVUlMRF9OQU1FPSIiOyAmJ2M6L1dpbmRvd3MvVGVtcC9zY3JpcHQucHMxJztleGl0ICRMYXN0RXhpdENvZGU=` expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAEUAUgBfAFQAWQBQAEUAPQAiACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABfAE4AQQBNAEUAPQAiACIAOwAgACYAJwBjADoALwBXAGkAbgBkAG8AdwBzAC8AVABlAG0AcAAvAHMAYwByAGkAcAB0AC4AcABzADEAJwA7AGUAeABpAHQAIAAkAEwAYQBzAHQARQB4AGkAdABDAG8AZABlAA==`
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand ` expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded