From d91a9e05ef6c351f40d931d2f7d19e3a3979279c Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sun, 16 Nov 2008 17:26:14 -0500 Subject: add some more informative debug output to key processing. --- src/common | 6 +++++- src/monkeysphere-ssh-proxycommand | 14 +++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/common b/src/common index efee9bd..51b0470 100644 --- a/src/common +++ b/src/common @@ -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-ssh-proxycommand b/src/monkeysphere-ssh-proxycommand index b039844..aeea30d 100755 --- a/src/monkeysphere-ssh-proxycommand +++ b/src/monkeysphere-ssh-proxycommand @@ -45,20 +45,24 @@ output_no_valid_key() { local sshKeyGPG local sshFingerprint - log "OpenPGP keys with*out* full validity found for this host:" + userID="ssh://${HOSTP}" + + log "Monkeysphere found only OpenPGP keys for this host with*out* full validity." + log "host: $userID" log # 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 + # output gpg info for userid and store 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 -- cgit v1.2.3 From 864a89f60b05f0f32cf8ef2bb5677c2d50062749 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sun, 16 Nov 2008 19:10:03 -0500 Subject: fix quoting in output of ssh_host_rsa_key.pub.gpg. remember, at the moment the gpg_authentication function can only accept a single argument, so the entire gpg command string needs to be in a single quoted string. --- src/monkeysphere-server | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/monkeysphere-server b/src/monkeysphere-server index bb26c04..018a1ec 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -402,7 +402,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 --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" } -- cgit v1.2.3 From 11a42a66941cc1bb4c1268895ac4522ecb5fb6e6 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sun, 16 Nov 2008 19:32:58 -0500 Subject: really fix the ssh_host_rsa_key.pub.gpg output. --- src/monkeysphere-server | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 018a1ec..34b06b7 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -402,7 +402,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" } -- cgit v1.2.3 From f7dfcead0281c9f6dd26908f76282efc843a7e52 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Mon, 17 Nov 2008 01:14:20 -0500 Subject: More work on the marginal case output for the ssh-proxycommand. For a key matching that offered by the host, now outputs just the information (including sigs) of the relevant user ID. There is some other useful output for other cases as well. I also added a couple of FIXMEs for some other cases that I think we should think about and maybe tweak behavior for. --- src/monkeysphere-ssh-proxycommand | 74 +++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/monkeysphere-ssh-proxycommand b/src/monkeysphere-ssh-proxycommand index aeea30d..b3dc562 100755 --- a/src/monkeysphere-ssh-proxycommand +++ b/src/monkeysphere-ssh-proxycommand @@ -43,20 +43,21 @@ output_no_valid_key() { local uidfpr local usage local sshKeyGPG + local tmpkey local sshFingerprint + local gpgSigOut userID="ssh://${HOSTP}" - log "Monkeysphere found only OpenPGP keys for this host with*out* full validity." - log "host: $userID" - log + 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 + # FIXME: should we do any checks for failed keyscans, eg. host not # found? - # output gpg info for 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) @@ -73,26 +74,68 @@ 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 }') + sshFingerprint=$(ssh-keygen -l -f "$tmpkey" | \ + awk '{ print $2 }') rm -rf "$tmpkey" - # 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 --------------------" } ######################################################################## @@ -186,6 +229,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 -- cgit v1.2.3 From 6a43a89f5b2cd6ce91fa9c0bfddb5e2d44e77200 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Mon, 17 Nov 2008 18:07:33 -0500 Subject: HA! I figured out how to get ssh-keygen to read stdin by using the bash "Here Strings" redirection. No more stupid tempfiles to get ssh key fingerprints. --- src/monkeysphere-server | 12 ++++++------ src/monkeysphere-ssh-proxycommand | 9 ++++----- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 34b06b7..a1844ee 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -132,13 +132,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" } diff --git a/src/monkeysphere-ssh-proxycommand b/src/monkeysphere-ssh-proxycommand index b3dc562..a609199 100755 --- a/src/monkeysphere-ssh-proxycommand +++ b/src/monkeysphere-ssh-proxycommand @@ -77,12 +77,11 @@ output_no_valid_key() { 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" | \ + # 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 }') - rm -rf "$tmpkey" # get the sigs for the matching key gpgSigOut=$(gpg --check-sigs \ -- cgit v1.2.3 From 34af6daef32adbb7964e4fd1354eaaa737adc4ac Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sun, 30 Nov 2008 17:15:56 -0500 Subject: add new check_host_keyring function for better checks for the existence of a host private key for functions that require it to be there. --- packaging/debian/changelog | 8 ++++++++ src/monkeysphere-server | 24 ++++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/packaging/debian/changelog b/packaging/debian/changelog index c917562..2aaa9ca 100644 --- a/packaging/debian/changelog +++ b/packaging/debian/changelog @@ -1,3 +1,11 @@ +monkeysphere (0.23~pre-1) UNRELEASED; urgency=low + + * New upstream release: + - added better checks for the existence of a host private key for + functions that require it to be there. + + -- Jameson Graef Rollins Sun, 30 Nov 2008 17:14:50 -0500 + monkeysphere (0.22-1) unstable; urgency=low * New upstream release: diff --git a/src/monkeysphere-server b/src/monkeysphere-server index a1844ee..388e50b 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 \ @@ -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 @@ -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") @@ -990,6 +997,7 @@ shift case $COMMAND in 'update-users'|'update-user'|'u') + check_host_keyring update_users "$@" ;; @@ -998,22 +1006,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 +1035,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 "$@" ;; -- cgit v1.2.3 From 53b6ca110b9a6f17a7c7bc22e4f10d55bb6c2fb1 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Sun, 30 Nov 2008 17:59:28 -0500 Subject: added yet another FIXME to m-s d --- src/monkeysphere-server | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 388e50b..a73b253 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -716,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 -- cgit v1.2.3 From 2483b7de82423d6bf0dec774526a2ca9fef3d64d Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sun, 30 Nov 2008 23:27:36 -0500 Subject: add a couple of bugs about posix compliance and the use of getopts instead of getopt. --- src/common | 2 +- src/monkeysphere | 2 +- src/monkeysphere-server | 4 ++-- website/bugs/posix_compliance.mdwn | 9 +++++++++ website/bugs/use_getopts_instead_of_getopt.mdwn | 4 ++++ 5 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 website/bugs/posix_compliance.mdwn create mode 100644 website/bugs/use_getopts_instead_of_getopt.mdwn (limited to 'src') diff --git a/src/common b/src/common index 51b0470..f6000d3 100644 --- a/src/common +++ b/src/common @@ -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: 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 a73b253..c4f6985 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -866,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)." diff --git a/website/bugs/posix_compliance.mdwn b/website/bugs/posix_compliance.mdwn new file mode 100644 index 0000000..c2908ad --- /dev/null +++ b/website/bugs/posix_compliance.mdwn @@ -0,0 +1,9 @@ +It would be nice to make all of the Monkeysphere scripts POSIX +compliant, for portability and light-weightedness. Better POSIX +compliance would probably at least be better for compatibility with +o{ther,lder} versions of bash. Unfortunately there are quite a few +bashism at the moment, so this may not be trivial. For instance: + + servo:~/cmrg/monkeysphere/git 0$ checkbashisms -f src/monkeysphere-server 2>&1 | wc -l + 50 + servo:~/cmrg/monkeysphere/git 0$ diff --git a/website/bugs/use_getopts_instead_of_getopt.mdwn b/website/bugs/use_getopts_instead_of_getopt.mdwn new file mode 100644 index 0000000..db087b4 --- /dev/null +++ b/website/bugs/use_getopts_instead_of_getopt.mdwn @@ -0,0 +1,4 @@ +Since Monkeysphere is using bash, it would be nice to use the shell +build in getopts function, instead of the external getopt program. +This would reduce an external dependency, which would definitely be +better for portability. -- cgit v1.2.3