diff --git a/spec/vhdbuilder/packer/test/run_test_spec.sh b/spec/vhdbuilder/packer/test/run_test_spec.sh index 4ff4b294f55..44b05cb3fa9 100644 --- a/spec/vhdbuilder/packer/test/run_test_spec.sh +++ b/spec/vhdbuilder/packer/test/run_test_spec.sh @@ -103,3 +103,38 @@ Describe 'Linux content-test Run Command parameters' The output should equal "$expected_output" End End + +Describe 'Test VM credential log hygiene' + openssl() { printf 'deadbeefcafebabe1234567890abcdef\n'; } + az() { printf '%s\n' "$@" > "$AZ_ARGS"; } + + run_vm_create() ( + set -eux + VM_NAME=test-vm TEST_VM_RESOURCE_GROUP_NAME=test-rg MANAGED_SIG_ID=sig-id + TEST_VM_ADMIN_USERNAME=azureuser TESTING_NIC_ID=nic-id + TARGET_COMMAND_STRING='--size Standard_D2ds_v5' + TEST_VM_USER_DATA_ARGS=() + eval "$(sed -n '/^set +x$/,/^set -x$/p' vhdbuilder/packer/test/run-test.sh)" + eval "$(sed -n "/^$1set +x$/,/^$1set -x$/p" vhdbuilder/packer/test/run-test.sh)" + eval "$(grep '^echo "VHD test VM username:' vhdbuilder/packer/test/run-test.sh)" + ) + + Parameters + linux ' ' + windows ' ' + End + + It "passes the generated password to az vm create on $1 without logging it" + AZ_ARGS="${SHELLSPEC_WORKDIR}/az-args-$1" + When run run_vm_create "$2" + The status should be success + The contents of file "$AZ_ARGS" should include 'vm' + The contents of file "$AZ_ARGS" should include '--admin-password' + The contents of file "$AZ_ARGS" should include 'TestVM@deadbeefcafebabe1234567890abcdef' + The contents of file "$AZ_ARGS" should not include '--debug' + The output should include 'VHD test VM username: azureuser' + The output should not include 'deadbeefcafebabe' + The error should include "+ echo 'VHD test VM username: azureuser'" + The error should not include 'deadbeefcafebabe' + End +End diff --git a/vhdbuilder/packer/test/run-test.sh b/vhdbuilder/packer/test/run-test.sh index 17fb803cc76..891a7660eb5 100755 --- a/vhdbuilder/packer/test/run-test.sh +++ b/vhdbuilder/packer/test/run-test.sh @@ -24,7 +24,10 @@ fi echo "SIG image version ID from packer output: ${MANAGED_SIG_ID}" set +x -TEST_VM_ADMIN_PASSWORD="TestVM@$(date +%s)" +# use a random, non-guessable admin password (prefix guarantees upper/lower/special to satisfy Azure VM complexity rules). +# openssl rand -hex avoids piping through tr: under `set -e` without `pipefail`, a pipeline's exit status is +# that of its last command, so a silent openssl failure would otherwise go undetected (tr succeeds on empty input). +TEST_VM_ADMIN_PASSWORD="TestVM@$(openssl rand -hex 24)" set -x # For linux VHDs, override AZURE_LOCATION with PACKER_BUILD_LOCATION to make sure @@ -136,6 +139,8 @@ if [ "${OS_TYPE,,}" = "linux" ]; then "" \ "$TEST_VM_RESOURCE_GROUP_NAME" || exit $? else + # disable tracing so the admin password isn't emitted to the build log + set +x az vm create \ --resource-group "$TEST_VM_RESOURCE_GROUP_NAME" \ --name "$VM_NAME" \ @@ -145,10 +150,12 @@ if [ "${OS_TYPE,,}" = "linux" ]; then --nics "$TESTING_NIC_ID" \ "${TEST_VM_USER_DATA_ARGS[@]}" \ ${TARGET_COMMAND_STRING} + set -x fi else + # disable tracing so the admin password isn't emitted to the build log + set +x az vm create \ - --debug \ --resource-group "$TEST_VM_RESOURCE_GROUP_NAME" \ --name "$VM_NAME" \ --image "$MANAGED_SIG_ID" \ @@ -156,9 +163,10 @@ else --admin-password "$TEST_VM_ADMIN_PASSWORD" \ --public-ip-address "" \ ${TARGET_COMMAND_STRING} + set -x fi -echo "VHD test VM username: $TEST_VM_ADMIN_USERNAME, password: $TEST_VM_ADMIN_PASSWORD" +echo "VHD test VM username: $TEST_VM_ADMIN_USERNAME" time az vm wait -g "$TEST_VM_RESOURCE_GROUP_NAME" -n "$VM_NAME" --created capture_benchmark "${SCRIPT_NAME}_create_test_vm" diff --git a/vhdbuilder/packer/vhd-scanning.sh b/vhdbuilder/packer/vhd-scanning.sh index 1223e204bc0..582f7518db8 100755 --- a/vhdbuilder/packer/vhd-scanning.sh +++ b/vhdbuilder/packer/vhd-scanning.sh @@ -61,7 +61,10 @@ else fi set +x -SCAN_VM_ADMIN_PASSWORD="ScanVM@$CURRENT_TIME" +# use a random, non-guessable admin password (prefix guarantees upper/lower/special to satisfy Azure VM complexity rules). +# openssl rand -hex avoids piping through tr: under `set -e` without `pipefail`, a pipeline's exit status is +# that of its last command, so a silent openssl failure would otherwise go undetected (tr succeeds on empty input). +SCAN_VM_ADMIN_PASSWORD="ScanVM@$(openssl rand -hex 24)" set -x RESOURCE_GROUP_NAME="$SCAN_RESOURCE_PREFIX-$CURRENT_TIME-$RANDOM"