diff options
-rwxr-xr-x | cmdline/apt-key | 59 | ||||
-rwxr-xr-x | test/integration/test-apt-key | 68 |
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~ |