[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#341976: patch for apt-key adding interactive mode and keyserver support



tags 341976 + patch

Greetings,
I created the attached patch that adds the following features to
apt-key:

apt-key --interactive add <filename>

will show the keys that are to be imported with their fingerprints,
making it possible to inspect them before adding them to the keyring
and without polluting the personal key ring with keys that will never
be used.

apt-key --interactive fetch <keyid>

will download the specified key from a keyserver, presenting its data
to the user and awaiting confirmation before adding the key.

Without --interactive/-i, the fetch command will be denied due to security
considerations.

The patch implements these new features by creating a temporary GnuPG directory,
importing the keys there and preparing them for inspection.
diff --git a/cmdline/apt-key b/cmdline/apt-key
index 7bb3024..b3ffdfe 100755
--- a/cmdline/apt-key
+++ b/cmdline/apt-key
@@ -18,6 +18,27 @@ ARCHIVE_KEYRING_URI=""
 ARCHIVE_KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg
 REMOVED_KEYS=/usr/share/keyrings/debian-archive-removed-keys.gpg
 
+cmd_add() {
+    local FILE="$1"
+    if [ "$INTERACTIVE" = "0" ]; then
+        add_keys_to_keyring "$FILE"
+    else
+        prepare_tmp
+        $GPG_TMP --batch --import "$FILE" || return 1
+        confirm_tmpkeys && add_tmpkeys_to_keyring
+        destroy_tmp
+    fi
+}
+
+add_keys_to_keyring() {
+    local FILE="$1"
+    $GPG --quiet --batch --import "$FILE" && echo "OK"
+}
+
+add_tmpkeys_to_keyring() {
+    $GPG_TMP -q --no-tty --export | add_keys_to_keyring -
+}
+
 add_keys_with_verify_against_master_keyring() {
     ADD_KEYRING=$1
     MASTER=$2
@@ -102,9 +123,89 @@ update() {
     done
 }
 
+# variables for handling temporary key data
+TMP=""
+TMP_GPGHOME=""
+GPG_TMP=""
+
+prepare_tmp() {
+    if [ -n "$TMP" ]; then
+        echo "prepare_temp() called twice, aborting"
+        exit 1
+    fi
+    TMP=$(mktemp -d -t apt-key.XXXXXX)
+    TMP_GPGHOME="$TMP/gpg"
+    
+    trap destroy_tmp EXIT INT
+
+    mkdir -p "$TMP_GPGHOME"
+    chmod go-rwx "$TMP_GPGHOME"
+    # create empty keyrings
+    > $TMP_GPGHOME/pubring.gpg
+    > $TMP_GPGHOME/secring.gpg
+
+    GPG_TMP="gpg --homedir $TMP_GPGHOME --no-options --no-default-keyring --batch"
+}
+
+destroy_tmp() {
+     if [ -z "$TMP" ]; then
+        echo "destroy_tmp() called without prepare_tmp() before, aborting"
+        exit 1
+    fi
+    # uninstall handler
+    trap - EXIT INT
+   
+    rm -fr $TMP
+    TMP=""
+    TMP_GPGHOME=""
+    GPG_TMP=""
+}
+
+fetch() {
+    local KEYID="$1"
+    local KEYSERVER="wwwkeys.de.pgp.net"
+
+    if [ "$INTERACTIVE" = "0" ]; then
+        echo "For security reasons, fetching keys from a keyserver does only work in --interactive mode."
+        return 1
+    fi
+
+    if [ -z "$KEYID" ]; then
+        echo "Nothing to fetch"
+        return 1
+    fi
+    
+    $GPG_TMP -q --no-tty --keyserver $KEYSERVER --recv-keys "$KEYID" || return 1
+
+    if confirm_tmpkeys; then
+        # keys confirmed, import them in the keyring
+        add_tmpkeys_to_keyring
+    else
+        echo "Aborted"
+        return 1
+    fi
+}
+
+confirm_tmpkeys() {
+    echo
+    echo "Please compare the key identities and fingerprints below to an"
+    echo "independent source to confirm their integrity."
+    echo
+    
+    $GPG_TMP --fingerprint
+
+    CONFIRMATION="Yes, I will"
+
+    echo "Do your trust this key and wish to add it to your apt keyring?"
+    echo "So answer with '$CONFIRMATION'."
+    read -p " > " ANSWER
+    
+    [ "$ANSWER" = "$CONFIRMATION" ]
+}
+
 
 usage() {
-    echo "Usage: apt-key [command] [arguments]"
+    echo "Usage: apt-key [--interactive|-i] [command] [arguments]"
     echo
     echo "Manage apt's list of trusted keys"
     echo
@@ -116,10 +217,18 @@ usage() {
     echo "  apt-key net-update          - update keys using the network"
     echo "  apt-key list                - list keys"
     echo "  apt-key finger              - list fingerprints"
-    echo "  apt-key adv                 - pass advanced options to gpg (download key)"
+    echo "  apt-key -i fetch <keyid>    - fetch key from keyserver (required interactive mode)"
+    echo "  apt-key adv                 - pass advanced options to gpg"
     echo
 }
 
+INTERACTIVE=0
+
+if [ "$1" = "--interactive" ] || [ "$1" = "-i" ]; then
+    INTERACTIVE=1
+    shift
+fi
+
 command="$1"
 if [ -z "$command" ]; then
     usage
@@ -135,8 +244,7 @@ fi
 
 case "$command" in
     add)
-        $GPG --quiet --batch --import "$1"
-        echo "OK"
+        cmd_add "$1"
         ;;
     del|rm|remove)
         $GPG --quiet --batch --delete-key --yes "$1"
@@ -164,6 +272,11 @@ case "$command" in
         echo "Executing: $GPG $*"
         $GPG $*
         ;;
+    fetch)
+        prepare_tmp;
+        fetch $*
+        destroy_tmp;
+        ;;
     help)
         usage
         ;;

Reply to: