diff options
author | Matt Goins <mjgoins@openflows.com> | 2009-02-21 16:54:39 -0500 |
---|---|---|
committer | Matt Goins <mjgoins@openflows.com> | 2009-02-21 16:54:39 -0500 |
commit | 4e0502a242b89c73535b00cc1b199dfea38ce4d4 (patch) | |
tree | 6bed970da1f85171b1c0b13095b702825a90754b /src | |
parent | d41fe28eb49e42d7773a223a43fd108913410c99 (diff) | |
parent | eb88374be90344d1808fe49a5bc69a547a09280d (diff) |
Merge branch 'master' of git://lair.fifthhorseman.net/~dkg/monkeysphere
Diffstat (limited to 'src')
-rwxr-xr-x | src/monkeysphere | 18 | ||||
-rwxr-xr-x | src/monkeysphere-host | 13 | ||||
-rw-r--r-- | src/share/common | 17 | ||||
-rw-r--r-- | src/share/m/ssh_proxycommand | 10 | ||||
-rw-r--r-- | src/share/m/subkey_to_ssh_agent | 12 | ||||
-rw-r--r-- | src/share/ma/add_certifier | 16 | ||||
-rw-r--r-- | src/share/ma/diagnostics | 2 | ||||
-rw-r--r-- | src/share/ma/remove_certifier | 2 | ||||
-rw-r--r-- | src/share/ma/update_users | 5 | ||||
-rw-r--r-- | src/share/mh/add_hostname | 6 | ||||
-rw-r--r-- | src/share/mh/add_revoker | 16 | ||||
-rw-r--r-- | src/share/mh/import_key | 15 | ||||
-rw-r--r-- | src/share/mh/revoke_hostname | 6 | ||||
-rw-r--r-- | src/share/mh/revoke_key | 70 |
14 files changed, 136 insertions, 72 deletions
diff --git a/src/monkeysphere b/src/monkeysphere index a65cef6..371983f 100755 --- a/src/monkeysphere +++ b/src/monkeysphere @@ -12,6 +12,8 @@ # or later. ######################################################################## +set -e + PGRM=$(basename $0) SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"} @@ -27,9 +29,6 @@ DATE=$(date -u '+%FT%T') # unset some environment variables that could screw things up unset GREP_OPTIONS -# default return code -RETURN=0 - # set the file creation mask to be only owner rw umask 077 @@ -87,9 +86,9 @@ check_gpg_sec_key_id() { echo "$gpgSecOut" | cut -d: -f5 ;; *) - echo "Multiple primary secret keys found:" | log error - echo "$gpgSecOut" | cut -d: -f5 | log error - echo "Please specify which primary key to use." | log error + echo "Multiple primary secret keys found:" + echo "$gpgSecOut" | cut -d: -f5 + echo "Please specify which primary key to use." failure ;; esac @@ -123,7 +122,7 @@ check_gpg_authentication_subkey() { fi # if authentication key is valid, prompt to continue if [ "$validity" = 'u' ] ; then - echo "A valid authentication key already exists for primary key '$keyID'." + echo "A valid authentication key already exists for primary key '$keyID'." 1>&2 if [ "$PROMPT" = "true" ] ; then read -p "Are you sure you would like to generate another one? (y/N) " OK; OK=${OK:N} if [ "${OK/y/Y}" != 'Y' ] ; then @@ -203,13 +202,11 @@ case $COMMAND in # those hosts if [ "$1" ] ; then update_known_hosts "$@" - RETURN="$?" # otherwise, if no hosts are specified, process every host # in the user's known_hosts file else process_known_hosts - RETURN="$?" fi ;; @@ -219,7 +216,6 @@ case $COMMAND in # process authorized_user_ids file process_authorized_user_ids "$AUTHORIZED_USER_IDS" - RETURN="$?" ;; 'import-subkey'|'i') @@ -255,5 +251,3 @@ case $COMMAND in Type '$PGRM help' for usage." ;; esac - -exit "$RETURN" diff --git a/src/monkeysphere-host b/src/monkeysphere-host index 4c7df88..540a8ab 100755 --- a/src/monkeysphere-host +++ b/src/monkeysphere-host @@ -54,14 +54,15 @@ usage: $PGRM <subcommand> [options] [args] Monkeysphere host admin tool. subcommands: - import-key (i) FILE [NAME[:PORT]] import existing ssh key to gpg + 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/common b/src/share/common index 653d58b..5e0cb6a 100644 --- a/src/share/common +++ b/src/share/common @@ -586,8 +586,8 @@ gpg2authorized_keys() { # FIXME: need to figure out how to retrieve all matching keys # (not just first N (5 in this case)) gpg_fetch_userid() { + local returnCode=0 local userID - local returnCode if [ "$CHECK_KEYSERVER" != 'true' ] ; then return 0 @@ -626,6 +626,7 @@ gpg_fetch_userid() { # # expects global variable: "MODE" process_user_id() { + local returnCode=0 local userID local requiredCapability local requiredPubCapability @@ -657,10 +658,10 @@ process_user_id() { # output gpg info for (exact) userid and store gpgOut=$(gpg --list-key --fixed-list-mode --with-colon \ --with-fingerprint --with-fingerprint \ - ="$userID" 2>/dev/null) + ="$userID" 2>/dev/null) || returnCode="$?" # if the gpg query return code is not 0, return 1 - if [ "$?" -ne 0 ] ; then + if [ "$returnCode" -ne 0 ] ; then log verbose " no primary keys found." return 1 fi @@ -890,6 +891,7 @@ process_host_known_hosts() { # update the known_hosts file for a set of hosts listed on command # line update_known_hosts() { + local returnCode=0 local nHosts local nHostsOK local nHostsBAD @@ -919,9 +921,9 @@ update_known_hosts() { for host ; do # process the host - process_host_known_hosts "$host" + process_host_known_hosts "$host" || returnCode="$?" # note the result - case "$?" in + case "$returnCode" in 0) nHostsOK=$((nHostsOK+1)) ;; @@ -1043,6 +1045,7 @@ process_uid_authorized_keys() { # update the authorized_keys files from a list of user IDs on command # line update_authorized_keys() { + local returnCode=0 local userID local nIDs local nIDsOK @@ -1072,10 +1075,10 @@ update_authorized_keys() { for userID ; do # process the user ID, change return code if key not found for # user ID - process_uid_authorized_keys "$userID" + process_uid_authorized_keys "$userID" || returnCode="$?" # note the result - case "$?" in + case "$returnCode" in 0) nIDsOK=$((nIDsOK+1)) ;; diff --git a/src/share/m/ssh_proxycommand b/src/share/m/ssh_proxycommand index bd09588..abe068d 100644 --- a/src/share/m/ssh_proxycommand +++ b/src/share/m/ssh_proxycommand @@ -18,6 +18,7 @@ # "marginal case" ouput in the case that there is not a full # validation path to the host output_no_valid_key() { + local returnCode=0 local sshKeyOffered local userID local type @@ -112,11 +113,11 @@ EOF fi ;; esac - done + done || returnCode="$?" # if no key match was made (and the "while read" subshell returned # 1) output how many keys were found - if (($? != 1)) ; then + if (( returnCode != 1 )) ; then cat <<EOF | log info None of the found keys matched the key offered by the host. Run the following command for more info about the found keys: @@ -200,12 +201,13 @@ fi CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:=$CHECK_KEYSERVER} # update the known_hosts file for the host -update_known_hosts "$HOSTP" +local returnCode=0 +update_known_hosts "$HOSTP" || returnCode="$?" # output on depending on the return of the update-known_hosts # subcommand, which is (ultimately) the return code of the # update_known_hosts function in common -case $? in +case "$returnCode" in 0) # acceptable host key found so continue to ssh true diff --git a/src/share/m/subkey_to_ssh_agent b/src/share/m/subkey_to_ssh_agent index 818f4f7..7fb2fdb 100644 --- a/src/share/m/subkey_to_ssh_agent +++ b/src/share/m/subkey_to_ssh_agent @@ -14,11 +14,11 @@ # try to add all authentication subkeys to the agent subkey_to_ssh_agent() { - local sshaddresponse + local sshaddresponse=0 local secretkeys local authsubkeys local workingdir - local keysuccess + local keysuccess=0 local subkey local publine local kname @@ -38,8 +38,7 @@ For more details, see: # and if it looks like it's running, but we can't actually talk to # it, bail out: - ssh-add -l >/dev/null - sshaddresponse="$?" + ssh-add -l >/dev/null || sshaddresponse="$?" if [ "$sshaddresponse" = "2" ]; then failure "Could not connect to ssh-agent" fi @@ -100,8 +99,7 @@ You might want to 'monkeysphere gen-subkey'" passphrase_prompt "Enter passphrase for key $kname: " "$workingdir/passphrase" wait %2 - fi - keysuccess="$?" + fi || keysuccess="$?" rm -f "$workingdir/$kname" done @@ -112,5 +110,5 @@ You might want to 'monkeysphere gen-subkey'" # FIXME: sort out the return values: we're just returning the # success or failure of the final authentication subkey in this # case. What if earlier ones failed? - exit "$keysuccess" + return "$keysuccess" } diff --git a/src/share/ma/add_certifier b/src/share/ma/add_certifier index f2cadf2..6f85ecf 100644 --- a/src/share/ma/add_certifier +++ b/src/share/ma/add_certifier @@ -120,14 +120,24 @@ else # get the full fingerprint of new certifier key log debug "getting fingerprint of certifier key..." fingerprint=$(gpg_sphere "--list-key --with-colons --with-fingerprint 0x${keyID}!" \ - | grep '^fpr:' | grep "$keyID" | cut -d: -f10) + | grep '^fpr:' | cut -d: -f10) + + # test that there is only a single fingerprint + if (( $(echo "$fingerprint" | wc -l) != 1 )) ; then + cat <<EOF +More than one fingerprint found: +$fingerprint +Please use a more specific key ID. +EOF + failure + fi log info "key found:" gpg_sphere "--fingerprint 0x${fingerprint}!" if [ "$PROMPT" = "true" ] ; then - echo "Are you sure you want to add the above key as a" - read -p "certifier of users on this system? (Y/n) " OK; OK=${OK:-Y} + echo "Are you sure you want to add the above key as a certifier" + read -p "of users on this system? (Y/n) " OK; OK=${OK:-Y} if [ "${OK/y/Y}" != 'Y' ] ; then failure "Identity certifier not added." fi diff --git a/src/share/ma/diagnostics b/src/share/ma/diagnostics index ce463b2..8fc4b31 100644 --- a/src/share/ma/diagnostics +++ b/src/share/ma/diagnostics @@ -105,7 +105,7 @@ echo echo "Checking for Identity Certifiers..." if ! monkeysphere-authentication list-identity-certifiers | egrep -q '^[A-F0-9]{40}:' then echo "! No Identity Certifiers found!" - echo " - Recommendation: once you know who should be able to certify identities for + echo " - Recommendation: once you know who should be able to certify the identities of connecting users, you should add their key, with: monkeysphere-authentication add-identity-certifier" problemsfound=$(($problemsfound+1)) diff --git a/src/share/ma/remove_certifier b/src/share/ma/remove_certifier index a9a1451..6c90358 100644 --- a/src/share/ma/remove_certifier +++ b/src/share/ma/remove_certifier @@ -27,7 +27,7 @@ fi gpg_core --list-key --fingerprint "0x${keyID}!" || failure if [ "$PROMPT" = "true" ] ; then - read -p "Really remove the identity certifier above? (Y/n) " OK; OK=${OK:-Y} + read -p "Really remove the above listed identity certifier? (Y/n) " OK; OK=${OK:-Y} if [ "${OK/y/Y}" != 'Y' ] ; then failure "Identity certifier not removed." fi diff --git a/src/share/ma/update_users b/src/share/ma/update_users index 092d108..bfefc31 100644 --- a/src/share/ma/update_users +++ b/src/share/ma/update_users @@ -93,8 +93,8 @@ for uname in $unames ; do # process authorized_user_ids file, as monkeysphere user su_monkeysphere_user \ - ". ${SYSSHAREDIR}/common; process_authorized_user_ids $TMP_AUTHORIZED_USER_IDS" - RETURN="$?" + ". ${SYSSHAREDIR}/common; process_authorized_user_ids $TMP_AUTHORIZED_USER_IDS" \ + || RETURN="$?" else log debug "not processing authorized_user_ids." fi @@ -154,4 +154,5 @@ for uname in $unames ; do rm -rf "$TMPLOC" done +return $RETURN } diff --git a/src/share/mh/add_hostname b/src/share/mh/add_hostname index 0da6a06..b08d688 100644 --- a/src/share/mh/add_hostname +++ b/src/share/mh/add_hostname @@ -32,9 +32,9 @@ find_host_userid > /dev/null && \ failure "Host userID '$userID' already exists." if [ "$PROMPT" = "true" ] ; then - echo "The following user ID will be added to the host key:" - echo " $userID" - read -p "Are you sure you would like to add this user ID? (Y/n) " OK; OK=${OK:=Y} + read -p "The following user ID will be added to the host key: + $userID +Are you sure you would like to add this user ID? (Y/n) " OK; OK=${OK:=Y} if [ "${OK/y/Y}" != 'Y' ] ; then failure "User ID not added." fi diff --git a/src/share/mh/add_revoker b/src/share/mh/add_revoker index 428b958..03ae56f 100644 --- a/src/share/mh/add_revoker +++ b/src/share/mh/add_revoker @@ -74,14 +74,24 @@ else # 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}!" \ - | grep '^fpr:' | grep "$keyID" | cut -d: -f10) + | grep '^fpr:' | cut -d: -f10) + + # test that there is only a single fingerprint + if (( $(echo "$fingerprint" | wc -l) != 1 )) ; then + cat <<EOF +More than one fingerprint found: +$fingerprint +Please use a more specific key ID. +EOF + failure + fi log info "key found:" su_monkeysphere_user "GNUPGHOME=$tmpDir gpg --fingerprint 0x${fingerprint}!" if [ "$PROMPT" = "true" ] ; then - echo "Are you sure you want to add the above key as a" - read -p "revoker of the host key? (Y/n) " OK; OK=${OK:-Y} + read -p "Are you sure you want to add the above key as a revoker +of the host key? (Y/n) " OK; OK=${OK:-Y} if [ "${OK/y/Y}" != 'Y' ] ; then failure "revoker not added." fi diff --git a/src/share/mh/import_key b/src/share/mh/import_key index 040b41c..f7c69c3 100644 --- a/src/share/mh/import_key +++ b/src/share/mh/import_key @@ -26,20 +26,9 @@ if [ -z "$sshKeyFile" ] ; then failure "Must specify ssh key file to import, or specify '-' for stdin." fi -# use the default hostname if not specified +# fail if hostname not specified if [ -z "$hostName" ] ; then - hostName=$(hostname -f) || failure "Could not determine hostname." - # test that the domain is not obviously illegitimate - domain=${foo##*.} - case $domain in - 'local'|'localdomain') - failure "Host domain '$domain' is not legitimate. Aborting key import." - ;; - esac - # test that there are at least two parts - if (( $(echo "$hostName" | tr . ' ' | wc -w) < 2 )) ; then - failure "Host name '$hostName' is not legitimate. Aborting key import." - fi + failure "You must specify a fully-qualified domain name for use in the host certificate user ID." fi userID="ssh://${hostName}" diff --git a/src/share/mh/revoke_hostname b/src/share/mh/revoke_hostname index 71b56ed..2142af7 100644 --- a/src/share/mh/revoke_hostname +++ b/src/share/mh/revoke_hostname @@ -43,9 +43,9 @@ uidIndex=$(find_host_userid) || \ failure "No non-revoked user ID found matching '$userID'." if [ "$PROMPT" = "true" ] ; then - echo "The following host key user ID will be revoked:" - echo " $userID" - read -p "Are you sure you would like to revoke this user ID? (N/y) " OK; OK=${OK:=Y} + read -p "The following host key user ID will be revoked: + $userID +Are you sure you would like to revoke this user ID? (Y/n) " OK; OK=${OK:=Y} if [ "${OK/y/Y}" != 'Y' ] ; then failure "User ID not revoked." fi diff --git a/src/share/mh/revoke_key b/src/share/mh/revoke_key index 380236b..ad68d5f 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 <<EOF >&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,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. + local revoke_commands="y +1 +Monkeysphere host key revocation (automated) $(date '+%F_%T%z') - # 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 } |