regression test for known_host file editing using
authordjm <djm@openbsd.org>
Sun, 18 Jan 2015 22:00:18 +0000 (22:00 +0000)
committerdjm <djm@openbsd.org>
Sun, 18 Jan 2015 22:00:18 +0000 (22:00 +0000)
ssh-keygen (-H / -R / -F) after hostkeys_foreach() change;
feedback and ok markus@

regress/usr.bin/ssh/Makefile
regress/usr.bin/ssh/keygen-knownhosts.sh [new file with mode: 0644]

index 731893c..ad415b7 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.75 2015/01/18 19:47:55 djm Exp $
+#      $OpenBSD: Makefile,v 1.76 2015/01/18 22:00:18 djm Exp $
 
 REGRESS_FAIL_EARLY= yes
 REGRESS_TARGETS=       unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12
@@ -62,7 +62,8 @@ LTESTS=       connect \
                krl \
                multipubkey \
                limit-keytype \
-               hostkey-agent
+               hostkey-agent \
+               keygen-knownhosts
 
 INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
 #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
@@ -82,7 +83,7 @@ CLEANFILES+=  authorized_keys_${USER} known_hosts pidfile \
                sshd_proxy.* authorized_keys_${USER}.* revoked-* krl-* \
                ssh.log failed-ssh.log sshd.log failed-sshd.log \
                regress.log failed-regress.log ssh-log-wrapper.sh \
-               sftp-server.sh sftp-server.log sftp.log
+               sftp-server.sh sftp-server.log sftp.log kh.*
 
 SUDO_CLEAN+=   /var/run/testdata_${USER} /var/run/keycommand_${USER}
 
diff --git a/regress/usr.bin/ssh/keygen-knownhosts.sh b/regress/usr.bin/ssh/keygen-knownhosts.sh
new file mode 100644 (file)
index 0000000..35a5ea4
--- /dev/null
@@ -0,0 +1,197 @@
+#      $OpenBSD: keygen-knownhosts.sh,v 1.1 2015/01/18 22:00:18 djm Exp $
+#      Placed in the Public Domain.
+
+tid="ssh-keygen known_hosts"
+
+rm -f $OBJ/kh.*
+
+# Generate some keys for testing (just ed25519 for speed) and make a hosts file.
+for x in host-a host-b host-c host-d host-e host-f host-a2 host-b2; do
+       ${SSHKEYGEN} -qt ed25519 -f $OBJ/kh.$x -C "$x" -N "" || \
+               fatal "ssh-keygen failed"
+       # Add a comment that we expect should be preserved.
+       echo "# $x" >> $OBJ/kh.hosts
+       (
+               case "$x" in
+               host-a|host-b)  echo -n "$x " ;;
+               host-c)         echo -n "@cert-authority $x " ;;
+               host-d)         echo -n "@revoked $x " ;;
+               host-e)         echo -n "host-e* " ;;
+               host-f)         echo -n "host-f,host-g,host-h " ;;
+               host-a2)        echo -n "host-a " ;;
+               host-b2)        echo -n "host-b " ;;
+               esac
+               cat $OBJ/kh.${x}.pub
+               # Blank line should be preserved.
+               echo "" >> $OBJ/kh.hosts
+       ) >> $OBJ/kh.hosts
+done
+
+# Generate a variant with an invalid line. We'll use this for most tests,
+# because keygen should be able to cope and it should be preserved in any
+# output file.
+cat $OBJ/kh.hosts >> $OBJ/kh.invalid
+echo "host-i " >> $OBJ/kh.invalid
+
+cp $OBJ/kh.invalid $OBJ/kh.invalid.orig
+cp $OBJ/kh.hosts $OBJ/kh.hosts.orig
+
+expect_key() {
+       _host=$1
+       _hosts=$2
+       _key=$3
+       _line=$4
+       _mark=$5
+       _marker=""
+       test "x$_mark" = "xCA" && _marker="@cert-authority "
+       test "x$_mark" = "xREVOKED" && _marker="@revoked "
+       test "x$_line" != "x" &&
+           echo "# Host $_host found: line $_line $_mark" >> $OBJ/kh.expect
+       echo -n "${_marker}$_hosts " >> $OBJ/kh.expect
+       cat $OBJ/kh.${_key}.pub >> $OBJ/kh.expect ||
+           fatal "${_key}.pub missing"
+}
+
+check_find() {
+       _host=$1
+       _name=$2
+       _keygenopt=$3
+       ${SSHKEYGEN} $_keygenopt -f $OBJ/kh.invalid -F $_host > $OBJ/kh.result
+       if ! diff -uw $OBJ/kh.expect $OBJ/kh.result ; then
+               fail "didn't find $_name"
+       fi
+}
+
+# Find key
+rm -f $OBJ/kh.expect
+expect_key host-a host-a host-a 2
+expect_key host-a host-a host-a2 20
+check_find host-a "simple find"
+
+# find CA key
+rm -f $OBJ/kh.expect
+expect_key host-c host-c host-c 8 CA
+check_find host-c "find CA key"
+
+# find revoked key
+rm -f $OBJ/kh.expect
+expect_key host-d host-d host-d 11 REVOKED
+check_find host-d "find revoked key"
+
+# find key with wildcard
+rm -f $OBJ/kh.expect
+expect_key host-e.somedomain "host-e*" host-e 14
+check_find host-e.somedomain "find wildcard key"
+
+# find key among multiple hosts
+rm -f $OBJ/kh.expect
+expect_key host-h "host-f,host-g,host-h " host-f 17
+check_find host-h "find multiple hosts"
+
+check_hashed_find() {
+       _host=$1
+       _name=$2
+       _file=$3
+       test "x$_file" = "x" && _file=$OBJ/kh.invalid
+       ${SSHKEYGEN} -f $_file -HF $_host | grep '|1|' | \
+           sed "s/^[^ ]*/$_host/" > $OBJ/kh.result
+       if ! diff -uw $OBJ/kh.expect $OBJ/kh.result ; then
+               fail "didn't find $_name"
+       fi
+}
+
+# Find key and hash
+rm -f $OBJ/kh.expect
+expect_key host-a host-a host-a
+expect_key host-a host-a host-a2
+check_hashed_find host-a "find simple and hash"
+
+# Find CA key and hash
+rm -f $OBJ/kh.expect
+expect_key host-c host-c host-c "" CA
+# CA key output is not hashed.
+check_find host-c "find simple and hash" -H
+
+# Find revoked key and hash
+rm -f $OBJ/kh.expect
+expect_key host-d host-d host-d "" REVOKED
+# Revoked key output is not hashed.
+check_find host-d "find simple and hash" -H
+
+# find key with wildcard and hash
+rm -f $OBJ/kh.expect
+expect_key host-e "host-e*" host-e ""
+# Key with wildcard hostname should not be hashed.
+check_find host-e "find wildcard key" -H
+
+# find key among multiple hosts
+rm -f $OBJ/kh.expect
+# Comma-separated hostnames should be expanded and hashed.
+expect_key host-f "host-h " host-f
+expect_key host-g "host-h " host-f
+expect_key host-h "host-h " host-f
+check_hashed_find host-h "find multiple hosts"
+
+# Attempt remove key on invalid file.
+cp $OBJ/kh.invalid.orig $OBJ/kh.invalid
+${SSHKEYGEN} -qf $OBJ/kh.invalid -R host-a 2>/dev/null
+diff -u $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "remove on invalid succeeded"
+
+# Remove key
+cp $OBJ/kh.hosts.orig $OBJ/kh.hosts
+${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-a 2>/dev/null
+grep -v "^host-a " $OBJ/kh.hosts.orig > $OBJ/kh.expect
+diff -u $OBJ/kh.hosts $OBJ/kh.expect || fail "remove simple"
+
+# Remove CA key
+cp $OBJ/kh.hosts.orig $OBJ/kh.hosts
+${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-c 2>/dev/null
+# CA key should not be removed.
+diff -u $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove CA"
+
+# Remove revoked key
+cp $OBJ/kh.hosts.orig $OBJ/kh.hosts
+${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-d 2>/dev/null
+# revoked key should not be removed.
+diff -u $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove revoked"
+
+# Remove wildcard
+cp $OBJ/kh.hosts.orig $OBJ/kh.hosts
+${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-e.blahblah 2>/dev/null
+grep -v "^host-e[*] " $OBJ/kh.hosts.orig > $OBJ/kh.expect
+diff -u $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard"
+
+# Remove multiple
+cp $OBJ/kh.hosts.orig $OBJ/kh.hosts
+${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-h 2>/dev/null
+grep -v "^host-f," $OBJ/kh.hosts.orig > $OBJ/kh.expect
+diff -u $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard"
+
+# Attempt hash on invalid file
+cp $OBJ/kh.invalid.orig $OBJ/kh.invalid
+${SSHKEYGEN} -qf $OBJ/kh.invalid -H 2>/dev/null && fail "hash invalid succeeded"
+diff -u $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "invalid file modified"
+
+# Hash valid file
+cp $OBJ/kh.hosts.orig $OBJ/kh.hosts
+${SSHKEYGEN} -qf $OBJ/kh.hosts -H 2>/dev/null || fail "hash failed"
+diff -u $OBJ/kh.hosts.old $OBJ/kh.hosts.orig || fail "backup differs"
+grep "^host-[abfgh]" $OBJ/kh.hosts && fail "original hostnames persist"
+
+cp $OBJ/kh.hosts $OBJ/kh.hashed.orig
+
+# Test lookup
+rm -f $OBJ/kh.expect
+expect_key host-a host-a host-a
+expect_key host-a host-a host-a2
+check_hashed_find host-a "find simple in hashed" $OBJ/kh.hosts
+
+# Test multiple expanded
+rm -f $OBJ/kh.expect
+expect_key host-h host-h host-f
+check_hashed_find host-h "find simple in hashed" $OBJ/kh.hosts
+
+# Test remove
+cp $OBJ/kh.hashed.orig $OBJ/kh.hashed
+${SSHKEYGEN} -qf $OBJ/kh.hashed -R host-a 2>/dev/null
+${SSHKEYGEN} -qf $OBJ/kh.hashed -F host-a && fail "found key after hashed remove"