X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/e23ee4c21c6d8045ab020526aa864a48dc16ddd9..dd592790c8f1be4925f74266742c163516ab80c7:/cmdline/apt-key.in diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index f1d021e8a..80eee6265 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -4,17 +4,14 @@ set -e unset GREP_OPTIONS export IFS="$(printf "\n\b")" -APT_DIR="/" -eval $(apt-config shell APT_DIR Dir) - MASTER_KEYRING='&keyring-master-filename;' -eval $(apt-config shell MASTER_KEYRING APT::Key::MasterKeyring) +eval "$(apt-config shell MASTER_KEYRING APT::Key::MasterKeyring)" ARCHIVE_KEYRING='&keyring-filename;' -eval $(apt-config shell ARCHIVE_KEYRING APT::Key::ArchiveKeyring) +eval "$(apt-config shell ARCHIVE_KEYRING APT::Key::ArchiveKeyring)" REMOVED_KEYS='&keyring-removed-filename;' -eval $(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys) +eval "$(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys)" ARCHIVE_KEYRING_URI='&keyring-uri;' -eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI) +eval "$(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI)" aptkey_echo() { echo "$@"; } @@ -40,6 +37,10 @@ command_available() { return 1 } +escape_shell() { + echo "$@" | sed -e "s#'#'\"'\"'#g" +} + get_fingerprints_of_keyring() { aptkey_execute "$GPG_SH" --keyring "$1" --with-colons --fingerprint | while read publine; do # search for a public key @@ -55,8 +56,8 @@ get_fingerprints_of_keyring() { } add_keys_with_verify_against_master_keyring() { - ADD_KEYRING=$1 - MASTER=$2 + ADD_KEYRING="$1" + MASTER="$2" if [ ! -f "$ADD_KEYRING" ]; then echo >&2 "ERROR: '$ADD_KEYRING' not found" @@ -72,8 +73,8 @@ add_keys_with_verify_against_master_keyring() { # all keys that are exported must have a valid signature # from a key in the $distro-master-keyring add_keys="$(get_fingerprints_of_keyring "$ADD_KEYRING")" - all_add_keys=`aptkey_execute "$GPG_SH" --keyring "$ADD_KEYRING" --with-colons --list-keys | grep ^[ps]ub | cut -d: -f5` - master_keys=`aptkey_execute "$GPG_SH" --keyring "$MASTER" --with-colons --list-keys | grep ^pub | cut -d: -f5` + all_add_keys="$(aptkey_execute "$GPG_SH" --keyring "$ADD_KEYRING" --with-colons --list-keys | grep ^[ps]ub | cut -d: -f5)" + master_keys="$(aptkey_execute "$GPG_SH" --keyring "$MASTER" --with-colons --list-keys | grep ^pub | cut -d: -f5)" # ensure there are no colisions LP: #857472 for all_add_key in $all_add_keys; do @@ -114,6 +115,9 @@ add_keys_with_verify_against_master_keyring() { # the archive-keyring keys needs to be signed with the master key # (otherwise it does not make sense from a security POV) net_update() { + local APT_DIR='/' + eval $(apt-config shell APT_DIR Dir) + # Disabled for now as code is insecure (LP: #1013639 (and 857472, 1013128)) APT_KEY_NET_UPDATE_ENABLED="" eval $(apt-config shell APT_KEY_NET_UPDATE_ENABLED APT::Key::Net-Update-Enabled) @@ -137,7 +141,7 @@ net_update() { keyring="${APT_DIR}/var/lib/apt/keyrings/$(basename "$ARCHIVE_KEYRING_URI")" old_mtime=0 if [ -e $keyring ]; then - old_mtime=$(stat -c %Y $keyring) + old_mtime=$(stat -c %Y "$keyring") fi (cd "${APT_DIR}/var/lib/apt/keyrings"; wget --timeout=90 -q -N "$ARCHIVE_KEYRING_URI") if [ ! -e "$keyring" ]; then @@ -228,7 +232,7 @@ foreach_keyring_do() { $ACTION "$TRUSTEDFILE" "$@" fi local TRUSTEDPARTS="/etc/apt/trusted.gpg.d" - eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) + eval "$(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)" if [ -d "$TRUSTEDPARTS" ]; then # strip / suffix as gpg will double-slash in that case (#665411) local STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}" @@ -360,7 +364,7 @@ setup_merged_keyring() { FORCED_KEYRING="${GPGHOMEDIR}/forcedkeyid.gpg" TRUSTEDFILE="${FORCED_KEYRING}" echo "#!/bin/sh -exec sh \"${GPG}\" --keyring \"${TRUSTEDFILE}\" \"\$@\"" > "${GPGHOMEDIR}/gpg.1.sh" +exec sh '($(escape_shell "${GPG}")' --keyring '$(escape_shell "${TRUSTEDFILE}")' \"\$@\"" > "${GPGHOMEDIR}/gpg.1.sh" GPG="${GPGHOMEDIR}/gpg.1.sh" # ignore error as this "just" means we haven't found the forced keyid and the keyring will be empty import_keyring_into_keyring '' "$TRUSTEDFILE" "$FORCED_KEYID" || true @@ -372,12 +376,12 @@ exec sh \"${GPG}\" --keyring \"${TRUSTEDFILE}\" \"\$@\"" > "${GPGHOMEDIR}/gpg.1. touch "${GPGHOMEDIR}/pubring.gpg" "${GPGHOMEDIR}/pubring.orig.gpg" fi echo "#!/bin/sh -exec sh \"${GPG}\" --keyring \"${GPGHOMEDIR}/pubring.gpg\" \"\$@\"" > "${GPGHOMEDIR}/gpg.1.sh" +exec sh '$(escape_shell "${GPG}")' --keyring '$(escape_shell "${GPGHOMEDIR}/pubring.gpg")' \"\$@\"" > "${GPGHOMEDIR}/gpg.1.sh" GPG="${GPGHOMEDIR}/gpg.1.sh" else create_new_keyring "$TRUSTEDFILE" echo "#!/bin/sh -exec sh \"${GPG}\" --keyring \"${TRUSTEDFILE}\" \"\$@\"" > "${GPGHOMEDIR}/gpg.1.sh" +exec sh '$(escape_shell "${GPG}")' --keyring '$(escape_shell "${TRUSTEDFILE}")' \"\$@\"" > "${GPGHOMEDIR}/gpg.1.sh" GPG="${GPGHOMEDIR}/gpg.1.sh" fi } @@ -479,13 +483,13 @@ create_gpg_home() { fi fi GPGHOMEDIR="$(mktemp -d)" - CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';" + CURRENTTRAP="${CURRENTTRAP} rm -rf '$(escape_shell "${GPGHOMEDIR}")';" trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM chmod 700 "$GPGHOMEDIR" } prepare_gpg_home() { - eval $(apt-config shell GPG_EXE Apt::Key::gpgcommand) + eval "$(apt-config shell GPG_EXE Apt::Key::gpgcommand)" if [ -n "$GPG_EXE" ] && command_available "$GPG_EXE"; then true @@ -502,38 +506,38 @@ prepare_gpg_home() { create_gpg_home - # We don't use a secret keyring, of course, but gpg panics and - # implodes if there isn't one available - and writeable for imports - SECRETKEYRING="${GPGHOMEDIR}/secring.gpg" - touch "$SECRETKEYRING" - # create the trustdb with an (empty) dummy keyring # older gpgs required it, newer gpgs even warn that it isn't needed, # but require it nonetheless for some commands, so we just play safe # here for the foreseeable future and create a dummy one + touch "${GPGHOMEDIR}/empty.gpg" if ! "$GPG_EXE" --ignore-time-conflict --no-options --no-default-keyring \ - --homedir "$GPGHOMEDIR" --quiet --check-trustdb --keyring "$SECRETKEYRING" >"${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + --homedir "$GPGHOMEDIR" --quiet --check-trustdb --keyring "${GPGHOMEDIR}/empty.gpg" >"${GPGHOMEDIR}/gpgoutput.log" 2>&1; then cat >&2 "${GPGHOMEDIR}/gpgoutput.log" false fi - # tell gpg that it shouldn't try to maintain a trustdb file + + # now tell gpg that it shouldn't try to maintain this trustdb file echo "#!/bin/sh -exec \"${GPG_EXE}\" --ignore-time-conflict --no-options --no-default-keyring \\ - --homedir \"${GPGHOMEDIR}\" --no-auto-check-trustdb --trust-model always \"\$@\"" > "${GPGHOMEDIR}/gpg.0.sh" +exec '$(escape_shell "${GPG_EXE}")' --ignore-time-conflict --no-options --no-default-keyring \\ +--homedir '$(escape_shell "${GPGHOMEDIR}")' --no-auto-check-trustdb --trust-model always \"\$@\"" > "${GPGHOMEDIR}/gpg.0.sh" GPG_SH="${GPGHOMEDIR}/gpg.0.sh" GPG="$GPG_SH" + # We don't usually need a secret keyring, of course, but # for advanced operations, we might really need a secret keyring after all if [ -n "$FORCED_SECRET_KEYRING" ] && [ -r "$FORCED_SECRET_KEYRING" ]; then - rm -f "$SECRETKEYRING" - cp -a "$FORCED_SECRET_KEYRING" "$SECRETKEYRING" + if ! aptkey_execute "$GPG" -v --batch --import "$FORCED_SECRET_KEYRING" >"${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + cat >&2 "${GPGHOMEDIR}/gpgoutput.log" + false + fi + else + # and then, there are older versions of gpg which panic and implode + # if there isn't one available - and writeable for imports + # and even if not output is littered with the creation of a secring, + # so lets call import once to have it create what it wants in silence + echo -n | aptkey_execute "$GPG" --batch --import >/dev/null 2>&1 || true fi - - # older gpg versions need a secring file, but newer versions take it as - # a hint to start a migration from earlier versions. The file is empty - # anyhow, so nothing actually happens, but its three lines of output - # nobody expects to see in apt-key context, so trigger it in silence - echo -n | aptkey_execute "$GPG" --batch --import >/dev/null 2>&1 || true } if [ "$command" != 'help' ] && [ "$command" != 'verify' ]; then