1# $OpenBSD: keygen-knownhosts.sh,v 1.4 2018/06/01 03:52:37 djm Exp $ 2# Placed in the Public Domain. 3 4tid="ssh-keygen known_hosts" 5 6rm -f $OBJ/kh.* 7 8# Generate some keys for testing (just ed25519 for speed) and make a hosts file. 9for x in host-a host-b host-c host-d host-e host-f host-a2 host-b2; do 10 ${SSHKEYGEN} -qt ed25519 -f $OBJ/kh.$x -C "$x" -N "" || \ 11 fatal "ssh-keygen failed" 12 # Add a comment that we expect should be preserved. 13 echo "# $x" >> $OBJ/kh.hosts 14 ( 15 case "$x" in 16 host-a|host-b) printf "$x " ;; 17 host-c) printf "@cert-authority $x " ;; 18 host-d) printf "@revoked $x " ;; 19 host-e) printf "host-e* " ;; 20 host-f) printf "host-f,host-g,host-h " ;; 21 host-a2) printf "host-a " ;; 22 host-b2) printf "host-b " ;; 23 esac 24 cat $OBJ/kh.${x}.pub 25 # Blank line should be preserved. 26 echo "" >> $OBJ/kh.hosts 27 ) >> $OBJ/kh.hosts 28done 29 30# Generate a variant with an invalid line. We'll use this for most tests, 31# because keygen should be able to cope and it should be preserved in any 32# output file. 33cat $OBJ/kh.hosts >> $OBJ/kh.invalid 34echo "host-i " >> $OBJ/kh.invalid 35 36cp $OBJ/kh.invalid $OBJ/kh.invalid.orig 37cp $OBJ/kh.hosts $OBJ/kh.hosts.orig 38 39expect_key() { 40 _host=$1 41 _hosts=$2 42 _key=$3 43 _line=$4 44 _mark=$5 45 _marker="" 46 test "x$_mark" = "xCA" && _marker="@cert-authority " 47 test "x$_mark" = "xREVOKED" && _marker="@revoked " 48 test "x$_line" != "x" && 49 echo "# Host $_host found: line $_line $_mark" >> $OBJ/kh.expect 50 printf "${_marker}$_hosts " >> $OBJ/kh.expect 51 cat $OBJ/kh.${_key}.pub >> $OBJ/kh.expect || 52 fatal "${_key}.pub missing" 53} 54 55check_find() { 56 _host=$1 57 _name=$2 58 shift; shift 59 ${SSHKEYGEN} "$@" -f $OBJ/kh.invalid -F $_host > $OBJ/kh.result 60 if ! diff -w $OBJ/kh.expect $OBJ/kh.result ; then 61 fail "didn't find $_name" 62 fi 63} 64 65check_find_exit_code() { 66 _host=$1 67 _name=$2 68 _keygenopt=$3 69 _exp_exit_code=$4 70 ${SSHKEYGEN} $_keygenopt -f $OBJ/kh.invalid -F $_host > /dev/null 71 if [ "$?" != "$_exp_exit_code" ] ; then 72 fail "Unexpected exit code $_name" 73 fi 74} 75 76# Find key 77rm -f $OBJ/kh.expect 78expect_key host-a host-a host-a 2 79expect_key host-a host-a host-a2 20 80check_find host-a "simple find" 81 82# find CA key 83rm -f $OBJ/kh.expect 84expect_key host-c host-c host-c 8 CA 85check_find host-c "find CA key" 86 87# find revoked key 88rm -f $OBJ/kh.expect 89expect_key host-d host-d host-d 11 REVOKED 90check_find host-d "find revoked key" 91 92# find key with wildcard 93rm -f $OBJ/kh.expect 94expect_key host-e.somedomain "host-e*" host-e 14 95check_find host-e.somedomain "find wildcard key" 96 97# find key among multiple hosts 98rm -f $OBJ/kh.expect 99expect_key host-h "host-f,host-g,host-h " host-f 17 100check_find host-h "find multiple hosts" 101 102# Check exit code, known host 103check_find_exit_code host-a "known host" "-q" "0" 104 105# Check exit code, unknown host 106check_find_exit_code host-aa "unknown host" "-q" "1" 107 108# Check exit code, the hash mode, known host 109check_find_exit_code host-a "known host" "-q -H" "0" 110 111# Check exit code, the hash mode, unknown host 112check_find_exit_code host-aa "unknown host" "-q -H" "1" 113 114check_hashed_find() { 115 _host=$1 116 _name=$2 117 _file=$3 118 test "x$_file" = "x" && _file=$OBJ/kh.invalid 119 ${SSHKEYGEN} -f $_file -HF $_host | grep '|1|' | \ 120 sed "s/^[^ ]*/$_host/" > $OBJ/kh.result 121 if ! diff -w $OBJ/kh.expect $OBJ/kh.result ; then 122 fail "didn't find $_name" 123 fi 124} 125 126# Find key and hash 127rm -f $OBJ/kh.expect 128expect_key host-a host-a host-a 129expect_key host-a host-a host-a2 130check_hashed_find host-a "find simple and hash" 131 132# Find CA key and hash 133rm -f $OBJ/kh.expect 134expect_key host-c host-c host-c "" CA 135# CA key output is not hashed. 136check_find host-c "find simple and hash" -Hq 137 138# Find revoked key and hash 139rm -f $OBJ/kh.expect 140expect_key host-d host-d host-d "" REVOKED 141# Revoked key output is not hashed. 142check_find host-d "find simple and hash" -Hq 143 144# find key with wildcard and hash 145rm -f $OBJ/kh.expect 146expect_key host-e "host-e*" host-e "" 147# Key with wildcard hostname should not be hashed. 148check_find host-e "find wildcard key" -Hq 149 150# find key among multiple hosts 151rm -f $OBJ/kh.expect 152# Comma-separated hostnames should be expanded and hashed. 153expect_key host-f "host-h " host-f 154expect_key host-g "host-h " host-f 155expect_key host-h "host-h " host-f 156check_hashed_find host-h "find multiple hosts" 157 158# Attempt remove key on invalid file. 159cp $OBJ/kh.invalid.orig $OBJ/kh.invalid 160${SSHKEYGEN} -qf $OBJ/kh.invalid -R host-a 2>/dev/null 161diff $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "remove on invalid succeeded" 162 163# Remove key 164cp $OBJ/kh.hosts.orig $OBJ/kh.hosts 165${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-a 2>/dev/null 166grep -v "^host-a " $OBJ/kh.hosts.orig > $OBJ/kh.expect 167diff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove simple" 168 169# Remove CA key 170cp $OBJ/kh.hosts.orig $OBJ/kh.hosts 171${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-c 2>/dev/null 172# CA key should not be removed. 173diff $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove CA" 174 175# Remove revoked key 176cp $OBJ/kh.hosts.orig $OBJ/kh.hosts 177${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-d 2>/dev/null 178# revoked key should not be removed. 179diff $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove revoked" 180 181# Remove wildcard 182cp $OBJ/kh.hosts.orig $OBJ/kh.hosts 183${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-e.blahblah 2>/dev/null 184grep -v "^host-e[*] " $OBJ/kh.hosts.orig > $OBJ/kh.expect 185diff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" 186 187# Remove multiple 188cp $OBJ/kh.hosts.orig $OBJ/kh.hosts 189${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-h 2>/dev/null 190grep -v "^host-f," $OBJ/kh.hosts.orig > $OBJ/kh.expect 191diff $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" 192 193# Attempt hash on invalid file 194cp $OBJ/kh.invalid.orig $OBJ/kh.invalid 195${SSHKEYGEN} -qf $OBJ/kh.invalid -H 2>/dev/null && fail "hash invalid succeeded" 196diff $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "invalid file modified" 197 198# Hash valid file 199cp $OBJ/kh.hosts.orig $OBJ/kh.hosts 200${SSHKEYGEN} -qf $OBJ/kh.hosts -H 2>/dev/null || fail "hash failed" 201diff $OBJ/kh.hosts.old $OBJ/kh.hosts.orig || fail "backup differs" 202grep "^host-[abfgh]" $OBJ/kh.hosts && fail "original hostnames persist" 203 204cp $OBJ/kh.hosts $OBJ/kh.hashed.orig 205 206# Test lookup 207rm -f $OBJ/kh.expect 208expect_key host-a host-a host-a 209expect_key host-a host-a host-a2 210check_hashed_find host-a "find simple in hashed" $OBJ/kh.hosts 211 212# Test multiple expanded 213rm -f $OBJ/kh.expect 214expect_key host-h host-h host-f 215check_hashed_find host-h "find simple in hashed" $OBJ/kh.hosts 216 217# Test remove 218cp $OBJ/kh.hashed.orig $OBJ/kh.hashed 219${SSHKEYGEN} -qf $OBJ/kh.hashed -R host-a 2>/dev/null 220${SSHKEYGEN} -qf $OBJ/kh.hashed -F host-a && fail "found key after hashed remove" 221