#!/bin/sh public_suffix=cryptonomic.net die() { printf "Error: %s\n" "$*" >&2 exit 1 } b16_to_b32() { printf %s "$1" | basez -x -d | basez -j -l | tr -d = } openssh_knownhost_to_dnsname() { local hashtype=2 local keystring keytype sshfp_b16 sshfp_b32 [ -f "$1" ] || return [ -s "$1" ] || return sshfp_raw=$(ssh-keygen -r . -f "$1" | grep -E -e "^. IN SSHFP [0-9]+ $hashtype ") case "$sshfp_raw" in '. IN SSHFP 1 '*) keytype=1; keystring=rsa ;; '. IN SSHFP 4 '*) keytype=4; keystring=ed25519 ;; *) return 1 ;; esac sshfp_b16=$(printf '%s' "$sshfp_raw" | sed -ne "s/^. IN SSHFP $keytype $hashtype //p") && [ "$sshfp_b16" ] || die "could not determine ssh client fingerprint" sshfp_b32=$(b16_to_b32 "$sshfp_b16") printf %s.%s.%s "$sshfp_b32" "$keystring" "$public_suffix" | tail -c64 } dnsname_to_openssh_knownhost() { local host="$1" t r t=$(mktemp) case "$host" in *.ed25519."$public_suffix" ) ;; * ) return 1 ;; esac ssh-keyscan -t ed25519 "$host" 2>/dev/null | ( while read h keytype keydata comment do [ "$h $keytype" = "$host ssh-ed25519" ] || continue echo "$keytype $keydata" > "$t" validated=$(openssh_knownhost_to_dnsname "$t") || continue case "$host" in "$validated" | *."$validated" ) read line < "$t" echo "$host $line" rm -f "$t" exit 0 ;; esac done rm -f "$t" exit 1 ) } set -e [ $# = 1 ] || die 'usage' host=$1 shift _TEMP_DIR_=$(mktemp -d) cd "$_TEMP_DIR_" trap 'rm -rf "$_TEMP_DIR_"' EXIT if ssh-keygen -F "${host#*@}" | grep -v '^#' > ssh_known_hosts 2>/dev/null then cp ssh_known_hosts ssh_known_hosts~ else touch ssh_known_hosts~ dnsname_to_openssh_knownhost "${host##*@}" >> ssh_known_hosts || die "could not validate hostname cryptographically" fi modify_known_hosts=y set -- ssh if [ ! "$modify_known_hosts" ] then set -- "$@" -F /dev/null set -- "$@" -o GlobalKnownHostsFile=$PWD/ssh_known_hosts set -- "$@" -o UserKnownHostsFile=$PWD/ssh_known_hosts fi set -- "$@" -o UpdateHostKeys=yes set -- "$@" -o PasswordAuthentication=no set -- "$@" -o StrictHostKeyChecking=yes set -- "$@" -n -T set -- "$@" "$host" "$@" || true if test -t 1 then diff -u ssh_known_hosts~ ssh_known_hosts || true else cat ssh_known_hosts fi