commit: 3287c2fa3e468949fe1663a0e35368a5af66f823
Author: Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Thu Jun 19 01:18:44 2025 +0000
Commit: Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Jun 19 18:13:10 2025 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=3287c2fa
emerge-webrsync: make die/exit behave properly in check_file_signature_gpg()
A recent commit introduced the ability for emerge-webrsync to ensure
that defunct gpg-agent(1) processes are terminated upon the
check_file_signature_gpg() function returning, provided that it was
tasked with creating an ephemeral keyring. However, it also introduced a
minor regression as concerns error handling and the conveyance of
diagnostic messages. Consider the following as a case in point.
fingerprint=$(gpg_fingerprint '<infrastructure <AT> gentoo.org>') \
|| die "couldn't find a fingerprint for the <infrastructure <AT> gentoo.org>
key"
The intention is straightforward: should it prove impossible to obtain
the fingerprint of the applicable signing key then display a diagnostic
message before immediately exiting the program. Yet, because the
definition of the function is a compound command that incurs a subshell,
only the subshell will be exited. The function will then yield to its
caller, check_file_signature(), which responds as follows.
die "signature verification failed for ${file@Q}"
Only then shall emerge-webrsync exit, resulting in an additional
diagnostic message being unintentionally shown.
* Checking signature ...
emerge-webrsync: couldn't find a fingerprint for the <infrastructure <AT>
gentoo.org> key
emerge-webrsync: signature verification failed for 'gentoo-20250617.tar.xz'
Address this issue in a manner twofold. Firstly, declare the function as
a compound command of the { … } form so as not to incur a subshell.
Secondly, delegate the responsibility for terminating gpg-agent(1) to
the EXIT trap that is already declared by the main() function.
Additionally, given that the trap is already responsible for wiping the
temporary directory, relocate the trap payload to a dedicated function
by the name of cleanup(). This helps to keep the code reasonably tidy.
Fixes: c9147587da34ecf6cd19bf1ed2d0835d3d8c1777
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>
bin/emerge-webrsync | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync
index 22df8ce635..a705a59eef 100755
--- a/bin/emerge-webrsync
+++ b/bin/emerge-webrsync
@@ -57,9 +57,12 @@ main() {
mkdir -p "${PORTAGE_TMPDIR}/portage"
- # Create a temporary directory whose subsequent removal is guaranteed.
- tmpdir=
- trap 'rm -rf -- "${tmpdir}"' EXIT
+ # The cleanup function shall terminate defunct gpg-agent(1) processes
+ # and remove the destructable temporary directory.
+ unset -v GNUPGHOME tmpdir
+ trap cleanup EXIT
+
+ # Create a destructable temporary directory and switch to it.
tmpdir=$(mktemp -d -- "${PORTAGE_TMPDIR}/portage/webrsync.XXXXXX") \
&& cd -- "${tmpdir}" \
|| exit
@@ -88,6 +91,15 @@ main() {
fi
}
+cleanup() {
+ # Prevent gpg-agent(1) from lingering for ephemeral keyrings.
+ if [[ ${GNUPGHOME} && ! ${PORTAGE_GPG_DIR} ]]; then
+ gpgconf -K gpg-agent
+ fi
+
+ rm -rf -- "${tmpdir}"
+}
+
usage() {
cat <<-EOF
Usage: $0 [options]
@@ -277,10 +289,9 @@ check_file_signature_gemato() {
gemato "${gemato_args[@]}" -- "${signature}" "${file}"
}
-check_file_signature_gpg() (
+check_file_signature_gpg() {
local signature=$1 file=$2
local fingerprint key
- local -x GNUPGHOME
if [[ -n ${PORTAGE_GPG_KEY} ]] ; then
key="${PORTAGE_GPG_KEY}"
@@ -297,12 +308,13 @@ check_file_signature_gpg() (
die "${key@Q} does not exist (or is not a file)"
fi
+ export GNUPGHOME
+
if [[ ! ${GNUPGHOME=${PORTAGE_GPG_DIR}} ]]; then
# The PORTAGE_GPG_DIR variable is either unset or empty. Create
# a temporary directory to contain an ephemeral keyring into
# which Gentoo's distributed public key block shall be imported.
GNUPGHOME=$(mktemp -d --
"${PORTAGE_TMPDIR}/portage/webrsync.XXXXXX") \
- && trap 'gpgconf -K gpg-agent' EXIT \
&& gpg --batch --import "${key}" \
|| exit
@@ -317,7 +329,7 @@ check_file_signature_gpg() (
fi
gpg_verify "${signature}" "${file}"
-)
+}
gpg_fingerprint() {
local -a fields