keygen-knownhosts.sh 6.4 KB

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