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>
This commit is contained in:
Morten Linderud 2021-02-22 00:09:07 +01:00 committed by Allan McRae
parent 7587153a44
commit 0f75ab3224

View file

@ -540,11 +540,36 @@ receive_keys() {
} }
refresh_keys() { refresh_keys() {
local ret=0 ids masterkey emails
check_keyids_exist "$@" check_keyids_exist "$@"
if ! "${GPG_PACMAN[@]}" --refresh-keys "$@" ; then
error "$(gettext "A specified local key could not be updated from a keyserver.")" # don't try to refresh the user's local masterkey
exit 1 masterkey="$("${GPG_PACMAN[@]}" --list-keys --with-colons pacman@localhost |
fi 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() { verify_sig() {