summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Linderud <morten@linderud.pw>2021-02-22 00:09:07 +0100
committerAllan McRae <allan@archlinux.org>2021-02-24 14:05:48 +0100
commit0f75ab3224141a5e8a4fe72b48b4639c83c6316b (patch)
treee2357a0c892571dd81fb03e8804b5f8db0cdafe7
parent7587153a447bd537c8f138be9ca0a3886a5f1e57 (diff)
downloadpacman-0f75ab3224141a5e8a4fe72b48b4639c83c6316b.tar.gz
pacman-0f75ab3224141a5e8a4fe72b48b4639c83c6316b.tar.xz
pacman-key: --refresh-keys queries WKD before keyserver
With the recent outages of the keyservers there is a possibility of `--refresh-keys` failing to fetch new keys. A lot of current key distribution is done over WKD these days, and `pacman-key` has the ability to use it for `--recv-key`. There was a hope `gpg` would end up supporting WKD for the refresh functionality, but this seems to be limited to expired keys fetched through WKD. Since this functionality isn't yet available it makes sense to stuff it into `pacman-key`. The current implementation looks over all available keyids in the keyring, attempts to fetch over WKD and then fall backs to keyservers if no email has a valid WKD available. The downside of this approach is that it takes a bit longer to refresh the keys, but it should be more robust as the distribution should be providing their own WKDs. Co-authored-by: Jonas Witschel <diabonas@archlinux.org> Signed-off-by: Morten Linderud <morten@linderud.pw> Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r--scripts/pacman-key.sh.in33
1 files changed, 29 insertions, 4 deletions
diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
index c65669f5..7e364c30 100644
--- a/scripts/pacman-key.sh.in
+++ b/scripts/pacman-key.sh.in
@@ -540,11 +540,36 @@ receive_keys() {
}
refresh_keys() {
+ local ret=0 ids masterkey emails
+
check_keyids_exist "$@"
- if ! "${GPG_PACMAN[@]}" --refresh-keys "$@" ; then
- error "$(gettext "A specified local key could not be updated from a keyserver.")"
- exit 1
- fi
+
+ # don't try to refresh the user's local masterkey
+ masterkey="$("${GPG_PACMAN[@]}" --list-keys --with-colons pacman@localhost |
+ awk -F: '$1 == "pub" { print $5 }')"
+
+ mapfile -t ids < \
+ <("${GPG_PACMAN[@]}" --list-keys --with-colons "$@" |
+ awk -F: '$1 == "pub" { print $5 }' | grep -vx "$masterkey")
+
+ for id in "${ids[@]}"; do
+ mapfile -t emails < \
+ <("${GPG_PACMAN[@]}" --list-keys --list-options show-only-fpr-mbox "$id" |
+ awk '{print $2 }')
+
+ # first try looking up the key in a WKD (only works by email address)
+ for email in "${emails[@]}"; do
+ "${GPG_PACMAN[@]}" --locate-external-keys "$email" && break
+ done
+
+ # if no key was found, fall back to using the keyservers (with the key fingerprint instead)
+ if (( $? )) && ! "${GPG_PACMAN[@]}" --refresh-keys "$id"; then
+ error "$(gettext "Could not update key: %s") "$id"
+ ret=1
+ fi
+ done
+
+ exit $ret
}
verify_sig() {