]> git.saurik.com Git - apt.git/commitdiff
apt-key: warn instead of fail on unreadable keyrings
authorDavid Kalnischkies <david@kalnischkies.de>
Thu, 25 Aug 2016 10:42:36 +0000 (12:42 +0200)
committerJulian Andres Klode <jak@debian.org>
Wed, 23 Nov 2016 15:21:55 +0000 (16:21 +0100)
apt-key has inconsistent behaviour if it can't read a keyring file:
Commands like 'list' skipped silently over such keyrings while 'verify'
failed hard resulting in apt to report cconfusing gpg errors (#834973).

As a first step we teach apt-key to be more consistent here skipping in
all commands over unreadable keyrings, but issuing a warning in the
process, which is as usual for apt commands displayed at the end of the
run.

(cherry picked from commit 105503b4b470c124bc0c271bd8a50e25ecbe9133)
(removed the buffering of warnings in aptwarnings.log, as we do not
 have a cleanup function where we can cat it)

LP: #1642386

cmdline/apt-key.in
test/integration/test-apt-key

index 4f2bc916b377bf2cfa1c2779afdd145aef466f2f..e231d6f6132f43ab5ada3fccca68b2ec1fd4d1ad 100644 (file)
@@ -224,6 +224,17 @@ remove_key_from_keyring() {
     done
 }
 
+accessible_file_exists() {
+   if ! test -s "$1"; then
+      return 1
+   fi
+   if test -r "$1"; then
+      return 0
+   fi
+   warn "The key(s) in the keyring $1 are ignored as the file is not readable by user '$USER' executing apt-key."
+   return 1
+}
+
 foreach_keyring_do() {
    local ACTION="$1"
    shift
@@ -232,7 +243,7 @@ foreach_keyring_do() {
        $ACTION "$FORCED_KEYRING" "$@"
    else
        # otherwise all known keyrings are up for inspection
-       if [ -s "$TRUSTEDFILE" ]; then
+       if accessible_file_exists "$TRUSTEDFILE"; then
            $ACTION "$TRUSTEDFILE" "$@"
        fi
        local TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
@@ -241,7 +252,7 @@ foreach_keyring_do() {
            TRUSTEDPARTS="$(readlink -f "$TRUSTEDPARTS")"
            local TRUSTEDPARTSLIST="$(cd /; find "$TRUSTEDPARTS" -mindepth 1 -maxdepth 1 -name '*.gpg')"
            for trusted in $(echo "$TRUSTEDPARTSLIST" | sort); do
-               if [ -s "$trusted" ]; then
+               if accessible_file_exists "$trusted"; then
                    $ACTION "$trusted" "$@"
                fi
            done
@@ -294,35 +305,18 @@ import_keyring_into_keyring() {
     fi
 }
 
+catfile() {
+   cat "$1" >> "$2"
+}
+
 merge_all_trusted_keyrings_into_pubring() {
     # does the same as:
     # foreach_keyring_do 'import_keys_from_keyring' "${GPGHOMEDIR}/pubring.gpg"
     # but without using gpg, just cat and find
     local PUBRING="$(readlink -f "${GPGHOMEDIR}/pubring.gpg")"
-    # if a --keyring was given, just use this one
-    if [ -n "$FORCED_KEYRING" ]; then
-       if [ -s "$FORCED_KEYRING" ]; then
-           cp --dereference "$FORCED_KEYRING" "$PUBRING"
-       fi
-    else
-       # otherwise all known keyrings are merged
-       local TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
-       eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
-       if [ -d "$TRUSTEDPARTS" ]; then
-           rm -f "$PUBRING"
-           if [ -s "$TRUSTEDFILE" ]; then
-               cat "$TRUSTEDFILE" > "$PUBRING"
-           fi
-           TRUSTEDPARTS="$(readlink -f "$TRUSTEDPARTS")"
-           (cd /; find "$TRUSTEDPARTS" -mindepth 1 -maxdepth 1 -name '*.gpg' -exec cat {} + >> "$PUBRING";)
-       elif [ -s "$TRUSTEDFILE" ]; then
-           cp --dereference "$TRUSTEDFILE" "$PUBRING"
-       fi
-    fi
-
-    if [ ! -s "$PUBRING" ]; then
-       touch "$PUBRING"
-    fi
+    rm -f "$PUBRING"
+    touch "$PUBRING"
+    foreach_keyring_do 'catfile' "$PUBRING"
 }
 
 import_keys_from_keyring() {
@@ -472,6 +466,10 @@ if [ -z "$command" ]; then
 fi
 shift
 
+warn() {
+    echo >&2 'W:' "$@"
+}
+
 create_gpg_home() {
     # 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
index ddb9bf9d297e95c80b1bfd69d5c3615a9152a41c..1929550c6e79bb3a3ea0522290386079f03eb02b 100755 (executable)
@@ -82,6 +82,21 @@ gpg:              unchanged: 1' aptkey --fakeroot update
        testsuccess --nomsg aptkey --fakeroot del d141dbac8dae
        testempty aptkey list
 
+       if [ "$(id -u)" != '0' ]; then
+               msgtest 'Test key removal with' 'unreadable key'
+               cleanplate
+               cp -a "keys/joesixpack.pub" "rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg"
+               echo 'foobar' > "rootdir/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+               chmod 000 "rootdir/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+               aptkey --fakeroot del d141dbac8dae
+               testwarning --nomsg aptkey --fakeroot del d141dbac8dae
+               testwarning aptkey list
+               chmod 644 "rootdir/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+               rm -f "rootdir/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+               grep -v '^W: ' "rootdir/tmp/testwarning.output" > "rootdir/aptkeylist.output" || true
+               testempty cat "rootdir/aptkeylist.output"
+       fi
+
        msgtest 'Test key removal with' 'single key in real file'
        cleanplate
        cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
@@ -189,6 +204,17 @@ gpg:              unchanged: 1' aptkey --fakeroot update
                msgtest 'Test verify a file' 'with all keys'
                testsuccess --nomsg aptkey --quiet --readonly verify signature.gpg signature
 
+               if [ "$(id -u)" != '0' ]; then
+                       msgtest 'Test verify a file' 'with unreadable key'
+                       echo 'foobar' > "rootdir/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+                       chmod 000 "rootdir/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+                       aptkey --quiet --readonly verify "signature.gpg" "signature"
+                       testwarning --nomsg aptkey --quiet --readonly verify "signature.gpg" "signature"
+                       testwarning aptkey list
+                       chmod 644 "rootdir/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+                       rm -f "rootdir/etc/apt/trusted.gpg.d/unreadablekey.gpg"
+               fi
+
                msgtest 'Test verify a file' 'with good keyring'
                testsuccess --nomsg aptkey --quiet --readonly --keyring keys/testcase-multikey.pub verify signature.gpg signature