summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2013-08-12 16:19:37 +0200
committerDavid Kalnischkies <kalnischkies@gmail.com>2013-08-12 18:01:38 +0200
commit04937adc655ceda0b3367f540e76df10296cfba1 (patch)
tree303abe83359ad2db9b15e7cd56892f6fe75d8973
parent804d4a0d92a2e107aad38198ac08f1d2d64b5e53 (diff)
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).
-rwxr-xr-xcmdline/apt-key59
-rwxr-xr-xtest/integration/test-apt-key68
2 files changed, 124 insertions, 3 deletions
diff --git a/cmdline/apt-key b/cmdline/apt-key
index a9cbea55c..713a41c07 100755
--- a/cmdline/apt-key
+++ b/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"
diff --git a/test/integration/test-apt-key b/test/integration/test-apt-key
index 5beb6f220..68b3f9710 100755
--- a/test/integration/test-apt-key
+++ b/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~