From cee12b2bd16b001153051fa8cbaacb7b1fe1403b Mon Sep 17 00:00:00 2001 From: Igor Soarez Date: Mon, 2 Nov 2026 13:09:27 +0200 Subject: yubikey-git: three keys, one per YubiKey; any one of them will do --- bin/yubikey-git | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'bin') diff --git a/bin/yubikey-git b/bin/yubikey-git index 9083097..6e46c1f 100755 --- a/bin/yubikey-git +++ b/bin/yubikey-git @@ -1,12 +1,12 @@ #!/bin/bash -# Opt this host in to git over ssh with the YubiKey git key, or back out. +# Opt this host in to git over ssh with the YubiKey git keys, or back out. # # yubikey-git enable set it up; safe to re-run # yubikey-git disable undo everything enable did # yubikey-git status what is in place # -# Then, with the YubiKey plugged in, one touch per fetch or push: +# Then, with any one of the YubiKeys plugged in, one touch per fetch or push: # # git clone git@git.soarez.net:sz/.git # @@ -16,11 +16,11 @@ # # What enable does, all of it undone by disable: # -# ~/.ssh/id_ed25519_sk_git a copy of config/ssh/yubikey-git's key, at +# ~/.ssh/id_ed25519_sk_git* copies of config/ssh/yubikey-git's keys, at # mode 600, which ssh insists on and git -# cannot store. It is the key's handle, not +# cannot store. Each is a key's handle, not # its private half: see that directory's -# config for why it is safe in this repo. +# config for why they are safe in this repo. # ~/.config/ssh/yubikey-git a link to that directory: the ssh config # and git.soarez.net's pinned host key # ~/.config/ssh/enabled.d/yubikey-git.conf @@ -36,7 +36,8 @@ set -euo pipefail name="yubikey-git" -key="${HOME}/.ssh/id_ed25519_sk_git" +# One per YubiKey, each its own key; any of them will do. +keys=(id_ed25519_sk_git_main_nfc id_ed25519_sk_git_backup_nfc id_ed25519_sk_git) # The same path config/ssh/entry includes from, not $XDG_CONFIG_HOME. cfg="${HOME}/.config/ssh" dir_link="${cfg}/${name}" @@ -82,14 +83,18 @@ need_fido_ssh() { } enable() { + local k key need_fido_ssh install -d -m 700 "${HOME}/.ssh" - if [[ -e "${key}" ]] && ! cmp -s "${key}" "${src_dir}/id_ed25519_sk_git"; then - die "${key} exists and is a different key; move it aside first" - fi - install -m 600 "${src_dir}/id_ed25519_sk_git" "${key}" - install -m 644 "${src_dir}/id_ed25519_sk_git.pub" "${key}.pub" + for k in "${keys[@]}"; do + key="${HOME}/.ssh/${k}" + if [[ -e "${key}" ]] && ! cmp -s "${key}" "${src_dir}/${k}"; then + die "${key} exists and is a different key; move it aside first" + fi + install -m 600 "${src_dir}/${k}" "${key}" + install -m 644 "${src_dir}/${k}.pub" "${key}.pub" + done mkdir -p "${cfg}/enabled.d" if [[ -e "${dir_link}" || -L "${dir_link}" ]] && ! ours "${dir_link}" "${src_dir}"; then @@ -108,24 +113,31 @@ enable() { die "ssh did not pick the config up, so it is undone; is ~/.ssh/config this repo's config/ssh/entry?" fi - echo "${name}: enabled. With the YubiKey plugged in:" + echo "${name}: enabled. With one of the YubiKeys plugged in:" echo " git clone git@git.soarez.net:sz/.git" } disable() { + local k key ours "${conf_link}" "${dir_link}/config" && rm "${conf_link}" ours "${dir_link}" "${src_dir}" && rm "${dir_link}" - if [[ -f "${key}" ]] && cmp -s "${key}" "${src_dir}/id_ed25519_sk_git"; then - rm -f "${key}" "${key}.pub" - fi + for k in "${keys[@]}"; do + key="${HOME}/.ssh/${k}" + if [[ -f "${key}" ]] && cmp -s "${key}" "${src_dir}/${k}"; then + rm -f "${key}" "${key}.pub" + fi + done echo "${name}: disabled" } status() { - local on=y + local on=y k key if ours "${conf_link}" "${dir_link}/config"; then echo "ssh config: enabled (${conf_link})"; else echo "ssh config: not enabled"; on=""; fi if ours "${dir_link}" "${src_dir}"; then echo "config dir: ${dir_link}"; else echo "config dir: missing"; on=""; fi - if [[ -f "${key}" ]] && cmp -s "${key}" "${src_dir}/id_ed25519_sk_git"; then echo "key handle: ${key}"; else echo "key handle: missing"; on=""; fi + for k in "${keys[@]}"; do + key="${HOME}/.ssh/${k}" + if [[ -f "${key}" ]] && cmp -s "${key}" "${src_dir}/${k}"; then echo "key handle: ${key}"; else echo "key handle: ${k} missing"; on=""; fi + done echo "ssh: $(command -v ssh) ($(ssh -V 2>&1))" [[ -n "${on}" ]] } -- cgit v1.2.3