From 3e032cda2d3558c076a559697e664546da56c243 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 15:02:39 +0100 Subject: remove leftover debug output from multikey softlink Git-Dch: Ignore --- cmdline/apt-key.in | 1 - 1 file changed, 1 deletion(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 0774cf4b7..59b69b89c 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -198,7 +198,6 @@ remove_key_from_keyring() { REALTARGET="$(readlink -f "$1")" mv -f "$1" "${1}.dpkg-tmp" cp -a "$REALTARGET" "$1" - ls "$(dirname $1)" fi # delete the key from the keyring $GPG --batch --delete-key --yes "$2" -- cgit v1.2.3 From 3d0def059874a6e63566ce13579de296ccd26932 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 16:43:19 +0100 Subject: add a (hidden) --quiet option for apt-key --- cmdline/apt-key.in | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 59b69b89c..d50ad40ac 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -39,6 +39,8 @@ ARCHIVE_KEYRING_URI='&keyring-uri;' eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI) TMP_KEYRING=${APT_DIR}/var/lib/apt/keyrings/maybe-import-keyring.gpg +aptkey_echo() { echo "$@"; } + requires_root() { if [ "$(id -u)" -ne 0 ]; then echo >&1 "ERROR: This command can only be used by root." @@ -142,7 +144,7 @@ net_update() { fi new_mtime=$(stat -c %Y $keyring) if [ $new_mtime -ne $old_mtime ]; then - echo "Checking for new archive signing keys now" + aptkey_echo "Checking for new archive signing keys now" add_keys_with_verify_against_master_keyring $keyring $MASTER_KEYRING fi } @@ -227,7 +229,7 @@ remove_key() { done fi fi - echo "OK" + aptkey_echo "OK" } @@ -267,6 +269,10 @@ while [ -n "$1" ]; do requires_root() { true; } shift ;; + --quiet) + aptkey_echo() { true; } + shift + ;; --*) echo >&2 "Unknown option: $1" usage @@ -316,7 +322,7 @@ case "$command" in requires_root init_keyring "$TRUSTEDFILE" $GPG --quiet --batch --import "$1" - echo "OK" + aptkey_echo "OK" ;; del|rm|remove) init_keyring "$TRUSTEDFILE" @@ -348,7 +354,7 @@ case "$command" in ;; adv*) init_keyring "$TRUSTEDFILE" - echo "Executing: $GPG $*" + aptkey_echo "Executing: $GPG $*" $GPG $* ;; help) -- cgit v1.2.3 From 84b286f65c55e21b4734a17474f1cba464cbbd9c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 16:44:49 +0100 Subject: all errors should be printed to stderr Git-Dch: Ignore --- cmdline/apt-key.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index d50ad40ac..e592925d6 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -43,7 +43,7 @@ aptkey_echo() { echo "$@"; } requires_root() { if [ "$(id -u)" -ne 0 ]; then - echo >&1 "ERROR: This command can only be used by root." + echo >&2 "ERROR: This command can only be used by root." exit 1 fi } @@ -63,11 +63,11 @@ add_keys_with_verify_against_master_keyring() { MASTER=$2 if [ ! -f "$ADD_KEYRING" ]; then - echo "ERROR: '$ADD_KEYRING' not found" + echo >&2 "ERROR: '$ADD_KEYRING' not found" return - fi + fi if [ ! -f "$MASTER" ]; then - echo "ERROR: '$MASTER' not found" + echo >&2 "ERROR: '$MASTER' not found" return fi @@ -175,7 +175,7 @@ update() { fi done else - echo "Warning: removed keys keyring $REMOVED_KEYS missing or not readable" >&2 + echo >&2 "Warning: removed keys keyring $REMOVED_KEYS missing or not readable" fi } -- cgit v1.2.3 From 9fda3be1ae000e81e15dc8840271946e140765c9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 17:14:52 +0100 Subject: only create new trusted.gpg if directory is writeable --- cmdline/apt-key.in | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index e592925d6..66e26ef0c 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -48,16 +48,6 @@ requires_root() { fi } -# gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. -init_keyring() { - for path; do - if ! [ -e "$path" ]; then - touch -- "$path" - chmod 0644 -- "$path" - fi - done -} - add_keys_with_verify_against_master_keyring() { ADD_KEYRING=$1 MASTER=$2 @@ -311,49 +301,50 @@ if [ -z "$command" ]; then fi shift -if [ "$command" != "help" ] && ! which gpg >/dev/null 2>&1; then - echo >&2 "Warning: gnupg does not seem to be installed." - echo >&2 "Warning: apt-key requires gnupg for most operations." - echo >&2 +if [ "$command" != "help" ]; then + if ! which gpg >/dev/null 2>&1; then + echo >&2 "Warning: gnupg does not seem to be installed." + echo >&2 "Warning: apt-key requires gnupg for most operations." + echo >&2 + fi + + # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. + if ! [ -e "$TRUSTEDFILE" ]; then + if [ -w "$(dirname "$TRUSTEDFILE")" ]; then + touch -- "$TRUSTEDFILE" + chmod 0644 -- "$TRUSTEDFILE" + fi + fi fi case "$command" in add) requires_root - init_keyring "$TRUSTEDFILE" $GPG --quiet --batch --import "$1" aptkey_echo "OK" ;; del|rm|remove) - init_keyring "$TRUSTEDFILE" remove_key "$1" ;; update) - init_keyring "$TRUSTEDFILE" update ;; net-update) - init_keyring "$TRUSTEDFILE" net_update ;; list) - init_keyring "$TRUSTEDFILE" $GPG --batch --list-keys ;; finger*) - init_keyring "$TRUSTEDFILE" $GPG --batch --fingerprint ;; export) - init_keyring "$TRUSTEDFILE" $GPG --armor --export "$1" ;; exportall) - init_keyring "$TRUSTEDFILE" $GPG --armor --export ;; adv*) - init_keyring "$TRUSTEDFILE" aptkey_echo "Executing: $GPG $*" $GPG $* ;; -- cgit v1.2.3 From 4f51a496d56807c73586220dd736173d7783c8b3 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 17:24:56 +0100 Subject: support (multiple) arguments properly in apt-key --- cmdline/apt-key.in | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 66e26ef0c..ab62d4c8f 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -202,24 +202,27 @@ remove_key_from_keyring() { remove_key() { requires_root - # if a --keyring was given, just remove from there - if [ -n "$FORCED_KEYRING" ]; then - remove_key_from_keyring "$FORCED_KEYRING" "$1" - else - # otherwise all known keyrings are up for inspection - local TRUSTEDFILE="/etc/apt/trusted.gpg" - eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) - eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) - remove_key_from_keyring "$TRUSTEDFILE" "$1" - TRUSTEDPARTS="/etc/apt/trusted.gpg.d" - eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) - if [ -d "$TRUSTEDPARTS" ]; then - for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do - remove_key_from_keyring "$trusted" "$1" - done + while [ -n "$1" ]; do + # if a --keyring was given, just remove from there + if [ -n "$FORCED_KEYRING" ]; then + remove_key_from_keyring "$FORCED_KEYRING" "$1" + else + # otherwise all known keyrings are up for inspection + local TRUSTEDFILE="/etc/apt/trusted.gpg" + eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) + eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) + remove_key_from_keyring "$TRUSTEDFILE" "$1" + TRUSTEDPARTS="/etc/apt/trusted.gpg.d" + eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) + if [ -d "$TRUSTEDPARTS" ]; then + for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do + remove_key_from_keyring "$trusted" "$1" + done + fi fi - fi - aptkey_echo "OK" + aptkey_echo "OK" + shift + done } @@ -320,11 +323,11 @@ fi case "$command" in add) requires_root - $GPG --quiet --batch --import "$1" + $GPG --quiet --batch --import "$@" aptkey_echo "OK" ;; del|rm|remove) - remove_key "$1" + remove_key "$@" ;; update) update @@ -333,20 +336,17 @@ case "$command" in net_update ;; list) - $GPG --batch --list-keys + $GPG --batch --list-keys "$@" ;; finger*) - $GPG --batch --fingerprint - ;; - export) - $GPG --armor --export "$1" + $GPG --batch --fingerprint "$@" ;; - exportall) - $GPG --armor --export + export|exportall) + $GPG --armor --export "$@" ;; adv*) aptkey_echo "Executing: $GPG $*" - $GPG $* + $GPG "$@" ;; help) usage -- cgit v1.2.3 From 08cfcd73f517e909823c100143c4938b9997343e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 17:41:35 +0100 Subject: set a primary-keyring only if we have access to it --- cmdline/apt-key.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index ab62d4c8f..9da5fceb8 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -281,8 +281,8 @@ if [ -z "$TRUSTEDFILE" ]; then eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) if [ -r "$TRUSTEDFILE" ]; then GPG="$GPG --keyring $TRUSTEDFILE" + GPG="$GPG --primary-keyring $TRUSTEDFILE" fi - GPG="$GPG --primary-keyring $TRUSTEDFILE" TRUSTEDPARTS="/etc/apt/trusted.gpg.d" eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) if [ -d "$TRUSTEDPARTS" ]; then @@ -316,6 +316,8 @@ if [ "$command" != "help" ]; then if [ -w "$(dirname "$TRUSTEDFILE")" ]; then touch -- "$TRUSTEDFILE" chmod 0644 -- "$TRUSTEDFILE" + GPG="$GPG --keyring $TRUSTEDFILE" + GPG="$GPG --primary-keyring $TRUSTEDFILE" fi fi fi -- cgit v1.2.3 From 4b30c1dc053278a6b9bdb50f0d91b3f934e8613d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 18:24:43 +0100 Subject: refactor key removal code to reuse it in next step Git-Dch: Ignore --- cmdline/apt-key.in | 103 ++++++++++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 48 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 9da5fceb8..9adbd6443 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -170,62 +170,69 @@ update() { } remove_key_from_keyring() { - local GPG="$GPG_CMD --keyring $1" - # check if the key is in this keyring: the key id is in the 5 column at the end - if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+$2:"; then - return - fi - if [ ! -w "$1" ]; then - echo >&2 "Key ${2} is in keyring ${1}, but can't be removed as it is read only." - return - fi - # check if it is the only key in the keyring and if so remove the keyring altogether - if [ '1' = "$($GPG --with-colons --list-keys | grep "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+:" | wc -l)" ]; then - mv -f "$1" "${1}~" # behave like gpg - return - fi - # we can't just modify pointed to files as these might be in /usr or something - local REALTARGET - if [ -L "$1" ]; then - REALTARGET="$(readlink -f "$1")" - mv -f "$1" "${1}.dpkg-tmp" - cp -a "$REALTARGET" "$1" - fi - # delete the key from the keyring - $GPG --batch --delete-key --yes "$2" - if [ -n "$REALTARGET" ]; then - # the real backup is the old link, not the copy we made - mv -f "${1}.dpkg-tmp" "${1}~" - fi + local KEYRINGFILE="$1" + shift + local GPG="$GPG_CMD --keyring $KEYRINGFILE" + while [ -n "$1" ]; do + local KEY="$1" + shift + # check if the key is in this keyring: the key id is in the 5 column at the end + if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+${KEY}:"; then + continue + fi + if [ ! -w "$KEYRINGFILE" ]; then + echo >&2 "Key ${KEY} is in keyring ${KEYRINGFILE}, but can't be removed as it is read only." + continue + fi + # check if it is the only key in the keyring and if so remove the keyring altogether + if [ '1' = "$($GPG --with-colons --list-keys | grep "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+:" | wc -l)" ]; then + mv -f "$KEYRINGFILE" "${KEYRINGFILE}~" # behave like gpg + return + fi + # we can't just modify pointed to files as these might be in /usr or something + local REALTARGET + if [ -L "$KEYRINGFILE" ]; then + REALTARGET="$(readlink -f "$KEYRINGFILE")" + mv -f "$KEYRINGFILE" "${KEYRINGFILE}.dpkg-tmp" + cp -a "$REALTARGET" "$KEYRINGFILE" + fi + # delete the key from the keyring + $GPG --batch --delete-key --yes "$KEY" + if [ -n "$REALTARGET" ]; then + # the real backup is the old link, not the copy we made + mv -f "${KEYRINGFILE}.dpkg-tmp" "${KEYRINGFILE}~" + fi + done } remove_key() { requires_root + foreach_keyring_do 'remove_key_from_keyring' "$@" + aptkey_echo "OK" + } - while [ -n "$1" ]; do - # if a --keyring was given, just remove from there - if [ -n "$FORCED_KEYRING" ]; then - remove_key_from_keyring "$FORCED_KEYRING" "$1" - else - # otherwise all known keyrings are up for inspection - local TRUSTEDFILE="/etc/apt/trusted.gpg" - eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) - eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) - remove_key_from_keyring "$TRUSTEDFILE" "$1" - TRUSTEDPARTS="/etc/apt/trusted.gpg.d" - eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) - if [ -d "$TRUSTEDPARTS" ]; then - for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do - remove_key_from_keyring "$trusted" "$1" - done - fi +foreach_keyring_do() { + local ACTION="$1" + shift + # if a --keyring was given, just remove from there + if [ -n "$FORCED_KEYRING" ]; then + $ACTION "$FORCED_KEYRING" "$@" + else + # otherwise all known keyrings are up for inspection + local TRUSTEDFILE="/etc/apt/trusted.gpg" + eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) + eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) + $ACTION "$TRUSTEDFILE" "$@" + local TRUSTEDPARTS="/etc/apt/trusted.gpg.d" + eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d) + if [ -d "$TRUSTEDPARTS" ]; then + for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do + $ACTION "$trusted" "$@" + done fi - aptkey_echo "OK" - shift - done + fi } - usage() { echo "Usage: apt-key [--keyring file] [command] [arguments]" echo -- cgit v1.2.3 From 5beb682d2de2003e1c022cb298d6c2ec0cf91c0d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 24 Jan 2014 22:40:52 +0100 Subject: merge fragment keyrings in apt-key to avoid hitting gpg limits gnupg has a hardlimit of 40 (at the moment) keyrings per invocation, which can be exceeded with (many) repositories. That is rather misfortune as the longrun goal was to drop gnupg dependency at some point in the future, but this can now be considered missed and dropped. It also means that 'apt-key adv' commands might not have the behaviour one would expect it to have as it mainly operates on a big temporary keyring, so commands modifying keys will break. Doing this was never a good idea anyway through, so lets just hope nothing break too badly. Closes: 733028 --- cmdline/apt-key.in | 134 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 57 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 9adbd6443..9d8e60ec0 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -23,7 +23,6 @@ GPG_CMD="$GPG_CMD --homedir $GPGHOMEDIR" $GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING >/dev/null 2>&1 # tell gpg that it shouldn't try to maintain a trustdb file GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always" - GPG="$GPG_CMD" APT_DIR="/" @@ -113,7 +112,6 @@ net_update() { echo >&2 "ERROR: Your distribution is not supported in net-update as no uri for the archive-keyring is set" exit 1 fi - requires_root # in theory we would need to depend on wget for this, but this feature # isn't useable in debian anyway as we have no keyring uri nor a master key if ! which wget >/dev/null 2>&1; then @@ -145,7 +143,6 @@ update() { echo >&2 "Is the &keyring-package; package installed?" exit 1 fi - requires_root # add new keys from the package; @@ -158,11 +155,8 @@ update() { if [ -r "$REMOVED_KEYS" ]; then # remove no-longer supported/used keys - keys=`$GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5` - for key in $keys; do - if $GPG --list-keys --with-colons | grep ^pub | cut -d: -f5 | grep -q $key; then - $GPG --quiet --batch --delete-key --yes ${key} - fi + $GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5 | while read key; do + foreach_keyring_do 'remove_key_from_keyring' "$key" done else echo >&2 "Warning: removed keys keyring $REMOVED_KEYS missing or not readable" @@ -172,12 +166,17 @@ update() { remove_key_from_keyring() { local KEYRINGFILE="$1" shift + # non-existent keyrings have by definition no keys + if [ ! -e "$KEYRINGFILE" ]; then + return + fi + local GPG="$GPG_CMD --keyring $KEYRINGFILE" while [ -n "$1" ]; do local KEY="$1" shift # check if the key is in this keyring: the key id is in the 5 column at the end - if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+${KEY}:"; then + if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*${KEY}:"; then continue fi if [ ! -w "$KEYRINGFILE" ]; then @@ -205,12 +204,6 @@ remove_key_from_keyring() { done } -remove_key() { - requires_root - foreach_keyring_do 'remove_key_from_keyring' "$@" - aptkey_echo "OK" - } - foreach_keyring_do() { local ACTION="$1" shift @@ -219,20 +212,62 @@ foreach_keyring_do() { $ACTION "$FORCED_KEYRING" "$@" else # otherwise all known keyrings are up for inspection - local TRUSTEDFILE="/etc/apt/trusted.gpg" - eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) - eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) - $ACTION "$TRUSTEDFILE" "$@" + if [ -s "$TRUSTEDFILE" ]; then + $ACTION "$TRUSTEDFILE" "$@" + fi local TRUSTEDPARTS="/etc/apt/trusted.gpg.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%/}" + if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then + TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS" + fi for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do - $ACTION "$trusted" "$@" + if [ -s "$trusted" ]; then + $ACTION "$trusted" "$@" + fi done fi fi } +list_keys_from_keyring() { + local KEYRINGFILE="$1" + shift + # don't show the error message if this keyring doesn't include the key + $GPG_CMD --keyring "$KEYRINGFILE" --batch --list-keys "$@" 2>/dev/null || true +} + +fingerprint_keys_from_keyring() { + local KEYRINGFILE="$1" + shift + # don't show the error message if this keyring doesn't include the fingerprint + $GPG_CMD --keyring "$KEYRINGFILE" --batch --fingerprint "$@" 2>/dev/null || true +} + +import_keys_from_keyring() { + local IMPORT="$1" + local KEYRINGFILE="$2" + $GPG_CMD --keyring "$KEYRINGFILE" --batch --import "$IMPORT" >/dev/null 2>&1 +} + +setup_merged_keyring() { + local TRUSTEDFILE_BAK="$TRUSTEDFILE" + TRUSTEDFILE='/dev/null' + foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg" + TRUSTEDFILE="$TRUSTEDFILE_BAK" + # mark it as non-writeable so users get errors if gnupg tries to modify it + if [ -s "${GPGHOMEDIR}/trusted.gpg" ]; then + chmod -w "${GPGHOMEDIR}/trusted.gpg" + GPG="$GPG --keyring ${GPGHOMEDIR}/trusted.gpg" + fi + if [ -r "$TRUSTEDFILE" ]; then + GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE" + fi +} + + usage() { echo "Usage: apt-key [--keyring file] [command] [arguments]" echo @@ -257,12 +292,6 @@ while [ -n "$1" ]; do shift TRUSTEDFILE="$1" FORCED_KEYRING="$1" - if [ -r "$TRUSTEDFILE" ] || [ "$2" = 'add' ] || [ "$2" = 'adv' ]; then - GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE" - else - echo >&2 "Error: The specified keyring »$TRUSTEDFILE« is missing or not readable" - exit 1 - fi shift ;; --fakeroot) @@ -286,22 +315,6 @@ if [ -z "$TRUSTEDFILE" ]; then TRUSTEDFILE="/etc/apt/trusted.gpg" eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring) eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f) - if [ -r "$TRUSTEDFILE" ]; then - GPG="$GPG --keyring $TRUSTEDFILE" - GPG="$GPG --primary-keyring $TRUSTEDFILE" - fi - TRUSTEDPARTS="/etc/apt/trusted.gpg.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) - STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}" - if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then - TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS" - fi - for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do - GPG="$GPG --keyring $trusted" - done - fi fi command="$1" @@ -323,40 +336,47 @@ if [ "$command" != "help" ]; then if [ -w "$(dirname "$TRUSTEDFILE")" ]; then touch -- "$TRUSTEDFILE" chmod 0644 -- "$TRUSTEDFILE" - GPG="$GPG --keyring $TRUSTEDFILE" - GPG="$GPG --primary-keyring $TRUSTEDFILE" fi fi fi case "$command" in add) - requires_root - $GPG --quiet --batch --import "$@" - aptkey_echo "OK" + requires_root + setup_merged_keyring + $GPG --quiet --batch --import "$@" + aptkey_echo "OK" ;; del|rm|remove) - remove_key "$@" + requires_root + foreach_keyring_do 'remove_key_from_keyring' "$@" + aptkey_echo "OK" ;; update) + requires_root + setup_merged_keyring update ;; net-update) + requires_root + setup_merged_keyring net_update ;; list) - $GPG --batch --list-keys "$@" - ;; + foreach_keyring_do 'list_keys_from_keyring' "$@" + ;; finger*) - $GPG --batch --fingerprint "$@" - ;; + foreach_keyring_do 'fingerprint_keys_from_keyring' "$@" + ;; export|exportall) - $GPG --armor --export "$@" - ;; + foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg" + $GPG_CMD --keyring "${GPGHOMEDIR}/trusted.gpg" --armor --export "$@" + ;; adv*) - aptkey_echo "Executing: $GPG $*" - $GPG "$@" - ;; + setup_merged_keyring + aptkey_echo "Executing: $GPG $*" + $GPG "$@" + ;; help) usage ;; -- cgit v1.2.3 From 059911800900a42c4246f1e209b51656055215b2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 26 Jan 2014 17:37:00 +0100 Subject: delay gnupg setup in apt-key until it is needed 'apt-key help' and incorrect usage do not need a functioning gnupg setup, as well as we shouldn't try to setup gnupg before we actually test if it is available (and print a message if it is not). --- cmdline/apt-key.in | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 9d8e60ec0..b8fdfe121 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -3,28 +3,6 @@ set -e unset GREP_OPTIONS -GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring" - -# 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 -GPGHOMEDIR="$(mktemp -d)" -CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';" -trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM -chmod 700 "$GPGHOMEDIR" -# 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 -GPG_CMD="$GPG_CMD --homedir $GPGHOMEDIR" -# 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 -$GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING >/dev/null 2>&1 -# tell gpg that it shouldn't try to maintain a trustdb file -GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always" -GPG="$GPG_CMD" - APT_DIR="/" eval $(apt-config shell APT_DIR Dir) @@ -331,6 +309,28 @@ if [ "$command" != "help" ]; then echo >&2 fi + GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring" + + # 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 + GPGHOMEDIR="$(mktemp -d)" + CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';" + trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM + chmod 700 "$GPGHOMEDIR" + # 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 + GPG_CMD="$GPG_CMD --homedir $GPGHOMEDIR" + # 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 + $GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING >/dev/null 2>&1 + # tell gpg that it shouldn't try to maintain a trustdb file + GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always" + GPG="$GPG_CMD" + # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. if ! [ -e "$TRUSTEDFILE" ]; then if [ -w "$(dirname "$TRUSTEDFILE")" ]; then -- cgit v1.2.3 From 93d0d08cdd6854f9bfb779c13b5b78cd6ed263aa Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 26 Jan 2014 18:28:50 +0100 Subject: support gnupg2 as drop-in replacement for gnupg If both are available APT will still prefer gpg over gpg2 as it is a bit more lightweight, but it shouldn't be a problem to use one or the other (at least at the moment, who knows what will happen in the future). --- cmdline/apt-key.in | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index b8fdfe121..12aee9750 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -303,13 +303,22 @@ fi shift if [ "$command" != "help" ]; then - if ! which gpg >/dev/null 2>&1; then - echo >&2 "Warning: gnupg does not seem to be installed." - echo >&2 "Warning: apt-key requires gnupg for most operations." + eval $(apt-config shell GPG_EXE Apt::Key::gpgcommand) + + if [ -n "$GPG_EXE" ] && which "$GPG_EXE" >/dev/null 2>&1; then + true + elif which gpg >/dev/null 2>&1; then + GPG_EXE="gpg" + elif which gpg2 >/dev/null 2>&1; then + GPG_EXE="gpg2" + else + echo >&2 "Error: gnupg or gnupg2 do not seem to be installed," + echo >&2 "Error: but apt-key requires gnupg or gnupg2 for operation." echo >&2 + exit 255 fi - GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring" + GPG_CMD="$GPG_EXE --ignore-time-conflict --no-options --no-default-keyring" # 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 -- cgit v1.2.3 From 0740a31033739ba30e7cb6754111f968167cbbf5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 26 Jan 2014 19:14:13 +0100 Subject: respect --keyring also in merged keyring commands Git-Dch: Ignore --- cmdline/apt-key.in | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 12aee9750..c54b608e1 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -231,14 +231,16 @@ import_keys_from_keyring() { } setup_merged_keyring() { - local TRUSTEDFILE_BAK="$TRUSTEDFILE" - TRUSTEDFILE='/dev/null' - foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg" - TRUSTEDFILE="$TRUSTEDFILE_BAK" - # mark it as non-writeable so users get errors if gnupg tries to modify it - if [ -s "${GPGHOMEDIR}/trusted.gpg" ]; then - chmod -w "${GPGHOMEDIR}/trusted.gpg" - GPG="$GPG --keyring ${GPGHOMEDIR}/trusted.gpg" + if [ -z "$FORCED_KEYRING" ]; then + local TRUSTEDFILE_BAK="$TRUSTEDFILE" + TRUSTEDFILE='/dev/null' + foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg" + TRUSTEDFILE="$TRUSTEDFILE_BAK" + # mark it as non-writeable so users get errors if gnupg tries to modify it + if [ -s "${GPGHOMEDIR}/pubring.gpg" ]; then + chmod -w "${GPGHOMEDIR}/pubring.gpg" + GPG="$GPG --keyring ${GPGHOMEDIR}/pubring.gpg" + fi fi if [ -r "$TRUSTEDFILE" ]; then GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE" -- cgit v1.2.3 From 38005d8b24bb81f4862d2c2a228e4a49a2af4ccd Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 27 Jan 2014 16:59:46 +0100 Subject: add a test for apt-key export{,all} Git-Dch: Ignore --- cmdline/apt-key.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index c54b608e1..a3f8dde3a 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -380,8 +380,8 @@ case "$command" in foreach_keyring_do 'fingerprint_keys_from_keyring' "$@" ;; export|exportall) - foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/trusted.gpg" - $GPG_CMD --keyring "${GPGHOMEDIR}/trusted.gpg" --armor --export "$@" + foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg" + $GPG_CMD --keyring "${GPGHOMEDIR}/pubring.gpg" --armor --export "$@" ;; adv*) setup_merged_keyring -- cgit v1.2.3 From ba72845c07b2682f251dc7661869d20095260f8f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 27 Jan 2014 17:04:53 +0100 Subject: allow to specify fingerprints in 'apt-key del' --- cmdline/apt-key.in | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index a3f8dde3a..74ca4d135 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -25,6 +25,19 @@ requires_root() { fi } +get_fingerprints_of_keyring() { + $GPG_CMD --keyring "$1" --with-colons --fingerprint | while read publine; do + # search for a public key + if [ "${publine%%:*}" != 'pub' ]; then continue; fi + # search for the associated fingerprint (should be the very next line) + while read fprline; do + if [ "${fprline%%:*}" = 'sub' ]; then break; # should never happen + elif [ "${fprline%%:*}" != 'fpr' ]; then continue; fi + echo "$fprline" | cut -d':' -f 10 + done + done +} + add_keys_with_verify_against_master_keyring() { ADD_KEYRING=$1 MASTER=$2 @@ -42,7 +55,7 @@ add_keys_with_verify_against_master_keyring() { # is honored. so: # all keys that are exported must have a valid signature # from a key in the $distro-master-keyring - add_keys=`$GPG_CMD --keyring $ADD_KEYRING --with-colons --list-keys | grep ^pub | cut -d: -f5` + add_keys="$(get_fingerprints_of_keyring "$ADD_KEYRING")" all_add_keys=`$GPG_CMD --keyring $ADD_KEYRING --with-colons --list-keys | grep ^[ps]ub | cut -d: -f5` master_keys=`$GPG_CMD --keyring $MASTER --with-colons --list-keys | grep ^pub | cut -d: -f5` @@ -133,7 +146,7 @@ update() { if [ -r "$REMOVED_KEYS" ]; then # remove no-longer supported/used keys - $GPG_CMD --keyring $REMOVED_KEYS --with-colons --list-keys | grep ^pub | cut -d: -f5 | while read key; do + get_fingerprints_of_keyring "$REMOVED_KEYS" | while read key; do foreach_keyring_do 'remove_key_from_keyring' "$key" done else @@ -154,7 +167,7 @@ remove_key_from_keyring() { local KEY="$1" shift # check if the key is in this keyring: the key id is in the 5 column at the end - if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*${KEY}:"; then + if ! get_fingerprints_of_keyring "$KEYRINGFILE" | grep -q "^[0-9A-F]*${KEY}$"; then continue fi if [ ! -w "$KEYRINGFILE" ]; then @@ -162,7 +175,7 @@ remove_key_from_keyring() { continue fi # check if it is the only key in the keyring and if so remove the keyring altogether - if [ '1' = "$($GPG --with-colons --list-keys | grep "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+:" | wc -l)" ]; then + if [ '1' = "$(get_fingerprints_of_keyring "$KEYRINGFILE" | wc -l)" ]; then mv -f "$KEYRINGFILE" "${KEYRINGFILE}~" # behave like gpg return fi -- cgit v1.2.3 From bd7fb5aa31f58917e8630f2981e78d190d465198 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 27 Jan 2014 18:26:44 +0100 Subject: add --secret-keyring option for apt-key For some advanced usecases it might be handy to specify the secret keyring to be used (e.g. as it is used in the testcases), but specifying it via a normal option for gnupg might not be available forever: http://lists.gnupg.org/pipermail/gnupg-users/2013-August/047180.html Git-Dch: Ignore --- cmdline/apt-key.in | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 74ca4d135..36824b6ec 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -287,6 +287,11 @@ while [ -n "$1" ]; do FORCED_KEYRING="$1" shift ;; + --secret-keyring) + shift + FORCED_SECRET_KEYRING="$1" + shift + ;; --fakeroot) requires_root() { true; } shift @@ -355,6 +360,12 @@ if [ "$command" != "help" ]; then GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always" GPG="$GPG_CMD" + # 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" + fi + # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. if ! [ -e "$TRUSTEDFILE" ]; then if [ -w "$(dirname "$TRUSTEDFILE")" ]; then -- cgit v1.2.3 From 0dae96a2b5e8ecd80a1b6e44961f1692ad4aec15 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 27 Jan 2014 22:07:16 +0100 Subject: use only one --keyring in gpg interactions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We were down to at most two keyrings before, but gnupg upstream plans dropping support for multiple keyrings in the longrun, so with a single keyring we hope to be future proof – and 'apt-key adv' isn't a problem anymore as every change to the keys is merged back, so we have now the same behavior as before, but support an unlimited amount of trusted.gpg.d keyrings. --- cmdline/apt-key.in | 105 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 28 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 36824b6ec..9259fac0d 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -14,7 +14,6 @@ REMOVED_KEYS='&keyring-removed-filename;' eval $(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys) ARCHIVE_KEYRING_URI='&keyring-uri;' eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI) -TMP_KEYRING=${APT_DIR}/var/lib/apt/keyrings/maybe-import-keyring.gpg aptkey_echo() { echo "$@"; } @@ -68,24 +67,28 @@ add_keys_with_verify_against_master_keyring() { fi done done - + for add_key in $add_keys; do # export the add keyring one-by-one - rm -f $TMP_KEYRING - $GPG_CMD --keyring $ADD_KEYRING --output $TMP_KEYRING --export $add_key - # check if signed with the master key and only add in this case - ADDED=0 + local TMP_KEYRING="${GPGHOMEDIR}/tmp-keyring.gpg" + $GPG_CMD --batch --yes --keyring "$ADD_KEYRING" --output "$TMP_KEYRING" --export "$add_key" + if ! $GPG_CMD --batch --yes --keyring "$TMP_KEYRING" --import "$MASTER" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + cat "${GPGHOMEDIR}/gpgoutput.log" + false + fi + # check if signed with the master key and only add in this case + ADDED=0 for master_key in $master_keys; do - if $GPG_CMD --keyring $MASTER --keyring $TMP_KEYRING --check-sigs --with-colons $add_key | grep '^sig:!:' | cut -d: -f5 | grep -q $master_key; then - $GPG --import $TMP_KEYRING + if $GPG_CMD --keyring $TMP_KEYRING --check-sigs --with-colons $add_key | grep '^sig:!:' | cut -d: -f5 | grep -q $master_key; then + $GPG_CMD --batch --yes --keyring "$ADD_KEYRING" --export "$add_key" | $GPG --batch --yes --import ADDED=1 fi done if [ $ADDED = 0 ]; then echo >&2 "Key '$add_key' not added. It is not signed with a master key" fi + rm -f "${TMP_KEYRING}" done - rm -f $TMP_KEYRING } # update the current archive signing keyring from a network URI @@ -240,26 +243,75 @@ fingerprint_keys_from_keyring() { import_keys_from_keyring() { local IMPORT="$1" local KEYRINGFILE="$2" - $GPG_CMD --keyring "$KEYRINGFILE" --batch --import "$IMPORT" >/dev/null 2>&1 + if ! $GPG_CMD --keyring "$KEYRINGFILE" --batch --import "$IMPORT" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + cat "${GPGHOMEDIR}/gpgoutput.log" + false + fi +} + +merge_keys_into_keyrings() { + local KEYRINGFILE="$1" + local IMPORT="$2" + if ! $GPG_CMD --keyring "$KEYRINGFILE" --batch --import --import-options 'merge-only' "$IMPORT" > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + cat "${GPGHOMEDIR}/gpgoutput.log" + false + fi +} + +merge_back_changes() { + if [ -n "$FORCED_KEYRING" ]; then + # if the keyring was forced merge is already done + return + fi + if [ -s "${GPGHOMEDIR}/pubring.gpg" ]; then + # merge all updated keys + foreach_keyring_do 'merge_keys_into_keyrings' "${GPGHOMEDIR}/pubring.gpg" + fi + # no look for keys which were added or removed + get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.orig.gpg" > "${GPGHOMEDIR}/pubring.orig.keylst" + get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.gpg" > "${GPGHOMEDIR}/pubring.keylst" + #echo >&2 "MERGE BACK" + sort "${GPGHOMEDIR}/pubring.keylst" "${GPGHOMEDIR}/pubring.orig.keylst" | uniq --unique | while read key; do + if grep -q "^${key}$" "${GPGHOMEDIR}/pubring.orig.keylst"; then + # key isn't part of new keyring, so remove + foreach_keyring_do 'remove_key_from_keyring' "$key" + elif grep -q "^${key}$" "${GPGHOMEDIR}/pubring.keylst"; then + # key is part of new keyring, so we need to import it + create_new_keyring "$TRUSTEDFILE" + if ! $GPG --batch --yes --export "$key" | $GPG_CMD --keyring "$TRUSTEDFILE" --batch --yes --import > "${GPGHOMEDIR}/gpgoutput.log" 2>&1; then + cat "${GPGHOMEDIR}/gpgoutput.log" + false + fi + else + echo >&2 "Errror: Key ${key} (dis)appeared out of nowhere" + fi + done } setup_merged_keyring() { if [ -z "$FORCED_KEYRING" ]; then - local TRUSTEDFILE_BAK="$TRUSTEDFILE" - TRUSTEDFILE='/dev/null' foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg" - TRUSTEDFILE="$TRUSTEDFILE_BAK" - # mark it as non-writeable so users get errors if gnupg tries to modify it - if [ -s "${GPGHOMEDIR}/pubring.gpg" ]; then - chmod -w "${GPGHOMEDIR}/pubring.gpg" - GPG="$GPG --keyring ${GPGHOMEDIR}/pubring.gpg" + if [ -r "${GPGHOMEDIR}/pubring.gpg" ]; then + cp -a "${GPGHOMEDIR}/pubring.gpg" "${GPGHOMEDIR}/pubring.orig.gpg" + else + touch "${GPGHOMEDIR}/pubring.gpg" "${GPGHOMEDIR}/pubring.orig.gpg" fi - fi - if [ -r "$TRUSTEDFILE" ]; then - GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE" + GPG="$GPG --keyring ${GPGHOMEDIR}/pubring.gpg" + else + GPG="$GPG --keyring $TRUSTEDFILE" + create_new_keyring "$TRUSTEDFILE" fi } +create_new_keyring() { + # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. + if ! [ -e "$TRUSTEDFILE" ]; then + if [ -w "$(dirname "$TRUSTEDFILE")" ]; then + touch -- "$TRUSTEDFILE" + chmod 0644 -- "$TRUSTEDFILE" + fi + fi +} usage() { echo "Usage: apt-key [--keyring file] [command] [arguments]" @@ -365,14 +417,6 @@ if [ "$command" != "help" ]; then rm -f "$SECRETKEYRING" cp -a "$FORCED_SECRET_KEYRING" "$SECRETKEYRING" fi - - # gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead. - if ! [ -e "$TRUSTEDFILE" ]; then - if [ -w "$(dirname "$TRUSTEDFILE")" ]; then - touch -- "$TRUSTEDFILE" - chmod 0644 -- "$TRUSTEDFILE" - fi - fi fi case "$command" in @@ -380,22 +424,26 @@ case "$command" in requires_root setup_merged_keyring $GPG --quiet --batch --import "$@" + merge_back_changes aptkey_echo "OK" ;; del|rm|remove) requires_root foreach_keyring_do 'remove_key_from_keyring' "$@" + merge_back_changes aptkey_echo "OK" ;; update) requires_root setup_merged_keyring update + merge_back_changes ;; net-update) requires_root setup_merged_keyring net_update + merge_back_changes ;; list) foreach_keyring_do 'list_keys_from_keyring' "$@" @@ -411,6 +459,7 @@ case "$command" in setup_merged_keyring aptkey_echo "Executing: $GPG $*" $GPG "$@" + merge_back_changes ;; help) usage -- cgit v1.2.3 From 33a2267214eed2a11281c9f93b8cf10b4c436d94 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 6 Feb 2014 17:56:28 +0100 Subject: add --readonly option for apt-key adv Some advanced commands can be executed without the keyring being modified like --verify, so this adds an option to disable the mergeback and uses it for our gpg calling code. Git-Dch: Ignore --- cmdline/apt-key.in | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 9259fac0d..21d692631 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -337,20 +337,19 @@ while [ -n "$1" ]; do shift TRUSTEDFILE="$1" FORCED_KEYRING="$1" - shift ;; --secret-keyring) shift FORCED_SECRET_KEYRING="$1" - shift + ;; + --readonly) + merge_back_changes() { true; } ;; --fakeroot) requires_root() { true; } - shift ;; --quiet) aptkey_echo() { true; } - shift ;; --*) echo >&2 "Unknown option: $1" @@ -359,6 +358,7 @@ while [ -n "$1" ]; do *) break;; esac + shift done if [ -z "$TRUSTEDFILE" ]; then @@ -430,7 +430,6 @@ case "$command" in del|rm|remove) requires_root foreach_keyring_do 'remove_key_from_keyring' "$@" - merge_back_changes aptkey_echo "OK" ;; update) -- cgit v1.2.3 From 0b94a7bc2ebb42453d9e22dc58dde76b9261de50 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 6 Feb 2014 18:43:55 +0100 Subject: miscellaneous small cleanups in apt-key Git-Dch: Ignore --- cmdline/apt-key.in | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 21d692631..a9a729cce 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -166,9 +166,7 @@ remove_key_from_keyring() { fi local GPG="$GPG_CMD --keyring $KEYRINGFILE" - while [ -n "$1" ]; do - local KEY="$1" - shift + for KEY in "$@"; do # check if the key is in this keyring: the key id is in the 5 column at the end if ! get_fingerprints_of_keyring "$KEYRINGFILE" | grep -q "^[0-9A-F]*${KEY}$"; then continue @@ -226,18 +224,11 @@ foreach_keyring_do() { fi } -list_keys_from_keyring() { +run_cmd_on_keyring() { local KEYRINGFILE="$1" shift - # don't show the error message if this keyring doesn't include the key - $GPG_CMD --keyring "$KEYRINGFILE" --batch --list-keys "$@" 2>/dev/null || true -} - -fingerprint_keys_from_keyring() { - local KEYRINGFILE="$1" - shift - # don't show the error message if this keyring doesn't include the fingerprint - $GPG_CMD --keyring "$KEYRINGFILE" --batch --fingerprint "$@" 2>/dev/null || true + # fingerprint and co will fail if key isn't in this keyring + $GPG_CMD --keyring "$KEYRINGFILE" --batch "$@" 2>/dev/null || true } import_keys_from_keyring() { @@ -267,10 +258,9 @@ merge_back_changes() { # merge all updated keys foreach_keyring_do 'merge_keys_into_keyrings' "${GPGHOMEDIR}/pubring.gpg" fi - # no look for keys which were added or removed + # look for keys which were added or removed get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.orig.gpg" > "${GPGHOMEDIR}/pubring.orig.keylst" get_fingerprints_of_keyring "${GPGHOMEDIR}/pubring.gpg" > "${GPGHOMEDIR}/pubring.keylst" - #echo >&2 "MERGE BACK" sort "${GPGHOMEDIR}/pubring.keylst" "${GPGHOMEDIR}/pubring.orig.keylst" | uniq --unique | while read key; do if grep -q "^${key}$" "${GPGHOMEDIR}/pubring.orig.keylst"; then # key isn't part of new keyring, so remove @@ -445,10 +435,10 @@ case "$command" in merge_back_changes ;; list) - foreach_keyring_do 'list_keys_from_keyring' "$@" + foreach_keyring_do 'run_cmd_on_keyring' --list-keys "$@" ;; finger*) - foreach_keyring_do 'fingerprint_keys_from_keyring' "$@" + foreach_keyring_do 'run_cmd_on_keyring' --fingerprint "$@" ;; export|exportall) foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg" -- cgit v1.2.3 From c46a36adaf51fc28464ea1a0e826c754ee60672b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 14 Apr 2014 18:24:17 +0200 Subject: add and use 'apt-key verify' which prefers gpgv over gpg gnupg/gnupg2 can do verify just fine of course, so we don't need to use gpgv here, but it is what we always used in the past, so there might be scripts expecting a certain output and more importantly the output of apt-cdrom contains messages from gpg and even with all the settings we activate to prevent it, it still shows (in some versions) a quiet scary: "gpg: WARNING: Using untrusted key!" message. Keeping the use of gpgv is the simplest way to prevent it. We are increasing also the "Breaks: apt" version from libapt as it requires a newer apt-key than might be installed in partial upgrades. --- cmdline/apt-key.in | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index a9a729cce..83a7a31b9 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -450,6 +450,14 @@ case "$command" in $GPG "$@" merge_back_changes ;; + verify) + setup_merged_keyring + if which gpgv >/dev/null 2>&1; then + gpgv --homedir "${GPGHOMEDIR}" --keyring "${GPGHOMEDIR}/pubring.gpg" --ignore-time-conflict "$@" + else + $GPG --verify "$@" + fi + ;; help) usage ;; -- cgit v1.2.3 From 7ffac4c10144a8458fec6de03c58f3b49d081e5c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 29 Sep 2014 11:43:37 +0200 Subject: Test if TMPDIR is a directory in apt-key and if not unset it This prevents a failure in mktemp -d - it will blindly trust TMPDIR and not use something else if the dir is not there. --- cmdline/apt-key.in | 3 +++ 1 file changed, 3 insertions(+) (limited to 'cmdline/apt-key.in') diff --git a/cmdline/apt-key.in b/cmdline/apt-key.in index 83a7a31b9..7a3852ee8 100644 --- a/cmdline/apt-key.in +++ b/cmdline/apt-key.in @@ -384,6 +384,9 @@ if [ "$command" != "help" ]; then # 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 + if [ ! -d "$TMPDIR" ]; then + unset TMPDIR + fi GPGHOMEDIR="$(mktemp -d)" CURRENTTRAP="${CURRENTTRAP} rm -rf '${GPGHOMEDIR}';" trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM -- cgit v1.2.3