]> git.saurik.com Git - apt.git/commitdiff
let apt-key del work better with softlink and single key keyrings
authorDavid Kalnischkies <kalnischkies@gmail.com>
Mon, 12 Aug 2013 14:19:37 +0000 (16:19 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Mon, 12 Aug 2013 16:01:38 +0000 (18:01 +0200)
Having fragement files means there is a good chance that there is one
key per keyring, so deal with that as well as with setups in which
keyrings are linked into trusted.gpg.d as we can't just modify those
files (they might be in /usr for example).

cmdline/apt-key
test/integration/test-apt-key

index a9cbea55c11620c4e93af9138463687df88acc47..713a41c0706997c400a3fc70af665ce44e5e16ca 100755 (executable)
@@ -151,6 +151,60 @@ update() {
     fi
 }
 
+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 alltogether
+    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"
+       ls "$(dirname $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
+}
+
+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
+       fi
+    fi
+    echo "OK"
+}
+
 
 usage() {
     echo "Usage: apt-key [--keyring file] [command] [arguments]"
@@ -175,6 +229,7 @@ while [ -n "$1" ]; do
       --keyring)
         shift
         TRUSTEDFILE="$1"
+        FORCED_KEYRING="$1"
         if [ -r "$TRUSTEDFILE" ] || [ "$2" = 'add' ] || [ "$2" = 'adv' ]; then
            GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE"
         else
@@ -239,10 +294,8 @@ case "$command" in
         echo "OK"
         ;;
     del|rm|remove)
-        requires_root
         init_keyring "$TRUSTEDFILE"
-        $GPG --quiet --batch --delete-key --yes "$1"
-        echo "OK"
+       remove_key "$1"
         ;;
     update)
         init_keyring "$TRUSTEDFILE"
index 5beb6f22065d366a8cd57fca723388b7a545abad..68b3f97100f8ee3b6d4d89c5ea855332b8956464 100755 (executable)
@@ -37,3 +37,71 @@ testsuccess --nomsg aptkey --fakeroot update
 
 aptkey list | grep '^pub' > aptkey.list
 testfileequal ./aptkey.list 'pub   2048R/DBAC8DAE 2010-08-18'
+
+msgtest "Try to remove a key which exists, but isn't in the" 'forced keyring'
+testsuccess --nomsg aptkey --fakeroot --keyring rootdir/etc/apt/trusted.gpg del DBAC8DAE
+
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub   2048R/DBAC8DAE 2010-08-18'
+
+testsuccess aptkey --fakeroot del DBAC8DAE
+testempty aptkey list
+
+# start from a clean plate again
+cleanplate() {
+       rm -rf rootdir/etc/apt/trusted.gpg.d/ rootdir/etc/apt/trusted.gpg
+       mkdir rootdir/etc/apt/trusted.gpg.d/
+}
+
+msgtest 'Test key removal with' 'single key in real file'
+cleanplate
+cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+testempty aptkey list
+testsuccess test ! -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
+
+msgtest 'Test key removal with' 'single key in softlink'
+cleanplate
+ln -s $(readlink -f ./keys/joesixpack.pub) rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+testempty aptkey list
+testsuccess test ! -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess test -L rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
+
+cleanplate
+testsuccess aptkey --fakeroot add ./keys/joesixpack.pub
+testsuccess aptkey --fakeroot add ./keys/marvinparanoid.pub
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub   2048R/DBAC8DAE 2010-08-18
+pub   2048R/528144E2 2011-01-16'
+cp -a rootdir/etc/apt/trusted.gpg keys/testcase-multikey.pub # store for reuse
+
+msgtest 'Test key removal with' 'multi key in real file'
+cleanplate
+cp -a keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub   2048R/528144E2 2011-01-16'
+testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
+
+msgtest 'Test key removal with' 'multi key in softlink'
+cleanplate
+ln -s $(readlink -f ./keys/testcase-multikey.pub) rootdir/etc/apt/trusted.gpg.d/multikey.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub   2048R/528144E2 2011-01-16'
+testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
+testsuccess test ! -L rootdir/etc/apt/trusted.gpg.d/multikey.gpg
+testsuccess test -L rootdir/etc/apt/trusted.gpg.d/multikey.gpg~
+
+msgtest 'Test key removal with' 'multiple files including key'
+cleanplate
+cp -a keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+cp -a keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg
+testsuccess --nomsg aptkey --fakeroot del DBAC8DAE
+aptkey list | grep '^pub' > aptkey.list
+testfileequal ./aptkey.list 'pub   2048R/528144E2 2011-01-16'
+testsuccess test ! -e rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg
+testsuccess cmp keys/joesixpack.pub rootdir/etc/apt/trusted.gpg.d/joesixpack.gpg~
+testsuccess cmp keys/testcase-multikey.pub rootdir/etc/apt/trusted.gpg.d/multikey.gpg~