# -*-shell-script-*- # This should be sourced by bash (though we welcome changes to make it POSIX sh compliant) # Monkeysphere ssh-proxycommand subcommand # # The monkeysphere scripts are written by: # Jameson Rollins # Daniel Kahn Gillmor # # They are Copyright 2008-2009, and are all released under the GPL, # version 3 or later. # This is meant to be run as an ssh ProxyCommand to initiate a # monkeysphere known_hosts update before an ssh connection to host is # established. Can be added to ~/.ssh/config as follows: # ProxyCommand monkeysphere ssh-proxycommand %h %p # output the key info, including the RSA fingerprint show_key_info() { local keyid="$1" local sshKeyGPGFile local sshFingerprint local gpgSigOut local otherUids # get the ssh key of the gpg key sshFingerprint=$(gpg2ssh "$keyid" | "$SYSSHAREDIR/keytrans" sshfpr) # get the sigs for the matching key gpgSigOut=$(gpg_user --check-sigs \ --list-options show-uid-validity \ "$keyid") echo | log info # 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; } } } ' # output ssh fingerprint cat </dev/null ) ; then # retrieve the ssh key being offered by the host sshKeyOffered=$(ssh-keyscan -t rsa -p "$PORT" "$HOST" 2>/dev/null \ | awk '{ print $2, $3 }') fi # get the gpg info for userid gpgOut=$(gpg_user --list-key --fixed-list-mode --with-colon \ --with-fingerprint --with-fingerprint \ ="$userID" 2>/dev/null) # output header log info < 0)) ; then log info </dev/null ; then # do not check the keyserver CHECK_KEYSERVER=${CHECK_KEYSERVER:="false"} # if the host is NOT in the keyring... else # FIXME: what about system-wide known_hosts file (/etc/ssh/known_hosts)? if [ -r "$KNOWN_HOSTS" ]; then # look up the host key is found in the known_hosts file... if (type ssh-keygen &>/dev/null) ; then hostKey=$(ssh-keygen -F "$HOST" -f "$KNOWN_HOSTS" 2>/dev/null) else # FIXME: we're not dealing with digested known_hosts if we # don't have ssh-keygen # But we could do this without needing ssh-keygen. hashed # known_hosts looks like: |1|X|Y where 1 means SHA1 (nothing # else is defined in openssh sources), X is the salt (same # length as the digest output), base64-encoded, and Y is the # digested hostname (also base64-encoded). # see hostfile.{c,h} in openssh sources. hostKey=$(cut -f1 -d\ < .ssh/known_hosts | tr ',' '\n' | grep -Fx -e "$HOST" || :) fi fi if [ "$hostKey" ] ; then # do not check the keyserver # FIXME: more nuanced checking should be done here to properly # take into consideration hosts that join monkeysphere by # converting an existing and known ssh key CHECK_KEYSERVER=${CHECK_KEYSERVER:="false"} # if the host key is not found in the known_hosts file... else # check the keyserver CHECK_KEYSERVER=${CHECK_KEYSERVER:="true"} fi fi # finally look in the MONKEYSPHERE_ environment variable for a # CHECK_KEYSERVER setting to override all else CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:=$CHECK_KEYSERVER} declare -i KEYS_PROCESSED=0 declare -i KEYS_VALID=0 # update the known_hosts file for the host source "${MSHAREDIR}/update_known_hosts" update_known_hosts "$HOSTP" if ((KEYS_PROCESSED > 0)) && ((KEYS_VALID == 0)) ; then log debug "output ssh marginal ui..." output_no_valid_key fi # 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 (type nc &>/dev/null); then exec nc "$HOST" "$PORT" elif (type socat &>/dev/null); then exec socat STDIO "TCP:$HOST:$PORT" else echo "Neither netcat nor socat found -- could not complete monkeysphere-ssh-proxycommand connection to $HOST:$PORT" >&2 exit 255 fi fi }