diff options
author | Matt Goins <mjgoins@openflows.com> | 2008-12-04 21:35:28 -0500 |
---|---|---|
committer | Matt Goins <mjgoins@openflows.com> | 2008-12-04 21:35:28 -0500 |
commit | c3b912f2506c3a150f128a77317085cea599a814 (patch) | |
tree | bec1f26bf3455a06fae6cac00e2c795d73358234 /src | |
parent | e7c994d6f67d380ed0de21f1500ec395eaab6640 (diff) | |
parent | 2483b7de82423d6bf0dec774526a2ca9fef3d64d (diff) |
Merge commit 'dkg/master'
Diffstat (limited to 'src')
-rw-r--r-- | src/common | 8 | ||||
-rwxr-xr-x | src/monkeysphere | 2 | ||||
-rwxr-xr-x | src/monkeysphere-server | 46 | ||||
-rwxr-xr-x | src/monkeysphere-ssh-proxycommand | 87 |
4 files changed, 111 insertions, 32 deletions
@@ -147,7 +147,7 @@ advance_date() { local shortunits # try things the GNU way first - if date -d "$number $longunits" "$format" >&/dev/null ; then + if date -d "$number $longunits" "$format" >/dev/null 2>&1; then date -d "$number $longunits" "$format" else # otherwise, convert to (a limited version of) BSD date syntax: @@ -639,7 +639,7 @@ process_user_id() { ;; 'uid') # user ids if [ "$lastKey" != pub ] ; then - log verbose " - got a user ID after a sub key?! user IDs should only follow primary keys!" + log verbose " ! got a user ID after a sub key?! user IDs should only follow primary keys!" continue fi # if an acceptable user ID was already found, skip @@ -652,6 +652,8 @@ process_user_id() { if [ "$validity" = 'u' -o "$validity" = 'f' ] ; then # mark user ID acceptable uidOK=true + else + log debug " - unacceptable user ID validity ($validity)." fi else continue @@ -693,10 +695,12 @@ process_user_id() { # if sub key validity is not ok, skip if [ "$validity" != 'u' -a "$validity" != 'f' ] ; then + log debug " - unacceptable sub key validity ($validity)." continue fi # if sub key capability is not ok, skip if ! check_capability "$usage" $requiredCapability ; then + log debug " - unacceptable sub key capability ($usage)." continue fi diff --git a/src/monkeysphere b/src/monkeysphere index 7e800cc..523ddfe 100755 --- a/src/monkeysphere +++ b/src/monkeysphere @@ -158,7 +158,7 @@ EOF log verbose "done." } -function subkey_to_ssh_agent() { +subkey_to_ssh_agent() { # try to add all authentication subkeys to the agent: local sshaddresponse diff --git a/src/monkeysphere-server b/src/monkeysphere-server index bb26c04..c4f6985 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -117,6 +117,16 @@ gpg_authentication() { su_monkeysphere_user "gpg $@" } +# function to check for host secret keys +# fails if host sec key exists, exits true otherwise +check_host_keyring() { + if ! gpg_host --list-secret-keys --fingerprint \ + --with-colons --fixed-list-mode 2>/dev/null | grep -q '^sec:' ; then + + failure "You don't appear to have a Monkeysphere host key on this server. Please run 'monkeysphere-server gen-key' first." + fi +} + # output just key fingerprint fingerprint_server_key() { gpg_host --list-secret-keys --fingerprint \ @@ -132,13 +142,13 @@ show_server_key() { fingerprint=$(fingerprint_server_key) gpg_authentication "--fingerprint --list-key --list-options show-unusable-uids $fingerprint" - # dumping to a file named ' ' so that the ssh-keygen output - # doesn't claim any potentially bogus hostname(s): - tmpkey=$(mktemp ${TMPDIR:-/tmp}/tmp.XXXXXXXXXX) || failure "Could not create temporary directory!" - gpg_authentication "--export $fingerprint" | openpgp2ssh "$fingerprint" 2>/dev/null > "$tmpkey" + # do some crazy "Here Strings" redirection to get the key to + # ssh-keygen, since it doesn't read from stdin cleanly echo -n "ssh fingerprint: " - ssh-keygen -l -f "$tmpkey" | awk '{ print $1, $2, $4 }' - rm -rf "$tmpkey" + ssh-keygen -l -f /dev/stdin \ + <<<$(gpg_authentication "--export $fingerprint" | \ + openpgp2ssh "$fingerprint" 2>/dev/null) | \ + awk '{ print $1, $2, $4 }' echo -n "OpenPGP fingerprint: " echo "$fingerprint" } @@ -337,6 +347,7 @@ gen_key() { userID="ssh://${hostName}" # check for presense of key with user ID + # FIXME: is this the proper test to be doing here? if gpg_host --list-key ="$userID" > /dev/null 2>&1 ; then failure "Key for '$userID' already exists" fi @@ -402,7 +413,7 @@ EOF log info "SSH host private key output to file: ${SYSDATADIR}/ssh_host_rsa_key" ssh-keygen -y -f "${SYSDATADIR}/ssh_host_rsa_key" > "${SYSDATADIR}/ssh_host_rsa_key.pub" log info "SSH host public key output to file: ${SYSDATADIR}/ssh_host_rsa_key.pub" - gpg_authentication --export-options export-minimal --export "0x${fingerprint}!" > "${SYSDATADIR}/ssh_host_rsa_key.pub.gpg" + gpg_authentication "--export-options export-minimal --armor --export 0x${fingerprint}\!" > "${SYSDATADIR}/ssh_host_rsa_key.pub.gpg" log info "SSH host public key in OpenPGP form: ${SYSDATADIR}/ssh_host_rsa_key.pub.gpg" } @@ -411,10 +422,6 @@ extend_key() { local fpr=$(fingerprint_server_key) local extendTo="$1" - if [ -z "$fpr" ] ; then - failure "You don't appear to have a MonkeySphere host key on this server. Try 'monkeysphere-server gen-key' first." - fi - # get the new expiration date extendTo=$(get_gpg_expiration "$extendTo") @@ -709,6 +716,10 @@ diagnostics() { echo " - Recommendation: remove the above HostKey lines from $sshd_config" problemsfound=$(($problemsfound+1)) fi + + # FIXME: test (with ssh-keyscan?) that the running ssh + # daemon is actually offering the monkeysphere host key. + fi fi @@ -855,9 +866,9 @@ add_certifier() { # export the key to the host keyring gpg_authentication "--export 0x${fingerprint}!" | gpg_host --import - if [ "$trust" == marginal ]; then + if [ "$trust" = marginal ]; then trustval=1 - elif [ "$trust" == full ]; then + elif [ "$trust" = full ]; then trustval=2 else failure "Trust value requested ('$trust') was unclear (only 'marginal' or 'full' are supported)." @@ -990,6 +1001,7 @@ shift case $COMMAND in 'update-users'|'update-user'|'u') + check_host_keyring update_users "$@" ;; @@ -998,22 +1010,27 @@ case $COMMAND in ;; 'extend-key'|'e') + check_host_keyring extend_key "$@" ;; 'add-hostname'|'add-name'|'n+') + check_host_keyring add_hostname "$@" ;; 'revoke-hostname'|'revoke-name'|'n-') + check_host_keyring revoke_hostname "$@" ;; 'show-key'|'show'|'s') + check_host_keyring show_server_key ;; 'publish-key'|'publish'|'p') + check_host_keyring publish_server_key ;; @@ -1022,14 +1039,17 @@ case $COMMAND in ;; 'add-identity-certifier'|'add-id-certifier'|'add-certifier'|'c+') + check_host_keyring add_certifier "$@" ;; 'remove-identity-certifier'|'remove-id-certifier'|'remove-certifier'|'c-') + check_host_keyring remove_certifier "$@" ;; 'list-identity-certifiers'|'list-id-certifiers'|'list-certifiers'|'list-certifier'|'c') + check_host_keyring list_certifiers "$@" ;; diff --git a/src/monkeysphere-ssh-proxycommand b/src/monkeysphere-ssh-proxycommand index b039844..a609199 100755 --- a/src/monkeysphere-ssh-proxycommand +++ b/src/monkeysphere-ssh-proxycommand @@ -43,22 +43,27 @@ output_no_valid_key() { local uidfpr local usage local sshKeyGPG + local tmpkey local sshFingerprint + local gpgSigOut - log "OpenPGP keys with*out* full validity found for this host:" - log + userID="ssh://${HOSTP}" + + log "-------------------- Monkeysphere warning -------------------" + log "Monkeysphere found OpenPGP keys for this hostname, but none had full validity." # retrieve the actual ssh key sshKeyOffered=$(ssh-keyscan -t rsa -p "$PORT" "$HOST" 2>/dev/null | awk '{ print $2, $3 }') + # FIXME: should we do any checks for failed keyscans, eg. host not + # found? - userID="ssh://${HOSTP}" - - # output gpg info for (exact) userid and store + # get the gpg info for userid gpgOut=$(gpg --list-key --fixed-list-mode --with-colon \ --with-fingerprint --with-fingerprint \ ="$userID" 2>/dev/null) - # loop over all lines in the gpg output and process. + # find all 'pub' and 'sub' lines in the gpg output, which each + # represent a retrieved key for the user ID echo "$gpgOut" | cut -d: -f1,2,5,10,12 | \ while IFS=: read -r type validity keyid uidfpr usage ; do case $type in @@ -69,26 +74,67 @@ output_no_valid_key() { # if one of keys found matches the one offered by the # host, then output info if [ "$sshKeyGPG" = "$sshKeyOffered" ] ; then + log "An OpenPGP key matching the ssh key offered by the host was found:" + log - # get the fingerprint of the ssh key - tmpkey=$(mktemp ${TMPDIR:-/tmp}/tmp.XXXXXXXXXX) - echo "$sshKeyGPG" > "$tmpkey" - sshFingerprint=$(ssh-keygen -l -f "$tmpkey" | awk '{ print $2 }') - rm -rf "$tmpkey" + # do some crazy "Here Strings" redirection to get the key to + # ssh-keygen, since it doesn't read from stdin cleanly + sshFingerprint=$(ssh-keygen -l -f /dev/stdin \ + <<<$(echo "$sshKeyGPG") | \ + awk '{ print $2 }') - # output gpg info - gpg --check-sigs \ + # get the sigs for the matching key + gpgSigOut=$(gpg --check-sigs \ --list-options show-uid-validity \ - "$keyid" >&2 + "$keyid") + + # output the sigs, but only those on the user ID + # we are looking for + echo "$gpgSigOut" | awk ' +{ +if (match($0,"^pub")) { print; } +if (match($0,"^uid")) { ok=0; } +if (match($0,"^uid.*'$userID'$")) { ok=1; print; } +if (ok) { if (match($0,"^sig")) { print; } } +} +' >&2 + log + + # output the other user IDs for reference + if (echo "$gpgSigOut" | grep "^uid" | grep -v -q "$userID") ; then + log "Other user IDs on this key:" + echo "$gpgSigOut" | grep "^uid" | grep -v "$userID" >&2 + log + fi # output ssh fingerprint log "RSA key fingerprint is ${sshFingerprint}." - log "Falling through to standard ssh host checking." - log + + # this whole process is in a "while read" + # subshell. the only way to get information out + # of the subshell is to change the return code. + # therefore we return 1 here to indicate that a + # matching gpg key was found for the ssh key + # offered by the host + return 1 fi ;; esac done + + # if no key match was made (and the "while read" subshell returned + # 1) output how many keys were found + if (($? != 1)) ; then + log "None of the found keys matched the key offered by the host." + log "Run the following command for more info about the found keys:" + log "gpg --check-sigs --list-options show-uid-validity =${userID}" + # FIXME: should we do anything extra here if the retrieved + # host key is actually in the known_hosts file and the ssh + # connection will succeed? Should the user be warned? + # prompted? + fi + + log "-------------------- ssh continues below --------------------" } ######################################################################## @@ -182,6 +228,15 @@ case $? in ;; esac +# FIXME: what about the case where monkeysphere successfully finds a +# valid key for the host and adds it to the known_hosts file, but a +# different non-monkeysphere key for the host already exists in the +# known_hosts, and it is this non-ms key that is offered by the host? +# monkeysphere will succeed, and the ssh connection will succeed, and +# the user will be left with the impression that they are dealing with +# a OpenPGP/PKI host key when in fact they are not. should we use +# ssh-keyscan to compare the keys first? + # exec a netcat passthrough to host for the ssh connection if [ -z "$NO_CONNECT" ] ; then if (which nc 2>/dev/null >/dev/null); then |