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/monkeysphere-ssh-proxycommand | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/monkeysphere-ssh-proxycommand') 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 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/monkeysphere-ssh-proxycommand') 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/monkeysphere-ssh-proxycommand') 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