Major rework of monkeysphere-host to handle multiple host keys.
[monkeysphere.git] / src / share / mh / revoke_key
index 380236b91b87daaf3d339b146dde59872f3fe966..5a013e0db67518842b3000578bf364d5f3ee06e1 100644 (file)
@@ -8,16 +8,40 @@
 # Jamie McClelland <jm@mayfirst.org>
 # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
 #
-# They are Copyright 2008-2009, and are all released under the GPL,
+# They are Copyright 2008-2010, and are all released under the GPL,
 # version 3 or later.
 
 # revoke host key
 
 revoke_key() {
 
-# Coming in here, we expect $HOST_FINGERPRINT to be set, and we
-# believe that there is in fact a key.
+    local keyID
+    local publish
 
+    keyID=$(check_key_input "$@")
+
+    if [ "$PROMPT" = "false" ] ; then
+       publish=N
+    else
+       cat <<EOF >&2
+This will generate a revocation certificate for key $keyID
+and dump the certificate to standard output.
+
+It can also directly publish the new revocation certificate
+to the public keyservers via $KEYSERVER if you want it to.
+
+Publishing this certificate will IMMEDIATELY and PERMANENTLY revoke
+your host key!
+
+EOF
+       printf "Publish the certificate after generation? (y/n/Q) " >&2
+       read publish
+       
+       if ! [ "${publish/y/Y}" = 'Y' -o "${publish/n/N}" = 'N' ] ; then
+           failure "aborting at user request"
+       fi
+    fi
+    
     # our current implementation is very simple: we just want to
     # generate the revocation certificate on stdout.  This provides
     # for the two most likely (but hopefully not common) scenarios:
@@ -28,18 +52,52 @@ revoke_key() {
     # transcribe from the terminal.
 
     # Alternately, an admin might want to publish the revocation
-    # certificate immediately.  here's a quick way to do this:
+    # certificate immediately, which we can help them do as well.
 
+    if [ "$PROMPT" = 'false' ] ; then
+       # FIXME: allow the end user to choose something other than
+       # "key was compromised" (1) and to supply their own revocation
+       # string.
 
-    # tmp=$(mktemp -d)
-    # export GNUPGHOME="$tmp"
-    # gpg --import < /var/lib/monkeysphere/ssh_host_rsa_key.pub.gpg
-    # monkeysphere-host revoke-key | gpg --import
-    # gpg --keyserver pool.sks-keyservers.net --send $(hostname -f)
+       local revoke_commands="y
+1
+Monkeysphere host key revocation (automated) $(date '+%F_%T%z')
 
+y
 
+"
+       revcert=$(GNUPGHOME="$GNUPGHOME_HOST" gpg_host --command-fd 0 --armor --gen-revoke "0x${keyID}!" <<<"$revoke_commands" ) \
+           || failure "Failed to generate revocation certificate!"
+
+    else
     # note: we're not using the gpg_host function because we actually
     # want to use gpg's UI in this case, so we want to omit --no-tty
+       revcert=$(GNUPGHOME="$GNUPGHOME_HOST" gpg --no-greeting --quiet --armor --gen-revoke "0x${keyID}!") \
+           || failure "Failed to generate revocation certificate!"
+    fi
+
+    # if you run gpg --gen-revoke but cancel it or quit in the middle,
+    # it returns success, but emits no revocation certificate:
+    if ! [ "$revcert" ] ; then
+       failure "Revocation canceled."
+    fi
+
+    ## ok, now we have the revocation certificate.  Print it, and
+    ## offer to publish if originally requested:
+    printf "%s\n" "$revcert"
 
-    GNUPGHOME="$GNUPGHOME_HOST" gpg --no-greeting --quiet --armor --gen-revoke "0x${HOST_FINGERPRINT}!"
+    if [ "${publish/y/Y}" = 'Y' ] ; then
+       printf "\n" >&2
+       printf "Really publish this cert to $KEYSERVER ? (Y/n) " >&2
+       read really
+       if [ "${really/n/N}" = 'N' ] ; then
+           printf "Not publishing.\n" >&2
+       else
+           local newhome=$(mkmstempdir)
+           GNUPGHOME="$newhome" gpg --no-tty --quiet --import < "$HOST_KEY_FILE"
+           GNUPGHOME="$newhome" gpg --no-tty --quiet --import <<< "$revcert"
+           GNUPGHOME="$newhome" gpg --keyserver "$KEYSERVER" --send "0x${HOST_FINGERPRINT}!"
+           rm -rf "$newhome"
+       fi
+    fi
 }