From 8375d5b58038fc026098dcccc3de87cd9d740334 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 17 Aug 2018 16:33:41 +0200 Subject: Support multiple keyrings in sources.list Signed-By A user can specify multiple fingerprints for a while now, so its seems counter-intuitive to support only one keyring, especially if this isn't really checked or enforced and while unlikely mixtures of both should work properly, too, instead of a kinda random behaviour. --- cmdline/apt-key.in | 157 +++++++++++++++++++++++++++++------------------------ 1 file changed, 86 insertions(+), 71 deletions(-) (limited to 'cmdline') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 7ec1b034c..e9187b423 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -15,6 +15,74 @@ eval "$(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI)" aptkey_echo() { echo "$@"; } +find_gpgv_status_fd() { + while [ -n "$1" ]; do + if [ "$1" = '--status-fd' ]; then + shift + echo "$1" + break + fi + shift + done +} +GPGSTATUSFD="$(find_gpgv_status_fd "$@")" + +apt_warn() { + if [ -z "$GPGHOMEDIR" ]; then + echo >&2 'W:' "$@" + else + echo 'W:' "$@" > "${GPGHOMEDIR}/aptwarnings.log" + fi + if [ -n "$GPGSTATUSFD" ]; then + echo >&${GPGSTATUSFD} '[APTKEY:] WARNING' "$@" + fi +} +apt_error() { + if [ -z "$GPGHOMEDIR" ]; then + echo >&2 'E:' "$@" + else + echo 'E:' "$@" > "${GPGHOMEDIR}/aptwarnings.log" + fi + if [ -n "$GPGSTATUSFD" ]; then + echo >&${GPGSTATUSFD} '[APTKEY:] ERROR' "$@" + fi +} + +cleanup_gpg_home() { + if [ -z "$GPGHOMEDIR" ]; then return; fi + if [ -s "$GPGHOMEDIR/aptwarnings.log" ]; then + cat >&2 "$GPGHOMEDIR/aptwarnings.log" + fi + if command_available 'gpgconf'; then + GNUPGHOME="${GPGHOMEDIR}" gpgconf --kill all >/dev/null 2>&1 || true + fi + rm -rf "$GPGHOMEDIR" +} + +# gpg needs (in different versions more or less) files to function correctly, +# so we give it its own homedir and generate some valid content for it later on +create_gpg_home() { + # for cases in which we want to cache a homedir due to expensive setup + if [ -n "$GPGHOMEDIR" ]; then + return + fi + if [ -n "$TMPDIR" ]; then + # tmpdir is a directory and current user has rwx access to it + # same tests as in apt-pkg/contrib/fileutl.cc GetTempDir() + if [ ! -d "$TMPDIR" ] || [ ! -r "$TMPDIR" ] || [ ! -w "$TMPDIR" ] || [ ! -x "$TMPDIR" ]; then + unset TMPDIR + fi + fi + GPGHOMEDIR="$(mktemp --directory --tmpdir 'apt-key-gpghome.XXXXXXXXXX')" + CURRENTTRAP="${CURRENTTRAP} cleanup_gpg_home;" + trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM + if [ -z "$GPGHOMEDIR" ]; then + apt_error "Could not create temporary gpg home directory in $TMPDIR (wrong permissions?)" + exit 28 + fi + chmod 700 "$GPGHOMEDIR" +} + requires_root() { if [ "$(id -u)" -ne 0 ]; then apt_error "This command can only be used by root." @@ -282,7 +350,7 @@ foreach_keyring_do() { shift # if a --keyring was given, just work on this one if [ -n "$FORCED_KEYRING" ]; then - $ACTION "$TRUSTEDFILE" "$@" + $ACTION "$FORCED_KEYRING" "$@" else # otherwise all known keyrings are up for inspection if accessible_file_exists "$TRUSTEDFILE" && is_supported_keyring "$TRUSTEDFILE"; then @@ -525,11 +593,26 @@ while [ -n "$1" ]; do case "$1" in --keyring) shift - TRUSTEDFILE="$1" - FORCED_KEYRING="$1" + if [ -z "$FORCED_KEYRING" -o "$FORCED_KEYRING" = '/dev/null' ]; then + TRUSTEDFILE="$1" + FORCED_KEYRING="$1" + elif [ "$TRUSTEDFILE" = "$FORCED_KEYRING" ]; then + create_gpg_home + FORCED_KEYRING="${GPGHOMEDIR}/mergedkeyrings.gpg" + echo -n '' > "$FORCED_KEYRING" + chmod 0644 -- "$FORCED_KEYRING" + catfile "$TRUSTEDFILE" "$FORCED_KEYRING" + catfile "$1" "$FORCED_KEYRING" + else + catfile "$1" "$FORCED_KEYRING" + fi ;; --keyid) shift + if [ -n "$FORCED_KEYID" ]; then + apt_error 'Specifying --keyid multiple times is not supported' + exit 1 + fi FORCED_KEYID="$1" ;; --secret-keyring) @@ -582,74 +665,6 @@ if [ -z "$command" ]; then fi shift -find_gpgv_status_fd() { - while [ -n "$1" ]; do - if [ "$1" = '--status-fd' ]; then - shift - echo "$1" - break - fi - shift - done -} -GPGSTATUSFD="$(find_gpgv_status_fd "$@")" - -apt_warn() { - if [ -z "$GPGHOMEDIR" ]; then - echo >&2 'W:' "$@" - else - echo 'W:' "$@" > "${GPGHOMEDIR}/aptwarnings.log" - fi - if [ -n "$GPGSTATUSFD" ]; then - echo >&${GPGSTATUSFD} '[APTKEY:] WARNING' "$@" - fi -} -apt_error() { - if [ -z "$GPGHOMEDIR" ]; then - echo >&2 'E:' "$@" - else - echo 'E:' "$@" > "${GPGHOMEDIR}/aptwarnings.log" - fi - if [ -n "$GPGSTATUSFD" ]; then - echo >&${GPGSTATUSFD} '[APTKEY:] ERROR' "$@" - fi -} - -cleanup_gpg_home() { - if [ -z "$GPGHOMEDIR" ]; then return; fi - if [ -s "$GPGHOMEDIR/aptwarnings.log" ]; then - cat >&2 "$GPGHOMEDIR/aptwarnings.log" - fi - if command_available 'gpgconf'; then - GNUPGHOME="${GPGHOMEDIR}" gpgconf --kill all >/dev/null 2>&1 || true - fi - rm -rf "$GPGHOMEDIR" -} - -# gpg needs (in different versions more or less) files to function correctly, -# so we give it its own homedir and generate some valid content for it later on -create_gpg_home() { - # for cases in which we want to cache a homedir due to expensive setup - if [ -n "$GPGHOMEDIR" ]; then - return - fi - if [ -n "$TMPDIR" ]; then - # tmpdir is a directory and current user has rwx access to it - # same tests as in apt-pkg/contrib/fileutl.cc GetTempDir() - if [ ! -d "$TMPDIR" ] || [ ! -r "$TMPDIR" ] || [ ! -w "$TMPDIR" ] || [ ! -x "$TMPDIR" ]; then - unset TMPDIR - fi - fi - GPGHOMEDIR="$(mktemp --directory --tmpdir 'apt-key-gpghome.XXXXXXXXXX')" - CURRENTTRAP="${CURRENTTRAP} cleanup_gpg_home;" - trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM - if [ -z "$GPGHOMEDIR" ]; then - apt_error "Could not create temporary gpg home directory in $TMPDIR (wrong permissions?)" - exit 28 - fi - chmod 700 "$GPGHOMEDIR" -} - prepare_gpg_home() { # crude detection if we are called from a maintainerscript where the # package depends on gnupg or not. We accept recommends here as -- cgit v1.2.3