| #!/bin/bash | |
| # Copyright 2020 The Fuchsia Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| ### Test fx verify_default_keys library | |
| BT_FILE_DEPS=( | |
| "tools/devshell/lib/verify-default-keys.sh" | |
| ) | |
| declare ssh_mock scp_mock local_gensshkeys_mock sync_remote_keys_intree_mock \ | |
| compare_remote_and_local_mock normalize_local_intree_key_mock \ | |
| normalize_remote_intree_key_mock | |
| export HOME="${BT_TEMP_DIR}/HOME" | |
| fx-warn() { | |
| echo "$@" | |
| } | |
| fx-error() { | |
| echo "$@" | |
| } | |
| BT_SET_UP() { | |
| source "${BT_TEMP_DIR}/tools/devshell/tests/lib/fuchsia-mock.sh" | |
| ssh_mock=$(btf::make_mock_binary "ssh") | |
| btf::add_binary_to_path "$ssh_mock" | |
| scp_mock=$(btf::make_mock_binary "scp") | |
| btf::add_binary_to_path "$scp_mock" | |
| local_gensshkeys_mock="${BT_TEMP_DIR}/tools/ssh-keys/gen-ssh-keys.sh" | |
| btf::make_mock "${local_gensshkeys_mock}" | |
| # make mock scripts of relevant methods, so that we can play around with | |
| # its inputs/outputs | |
| sync_remote_keys_intree_mock="${BT_TEMP_DIR}/tools/ssh-keys/sync_remote_keys_intree.sh" | |
| compare_remote_and_local_mock="${BT_TEMP_DIR}/tools/ssh-keys/compare_remote_and_local.sh" | |
| normalize_remote_intree_key_mock="${BT_TEMP_DIR}/tools/ssh-keys/normalize_remote_intree_key.sh" | |
| normalize_local_intree_key_mock="${BT_TEMP_DIR}/tools/ssh-keys/normalize_local_intree_key.sh" | |
| btf::make_mock "${sync_remote_keys_intree_mock}" | |
| btf::make_mock "${compare_remote_and_local_mock}" | |
| btf::make_mock "${normalize_remote_intree_key_mock}" | |
| btf::make_mock "${normalize_local_intree_key_mock}" | |
| { | |
| echo "function sync_remote_keys_intree { ${sync_remote_keys_intree_mock} --description \"\$@\"; }" | |
| echo "function compare_remote_and_local { ${compare_remote_and_local_mock} \"\$@\"; }" | |
| echo "function normalize_remote_intree_key { ${normalize_remote_intree_key_mock} \"\$@\"; }" | |
| echo "function normalize_local_intree_key { ${normalize_local_intree_key_mock} \"\$@\"; }" | |
| } >> "${BT_TEMP_DIR}/tools/devshell/lib/verify-default-keys.sh" | |
| source "${BT_TEMP_DIR}/tools/devshell/lib/verify-default-keys.sh" | |
| } | |
| # test if local keys are copied to remote if necessary | |
| TEST_sshkeys-localhas-remotedoesnt() { | |
| # key exists in local | |
| echo 0 > "${normalize_local_intree_key_mock}.mock_status" | |
| # key does not exist in remote | |
| echo 1 > "${normalize_remote_intree_key_mock}.mock_status" | |
| local out="${BT_TEMP_DIR}/output.log" | |
| mkdir -p "$HOME/.ssh" | |
| echo "myauthkeys mock" > "$HOME/.ssh/fuchsia_authorized_keys" | |
| # check if verify_default_keys executes with success status | |
| BT_EXPECT verify_default_keys "$BT_TEMP_DIR" "myhost" "fuchsia" >>${out} 2>&1 | |
| # check if scp was executed as expected | |
| btf::expect-mock-args "${scp_mock}" -q -p \ | |
| "$HOME/.ssh/fuchsia_ed25519" "$HOME/.ssh/fuchsia_ed25519.pub" "myhost:.ssh/" | |
| # check if ssh was executed as expected | |
| btf::expect-mock-args "${ssh_mock}" myhost "cat >> .ssh/fuchsia_authorized_keys" | |
| } | |
| # test if remote keys are copied to local if necessary | |
| TEST_sshkeys-remotehas-localdoesnt() { | |
| # key exists in remote | |
| echo 0 > "${normalize_remote_intree_key_mock}.mock_status" | |
| # key does not exist in local | |
| echo 1 > "${normalize_local_intree_key_mock}.mock_status" | |
| local out="${BT_TEMP_DIR}/output.log" | |
| # check if verify_default_keys executes with success status | |
| BT_EXPECT verify_default_keys "$BT_TEMP_DIR" "myhost" "fuchsia" >>${out} 2>&1 | |
| # check if scp was executed as expected | |
| btf::expect-mock-args "${scp_mock}" -q -p \ | |
| "myhost:.ssh/fuchsia_ed25519" "myhost:.ssh/fuchsia_ed25519.pub" "$HOME/.ssh" | |
| # check if ssh was executed as expected | |
| btf::expect-mock-args "${ssh_mock}" myhost cat .ssh/fuchsia_authorized_keys | |
| } | |
| # test if verify-default-keys fail if keys exist on remote and local but differ | |
| TEST_sshkeys-remotehas-localhas-mismatch() { | |
| # key exists in remote | |
| echo 0 > "${normalize_remote_intree_key_mock}.mock_status" | |
| # key exists in local | |
| echo 0 > "${normalize_local_intree_key_mock}.mock_status" | |
| # keys don't match | |
| echo 1 > "${compare_remote_and_local_mock}.mock_status" | |
| local out="${BT_TEMP_DIR}/output.log" | |
| # check if verify_default_keys executes with fail status | |
| # a subshell is needed because of 'exit' statements inside verify_default_keys | |
| BT_EXPECT_FAIL "( verify_default_keys \"$BT_TEMP_DIR\" myhost fuchsia )" >>${out} 2>&1 | |
| } | |
| # test if verify-default-keys succeeds if keys exist on remote and local and are | |
| # the same | |
| TEST_sshkeys-remotehas-localhas() { | |
| # key exists in remote | |
| echo 0 > "${normalize_remote_intree_key_mock}.mock_status" | |
| # key exists in local | |
| echo 0 > "${normalize_local_intree_key_mock}.mock_status" | |
| # keys match | |
| echo 0 > "${compare_remote_and_local_mock}.mock_status" | |
| local out="${BT_TEMP_DIR}/output.log" | |
| # check if verify_default_keys executes with success status | |
| BT_EXPECT verify_default_keys "$BT_TEMP_DIR" myhost fuchsia >>${out} 2>&1 | |
| } | |
| # test if a new key is generated in remote if no keys exist anywhere | |
| # and if the key is copied to local after being generated | |
| TEST_sshkeys-nokeys() { | |
| # no key in remote | |
| echo 1 > "${normalize_remote_intree_key_mock}.mock_status" | |
| # no key in local | |
| echo 1 > "${normalize_local_intree_key_mock}.mock_status" | |
| local out="${BT_TEMP_DIR}/output.log" | |
| # check if verify_default_keys executes with success status | |
| BT_EXPECT verify_default_keys "$BT_TEMP_DIR" myhost fuchsia >>${out} 2>&1 | |
| # check if remote gen-ssh-keys was executed | |
| btf::expect-mock-args "${sync_remote_keys_intree_mock}" "--description" _ANY_ | |
| # check if scp was executed as expected | |
| btf::expect-mock-args "${scp_mock}" -q -p \ | |
| "myhost:.ssh/fuchsia_ed25519" "myhost:.ssh/fuchsia_ed25519.pub" "$HOME/.ssh" | |
| # check if ssh was executed as expected | |
| btf::expect-mock-args "${ssh_mock}" myhost cat .ssh/fuchsia_authorized_keys | |
| } | |
| # test if scp is executed with the expected "-o ControlPath" if "-S" is | |
| # specified in the ssh_args argument. "-S" is the equivalent of | |
| # "-o ControlPath" for "ssh", but it is not supported in "scp", so | |
| # verify_default_keys converts it. | |
| TEST_sshkeys-controlpath-scp() { | |
| # key exists in remote | |
| echo 0 > "${normalize_remote_intree_key_mock}.mock_status" | |
| # key does not exist in local | |
| echo 1 > "${normalize_local_intree_key_mock}.mock_status" | |
| local out="${BT_TEMP_DIR}/output.log" | |
| # check if verify_default_keys executes with success status | |
| BT_EXPECT verify_default_keys "$BT_TEMP_DIR" myhost fuchsia -S mycontrolfile >>${out} 2>&1 | |
| # check if scp was executed as expected, with "-o ControlPath" instead of "-S" | |
| btf::expect-mock-args "${scp_mock}" -o ControlPath=mycontrolfile -q -p \ | |
| "myhost:.ssh/fuchsia_ed25519" "myhost:.ssh/fuchsia_ed25519.pub" "$HOME/.ssh" | |
| # check if ssh was executed as expected, with "-o ControlPath" instead of "-S" | |
| btf::expect-mock-args "${ssh_mock}" -o ControlPath=mycontrolfile myhost cat .ssh/fuchsia_authorized_keys | |
| } | |
| # test if the code path executes fine with an empty ssh_args. If not | |
| # handled properly, empty arrays crash the old bash version that comes | |
| # with Mac if "set -u" is used, like it is used by GN SDK, so if this | |
| # test passes, the ssh_args array is being handled correctly. | |
| TEST_sshkeys-empty-ssharg() { | |
| # key exists in remote | |
| echo 0 > "${normalize_remote_intree_key_mock}.mock_status" | |
| # key exists in local | |
| echo 0 > "${normalize_local_intree_key_mock}.mock_status" | |
| # keys match | |
| echo 0 > "${compare_remote_and_local_mock}.mock_status" | |
| local out="${BT_TEMP_DIR}/output.log" | |
| # check if verify_default_keys executes with success status | |
| ( | |
| set -u | |
| verify_default_keys "$BT_TEMP_DIR" myhost fuchsia >>${out} 2>&1 | |
| status=$? | |
| ) | |
| BT_EXPECT_GOOD_STATUS $status "verify_default_keys failed" | |
| # no output is expected. If empty ssh_args is not handled properly, | |
| # on old Bash scripts the code above will print an error ("Unbound variable") | |
| # although the exit code will still be valid. | |
| BT_EXPECT_FILE_CONTAINS ${out} "" | |
| } | |
| BT_RUN_TESTS "$@" |