From ce45ef5702e072e869fa9d1b703f99dc740eb000 Mon Sep 17 00:00:00 2001 From: Jameson Rollins Date: Fri, 15 Jan 2010 19:19:15 -0500 Subject: [PATCH] Major rework of monkeysphere-host to handle multiple host keys. This rework removes any assumption that monkeysphere-host is just managing a single host key, or that the keys are used specifically for ssh. The UI is exactly backwards compatible except that hostnames ('example.com') must be replaced by full service names ('ssh://example.com'). This incarnation passes the old tests with those changes only. There are a couple of things that still need to be done: - need to see if a transition script is needed (some local file names have changed) - need to fill in check_service_name function to verify that a specified service name fits the expected format. - update diagnostics appropriately --- src/monkeysphere-host | 206 ++++++++++-------- src/share/mh/add_hostname | 62 ------ src/share/mh/add_name | 68 ++++++ src/share/mh/add_revoker | 51 +++-- src/share/mh/import_key | 44 ++-- src/share/mh/publish_key | 17 +- src/share/mh/revoke_key | 18 +- src/share/mh/{revoke_hostname => revoke_name} | 38 ++-- src/share/mh/set_expire | 34 ++- 9 files changed, 292 insertions(+), 246 deletions(-) delete mode 100644 src/share/mh/add_hostname create mode 100644 src/share/mh/add_name rename src/share/mh/{revoke_hostname => revoke_name} (52%) diff --git a/src/monkeysphere-host b/src/monkeysphere-host index 4a449de..b45b50e 100755 --- a/src/monkeysphere-host +++ b/src/monkeysphere-host @@ -8,7 +8,7 @@ # Daniel Kahn Gillmor # Micah Anderson # -# 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. ######################################################################## @@ -34,7 +34,9 @@ MHSHAREDIR="${SYSSHAREDIR}/mh" MHDATADIR="${SYSDATADIR}/host" # host pub key files -HOST_KEY_FILE="${SYSDATADIR}/ssh_host_rsa_key.pub.gpg" +HOST_KEY_FILE="${SYSDATADIR}/host_keys.pub.gpg" +# host pub key fingerprints file +HOST_KEY_FPR_FILE="${SYSDATADIR}/host_keys.fprs" # UTC date in ISO 8601 format if needed DATE=$(date -u '+%FT%T') @@ -52,18 +54,21 @@ usage: $PGRM [options] [args] 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 (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 + import-key (i) FILE SERVICENAME import PEM-encoded key from file + show-keys (s) [KEYID ...] output host key information + publish-keys (p) [KEYID ...] publish key(s) to keyserver + set-expire (e) EXPIRE [KEYID] set key expiration + add-servicename (n+) SERVICENAME [KEYID] + add a service name to key + revoke-servicename (n-) SERVICENAME [KEYID] + revoke a service name from key + add-revoker (r+) REVOKER_KEYID|FILE [KEYID] + add a revoker to key + revoke-key [KEYID] generate and/or publish revocation + certificate for key + + version (v) show version number + help (h,?) this help See ${PGRM}(8) for more info. EOF @@ -74,84 +79,122 @@ gpg_host() { GNUPGHOME="$GNUPGHOME_HOST" gpg --no-greeting --quiet --no-tty "$@" } -# command to list the info about the host key, in colon format, to -# stdout -gpg_host_list() { +# list the info about the a key, in colon format, to stdout +gpg_host_list_keys() { gpg_host --list-keys --with-colons --fixed-list-mode \ --with-fingerprint --with-fingerprint \ - "0x${HOST_FINGERPRINT}!" - + "$1" } -# command for edit key scripts, takes scripts on stdin +# edit key scripts, takes scripts on stdin, and keyID as first input gpg_host_edit() { - gpg_host --command-fd 0 --edit-key "0x${HOST_FINGERPRINT}!" "$@" + gpg_host --command-fd 0 --edit-key "$@" } -# export the host public key to the monkeysphere gpg pub key file +# export the monkeysphere gpg pub key file update_gpg_pub_file() { log debug "updating openpgp public key file '$HOST_KEY_FILE'..." - gpg_host --export --armor --export-options export-minimal \ - "0x${HOST_FINGERPRINT}!" > "$HOST_KEY_FILE" + gpg_host --export --armor --export-options export-minimal > "$HOST_KEY_FILE" + log debug "updating fingerprint file '$HOST_KEY_FPR_FILE'..." + gpg_host --list-secret-key --with-colons --with-fingerprint \ + | awk -F: '/^fpr:/{ print $10 }' > "$HOST_KEY_FPR_FILE" } -# load the host fingerprint into the fingerprint variable, using the -# export gpg pub key file -# FIXME: this seems much less than ideal, with all this temp keyring -# stuff. is there a way we can do this without having to create temp -# files? what if we stored the fingerprint in MHDATADIR/fingerprint? -load_fingerprint() { - if [ -f "$HOST_KEY_FILE" ] ; then - HOST_FINGERPRINT=$( \ - (FUBAR=$(msmktempdir) && export GNUPGHOME="$FUBAR" \ - && gpg --quiet --import \ - && gpg --quiet --list-keys --with-colons --with-fingerprint \ - && rm -rf "$FUBAR") <"$HOST_KEY_FILE" \ - | grep '^fpr:' | cut -d: -f10 ) - else - failure "host key gpg pub file not found." - fi -} +host_fingerprints() { + local fprs=($(cat "$HOST_KEY_FPR_FILE")) -# load the host fingerprint into the fingerprint variable, using the -# gpg host secret key -load_fingerprint_secret() { - HOST_FINGERPRINT=$( \ - gpg_host --list-secret-key --with-colons --with-fingerprint \ - | grep '^fpr:' | cut -d: -f10 ) + log debug "host key fingerprints:" + printf '%s\n' "${fprs[@]}" | log debug + printf '%s\n' "${fprs[@]}" } -# fail if host key present -check_host_key() { - [ ! -s "$HOST_KEY_FILE" ] \ - || failure "An OpenPGP host key already exists." +# check that the service name is well formed +check_service_name() { + local name="$1" + log error "FIX ME: check service name" } # fail if host key not present -check_host_no_key() { - [ -s "$HOST_KEY_FILE" ] \ +check_no_keys() { + [ -s "$HOST_KEY_FILE" ] || [ -s "$HOST_KEY_FPR_FILE" ] \ || failure "You don't appear to have a Monkeysphere host key on this server. -Please run 'monkeysphere-host import-key...' first." +Please run 'monkeysphere-host import-key' import a key." +} + +# key input to functions, outputs full fingerprint of specified key if +# found +check_key_input() { + local keyID="$1" + # array of fingerprints + local fprs=($(host_fingerprints)) + + case ${#fprs[@]} in + 0) + failure "You don't appear to have any Monkeysphere host keys. +Please run 'monkeysphere-host import-key' to import a key." + ;; + 1) + : + ;; + *) + if [ -z "$keyID" ] ; then + failure "Keyring contains multiple keys. Please specify one to act on (see 'monkeysphere-host show-key')." + fi + ;; + esac + printf '%s\n' "${fprs[@]}" | grep "${keyID}$" \ + || failure "Key '$keyID' not found." } # return 0 if user ID was found. # return 1 if user ID not found. -find_host_userid() { - local userID="$1" +check_key_userid() { + local keyID="$1" + local userID="$2" local tmpuidMatch # match to only "unknown" user IDs (host has no need for ultimate trust) tmpuidMatch="uid:-:$(echo $userID | gpg_escape)" # See whether the requsted user ID is present - gpg_host_list | cut -f1,2,10 -d: | \ + gpg_host_list_keys "$keyID" | cut -f1,2,10 -d: | \ grep -q -x -F "$tmpuidMatch" 2>/dev/null } -# show info about the host key +# run command looped over keys +multi_key() { + local cmd="$1" + shift + local keys=$@ + local i=0 + local fprs=($(host_fingerprints)) + local key + + check_no_keys + + if [[ -z "$1" || "$1" == '--all' ]] ; then + keys="${fprs[@]}" + else + for key in $keys ; do + printf '%s\n' "${fprs[@]}" | grep "${key}$" \ + || failure "Key '$key' not found." + done + fi + + for key in $keys ; do + if (( i++ > 0 )) ; then + echo "##############################" + fi + eval "$cmd" "$key" + done +} + +# show info about the a key show_key() { + local id="$1" local GNUPGHOME local TMPSSH + local fingerprint local revokers # tmp gpghome dir @@ -165,22 +208,22 @@ show_key() { # create the ssh key TMPSSH="$GNUPGHOME"/ssh_host_key_rsa_pub - gpg --export | openpgp2ssh 2>/dev/null >"$TMPSSH" + gpg --export "$id" | openpgp2ssh 2>/dev/null >"$TMPSSH" # get the gpg fingerprint - HOST_FINGERPRINT=$(gpg --quiet --list-keys --with-colons --with-fingerprint \ + fingerprint=$(gpg --quiet --list-keys \ + --with-colons --with-fingerprint "$id" \ | grep '^fpr:' | cut -d: -f10 ) # list the host key info # FIXME: make no-show-keyring work so we don't have to do the grep'ing # FIXME: can we show uid validity somehow? - gpg --list-keys --fingerprint \ - --list-options show-unusable-uids 2>/dev/null \ + gpg --list-keys --list-options show-unusable-uids "$id" 2>/dev/null \ | grep -v "^${GNUPGHOME}/pubring.gpg$" \ | egrep -v '^-+$' # list revokers, if there are any - revokers=$(gpg --list-keys --with-colons --fixed-list-mode \ + revokers=$(gpg --list-keys --with-colons --fixed-list-mode "$id" \ | awk -F: '/^rvk:/{ print $10 }' ) if [ "$revokers" ] ; then echo "The following keys are allowed to revoke this host key:" @@ -191,7 +234,7 @@ show_key() { fi # list the pgp fingerprint - echo "OpenPGP fingerprint: $HOST_FINGERPRINT" + echo "OpenPGP fingerprint: $fingerprint" # list the ssh fingerprint echo -n "ssh fingerprint: " @@ -247,56 +290,42 @@ shift case $COMMAND in 'import-key'|'i') - check_host_key source "${MHSHAREDIR}/import_key" import_key "$@" ;; - 'show-key'|'show'|'s') - check_host_no_key - show_key + 'show-keys'|'show-key'|'show'|'s') + multi_key show_key "$@" ;; 'set-expire'|'extend-key'|'e') - check_host_no_key - load_fingerprint source "${MHSHAREDIR}/set_expire" set_expire "$@" ;; - 'add-hostname'|'add-name'|'n+') - check_host_no_key - load_fingerprint - source "${MHSHAREDIR}/add_hostname" - add_hostname "$@" + 'add-servicename'|'add-hostname'|'add-name'|'n+') + source "${MHSHAREDIR}/add_name" + add_name "$@" ;; - 'revoke-hostname'|'revoke-name'|'n-') - check_host_no_key - load_fingerprint - source "${MHSHAREDIR}/revoke_hostname" - revoke_hostname "$@" + 'revoke-servicename'|'revoke-hostname'|'revoke-name'|'n-') + source "${MHSHAREDIR}/revoke_name" + revoke_name "$@" ;; 'add-revoker'|'r+') - check_host_no_key - load_fingerprint source "${MHSHAREDIR}/add_revoker" add_revoker "$@" ;; 'revoke-key') - check_host_no_key - load_fingerprint source "${MHSHAREDIR}/revoke_key" revoke_key "$@" ;; - 'publish-key'|'publish'|'p') - check_host_no_key - load_fingerprint + 'publish-keys'|'publish-key'|'publish'|'p') source "${MHSHAREDIR}/publish_key" - publish_key + multi_key publish_key "$@" ;; 'diagnostics'|'d') @@ -305,7 +334,6 @@ case $COMMAND in ;; 'update-gpg-pub-file') - load_fingerprint_secret update_gpg_pub_file ;; diff --git a/src/share/mh/add_hostname b/src/share/mh/add_hostname deleted file mode 100644 index c1b32a9..0000000 --- a/src/share/mh/add_hostname +++ /dev/null @@ -1,62 +0,0 @@ -# -*-shell-script-*- -# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant) - -# Monkeysphere host add-hostname subcommand -# -# The monkeysphere scripts are written by: -# Jameson Rollins -# Jamie McClelland -# Daniel Kahn Gillmor -# -# They are Copyright 2008-2009, and are all released under the GPL, -# version 3 or later. - -# add hostname user ID to server key - -add_hostname() { - -local userID -local fingerprint -local tmpuidMatch -local line -local adduidCommand - -if [ -z "$1" ] ; then - failure "You must specify a hostname to add." -fi - -userID="ssh://${1}" - -# test that the desired user ID does not already exist -find_host_userid "$userID" && \ - failure "Host userID '$userID' already exists." - -if [ "$PROMPT" = "true" ] ; then - printf "The following user ID will be added to the host key:\n %s\nAre you sure you would like to add this user ID? (Y/n) " "$userID" >&2 - read OK; OK=${OK:=Y} - if [ "${OK/y/Y}" != 'Y' ] ; then - failure "User ID not added." - fi -else - log debug "adding user ID without prompting." -fi - -# execute edit-key script -if PEM2OPENPGP_USAGE_FLAGS=authenticate \ - <"$GNUPGHOME_HOST/secring.gpg" \ - "$SYSSHAREDIR/keytrans" adduserid \ - "$HOST_FINGERPRINT" "$userID" | gpg_host --import ; then - gpg_host --check-trustdb - - update_gpg_pub_file - - show_key - - echo - echo "NOTE: User ID added to key, but key not published." - echo "Run '$PGRM publish-key' to publish the new user ID." -else - failure "Problem adding user ID." -fi - -} diff --git a/src/share/mh/add_name b/src/share/mh/add_name new file mode 100644 index 0000000..b5922db --- /dev/null +++ b/src/share/mh/add_name @@ -0,0 +1,68 @@ +# -*-shell-script-*- +# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant) + +# Monkeysphere host add-hostname subcommand +# +# The monkeysphere scripts are written by: +# Jameson Rollins +# Jamie McClelland +# Daniel Kahn Gillmor +# +# They are Copyright 2008-2010, and are all released under the GPL, +# version 3 or later. + +# add servicename user ID to server key + +add_name() { + +local serviceName +local keyID +local fingerprint +local tmpuidMatch +local line +local adduidCommand + +if [ -z "$1" ] ; then + failure "You must specify a service name to add." +fi +serviceName="$1" +shift + +keyID=$(check_key_input "$@") + +# test that the desired user ID does not already exist +check_key_userid "$keyID" "$serviceName" && \ + failure "Service name '$serviceName' already exists on key '$keyID'." + +check_service_name "$serviceName" + +if [ "$PROMPT" = "true" ] ; then + printf "The following service name will be added to key '$keyID':\n %s\nAre you sure you would like to add this service name? (Y/n) " "$serviceName" >&2 + read OK; OK=${OK:=Y} + if [ "${OK/y/Y}" != 'Y' ] ; then + failure "Service name not added." + fi +else + log debug "adding service name without prompting." +fi + +# execute edit-key script +if PEM2OPENPGP_USAGE_FLAGS=authenticate \ + <"$GNUPGHOME_HOST/secring.gpg" \ + "$SYSSHAREDIR/keytrans" adduserid "$keyID" "$serviceName" \ + | gpg_host --import ; then + + gpg_host --check-trustdb + + update_gpg_pub_file + + show_key "$keyID" + + echo + echo "NOTE: Service name added to key, but key not published." + echo "Run '$PGRM publish-key' to publish the new service name." +else + failure "Problem adding service name." +fi + +} diff --git a/src/share/mh/add_revoker b/src/share/mh/add_revoker index 89e6fcf..264c255 100644 --- a/src/share/mh/add_revoker +++ b/src/share/mh/add_revoker @@ -8,24 +8,27 @@ # Jamie McClelland # Daniel Kahn Gillmor # -# They are Copyright 2008, and are all released under the GPL, version 3 -# or later. +# They are Copyright 2008-2010, and are all released under the GPL, +# version 3 or later. # add a revoker to the host key add_revoker() { +local revokerKeyID local keyID local tmpDir local fingerprint local addrevokerCommand -keyID="$1" - # check that key ID or file is specified -if [ -z "$keyID" ] ; then +if [ -z "$1" ] ; then failure "You must specify the key ID of a revoker key, or specify a file to read the key from." fi +revokerKeyID="$1" +shift + +keyID=$(check_key_input "$@") # make a temporary directory for storing keys during import, and set # the trap to delete it on exit @@ -33,33 +36,33 @@ tmpDir=$(msmktempdir) trap "rm -rf $tmpDir" EXIT # if file is specified -if [ -f "$keyID" -o "$keyID" = '-' ] ; then +if [ -f "$revokerKeyID" -o "$revokerKeyID" = '-' ] ; then # load the key from stdin - if [ "$keyID" = '-' ] ; then + if [ "$revokerKeyID" = '-' ] ; then # make a temporary file to hold the key from stdin - keyID="$tmpDir"/importkey - log verbose "reading key from stdin..." - cat > "$keyID" + revokerKeyID="$tmpDir"/importkey + log verbose "reading revoker key from stdin..." + cat > "$revokerKeyID" # load the key from the file - elif [ -f "$keyID" ] ; then - log verbose "reading key from file '$keyID'..." + elif [ -f "$revokerKeyID" ] ; then + log verbose "reading revoker key from file '$revokerKeyID'..." fi # check the key is ok as monkeysphere user before loading log debug "checking keys in file..." fingerprint=$(su_monkeysphere_user \ - ". ${SYSSHAREDIR}/common; list_primary_fingerprints" < "$keyID") + ". ${SYSSHAREDIR}/common; list_primary_fingerprints" < "$revokerKeyID") if [ $(printf "%s" "$fingerprint" | egrep -c '^[A-F0-9]{40}$') -ne 1 ] ; then failure "There was not exactly one gpg key in the file." fi # load the key - gpg_host --import <"$keyID" \ - || failure "could not read key from '$keyID'" + gpg_host --import <"$revokerKeyID" \ + || failure "could not read revoker key from '$revokerKeyID'" -# else, get the key from the keyserver +# else, get the revoker key from the keyserver else # fix permissions and ownership on temporary directory which will # be used by monkeysphere user for storing the downloaded key @@ -67,13 +70,13 @@ else chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_GROUP" "$tmpDir" # download the key from the keyserver as the monkeysphere user - log verbose "searching keyserver $KEYSERVER for keyID $keyID..." - su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --quiet --keyserver $KEYSERVER --recv-key 0x${keyID}!" \ - || failure "Could not receive a key with this ID from the '$KEYSERVER' keyserver." + log verbose "searching keyserver $KEYSERVER for revoker keyID $revokerKeyID..." + su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --quiet --keyserver $KEYSERVER --recv-key 0x${revokerKeyID}!" \ + || failure "Could not receive a key with this ID from keyserver '$KEYSERVER'." # get the full fingerprint of new revoker key log debug "getting fingerprint of revoker key..." - fingerprint=$(su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --list-key --with-colons --with-fingerprint 0x${keyID}!" \ + fingerprint=$(su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --list-key --with-colons --with-fingerprint ${revokerKeyID}" \ | grep '^fpr:' | cut -d: -f10) # test that there is only a single fingerprint @@ -86,11 +89,11 @@ EOF failure fi - log info "key found:" + log info "revoker key found:" su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --fingerprint 0x${fingerprint}!" if [ "$PROMPT" = "true" ] ; then - printf "Are you sure you want to add the above key as a revoker\nof the host key? (Y/n) " >&2 + printf "Are you sure you want to add the above key as a revoker\nof the key '$keyID'? (Y/n) " >&2 read OK; OK=${OK:-Y} if [ "${OK/y/Y}" != 'Y' ] ; then failure "revoker not added." @@ -100,7 +103,7 @@ EOF fi # export the new key to the host keyring - log debug "loading key into host keyring..." + log debug "loading revoker key into host keyring..." su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --quiet --export 0x${fingerprint}!" \ | gpg_host --import fi @@ -115,7 +118,7 @@ save # core ltsigns the newly imported revoker key log debug "executing add revoker script..." -if echo "$addrevokerCommand" | gpg_host_edit ; then +if echo "$addrevokerCommand" | gpg_host_edit "0x${keyID}!" ; then update_gpg_pub_file diff --git a/src/share/mh/import_key b/src/share/mh/import_key index f7c69c3..ada2914 100644 --- a/src/share/mh/import_key +++ b/src/share/mh/import_key @@ -8,60 +8,50 @@ # Jamie McClelland # Daniel Kahn Gillmor # -# 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. import_key() { -local sshKeyFile -local hostName -local domain -local userID - -sshKeyFile="$1" -hostName="$2" +local keyFile="$1" +local serviceName="$2" # check that key file specified -if [ -z "$sshKeyFile" ] ; then - failure "Must specify ssh key file to import, or specify '-' for stdin." +if [ -z "$keyFile" ] ; then + failure "Must specify PEM-encoded key file to import, or specify '-' for stdin." fi # fail if hostname not specified -if [ -z "$hostName" ] ; then - failure "You must specify a fully-qualified domain name for use in the host certificate user ID." +if [ -z "$serviceName" ] ; then + failure "You must specify a service name for use in the OpenPGP certificate user ID." fi -userID="ssh://${hostName}" +# check that the service name is well formatted +check_service_name "$serviceName" # create host home mkdir -p "${MHDATADIR}" mkdir -p "${GNUPGHOME_HOST}" chmod 700 "${GNUPGHOME_HOST}" -# import ssh key to a private key -if [ "$sshKeyFile" = '-' ] ; then - log verbose "importing ssh key from stdin..." - PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$userID" \ +# import pem-encoded key to an OpenPGP private key +if [ "$keyFile" = '-' ] ; then + log verbose "importing key from stdin..." + PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$serviceName" \ | gpg_host --import else - log verbose "importing ssh key from file '$sshKeyFile'..." - PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$userID" \ - <"$sshKeyFile" \ + log verbose "importing key from file '$keyFile'..." + PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$serviceName" \ + <"$keyFile" \ | gpg_host --import fi -# load the new host fpr into the fpr variable. this is so we can -# create the gpg pub key file. we have to do this from the secret key -# ring since we obviously don't have the gpg pub key file yet, since -# that's what we're trying to produce (see below). -load_fingerprint_secret - # export to gpg public key to file update_gpg_pub_file log info "host key imported:" # show info about new key -show_key +show_key "$serviceName" } diff --git a/src/share/mh/publish_key b/src/share/mh/publish_key index 48e4cbb..553cd72 100644 --- a/src/share/mh/publish_key +++ b/src/share/mh/publish_key @@ -8,23 +8,24 @@ # Jamie McClelland # Daniel Kahn Gillmor # -# They are Copyright 2008-2009, and are all released under the GPL, version 3 -# or later. +# They are Copyright 2008-2010, and are all released under the GPL, +# version 3 or later. -# publish server key to keyserver +# publish keys to keyserver publish_key() { +local keyID="$1" local GNUPGHOME if [ "$PROMPT" = "true" ] ; then - printf "Really publish host key to $KEYSERVER? (Y/n) " >&2 + printf "Really publish key '$keyID' to $KEYSERVER? (Y/n) " >&2 read OK; OK=${OK:=Y} if [ "${OK/y/Y}" != 'Y' ] ; then failure "key not published." fi else - log debug "publishing key without prompting." + log debug "publishing key '$keyID' without prompting." fi # create a temporary gnupg directory from which to publish the key @@ -35,13 +36,13 @@ chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_GROUP" "$GNUPGHOME" # trap to remove tmp dir if break trap "rm -rf $GNUPGHOME" EXIT -# import the host key into the tmp dir +# import the key into the tmp dir su_monkeysphere_user \ "gpg --quiet --import" <"$HOST_KEY_FILE" -# publish host key +# publish key su_monkeysphere_user \ - "gpg --keyserver $KEYSERVER --send-keys '0x${HOST_FINGERPRINT}!'" + "gpg --keyserver $KEYSERVER --send-keys '0x${keyID}!'" # remove the tmp file trap - EXIT diff --git a/src/share/mh/revoke_key b/src/share/mh/revoke_key index 5460e51..5a013e0 100644 --- a/src/share/mh/revoke_key +++ b/src/share/mh/revoke_key @@ -8,23 +8,24 @@ # Jamie McClelland # Daniel Kahn Gillmor # -# 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 <&2 -This will generate a revocation certificate for your host key -(fingerprint: $HOST_FINGERPRINT) and -dump the certificate to standard output. +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. @@ -65,14 +66,13 @@ Monkeysphere host key revocation (automated) $(date '+%F_%T%z') y " - revcert=$(GNUPGHOME="$GNUPGHOME_HOST" gpg_host --command-fd 0 --armor --gen-revoke "0x${HOST_FINGERPRINT}!" <<<"$revoke_commands" ) \ + 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${HOST_FINGERPRINT}!") \ + revcert=$(GNUPGHOME="$GNUPGHOME_HOST" gpg --no-greeting --quiet --armor --gen-revoke "0x${keyID}!") \ || failure "Failed to generate revocation certificate!" fi diff --git a/src/share/mh/revoke_hostname b/src/share/mh/revoke_name similarity index 52% rename from src/share/mh/revoke_hostname rename to src/share/mh/revoke_name index 6b80802..d080704 100644 --- a/src/share/mh/revoke_hostname +++ b/src/share/mh/revoke_name @@ -8,14 +8,15 @@ # Jamie McClelland # Daniel Kahn Gillmor # -# 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 hostname user ID from host key +# revoke service name user ID from host key -revoke_hostname() { +revoke_name() { -local userID +local serviceName +local keyID local fingerprint local tmpuidMatch local line @@ -23,23 +24,25 @@ local message local revuidCommand if [ -z "$1" ] ; then - failure "You must specify a hostname to revoke." + failure "You must specify a service name to revoke." fi +serviceName="$1" +shift -userID="ssh://${1}" +keyID=$(check_key_input "$@") -# make sure the user ID to revoke -find_host_userid "$userID" || \ - failure "No non-revoked user ID found matching '$userID'." +# make sure the user ID to revoke exists +check_key_userid "$keyID" "$serviceName" || \ + failure "No non-revoked service name found matching '$serviceName'." if [ "$PROMPT" = "true" ] ; then - printf "The following host key user ID will be revoked:\n %s\nAre you sure you would like to revoke this user ID? (Y/n) " "$userID" >&2 + printf "The following service name on key '$keyID' will be revoked:\n %s\nAre you sure you would like to revoke this service name? (Y/n) " "$serviceName" >&2 read OK; OK=${OK:=Y} if [ "${OK/y/Y}" != 'Y' ] ; then failure "User ID not revoked." fi else - log debug "revoking user ID without prompting." + log debug "revoking service name without prompting." fi # actually revoke: @@ -49,20 +52,21 @@ fi # --export won't contain the secret key. "keytrans revokeuserid" # needs access to both pieces, so we feed it both of them. -if (cat "$GNUPGHOME_HOST/secring.gpg" && gpg_host --export "$HOST_FINGERPRINT") | \ - "$SYSSHAREDIR/keytrans" revokeuserid \ - "$HOST_FINGERPRINT" "$userID" | gpg_host --import ; then +if (cat "$GNUPGHOME_HOST/secring.gpg" && gpg_host --export "$keyID") \ + | "$SYSSHAREDIR/keytrans" revokeuserid "$keyID" "$serviceName" \ + | gpg_host --import ; then + gpg_host --check-trustdb update_gpg_pub_file - show_key + show_key "$keyID" echo - echo "NOTE: User ID revoked, but revocation not published." + echo "NOTE: Service name revoked, but revocation not published." echo "Run '$PGRM publish-key' to publish the revocation." else - failure "Problem revoking user ID." + failure "Problem revoking service name." fi } diff --git a/src/share/mh/set_expire b/src/share/mh/set_expire index 9889e76..049c2c5 100644 --- a/src/share/mh/set_expire +++ b/src/share/mh/set_expire @@ -11,18 +11,32 @@ # Jamie McClelland # Daniel Kahn Gillmor # -# 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. set_expire() { -local extendTo +local extendBy +local keyID + +if [ -z "$1" ] ; then + cat <&2 +Must specify expiration. The possibilities are: + 0 = key does not expire + = key expires in n days + w = key expires in n weeks + m = key expires in n months + y = key expires in n years +EOF + failure +fi +extendBy="$1" +shift -# get the new expiration date -extendTo=$(get_gpg_expiration "$1") +keyID=$(check_key_input "$@") if [ "$PROMPT" = "true" ] ; then - printf "Are you sure you want to change the expiration on the host key to '%s'? (Y/n) " "$extendTo" >&2 + printf "Are you sure you want to change the expiration on key '$keyID' by '%s'? (Y/n) " "$extendBy" >&2 read OK; OK=${OK:-Y} if [ "${OK/y/Y}" != 'Y' ] ; then failure "expiration not set." @@ -31,18 +45,18 @@ else log debug "extending without prompting." fi -log info "setting host key expiration to ${extendTo}." +log info "setting key expiration to ${extendBy}." -log debug "executing host expire script..." -gpg_host_edit expire <