67 lines
2.4 KiB
Plaintext
67 lines
2.4 KiB
Plaintext
|
#!/bin/bash
|
||
|
|
||
|
# This is a small wrapper script for gpg intended to be used by git
|
||
|
# As far as I can tell, git cannot automatically pick a fallback signing key by itself
|
||
|
# Setting GIT_SIGN_FALLBACK_KEY_IDS="config" or leaving it unset will make the program try all keys listed by git config
|
||
|
# Setting GIT_SIGN_FALLBACK_KEY_IDS="all" will make the program try all keys listed by gpg
|
||
|
# Setting the fallback keys manually can be done like this: GIT_SIGN_FALLBACK_KEY_IDS="<key id 1> <key id 2>"
|
||
|
# This script was written in about two hours, if you find any bugs, tell Luca!
|
||
|
|
||
|
set -eu
|
||
|
|
||
|
# A quick and dirty array filtering function
|
||
|
function reject {
|
||
|
predicate=$1
|
||
|
shift
|
||
|
|
||
|
for el in "$@"; do
|
||
|
if ! eval ":() { [[ $predicate ]]; }; : '$el'"; then
|
||
|
echo "$el"
|
||
|
fi
|
||
|
done
|
||
|
}
|
||
|
|
||
|
case "$*" in
|
||
|
# Git is trying to sign a commit
|
||
|
*-bsau*)
|
||
|
# The key passed by git
|
||
|
primary_key=$(echo "$*" | grep -oP '(?<=-bsau )[A-Z0-9]{16}')
|
||
|
|
||
|
# Select fallback keys based on config
|
||
|
case "${GIT_SIGN_FALLBACK_KEY_IDS:-}" in
|
||
|
"" | "config")
|
||
|
mapfile -t signing_keys < <(git config --get-all user.signingKey)
|
||
|
mapfile -t fallback_keys < <(reject "\$1 == $primary_key" "${signing_keys[@]}")
|
||
|
;;
|
||
|
"all")
|
||
|
mapfile -t signing_keys < <(gpg --list-keys --with-colons | awk -F: '/^pub:/ {print $5}')
|
||
|
mapfile -t fallback_keys < <(reject "\$1 == $primary_key" "${signing_keys[@]}")
|
||
|
;;
|
||
|
*)
|
||
|
mapfile -t fallback_keys < <(echo "$GIT_SIGN_FALLBACK_KEY_IDS" | xargs -n 1)
|
||
|
;;
|
||
|
esac
|
||
|
|
||
|
# Number of signing keys
|
||
|
n_keys=$(($(echo "${fallback_keys[*]}" | wc -w) + 1))
|
||
|
|
||
|
# Unaccounted for gpg flags
|
||
|
mapfile -t extra_flags < <(reject "\$1 == -bsau || \$1 == --status-fd=2 || \$1 == $primary_key" "$@")
|
||
|
gpg_flags=("${extra_flags[@]}" --status-fd=2 -bsau)
|
||
|
|
||
|
# Try signing with the primary key first, then try the fallback keys
|
||
|
counter=0
|
||
|
try_key=$primary_key
|
||
|
while
|
||
|
[ "$counter" -lt "$n_keys" ] &&
|
||
|
! gpg "${gpg_flags[@]}" "$try_key"
|
||
|
do
|
||
|
try_key="${fallback_keys[$counter - 1]}"
|
||
|
counter=$((counter + 1))
|
||
|
done
|
||
|
;;
|
||
|
|
||
|
# Git is trying to do something else, so we just pass the flags through
|
||
|
*) gpg "$@" ;;
|
||
|
esac
|