1
0
Fork 0

git: stupid hack to enable signing key fallbacks

This commit is contained in:
Luca Bilke 2024-06-27 18:45:08 +02:00
parent cce48a0f65
commit 468c5311d3
Signed by: luca
GPG Key ID: F6E11C9BAA7C82F5
3 changed files with 72 additions and 2 deletions

View File

@ -1,3 +1,4 @@
# vim: set ft=gitconfig:
[init]
defaultBranch = main
[push]
@ -11,10 +12,12 @@
helper = store
[commit]
gpgsign = true
[tag]
gpgsign = true
[gpg]
program = /home/luca/.config/git/gpg-fallback-keys
[include]
path = ~/.config/git/host
[includeIf "gitdir:~/Documents/code/tralios/"]
path = ~/.config/git/tralios
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f

66
.config/git/gpg-fallback-keys Executable file
View File

@ -0,0 +1,66 @@
#!/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

View File

@ -120,6 +120,7 @@ export XBPS_DISTDIR="$XDG_DOCUMENTS_DIR/dev/server/void-packages"
export ZK_NOTEBOOK_DIR="$XDG_DOCUMENTS_DIR/notes"
export ZSH_COMPDUMP="$XDG_CACHE_HOME/zcompdump"
export _JAVA_OPTIONS="-Djava.util.prefs.userRoot=$XDG_CONFIG_HOME/java"
export GIT_SIGN_FALLBACK_KEY_IDS="config"
localpath=""
export PATH="$PATH:$localpath"