From 10888c602170f6157ff43a81bad920babdd6a59e Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Fri, 20 Feb 2009 12:27:01 -0500 Subject: [PATCH 1/1] monkeysphere-host revoke-key should now be capable of publishing the revocation certificate to the keyservers directly, should the admin want that. It can also run without prompting, if MONKEYSPHERE_PROMPT=false. In the no-prompts case, it never publishes to the keyserver, it indicates that the key was compromised, and it writes a boilerplate description to make it easy to identify this kind of certificate. --- man/man8/monkeysphere-host.8 | 14 ++++---- src/monkeysphere-host | 11 +++--- src/share/mh/revoke_key | 66 ++++++++++++++++++++++++++++++++---- tests/basic | 19 +++++++++-- 4 files changed, 90 insertions(+), 20 deletions(-) diff --git a/man/man8/monkeysphere-host.8 b/man/man8/monkeysphere-host.8 index 2ccaaec..0a9fc1b 100644 --- a/man/man8/monkeysphere-host.8 +++ b/man/man8/monkeysphere-host.8 @@ -62,15 +62,17 @@ in place of `revoke-hostname'. Add a revoker to the host's OpenPGP key. The key ID will be loaded from the keyserver. A file may be loaded instead of pulling the key from the keyserver by specifying the path to the file as the argument, -or by specifying `-` to load from stdin. `o' may be be used in place +or by specifying `-` to load from stdin. `r+' may be be used in place of `add-revoker'. .TP .B revoke-key -Revoke the host's OpenPGP key. This will ask you a series of -questions, and then generate a key revocation certificate on standard -out. If you publish this revocation certificate to the public -keyservers, your host key will be permanently revoked. `r' may be -used in place of `revoke-key'. +Generate (with the option to publish) a revocation certificate for the +host's OpenPGP key. If such a certificate is published, your host key +will be permanently revoked. This subcommand will ask you a series of +questions, and then generate a key revocation certificate, sending it +to stdout. If you explicitly tell it to publish the revocation +certificate immediately, it will send it to the public keyservers. +USE WITH CAUTION! .TP .B publish-key Publish the host's OpenPGP key to the keyserver. `p' may be used in diff --git a/src/monkeysphere-host b/src/monkeysphere-host index 4c7df88..efa48cd 100755 --- a/src/monkeysphere-host +++ b/src/monkeysphere-host @@ -56,12 +56,13 @@ Monkeysphere host admin tool. subcommands: import-key (i) FILE [NAME[:PORT]] import existing ssh key to gpg show-key (s) output all host key information + publish-key (p) publish host key to keyserver set-expire (e) [EXPIRE] set host key expiration add-hostname (n+) NAME[:PORT] add hostname user ID to host key revoke-hostname (n-) NAME[:PORT] revoke hostname user ID - add-revoker (o) [KEYID|FILE] add a revoker to the host key - revoke-key (r) revoke host key - publish-key (p) publish host key to keyserver + add-revoker (r+) [KEYID|FILE] add a revoker to the host key + revoke-key generate and/or publish revocation + certificate for host key version (v) show version number help (h,?) this help @@ -268,14 +269,14 @@ case $COMMAND in revoke_hostname "$@" ;; - 'add-revoker'|'o') + 'add-revoker'|'r+') check_host_no_key load_fingerprint source "${MHSHAREDIR}/add_revoker" add_revoker "$@" ;; - 'revoke-key'|'r') + 'revoke-key') check_host_no_key load_fingerprint source "${MHSHAREDIR}/revoke_key" diff --git a/src/share/mh/revoke_key b/src/share/mh/revoke_key index 380236b..271432b 100644 --- a/src/share/mh/revoke_key +++ b/src/share/mh/revoke_key @@ -18,6 +18,28 @@ revoke_key() { # Coming in here, we expect $HOST_FINGERPRINT to be set, and we # believe that there is in fact a key. + if [ "$PROMPT" = "false" ] ; then + publish=N + else + cat <&2 +This will generate a revocation certificate for your host key +(fingerprint: $HOST_FINGERPRINT) 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 + read -p "Publish the certificate after generation? (y/n/Q) " 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 +50,48 @@ 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 + local revoke_commands="y +1 +Monkeysphere host key revocation (no prompting) $(date '+%F_%T') - # 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) +y +" + revcert=$(GNUPGHOME="$GNUPGHOME_HOST" gpg_host --command-fd 0 --armor --gen-revoke "0x${HOST_FINGERPRINT}!" <<<"$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${HOST_FINGERPRINT}!") \ + || 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 + read -p "Really publish this cert to $KEYSERVER ? (Y/n) " 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 } diff --git a/tests/basic b/tests/basic index 3d50977..fd4f673 100755 --- a/tests/basic +++ b/tests/basic @@ -110,7 +110,13 @@ export MONKEYSPHERE_SYSDATADIR="$TEMPDIR" export MONKEYSPHERE_SYSCONFIGDIR="$TEMPDIR" export MONKEYSPHERE_SYSSHAREDIR="$TESTDIR"/../src/share export MONKEYSPHERE_MONKEYSPHERE_USER=$(whoami) + export MONKEYSPHERE_CHECK_KEYSERVER=false +# example.org does not respond to the HKP port, so this should cause +# any keyserver connection attempts that do happen (they shouldn't!) +# to hang, so we'll notice them: +export MONKEYSPHERE_KEYSERVER=example.org + export MONKEYSPHERE_LOG_LEVEL=DEBUG export MONKEYSPHERE_CORE_KEYLENGTH=1024 export MONKEYSPHERE_PROMPT=false @@ -202,7 +208,7 @@ monkeysphere-host set-expire 1 # (this would normally be done via keyservers) echo "##################################################" echo "### certifying server host key..." -GNUPGHOME="$MONKEYSPHERE_SYSCONFIGDIR"/host gpg --armor --export "$HOSTKEYID" | gpgadmin --import +< "$MONKEYSPHERE_SYSCONFIGDIR"/ssh_host_rsa_key.pub.gpg gpgadmin --import echo y | gpgadmin --command-fd 0 --sign-key "$HOSTKEYID" # FIXME: add revoker? @@ -301,13 +307,22 @@ echo "##################################################" echo "### ssh connection test for server authentication denial..." ssh_test 255 chmod o-w "$TESTHOME"/.monkeysphere/authorized_user_ids +monkeysphere-authentication update-users $(whoami) # FIXME: addtest: remove admin as id-certifier and check ssh failure # FIXME: addtest: add hostname on host key # FIXME: addtest: revoke hostname on host key and check ssh failure -# FIXME: addtest: revoke the host key and check ssh failure +# addtest: revoke the host key and check ssh failure +# test to make sure things are OK after the previous tests: +ssh_test +echo "##################################################" +echo "### ssh connection test for server with revoked key..." +# generate the revocation certificate and feed it directly to the test +# user's keyring (we're not publishing to the keyservers) +monkeysphere-host revoke-key | gpg --import +ssh_test 255 ###################################################################### -- 2.25.1