blob: 2cb2dc7e91098753b0a0bebb047a725af58d3135 [file] [log] [blame]
#!/usr/bin/env bash
# Copyright 2018 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.
readonly SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly FUCHSIA_ROOT="${SCRIPT_ROOT}/../.."
readonly _ERROR_NO_KEY=112
readonly _ERROR_MISMATCHED_KEYS=113
description="${USER}@$(hostname -f) Generated by Fuchsia tree on $(date)"
no_new_key=false
if [[ "$1" == "--no-new-key" ]]; then
no_new_key=true
elif [[ "$1" == "--description" ]]; then
shift
description="${description}: $@"
fi
function copy_ssh_keys {
local orig_key dest_key orig_auth_keys dest_auth_keys dest_dir
orig_key="$1"
dest_key="$2"
orig_auth_keys="$3"
dest_auth_keys="$4"
dest_dir="$(dirname "${dest_key}")"
(
# force subshell to limit scope of umask
umask 077 && mkdir -p "${dest_dir}"
umask 177
cp "${orig_key}" "${dest_key}"
umask 133
# Documentation previously recommended copying default SSH identity files
# (private keys) and authorized_keys files, but not public key files. When
# missing, these are skipped.
if [[ -f "${orig_key}.pub" ]]; then
cp "${orig_key}.pub" "${dest_key}.pub"
fi
cat "${orig_auth_keys}" >>"${dest_auth_keys}"
)
}
function mismatched_keys {
cat 1>&2 <<EOF
ERROR: You have different Fuchsia SSH credentials in HOME and in FUCHSIA_DIR.
- If you most recently successfully paved a device from the Fuchsia tree
(fx pave), the SSH credentials in your Fuchsia tree are probably more
relevant. In this case, backup and delete Fuchsia SSH keys in \$HOME/.ssh/fuchsia_*
- If you most recently successfully paved a device outside the Fuchsia tree
(like the GN SDK, using fpave.sh), the SSH credentials in \$HOME/.ssh are
probably more relevant. In this case, backup and delete Fuchsia SSH keys in
FUCHSIA_DIR/.ssh/pkey*
After removing one of the two credentials, execute //tools/ssh-keys/gen-ssh-keys.sh
so that they can be synchronized.
EOF
}
function normalize_local_keys {
local intree="${FUCHSIA_ROOT}/.ssh/pkey"
local inhome="${HOME}/.ssh/fuchsia_ed25519"
local have_in_tree=false
local have_in_home=false
test -f "$intree" && have_in_tree=true
test -f "$inhome" && have_in_home=true
if $have_in_tree && $have_in_home && ! cmp --silent "$intree" "$inhome"; then
mismatched_keys
exit $_ERROR_MISMATCHED_KEYS
elif $have_in_tree && ! $have_in_home; then
echo "Copying existing SSH credentials from //.ssh/pkey to ~/.ssh/fuchsia_ed25519"
copy_ssh_keys "$intree" "$inhome" \
"${FUCHSIA_ROOT}/.ssh/authorized_keys" \
"${HOME}/.ssh/fuchsia_authorized_keys"
elif ! $have_in_tree && $have_in_home; then
echo "Copying existing SSH credentials from ~/.ssh/fuchsia_ed25519 to //.ssh/pkey"
copy_ssh_keys "$inhome" "$intree" \
"${HOME}/.ssh/fuchsia_authorized_keys" \
"${FUCHSIA_ROOT}/.ssh/authorized_keys"
fi
}
# $INFRA_RECIPES is a variable set by infra bots. This keeps the infra recipes
# running inside its per-build directory without seeking keys in a user's home
# directory. See fxr/415297.
if [[ "${INFRA_RECIPES}" == "1" ]]; then
readonly SSH_DIR="${FUCHSIA_ROOT}/.ssh"
readonly keyfile="${SSH_DIR}/pkey"
readonly authfile="${SSH_DIR}/authorized_keys"
else
readonly SSH_DIR="${HOME}/.ssh"
readonly keyfile="${SSH_DIR}/fuchsia_ed25519"
readonly authfile="${SSH_DIR}/fuchsia_authorized_keys"
normalize_local_keys
fi
if [[ ! -f "${keyfile}" ]]; then
if $no_new_key; then
{
echo "ERROR: SSH key doesn't exist: ${keyfile}."
echo "Run //tools/ssh-keys/gen-ssh-keys.sh to generate a new one."
} 1>&2
exit $_ERROR_NO_KEY
fi
# force subshell to limit scope of umask
( umask 077 && mkdir -p "${SSH_DIR}"; )
ssh-keygen -N "" -t ed25519 -f "${keyfile}" -C "${description}"
ssh-keygen -y -f "${keyfile}" >>"${authfile}"
if [[ "${INFRA_RECIPES}" != "1" ]]; then
# normalize again, so that the key created is kept in sync
normalize_local_keys
fi
fi
if [[ -f "${FUCHSIA_ROOT}/.fx-ssh-path" ]]; then
{ read old_keyfile && read old_authfile; } < "${FUCHSIA_ROOT}/.fx-ssh-path"
if [[ "${old_keyfile}" == "${keyfile}" && "${old_authfile}" == "${authfile}" ]]; then
exit 0
fi
fi
echo -e "${keyfile}\n${authfile}" >"${FUCHSIA_ROOT}/.fx-ssh-path"