From 2459fa3ea277d7b9289945748619eab1e3441e5c Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sat, 15 Nov 2008 20:49:27 -0500 Subject: Added info log output when a new key is added to known_hosts file. --- src/common | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common b/src/common index 297e7f3..efee9bd 100644 --- a/src/common +++ b/src/common @@ -742,6 +742,7 @@ process_user_id() { process_host_known_hosts() { local host local userID + local noKey= local nKeys local nKeysOK local ok @@ -768,8 +769,9 @@ process_host_known_hosts() { continue fi - # remove the old host key line, and note if removed - remove_line "$KNOWN_HOSTS" "$sshKey" + # remove any old host key line, and note if removed nothing is + # removed + remove_line "$KNOWN_HOSTS" "$sshKey" || noKey=true # if key OK, add new host line if [ "$ok" -eq '0' ] ; then @@ -788,6 +790,11 @@ process_host_known_hosts() { else ssh2known_hosts "$host" "$sshKey" >> "$KNOWN_HOSTS" fi + + # log if this is a new key to the known_hosts file + if [ "$noKey" ] ; then + log info "* new key for $host added to known_hosts file." + fi fi done -- cgit v1.2.3 From d068b7c722211adf7d830b1c1b4ce9693eafbe4f Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Sun, 16 Nov 2008 00:57:27 -0500 Subject: m-s s: avoid failures when $TMPDIR has a space in it. (output might still be a bit garbled) --- 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 5edaa4f..665d916 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -137,7 +137,7 @@ show_server_key() { tmpkey=$(mktemp ${TMPDIR:-/tmp}/tmp.XXXXXXXXXX) || failure "Could not create temporary directory!" gpg_authentication "--export $fingerprint" | openpgp2ssh "$fingerprint" 2>/dev/null > "$tmpkey" echo -n "ssh fingerprint: " - ssh-keygen -l -f $tmpkey | awk '{ print $1, $2, $4 }' + ssh-keygen -l -f "$tmpkey" | awk '{ print $1, $2, $4 }' rm -rf "$tmpkey" echo -n "OpenPGP fingerprint: " echo "$fingerprint" -- cgit v1.2.3 From 9eed0790573d3f1f21707151ede87f8339dbecc0 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Sun, 16 Nov 2008 01:28:19 -0500 Subject: exporting SSH host public key (two variants: one traditional ssh, the other OpenPGP) during m-s gen-key --- src/monkeysphere-server | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 665d916..bb26c04 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -399,7 +399,11 @@ EOF (umask 077 && \ gpg_host --export-secret-key "$fingerprint" | \ openpgp2ssh "$fingerprint" > "${SYSDATADIR}/ssh_host_rsa_key") - log info "private SSH host key output to file: ${SYSDATADIR}/ssh_host_rsa_key" + 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" + log info "SSH host public key in OpenPGP form: ${SYSDATADIR}/ssh_host_rsa_key.pub.gpg" } # extend the lifetime of a host key: -- cgit v1.2.3 From dd002c89fc4dccabc16d488a15a40cc88383605f Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sun, 16 Nov 2008 03:17:36 -0500 Subject: added some useful output to the ssh-proxycommand for "marginal" cases where keys are found for host but do not have full validity. this uses ssh-keyscan to pull the key for the host in question, check this key against the keys against those found via gpg, and output some useful information about the one that matches. --- changelog | 2 +- packaging/debian/changelog | 6 ++- src/monkeysphere-server | 2 +- src/monkeysphere-ssh-proxycommand | 98 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 102 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/changelog b/changelog index b9a9e21..4264fa4 120000 --- a/changelog +++ b/changelog @@ -1 +1 @@ -website/changelog \ No newline at end of file +packaging/debian/changelog \ No newline at end of file diff --git a/packaging/debian/changelog b/packaging/debian/changelog index f1db037..e8ea1a9 100644 --- a/packaging/debian/changelog +++ b/packaging/debian/changelog @@ -1,9 +1,11 @@ monkeysphere (0.22-1) UNRELEASED; urgency=low * New upstream release: - - Added info log output when a new key is added to known_hosts file. + - added info log output when a new key is added to known_hosts file. + - added some useful output to the ssh-proxycommand for "marginal" + cases where keys are found for host but do not have full validity. - -- Jameson Graef Rollins Sat, 15 Nov 2008 20:49:13 -0500 + -- Jameson Graef Rollins Sun, 16 Nov 2008 03:17:16 -0500 monkeysphere (0.21-2) unstable; urgency=low diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 5edaa4f..665d916 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -137,7 +137,7 @@ show_server_key() { tmpkey=$(mktemp ${TMPDIR:-/tmp}/tmp.XXXXXXXXXX) || failure "Could not create temporary directory!" gpg_authentication "--export $fingerprint" | openpgp2ssh "$fingerprint" 2>/dev/null > "$tmpkey" echo -n "ssh fingerprint: " - ssh-keygen -l -f $tmpkey | awk '{ print $1, $2, $4 }' + ssh-keygen -l -f "$tmpkey" | awk '{ print $1, $2, $4 }' rm -rf "$tmpkey" echo -n "OpenPGP fingerprint: " echo "$fingerprint" diff --git a/src/monkeysphere-ssh-proxycommand b/src/monkeysphere-ssh-proxycommand index 6276092..b039844 100755 --- a/src/monkeysphere-ssh-proxycommand +++ b/src/monkeysphere-ssh-proxycommand @@ -13,14 +13,84 @@ # established. Can be added to ~/.ssh/config as follows: # ProxyCommand monkeysphere-ssh-proxycommand %h %p +######################################################################## +PGRM=$(basename $0) + +SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"} +export SYSSHAREDIR +. "${SYSSHAREDIR}/common" || exit 1 + +######################################################################## +# FUNCTIONS ######################################################################## usage() { -cat <&2 + cat <&2 usage: ssh -o ProxyCommand="$(basename $0) %h %p" ... EOF } +log() { + echo "$@" >&2 +} + +output_no_valid_key() { + local sshKeyOffered + local userID + local type + local validity + local keyid + local uidfpr + local usage + local sshKeyGPG + local sshFingerprint + + log "OpenPGP keys with*out* full validity found for this host:" + log + + # retrieve the actual ssh key + sshKeyOffered=$(ssh-keyscan -t rsa -p "$PORT" "$HOST" 2>/dev/null | awk '{ print $2, $3 }') + + userID="ssh://${HOSTP}" + + # 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) + + # loop over all lines in the gpg output and process. + echo "$gpgOut" | cut -d: -f1,2,5,10,12 | \ + while IFS=: read -r type validity keyid uidfpr usage ; do + case $type in + 'pub'|'sub') + # get the ssh key of the gpg key + sshKeyGPG=$(gpg2ssh "$keyid") + + # if one of keys found matches the one offered by the + # host, then output info + if [ "$sshKeyGPG" = "$sshKeyOffered" ] ; then + + # 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" + + # output gpg info + gpg --check-sigs \ + --list-options show-uid-validity \ + "$keyid" >&2 + + # output ssh fingerprint + log "RSA key fingerprint is ${sshFingerprint}." + log "Falling through to standard ssh host checking." + log + fi + ;; + esac + done +} + ######################################################################## # export the monkeysphere log level @@ -35,7 +105,7 @@ HOST="$1" PORT="$2" if [ -z "$HOST" ] ; then - echo "Host not specified." >&2 + log "Host not specified." usage exit 255 fi @@ -88,6 +158,30 @@ export MONKEYSPHERE_CHECK_KEYSERVER # update the known_hosts file for the host monkeysphere update-known_hosts "$HOSTP" +# 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 + 0) + # acceptable host key found so continue to ssh + true + ;; + 1) + # no hosts at all found so also continue (drop through to + # regular ssh host verification) + true + ;; + 2) + # at least one *bad* host key (and no good host keys) was + # found, so output some usefull information + output_no_valid_key + ;; + *) + # anything else drop through + true + ;; +esac + # 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 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