]> git.saurik.com Git - apt.git/blobdiff - cmdline/apt-key
make destructors virtual
[apt.git] / cmdline / apt-key
index e010e6e909e03a40df0250df79fb4759b482d9c1..713a41c0706997c400a3fc70af665ce44e5e16ca 100755 (executable)
@@ -26,12 +26,16 @@ GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always"
 GPG="$GPG_CMD"
 
 MASTER_KEYRING=""
-ARCHIVE_KEYRING_URI=""
 #MASTER_KEYRING=/usr/share/keyrings/debian-master-keyring.gpg
+eval $(apt-config shell MASTER_KEYRING APT::Key::MasterKeyring)
+ARCHIVE_KEYRING_URI=""
 #ARCHIVE_KEYRING_URI=http://ftp.debian.org/debian/debian-archive-keyring.gpg
+eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI)
 
 ARCHIVE_KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg
+eval $(apt-config shell ARCHIVE_KEYRING APT::Key::ArchiveKeyring)
 REMOVED_KEYS=/usr/share/keyrings/debian-archive-removed-keys.gpg
+eval $(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys)
 
 requires_root() {
        if [ "$(id -u)" -ne 0 ]; then
@@ -147,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]"
@@ -171,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
@@ -203,7 +262,12 @@ if [ -z "$TRUSTEDFILE" ]; then
    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
+      # strip / suffix as gpg will double-slash in that case (#665411)
+      STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}"
+      if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then
+        TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS"
+      fi
+      for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do
         GPG="$GPG --keyring $trusted"
       done
    fi
@@ -230,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"