Преглед изворни кода

let apt-key del work better with softlink and single key keyrings

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).
David Kalnischkies пре 13 година
родитељ
комит
04937adc65
2 измењених фајлова са 124 додато и 3 уклоњено
  1. 56 3
      cmdline/apt-key
  2. 68 0
      test/integration/test-apt-key

+ 56 - 3
cmdline/apt-key

@@ -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"

+ 68 - 0
test/integration/test-apt-key

@@ -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~