diff options
author | Colin Watson <cjwatson@debian.org> | 2015-08-19 14:23:51 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2015-08-19 16:48:11 +0100 |
commit | 0f0841b2d28b7463267d4d91577e72e3340a1d3a (patch) | |
tree | ba55fcd2b6e2cc22b30f5afb561dbb3da4c8b6c7 /regress | |
parent | f2a5f5dae656759efb0b76c3d94890b65c197a02 (diff) | |
parent | 8698446b972003b63dfe5dcbdb86acfe986afb85 (diff) |
New upstream release (6.8p1).
Diffstat (limited to 'regress')
112 files changed, 4851 insertions, 290 deletions
diff --git a/regress/.cvsignore b/regress/.cvsignore new file mode 100644 index 000000000..3fd25b02e --- /dev/null +++ b/regress/.cvsignore | |||
@@ -0,0 +1,31 @@ | |||
1 | *-agent | ||
2 | *.copy | ||
3 | *.log | ||
4 | *.prv | ||
5 | *.pub | ||
6 | actual | ||
7 | authorized_keys_* | ||
8 | batch | ||
9 | copy.dd* | ||
10 | data | ||
11 | expect | ||
12 | host.rsa* | ||
13 | key.* | ||
14 | known_hosts | ||
15 | krl-* | ||
16 | modpipe | ||
17 | remote_pid | ||
18 | revoked-* | ||
19 | revoked-ca | ||
20 | revoked-keyid | ||
21 | revoked-serials | ||
22 | rsa | ||
23 | rsa1 | ||
24 | sftp-server.sh | ||
25 | ssh-log-wrapper.sh | ||
26 | ssh_config | ||
27 | ssh_proxy* | ||
28 | sshd_config | ||
29 | sshd_proxy* | ||
30 | t*.out | ||
31 | t*.out[0-9] | ||
diff --git a/regress/Makefile b/regress/Makefile index 3feb7a997..99a7d60f5 100644 --- a/regress/Makefile +++ b/regress/Makefile | |||
@@ -1,11 +1,14 @@ | |||
1 | # $OpenBSD: Makefile,v 1.70 2014/06/24 01:14:17 djm Exp $ | 1 | # $OpenBSD: Makefile,v 1.78 2015/01/26 06:12:18 djm Exp $ |
2 | 2 | ||
3 | REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec | 3 | REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec |
4 | tests: $(REGRESS_TARGETS) | 4 | tests: prep $(REGRESS_TARGETS) |
5 | 5 | ||
6 | # Interop tests are not run by default | 6 | # Interop tests are not run by default |
7 | interop interop-tests: t-exec-interop | 7 | interop interop-tests: t-exec-interop |
8 | 8 | ||
9 | prep: | ||
10 | test "x${USE_VALGRIND}" = "x" || mkdir -p $(OBJ)/valgrind-out | ||
11 | |||
9 | clean: | 12 | clean: |
10 | for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done | 13 | for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done |
11 | test -z "${SUDO}" || ${SUDO} rm -f ${SUDO_CLEAN} | 14 | test -z "${SUDO}" || ${SUDO} rm -f ${SUDO_CLEAN} |
@@ -64,7 +67,14 @@ LTESTS= connect \ | |||
64 | keys-command \ | 67 | keys-command \ |
65 | forward-control \ | 68 | forward-control \ |
66 | integrity \ | 69 | integrity \ |
67 | krl | 70 | krl \ |
71 | multipubkey \ | ||
72 | limit-keytype \ | ||
73 | hostkey-agent \ | ||
74 | keygen-knownhosts \ | ||
75 | hostkey-rotate | ||
76 | |||
77 | |||
68 | # dhgex \ | 78 | # dhgex \ |
69 | 79 | ||
70 | INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers | 80 | INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers |
@@ -75,6 +85,7 @@ INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers | |||
75 | USER!= id -un | 85 | USER!= id -un |
76 | CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ | 86 | CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ |
77 | t8.out t8.out.pub t9.out t9.out.pub t10.out t10.out.pub \ | 87 | t8.out t8.out.pub t9.out t9.out.pub t10.out t10.out.pub \ |
88 | t12.out t12.out.pub \ | ||
78 | authorized_keys_${USER} known_hosts pidfile testdata \ | 89 | authorized_keys_${USER} known_hosts pidfile testdata \ |
79 | ssh_config sshd_config.orig ssh_proxy sshd_config sshd_proxy \ | 90 | ssh_config sshd_config.orig ssh_proxy sshd_config sshd_proxy \ |
80 | rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ | 91 | rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ |
@@ -91,7 +102,8 @@ CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ | |||
91 | regress.log failed-regress.log ssh-log-wrapper.sh \ | 102 | regress.log failed-regress.log ssh-log-wrapper.sh \ |
92 | sftp-server.sh sftp-server.log sftp.log setuid-allowed \ | 103 | sftp-server.sh sftp-server.log sftp.log setuid-allowed \ |
93 | data ed25519-agent ed25519-agent.pub key.ed25519-512 \ | 104 | data ed25519-agent ed25519-agent.pub key.ed25519-512 \ |
94 | key.ed25519-512.pub | 105 | key.ed25519-512.pub netcat host_krl_* host_revoked_* \ |
106 | kh.* user_*key* agent-key.* known_hosts.* hkr.* | ||
95 | 107 | ||
96 | SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/keycommand_${USER} | 108 | SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/keycommand_${USER} |
97 | 109 | ||
@@ -119,7 +131,7 @@ t3: | |||
119 | ${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub | 131 | ${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub |
120 | 132 | ||
121 | t4: | 133 | t4: |
122 | ${TEST_SSH_SSHKEYGEN} -lf ${.CURDIR}/rsa_openssh.pub |\ | 134 | ${TEST_SSH_SSHKEYGEN} -E md5 -lf ${.CURDIR}/rsa_openssh.pub |\ |
123 | awk '{print $$2}' | diff - ${.CURDIR}/t4.ok | 135 | awk '{print $$2}' | diff - ${.CURDIR}/t4.ok |
124 | 136 | ||
125 | t5: | 137 | t5: |
@@ -164,6 +176,16 @@ t10: $(OBJ)/t10.out | |||
164 | ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t10.out > /dev/null | 176 | ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t10.out > /dev/null |
165 | ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null | 177 | ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null |
166 | 178 | ||
179 | t11: | ||
180 | ${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\ | ||
181 | awk '{print $$2}' | diff - ${.CURDIR}/t11.ok | ||
182 | |||
183 | t12.out: | ||
184 | ${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -C 'test-comment-1234' -f $(OBJ)/$@ | ||
185 | |||
186 | t12: t12.out | ||
187 | ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t12.out.pub | grep test-comment-1234 >/dev/null | ||
188 | |||
167 | t-exec: ${LTESTS:=.sh} | 189 | t-exec: ${LTESTS:=.sh} |
168 | @if [ "x$?" = "x" ]; then exit 0; fi; \ | 190 | @if [ "x$?" = "x" ]; then exit 0; fi; \ |
169 | for TEST in ""$?; do \ | 191 | for TEST in ""$?; do \ |
@@ -184,7 +206,14 @@ interop: ${INTEROP_TARGETS} | |||
184 | # Unit tests, built by top-level Makefile | 206 | # Unit tests, built by top-level Makefile |
185 | unit: | 207 | unit: |
186 | set -e ; if test -z "${SKIP_UNIT}" ; then \ | 208 | set -e ; if test -z "${SKIP_UNIT}" ; then \ |
187 | ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ | 209 | V="" ; \ |
188 | ${.OBJDIR}/unittests/sshkey/test_sshkey \ | 210 | test "x${USE_VALGRIND}" = "x" || \ |
189 | -d ${.CURDIR}//unittests/sshkey/testdata ; \ | 211 | V=${.CURDIR}/valgrind-unit.sh ; \ |
212 | $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ | ||
213 | $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ | ||
214 | -d ${.CURDIR}/unittests/sshkey/testdata ; \ | ||
215 | $$V ${.OBJDIR}/unittests/bitmap/test_bitmap ; \ | ||
216 | $$V ${.OBJDIR}/unittests/kex/test_kex ; \ | ||
217 | $$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \ | ||
218 | -d ${.CURDIR}/unittests/hostkeys/testdata ; \ | ||
190 | fi | 219 | fi |
diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh index db33ab37e..3aa20c8b1 100644 --- a/regress/agent-pkcs11.sh +++ b/regress/agent-pkcs11.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: agent-pkcs11.sh,v 1.1 2010/02/08 10:52:47 markus Exp $ | 1 | # $OpenBSD: agent-pkcs11.sh,v 1.2 2015/01/12 11:46:32 djm Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="pkcs11 agent test" | 4 | tid="pkcs11 agent test" |
@@ -6,6 +6,8 @@ tid="pkcs11 agent test" | |||
6 | TEST_SSH_PIN="" | 6 | TEST_SSH_PIN="" |
7 | TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0 | 7 | TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0 |
8 | 8 | ||
9 | test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" | ||
10 | |||
9 | # setup environment for soft-pkcs11 token | 11 | # setup environment for soft-pkcs11 token |
10 | SOFTPKCS11RC=$OBJ/pkcs11.info | 12 | SOFTPKCS11RC=$OBJ/pkcs11.info |
11 | export SOFTPKCS11RC | 13 | export SOFTPKCS11RC |
diff --git a/regress/agent-timeout.sh b/regress/agent-timeout.sh index 68826594e..9598c2032 100644 --- a/regress/agent-timeout.sh +++ b/regress/agent-timeout.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: agent-timeout.sh,v 1.2 2013/05/17 01:16:09 dtucker Exp $ | 1 | # $OpenBSD: agent-timeout.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="agent timeout test" | 4 | tid="agent timeout test" |
@@ -12,7 +12,7 @@ if [ $r -ne 0 ]; then | |||
12 | fail "could not start ssh-agent: exit code $r" | 12 | fail "could not start ssh-agent: exit code $r" |
13 | else | 13 | else |
14 | trace "add keys with timeout" | 14 | trace "add keys with timeout" |
15 | for t in rsa rsa1; do | 15 | for t in ${SSH_KEYTYPES}; do |
16 | ${SSHADD} -t ${SSHAGENT_TIMEOUT} $OBJ/$t > /dev/null 2>&1 | 16 | ${SSHADD} -t ${SSHAGENT_TIMEOUT} $OBJ/$t > /dev/null 2>&1 |
17 | if [ $? -ne 0 ]; then | 17 | if [ $? -ne 0 ]; then |
18 | fail "ssh-add did succeed exit code 0" | 18 | fail "ssh-add did succeed exit code 0" |
diff --git a/regress/agent.sh b/regress/agent.sh index caad3c88e..c5e2794b7 100644 --- a/regress/agent.sh +++ b/regress/agent.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: agent.sh,v 1.10 2014/02/27 21:21:25 djm Exp $ | 1 | # $OpenBSD: agent.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="simple agent test" | 4 | tid="simple agent test" |
@@ -20,7 +20,7 @@ else | |||
20 | fi | 20 | fi |
21 | trace "overwrite authorized keys" | 21 | trace "overwrite authorized keys" |
22 | printf '' > $OBJ/authorized_keys_$USER | 22 | printf '' > $OBJ/authorized_keys_$USER |
23 | for t in ed25519 rsa rsa1; do | 23 | for t in ${SSH_KEYTYPES}; do |
24 | # generate user key for agent | 24 | # generate user key for agent |
25 | rm -f $OBJ/$t-agent | 25 | rm -f $OBJ/$t-agent |
26 | ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\ | 26 | ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\ |
@@ -46,7 +46,7 @@ else | |||
46 | fi | 46 | fi |
47 | 47 | ||
48 | trace "simple connect via agent" | 48 | trace "simple connect via agent" |
49 | for p in 1 2; do | 49 | for p in ${SSH_PROTOCOLS}; do |
50 | ${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p | 50 | ${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p |
51 | r=$? | 51 | r=$? |
52 | if [ $r -ne 5$p ]; then | 52 | if [ $r -ne 5$p ]; then |
@@ -55,7 +55,7 @@ else | |||
55 | done | 55 | done |
56 | 56 | ||
57 | trace "agent forwarding" | 57 | trace "agent forwarding" |
58 | for p in 1 2; do | 58 | for p in ${SSH_PROTOCOLS}; do |
59 | ${SSH} -A -$p -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1 | 59 | ${SSH} -A -$p -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1 |
60 | r=$? | 60 | r=$? |
61 | if [ $r -ne 0 ]; then | 61 | if [ $r -ne 0 ]; then |
diff --git a/regress/broken-pipe.sh b/regress/broken-pipe.sh index c08c849a7..a416f7a3b 100644 --- a/regress/broken-pipe.sh +++ b/regress/broken-pipe.sh | |||
@@ -1,9 +1,9 @@ | |||
1 | # $OpenBSD: broken-pipe.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ | 1 | # $OpenBSD: broken-pipe.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="broken pipe test" | 4 | tid="broken pipe test" |
5 | 5 | ||
6 | for p in 1 2; do | 6 | for p in ${SSH_PROTOCOLS}; do |
7 | trace "protocol $p" | 7 | trace "protocol $p" |
8 | for i in 1 2 3 4; do | 8 | for i in 1 2 3 4; do |
9 | ${SSH} -$p -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true | 9 | ${SSH} -$p -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true |
diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh index 1d9e0ed8e..51685dc2b 100644 --- a/regress/cert-hostkey.sh +++ b/regress/cert-hostkey.sh | |||
@@ -1,21 +1,29 @@ | |||
1 | # $OpenBSD: cert-hostkey.sh,v 1.9 2014/01/26 10:22:10 djm Exp $ | 1 | # $OpenBSD: cert-hostkey.sh,v 1.11 2015/01/19 06:01:32 djm Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="certified host keys" | 4 | tid="certified host keys" |
5 | 5 | ||
6 | rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key* | 6 | rm -f $OBJ/known_hosts-cert* $OBJ/host_ca_key* $OBJ/host_revoked_* |
7 | rm -f $OBJ/cert_host_key* $OBJ/host_krl_* | ||
7 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak | 8 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak |
8 | 9 | ||
9 | HOSTS='localhost-with-alias,127.0.0.1,::1' | 10 | HOSTS='localhost-with-alias,127.0.0.1,::1' |
10 | 11 | ||
11 | # Create a CA key and add it to known hosts | 12 | # Create a CA key and add it to known hosts. Ed25519 chosed for speed. |
12 | ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\ | 13 | ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/host_ca_key ||\ |
13 | fail "ssh-keygen of host_ca_key failed" | 14 | fail "ssh-keygen of host_ca_key failed" |
14 | ( | 15 | ( |
15 | printf '@cert-authority ' | 16 | printf '@cert-authority ' |
16 | printf "$HOSTS " | 17 | printf "$HOSTS " |
17 | cat $OBJ/host_ca_key.pub | 18 | cat $OBJ/host_ca_key.pub |
18 | ) > $OBJ/known_hosts-cert | 19 | ) > $OBJ/known_hosts-cert.orig |
20 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
21 | |||
22 | # Plain text revocation files | ||
23 | touch $OBJ/host_revoked_empty | ||
24 | touch $OBJ/host_revoked_plain | ||
25 | touch $OBJ/host_revoked_cert | ||
26 | cp $OBJ/host_ca_key.pub $OBJ/host_revoked_ca | ||
19 | 27 | ||
20 | PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` | 28 | PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` |
21 | 29 | ||
@@ -26,17 +34,33 @@ type_has_legacy() { | |||
26 | return 0 | 34 | return 0 |
27 | } | 35 | } |
28 | 36 | ||
37 | # Prepare certificate, plain key and CA KRLs | ||
38 | ${SSHKEYGEN} -kf $OBJ/host_krl_empty || fatal "KRL init failed" | ||
39 | ${SSHKEYGEN} -kf $OBJ/host_krl_plain || fatal "KRL init failed" | ||
40 | ${SSHKEYGEN} -kf $OBJ/host_krl_cert || fatal "KRL init failed" | ||
41 | ${SSHKEYGEN} -kf $OBJ/host_krl_ca $OBJ/host_ca_key.pub \ | ||
42 | || fatal "KRL init failed" | ||
43 | |||
29 | # Generate and sign host keys | 44 | # Generate and sign host keys |
45 | serial=1 | ||
30 | for ktype in $PLAIN_TYPES ; do | 46 | for ktype in $PLAIN_TYPES ; do |
31 | verbose "$tid: sign host ${ktype} cert" | 47 | verbose "$tid: sign host ${ktype} cert" |
32 | # Generate and sign a host key | 48 | # Generate and sign a host key |
33 | ${SSHKEYGEN} -q -N '' -t ${ktype} \ | 49 | ${SSHKEYGEN} -q -N '' -t ${ktype} \ |
34 | -f $OBJ/cert_host_key_${ktype} || \ | 50 | -f $OBJ/cert_host_key_${ktype} || \ |
35 | fail "ssh-keygen of cert_host_key_${ktype} failed" | 51 | fatal "ssh-keygen of cert_host_key_${ktype} failed" |
36 | ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key \ | 52 | ${SSHKEYGEN} -ukf $OBJ/host_krl_plain \ |
53 | $OBJ/cert_host_key_${ktype}.pub || fatal "KRL update failed" | ||
54 | cat $OBJ/cert_host_key_${ktype}.pub >> $OBJ/host_revoked_plain | ||
55 | ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key -z $serial \ | ||
37 | -I "regress host key for $USER" \ | 56 | -I "regress host key for $USER" \ |
38 | -n $HOSTS $OBJ/cert_host_key_${ktype} || | 57 | -n $HOSTS $OBJ/cert_host_key_${ktype} || |
39 | fail "couldn't sign cert_host_key_${ktype}" | 58 | fatal "couldn't sign cert_host_key_${ktype}" |
59 | ${SSHKEYGEN} -ukf $OBJ/host_krl_cert \ | ||
60 | $OBJ/cert_host_key_${ktype}-cert.pub || \ | ||
61 | fatal "KRL update failed" | ||
62 | cat $OBJ/cert_host_key_${ktype}-cert.pub >> $OBJ/host_revoked_cert | ||
63 | serial=`expr $serial + 1` | ||
40 | type_has_legacy $ktype || continue | 64 | type_has_legacy $ktype || continue |
41 | cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00 | 65 | cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00 |
42 | cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub | 66 | cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub |
@@ -44,10 +68,35 @@ for ktype in $PLAIN_TYPES ; do | |||
44 | ${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \ | 68 | ${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \ |
45 | -I "regress host key for $USER" \ | 69 | -I "regress host key for $USER" \ |
46 | -n $HOSTS $OBJ/cert_host_key_${ktype}_v00 || | 70 | -n $HOSTS $OBJ/cert_host_key_${ktype}_v00 || |
47 | fail "couldn't sign cert_host_key_${ktype}_v00" | 71 | fatal "couldn't sign cert_host_key_${ktype}_v00" |
72 | ${SSHKEYGEN} -ukf $OBJ/host_krl_cert \ | ||
73 | $OBJ/cert_host_key_${ktype}_v00-cert.pub || \ | ||
74 | fatal "KRL update failed" | ||
75 | cat $OBJ/cert_host_key_${ktype}_v00-cert.pub >> $OBJ/host_revoked_cert | ||
48 | done | 76 | done |
49 | 77 | ||
50 | # Basic connect tests | 78 | attempt_connect() { |
79 | _ident="$1" | ||
80 | _expect_success="$2" | ||
81 | shift; shift | ||
82 | verbose "$tid: $_ident expect success $_expect_success" | ||
83 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
84 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ | ||
85 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ | ||
86 | "$@" -F $OBJ/ssh_proxy somehost true | ||
87 | _r=$? | ||
88 | if [ "x$_expect_success" = "xyes" ] ; then | ||
89 | if [ $_r -ne 0 ]; then | ||
90 | fail "ssh cert connect $_ident failed" | ||
91 | fi | ||
92 | else | ||
93 | if [ $_r -eq 0 ]; then | ||
94 | fail "ssh cert connect $_ident succeeded unexpectedly" | ||
95 | fi | ||
96 | fi | ||
97 | } | ||
98 | |||
99 | # Basic connect and revocation tests. | ||
51 | for privsep in yes no ; do | 100 | for privsep in yes no ; do |
52 | for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do | 101 | for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do |
53 | verbose "$tid: host ${ktype} cert connect privsep $privsep" | 102 | verbose "$tid: host ${ktype} cert connect privsep $privsep" |
@@ -58,12 +107,24 @@ for privsep in yes no ; do | |||
58 | echo UsePrivilegeSeparation $privsep | 107 | echo UsePrivilegeSeparation $privsep |
59 | ) > $OBJ/sshd_proxy | 108 | ) > $OBJ/sshd_proxy |
60 | 109 | ||
61 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ | 110 | # test name expect success |
62 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ | 111 | attempt_connect "$ktype basic connect" "yes" |
63 | -F $OBJ/ssh_proxy somehost true | 112 | attempt_connect "$ktype empty KRL" "yes" \ |
64 | if [ $? -ne 0 ]; then | 113 | -oRevokedHostKeys=$OBJ/host_krl_empty |
65 | fail "ssh cert connect failed" | 114 | attempt_connect "$ktype KRL w/ plain key revoked" "no" \ |
66 | fi | 115 | -oRevokedHostKeys=$OBJ/host_krl_plain |
116 | attempt_connect "$ktype KRL w/ cert revoked" "no" \ | ||
117 | -oRevokedHostKeys=$OBJ/host_krl_cert | ||
118 | attempt_connect "$ktype KRL w/ CA revoked" "no" \ | ||
119 | -oRevokedHostKeys=$OBJ/host_krl_ca | ||
120 | attempt_connect "$ktype empty plaintext revocation" "yes" \ | ||
121 | -oRevokedHostKeys=$OBJ/host_revoked_empty | ||
122 | attempt_connect "$ktype plain key plaintext revocation" "no" \ | ||
123 | -oRevokedHostKeys=$OBJ/host_revoked_plain | ||
124 | attempt_connect "$ktype cert plaintext revocation" "no" \ | ||
125 | -oRevokedHostKeys=$OBJ/host_revoked_cert | ||
126 | attempt_connect "$ktype CA plaintext revocation" "no" \ | ||
127 | -oRevokedHostKeys=$OBJ/host_revoked_ca | ||
67 | done | 128 | done |
68 | done | 129 | done |
69 | 130 | ||
@@ -76,7 +137,8 @@ done | |||
76 | test -f "$OBJ/cert_host_key_${ktype}.pub" || fatal "no pubkey" | 137 | test -f "$OBJ/cert_host_key_${ktype}.pub" || fatal "no pubkey" |
77 | printf "@revoked * `cat $OBJ/cert_host_key_${ktype}.pub`\n" | 138 | printf "@revoked * `cat $OBJ/cert_host_key_${ktype}.pub`\n" |
78 | done | 139 | done |
79 | ) > $OBJ/known_hosts-cert | 140 | ) > $OBJ/known_hosts-cert.orig |
141 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
80 | for privsep in yes no ; do | 142 | for privsep in yes no ; do |
81 | for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do | 143 | for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do |
82 | verbose "$tid: host ${ktype} revoked cert privsep $privsep" | 144 | verbose "$tid: host ${ktype} revoked cert privsep $privsep" |
@@ -87,6 +149,7 @@ for privsep in yes no ; do | |||
87 | echo UsePrivilegeSeparation $privsep | 149 | echo UsePrivilegeSeparation $privsep |
88 | ) > $OBJ/sshd_proxy | 150 | ) > $OBJ/sshd_proxy |
89 | 151 | ||
152 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
90 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ | 153 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ |
91 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ | 154 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ |
92 | -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 | 155 | -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 |
@@ -104,7 +167,8 @@ done | |||
104 | printf '@revoked ' | 167 | printf '@revoked ' |
105 | printf "* " | 168 | printf "* " |
106 | cat $OBJ/host_ca_key.pub | 169 | cat $OBJ/host_ca_key.pub |
107 | ) > $OBJ/known_hosts-cert | 170 | ) > $OBJ/known_hosts-cert.orig |
171 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
108 | for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do | 172 | for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do |
109 | verbose "$tid: host ${ktype} revoked cert" | 173 | verbose "$tid: host ${ktype} revoked cert" |
110 | ( | 174 | ( |
@@ -112,6 +176,7 @@ for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do | |||
112 | echo HostKey $OBJ/cert_host_key_${ktype} | 176 | echo HostKey $OBJ/cert_host_key_${ktype} |
113 | echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub | 177 | echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub |
114 | ) > $OBJ/sshd_proxy | 178 | ) > $OBJ/sshd_proxy |
179 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
115 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ | 180 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ |
116 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ | 181 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ |
117 | -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 | 182 | -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 |
@@ -125,7 +190,8 @@ done | |||
125 | printf '@cert-authority ' | 190 | printf '@cert-authority ' |
126 | printf "$HOSTS " | 191 | printf "$HOSTS " |
127 | cat $OBJ/host_ca_key.pub | 192 | cat $OBJ/host_ca_key.pub |
128 | ) > $OBJ/known_hosts-cert | 193 | ) > $OBJ/known_hosts-cert.orig |
194 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
129 | 195 | ||
130 | test_one() { | 196 | test_one() { |
131 | ident=$1 | 197 | ident=$1 |
@@ -150,6 +216,7 @@ test_one() { | |||
150 | echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub | 216 | echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub |
151 | ) > $OBJ/sshd_proxy | 217 | ) > $OBJ/sshd_proxy |
152 | 218 | ||
219 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
153 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ | 220 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ |
154 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ | 221 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ |
155 | -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 | 222 | -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 |
@@ -212,7 +279,8 @@ done | |||
212 | printf '@cert-authority ' | 279 | printf '@cert-authority ' |
213 | printf "$HOSTS " | 280 | printf "$HOSTS " |
214 | cat $OBJ/host_ca_key.pub | 281 | cat $OBJ/host_ca_key.pub |
215 | ) > $OBJ/known_hosts-cert | 282 | ) > $OBJ/known_hosts-cert.orig |
283 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
216 | for v in v01 v00 ; do | 284 | for v in v01 v00 ; do |
217 | for kt in $PLAIN_TYPES ; do | 285 | for kt in $PLAIN_TYPES ; do |
218 | type_has_legacy $kt || continue | 286 | type_has_legacy $kt || continue |
@@ -232,6 +300,7 @@ for v in v01 v00 ; do | |||
232 | echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub | 300 | echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub |
233 | ) > $OBJ/sshd_proxy | 301 | ) > $OBJ/sshd_proxy |
234 | 302 | ||
303 | cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert | ||
235 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ | 304 | ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ |
236 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ | 305 | -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ |
237 | -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1 | 306 | -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1 |
@@ -241,4 +310,4 @@ for v in v01 v00 ; do | |||
241 | done | 310 | done |
242 | done | 311 | done |
243 | 312 | ||
244 | rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key* | 313 | rm -f $OBJ/known_hosts-cert* $OBJ/host_ca_key* $OBJ/cert_host_key* |
diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh index 80cf22930..056296398 100644 --- a/regress/cfgmatch.sh +++ b/regress/cfgmatch.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: cfgmatch.sh,v 1.8 2013/05/17 00:37:40 dtucker Exp $ | 1 | # $OpenBSD: cfgmatch.sh,v 1.9 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="sshd_config match" | 4 | tid="sshd_config match" |
@@ -56,7 +56,7 @@ start_sshd | |||
56 | #set -x | 56 | #set -x |
57 | 57 | ||
58 | # Test Match + PermitOpen in sshd_config. This should be permitted | 58 | # Test Match + PermitOpen in sshd_config. This should be permitted |
59 | for p in 1 2; do | 59 | for p in ${SSH_PROTOCOLS}; do |
60 | trace "match permitopen localhost proto $p" | 60 | trace "match permitopen localhost proto $p" |
61 | start_client -F $OBJ/ssh_config | 61 | start_client -F $OBJ/ssh_config |
62 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ | 62 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ |
@@ -65,7 +65,7 @@ for p in 1 2; do | |||
65 | done | 65 | done |
66 | 66 | ||
67 | # Same but from different source. This should not be permitted | 67 | # Same but from different source. This should not be permitted |
68 | for p in 1 2; do | 68 | for p in ${SSH_PROTOCOLS}; do |
69 | trace "match permitopen proxy proto $p" | 69 | trace "match permitopen proxy proto $p" |
70 | start_client -F $OBJ/ssh_proxy | 70 | start_client -F $OBJ/ssh_proxy |
71 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ | 71 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ |
@@ -74,11 +74,12 @@ for p in 1 2; do | |||
74 | done | 74 | done |
75 | 75 | ||
76 | # Retry previous with key option, should also be denied. | 76 | # Retry previous with key option, should also be denied. |
77 | printf 'permitopen="127.0.0.1:'$PORT'" ' >$OBJ/authorized_keys_$USER | 77 | cp /dev/null $OBJ/authorized_keys_$USER |
78 | cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER | 78 | for t in ${SSH_KEYTYPES}; do |
79 | printf 'permitopen="127.0.0.1:'$PORT'" ' >>$OBJ/authorized_keys_$USER | 79 | printf 'permitopen="127.0.0.1:'$PORT'" ' >> $OBJ/authorized_keys_$USER |
80 | cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER | 80 | cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER |
81 | for p in 1 2; do | 81 | done |
82 | for p in ${SSH_PROTOCOLS}; do | ||
82 | trace "match permitopen proxy w/key opts proto $p" | 83 | trace "match permitopen proxy w/key opts proto $p" |
83 | start_client -F $OBJ/ssh_proxy | 84 | start_client -F $OBJ/ssh_proxy |
84 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ | 85 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ |
@@ -88,7 +89,7 @@ done | |||
88 | 89 | ||
89 | # Test both sshd_config and key options permitting the same dst/port pair. | 90 | # Test both sshd_config and key options permitting the same dst/port pair. |
90 | # Should be permitted. | 91 | # Should be permitted. |
91 | for p in 1 2; do | 92 | for p in ${SSH_PROTOCOLS}; do |
92 | trace "match permitopen localhost proto $p" | 93 | trace "match permitopen localhost proto $p" |
93 | start_client -F $OBJ/ssh_config | 94 | start_client -F $OBJ/ssh_config |
94 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ | 95 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ |
@@ -102,7 +103,7 @@ echo "Match User $USER" >>$OBJ/sshd_proxy | |||
102 | echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy | 103 | echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy |
103 | 104 | ||
104 | # Test that a Match overrides a PermitOpen in the global section | 105 | # Test that a Match overrides a PermitOpen in the global section |
105 | for p in 1 2; do | 106 | for p in ${SSH_PROTOCOLS}; do |
106 | trace "match permitopen proxy w/key opts proto $p" | 107 | trace "match permitopen proxy w/key opts proto $p" |
107 | start_client -F $OBJ/ssh_proxy | 108 | start_client -F $OBJ/ssh_proxy |
108 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ | 109 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ |
@@ -117,7 +118,7 @@ echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy | |||
117 | 118 | ||
118 | # Test that a rule that doesn't match doesn't override, plus test a | 119 | # Test that a rule that doesn't match doesn't override, plus test a |
119 | # PermitOpen entry that's not at the start of the list | 120 | # PermitOpen entry that's not at the start of the list |
120 | for p in 1 2; do | 121 | for p in ${SSH_PROTOCOLS}; do |
121 | trace "nomatch permitopen proxy w/key opts proto $p" | 122 | trace "nomatch permitopen proxy w/key opts proto $p" |
122 | start_client -F $OBJ/ssh_proxy | 123 | start_client -F $OBJ/ssh_proxy |
123 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ | 124 | ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ |
diff --git a/regress/cipher-speed.sh b/regress/cipher-speed.sh index a6d53a78d..ad2f9b90b 100644 --- a/regress/cipher-speed.sh +++ b/regress/cipher-speed.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: cipher-speed.sh,v 1.11 2013/11/21 03:18:51 djm Exp $ | 1 | # $OpenBSD: cipher-speed.sh,v 1.12 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="cipher speed" | 4 | tid="cipher speed" |
@@ -31,7 +31,11 @@ for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do | |||
31 | n=`expr $n + 1` | 31 | n=`expr $n + 1` |
32 | done; done | 32 | done; done |
33 | 33 | ||
34 | ciphers="3des blowfish" | 34 | if ssh_version 1; then |
35 | ciphers="3des blowfish" | ||
36 | else | ||
37 | ciphers="" | ||
38 | fi | ||
35 | for c in $ciphers; do | 39 | for c in $ciphers; do |
36 | trace "proto 1 cipher $c" | 40 | trace "proto 1 cipher $c" |
37 | for x in $tries; do | 41 | for x in $tries; do |
diff --git a/regress/connect-privsep.sh b/regress/connect-privsep.sh index 41cb7af69..9a51f5690 100644 --- a/regress/connect-privsep.sh +++ b/regress/connect-privsep.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: connect-privsep.sh,v 1.5 2014/05/04 10:40:59 logan Exp $ | 1 | # $OpenBSD: connect-privsep.sh,v 1.6 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="proxy connect with privsep" | 4 | tid="proxy connect with privsep" |
@@ -6,7 +6,7 @@ tid="proxy connect with privsep" | |||
6 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig | 6 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig |
7 | echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy | 7 | echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy |
8 | 8 | ||
9 | for p in 1 2; do | 9 | for p in ${SSH_PROTOCOLS}; do |
10 | ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true | 10 | ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true |
11 | if [ $? -ne 0 ]; then | 11 | if [ $? -ne 0 ]; then |
12 | fail "ssh privsep+proxyconnect protocol $p failed" | 12 | fail "ssh privsep+proxyconnect protocol $p failed" |
@@ -16,7 +16,7 @@ done | |||
16 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy | 16 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy |
17 | echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy | 17 | echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy |
18 | 18 | ||
19 | for p in 1 2; do | 19 | for p in ${SSH_PROTOCOLS}; do |
20 | ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true | 20 | ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true |
21 | if [ $? -ne 0 ]; then | 21 | if [ $? -ne 0 ]; then |
22 | # XXX replace this with fail once sandbox has stabilised | 22 | # XXX replace this with fail once sandbox has stabilised |
@@ -27,7 +27,7 @@ done | |||
27 | # Because sandbox is sensitive to changes in libc, especially malloc, retest | 27 | # Because sandbox is sensitive to changes in libc, especially malloc, retest |
28 | # with every malloc.conf option (and none). | 28 | # with every malloc.conf option (and none). |
29 | for m in '' A F G H J P R S X '<' '>'; do | 29 | for m in '' A F G H J P R S X '<' '>'; do |
30 | for p in 1 2; do | 30 | for p in ${SSH_PROTOCOLS}; do |
31 | env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true | 31 | env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true |
32 | if [ $? -ne 0 ]; then | 32 | if [ $? -ne 0 ]; then |
33 | fail "ssh privsep/sandbox+proxyconnect protocol $p mopt '$m' failed" | 33 | fail "ssh privsep/sandbox+proxyconnect protocol $p mopt '$m' failed" |
diff --git a/regress/connect.sh b/regress/connect.sh index 2186fa6e7..f0d55d343 100644 --- a/regress/connect.sh +++ b/regress/connect.sh | |||
@@ -1,11 +1,11 @@ | |||
1 | # $OpenBSD: connect.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ | 1 | # $OpenBSD: connect.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="simple connect" | 4 | tid="simple connect" |
5 | 5 | ||
6 | start_sshd | 6 | start_sshd |
7 | 7 | ||
8 | for p in 1 2; do | 8 | for p in ${SSH_PROTOCOLS}; do |
9 | ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true | 9 | ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true |
10 | if [ $? -ne 0 ]; then | 10 | if [ $? -ne 0 ]; then |
11 | fail "ssh connect with protocol $p failed" | 11 | fail "ssh connect with protocol $p failed" |
diff --git a/regress/dynamic-forward.sh b/regress/dynamic-forward.sh index 42fa8acdc..dd67c9639 100644 --- a/regress/dynamic-forward.sh +++ b/regress/dynamic-forward.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: dynamic-forward.sh,v 1.10 2013/05/17 04:29:14 dtucker Exp $ | 1 | # $OpenBSD: dynamic-forward.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="dynamic forwarding" | 4 | tid="dynamic forwarding" |
@@ -17,7 +17,7 @@ trace "will use ProxyCommand $proxycmd" | |||
17 | 17 | ||
18 | start_sshd | 18 | start_sshd |
19 | 19 | ||
20 | for p in 1 2; do | 20 | for p in ${SSH_PROTOCOLS}; do |
21 | n=0 | 21 | n=0 |
22 | error="1" | 22 | error="1" |
23 | trace "start dynamic forwarding, fork to background" | 23 | trace "start dynamic forwarding, fork to background" |
diff --git a/regress/exit-status.sh b/regress/exit-status.sh index 56b78a622..397d8d732 100644 --- a/regress/exit-status.sh +++ b/regress/exit-status.sh | |||
@@ -1,9 +1,9 @@ | |||
1 | # $OpenBSD: exit-status.sh,v 1.6 2002/03/15 13:08:56 markus Exp $ | 1 | # $OpenBSD: exit-status.sh,v 1.7 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="remote exit status" | 4 | tid="remote exit status" |
5 | 5 | ||
6 | for p in 1 2; do | 6 | for p in ${SSH_PROTOCOLS}; do |
7 | for s in 0 1 4 5 44; do | 7 | for s in 0 1 4 5 44; do |
8 | trace "proto $p status $s" | 8 | trace "proto $p status $s" |
9 | verbose "test $tid: proto $p status $s" | 9 | verbose "test $tid: proto $p status $s" |
diff --git a/regress/forcecommand.sh b/regress/forcecommand.sh index 44d2b7ffd..8a9b090ea 100644 --- a/regress/forcecommand.sh +++ b/regress/forcecommand.sh | |||
@@ -1,30 +1,32 @@ | |||
1 | # $OpenBSD: forcecommand.sh,v 1.2 2013/05/17 00:37:40 dtucker Exp $ | 1 | # $OpenBSD: forcecommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="forced command" | 4 | tid="forced command" |
5 | 5 | ||
6 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak | 6 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak |
7 | 7 | ||
8 | printf 'command="true" ' >$OBJ/authorized_keys_$USER | 8 | cp /dev/null $OBJ/authorized_keys_$USER |
9 | cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER | 9 | for t in ${SSH_KEYTYPES}; do |
10 | printf 'command="true" ' >>$OBJ/authorized_keys_$USER | 10 | printf 'command="true" ' >>$OBJ/authorized_keys_$USER |
11 | cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER | 11 | cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER |
12 | done | ||
12 | 13 | ||
13 | for p in 1 2; do | 14 | for p in ${SSH_PROTOCOLS}; do |
14 | trace "forced command in key option proto $p" | 15 | trace "forced command in key option proto $p" |
15 | ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || | 16 | ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || |
16 | fail "forced command in key proto $p" | 17 | fail "forced command in key proto $p" |
17 | done | 18 | done |
18 | 19 | ||
19 | printf 'command="false" ' >$OBJ/authorized_keys_$USER | 20 | cp /dev/null $OBJ/authorized_keys_$USER |
20 | cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER | 21 | for t in ${SSH_KEYTYPES}; do |
21 | printf 'command="false" ' >>$OBJ/authorized_keys_$USER | 22 | printf 'command="false" ' >> $OBJ/authorized_keys_$USER |
22 | cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER | 23 | cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER |
24 | done | ||
23 | 25 | ||
24 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy | 26 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy |
25 | echo "ForceCommand true" >> $OBJ/sshd_proxy | 27 | echo "ForceCommand true" >> $OBJ/sshd_proxy |
26 | 28 | ||
27 | for p in 1 2; do | 29 | for p in ${SSH_PROTOCOLS}; do |
28 | trace "forced command in sshd_config overrides key option proto $p" | 30 | trace "forced command in sshd_config overrides key option proto $p" |
29 | ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || | 31 | ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || |
30 | fail "forced command in key proto $p" | 32 | fail "forced command in key proto $p" |
@@ -35,7 +37,7 @@ echo "ForceCommand false" >> $OBJ/sshd_proxy | |||
35 | echo "Match User $USER" >> $OBJ/sshd_proxy | 37 | echo "Match User $USER" >> $OBJ/sshd_proxy |
36 | echo " ForceCommand true" >> $OBJ/sshd_proxy | 38 | echo " ForceCommand true" >> $OBJ/sshd_proxy |
37 | 39 | ||
38 | for p in 1 2; do | 40 | for p in ${SSH_PROTOCOLS}; do |
39 | trace "forced command with match proto $p" | 41 | trace "forced command with match proto $p" |
40 | ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || | 42 | ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || |
41 | fail "forced command in key proto $p" | 43 | fail "forced command in key proto $p" |
diff --git a/regress/forward-control.sh b/regress/forward-control.sh index 7f7d105e8..91957098f 100644 --- a/regress/forward-control.sh +++ b/regress/forward-control.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: forward-control.sh,v 1.2 2013/11/18 05:09:32 naddy Exp $ | 1 | # $OpenBSD: forward-control.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="sshd control of local and remote forwarding" | 4 | tid="sshd control of local and remote forwarding" |
@@ -99,7 +99,7 @@ cp ${OBJ}/sshd_proxy ${OBJ}/sshd_proxy.bak | |||
99 | cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak | 99 | cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak |
100 | 100 | ||
101 | # Sanity check: ensure the default config allows forwarding | 101 | # Sanity check: ensure the default config allows forwarding |
102 | for p in 1 2 ; do | 102 | for p in ${SSH_PROTOCOLS} ; do |
103 | check_lfwd $p Y "proto $p, default configuration" | 103 | check_lfwd $p Y "proto $p, default configuration" |
104 | check_rfwd $p Y "proto $p, default configuration" | 104 | check_rfwd $p Y "proto $p, default configuration" |
105 | done | 105 | done |
@@ -115,7 +115,7 @@ all_tests() { | |||
115 | _permit_rfwd=$7 | 115 | _permit_rfwd=$7 |
116 | _badfwd=127.0.0.1:22 | 116 | _badfwd=127.0.0.1:22 |
117 | _goodfwd=127.0.0.1:${PORT} | 117 | _goodfwd=127.0.0.1:${PORT} |
118 | for _proto in 1 2 ; do | 118 | for _proto in ${SSH_PROTOCOLS} ; do |
119 | cp ${OBJ}/authorized_keys_${USER}.bak \ | 119 | cp ${OBJ}/authorized_keys_${USER}.bak \ |
120 | ${OBJ}/authorized_keys_${USER} | 120 | ${OBJ}/authorized_keys_${USER} |
121 | _prefix="proto $_proto, AllowTcpForwarding=$_tcpfwd" | 121 | _prefix="proto $_proto, AllowTcpForwarding=$_tcpfwd" |
diff --git a/regress/forwarding.sh b/regress/forwarding.sh index f799d4951..fb4f35aff 100644 --- a/regress/forwarding.sh +++ b/regress/forwarding.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: forwarding.sh,v 1.12 2014/07/15 15:54:15 millert Exp $ | 1 | # $OpenBSD: forwarding.sh,v 1.15 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="local and remote forwarding" | 4 | tid="local and remote forwarding" |
@@ -10,6 +10,9 @@ start_sshd | |||
10 | base=33 | 10 | base=33 |
11 | last=$PORT | 11 | last=$PORT |
12 | fwd="" | 12 | fwd="" |
13 | CTL=$OBJ/ctl-sock | ||
14 | rm -f $CTL | ||
15 | |||
13 | for j in 0 1 2; do | 16 | for j in 0 1 2; do |
14 | for i in 0 1 2; do | 17 | for i in 0 1 2; do |
15 | a=$base$j$i | 18 | a=$base$j$i |
@@ -20,8 +23,11 @@ for j in 0 1 2; do | |||
20 | last=$a | 23 | last=$a |
21 | done | 24 | done |
22 | done | 25 | done |
23 | for p in 1 2; do | 26 | for p in ${SSH_PROTOCOLS}; do |
24 | q=`expr 3 - $p` | 27 | q=`expr 3 - $p` |
28 | if ! ssh_version $q; then | ||
29 | q=$p | ||
30 | fi | ||
25 | trace "start forwarding, fork to background" | 31 | trace "start forwarding, fork to background" |
26 | ${SSH} -$p -F $OBJ/ssh_config -f $fwd somehost sleep 10 | 32 | ${SSH} -$p -F $OBJ/ssh_config -f $fwd somehost sleep 10 |
27 | 33 | ||
@@ -34,7 +40,7 @@ for p in 1 2; do | |||
34 | sleep 10 | 40 | sleep 10 |
35 | done | 41 | done |
36 | 42 | ||
37 | for p in 1 2; do | 43 | for p in ${SSH_PROTOCOLS}; do |
38 | for d in L R; do | 44 | for d in L R; do |
39 | trace "exit on -$d forward failure, proto $p" | 45 | trace "exit on -$d forward failure, proto $p" |
40 | 46 | ||
@@ -64,7 +70,7 @@ for d in L R; do | |||
64 | done | 70 | done |
65 | done | 71 | done |
66 | 72 | ||
67 | for p in 1 2; do | 73 | for p in ${SSH_PROTOCOLS}; do |
68 | trace "simple clear forwarding proto $p" | 74 | trace "simple clear forwarding proto $p" |
69 | ${SSH} -$p -F $OBJ/ssh_config -oClearAllForwardings=yes somehost true | 75 | ${SSH} -$p -F $OBJ/ssh_config -oClearAllForwardings=yes somehost true |
70 | 76 | ||
@@ -107,9 +113,9 @@ done | |||
107 | 113 | ||
108 | echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config | 114 | echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config |
109 | echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config | 115 | echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config |
110 | for p in 1 2; do | 116 | for p in ${SSH_PROTOCOLS}; do |
111 | trace "config file: start forwarding, fork to background" | 117 | trace "config file: start forwarding, fork to background" |
112 | ${SSH} -$p -F $OBJ/ssh_config -f somehost sleep 10 | 118 | ${SSH} -S $CTL -M -$p -F $OBJ/ssh_config -f somehost sleep 10 |
113 | 119 | ||
114 | trace "config file: transfer over forwarded channels and check result" | 120 | trace "config file: transfer over forwarded channels and check result" |
115 | ${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \ | 121 | ${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \ |
@@ -117,7 +123,7 @@ for p in 1 2; do | |||
117 | test -s ${COPY} || fail "failed copy of ${DATA}" | 123 | test -s ${COPY} || fail "failed copy of ${DATA}" |
118 | cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" | 124 | cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" |
119 | 125 | ||
120 | wait | 126 | ${SSH} -S $CTL -O exit somehost |
121 | done | 127 | done |
122 | 128 | ||
123 | for p in 2; do | 129 | for p in 2; do |
diff --git a/regress/host-expand.sh b/regress/host-expand.sh index 6cc0e6055..2a95bfe1b 100644 --- a/regress/host-expand.sh +++ b/regress/host-expand.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: host-expand.sh,v 1.3 2014/02/27 23:17:41 djm Exp $ | 1 | # $OpenBSD: host-expand.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="expand %h and %n" | 4 | tid="expand %h and %n" |
@@ -11,7 +11,7 @@ somehost | |||
11 | 127.0.0.1 | 11 | 127.0.0.1 |
12 | EOE | 12 | EOE |
13 | 13 | ||
14 | for p in 1 2; do | 14 | for p in ${SSH_PROTOCOLS}; do |
15 | verbose "test $tid: proto $p" | 15 | verbose "test $tid: proto $p" |
16 | ${SSH} -F $OBJ/ssh_proxy -$p somehost true >$OBJ/actual | 16 | ${SSH} -F $OBJ/ssh_proxy -$p somehost true >$OBJ/actual |
17 | diff $OBJ/expect $OBJ/actual || fail "$tid proto $p" | 17 | diff $OBJ/expect $OBJ/actual || fail "$tid proto $p" |
diff --git a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh new file mode 100644 index 000000000..a011ec831 --- /dev/null +++ b/regress/hostkey-agent.sh | |||
@@ -0,0 +1,52 @@ | |||
1 | # $OpenBSD: hostkey-agent.sh,v 1.5 2015/02/21 20:51:02 djm Exp $ | ||
2 | # Placed in the Public Domain. | ||
3 | |||
4 | tid="hostkey agent" | ||
5 | |||
6 | rm -f $OBJ/agent-key.* $OBJ/ssh_proxy.orig $OBJ/known_hosts.orig | ||
7 | |||
8 | trace "start agent" | ||
9 | eval `${SSHAGENT} -s` > /dev/null | ||
10 | r=$? | ||
11 | [ $r -ne 0 ] && fatal "could not start ssh-agent: exit code $r" | ||
12 | |||
13 | grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig | ||
14 | echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig | ||
15 | |||
16 | trace "load hostkeys" | ||
17 | for k in `${SSH} -Q key-plain` ; do | ||
18 | ${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k" | ||
19 | ( | ||
20 | printf 'localhost-with-alias,127.0.0.1,::1 ' | ||
21 | cat $OBJ/agent-key.$k.pub | ||
22 | ) >> $OBJ/known_hosts.orig | ||
23 | ${SSHADD} $OBJ/agent-key.$k >/dev/null 2>&1 || \ | ||
24 | fatal "couldn't load key $OBJ/agent-key.$k" | ||
25 | echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy.orig | ||
26 | # Remove private key so the server can't use it. | ||
27 | rm $OBJ/agent-key.$k || fatal "couldn't rm $OBJ/agent-key.$k" | ||
28 | done | ||
29 | cp $OBJ/known_hosts.orig $OBJ/known_hosts | ||
30 | |||
31 | unset SSH_AUTH_SOCK | ||
32 | |||
33 | for ps in no yes; do | ||
34 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy | ||
35 | echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy | ||
36 | for k in `${SSH} -Q key-plain` ; do | ||
37 | verbose "key type $k privsep=$ps" | ||
38 | opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy" | ||
39 | cp $OBJ/known_hosts.orig $OBJ/known_hosts | ||
40 | SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` | ||
41 | if [ $? -ne 0 ]; then | ||
42 | fail "protocol $p privsep=$ps failed" | ||
43 | fi | ||
44 | if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then | ||
45 | fail "bad SSH_CONNECTION key type $k privsep=$ps" | ||
46 | fi | ||
47 | done | ||
48 | done | ||
49 | |||
50 | trace "kill agent" | ||
51 | ${SSHAGENT} -k > /dev/null | ||
52 | |||
diff --git a/regress/hostkey-rotate.sh b/regress/hostkey-rotate.sh new file mode 100644 index 000000000..b5d542d12 --- /dev/null +++ b/regress/hostkey-rotate.sh | |||
@@ -0,0 +1,128 @@ | |||
1 | # $OpenBSD: hostkey-rotate.sh,v 1.2 2015/03/03 17:53:40 djm Exp $ | ||
2 | # Placed in the Public Domain. | ||
3 | |||
4 | tid="hostkey rotate" | ||
5 | |||
6 | # Need full names here since they are used in HostKeyAlgorithms | ||
7 | HOSTKEY_TYPES="ecdsa-sha2-nistp256 ssh-ed25519 ssh-rsa ssh-dss" | ||
8 | |||
9 | rm -f $OBJ/hkr.* $OBJ/ssh_proxy.orig | ||
10 | |||
11 | grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig | ||
12 | echo "UpdateHostkeys=yes" >> $OBJ/ssh_proxy | ||
13 | rm $OBJ/known_hosts | ||
14 | |||
15 | trace "prepare hostkeys" | ||
16 | nkeys=0 | ||
17 | all_algs="" | ||
18 | for k in `ssh -Q key-plain` ; do | ||
19 | ${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k" | ||
20 | echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig | ||
21 | nkeys=`expr $nkeys + 1` | ||
22 | test "x$all_algs" = "x" || all_algs="${all_algs}," | ||
23 | all_algs="${all_algs}$k" | ||
24 | done | ||
25 | |||
26 | dossh() { | ||
27 | # All ssh should succeed in this test | ||
28 | ${SSH} -F $OBJ/ssh_proxy "$@" x true || fail "ssh $@ failed" | ||
29 | } | ||
30 | |||
31 | expect_nkeys() { | ||
32 | _expected=$1 | ||
33 | _message=$2 | ||
34 | _n=`wc -l $OBJ/known_hosts | awk '{ print $1 }'` || fatal "wc failed" | ||
35 | [ "x$_n" = "x$_expected" ] || fail "$_message (got $_n wanted $_expected)" | ||
36 | } | ||
37 | |||
38 | check_key_present() { | ||
39 | _type=$1 | ||
40 | _kfile=$2 | ||
41 | test "x$_kfile" = "x" && _kfile="$OBJ/hkr.${_type}.pub" | ||
42 | _kpub=`awk "/$_type /"' { print $2 }' < $_kfile` || \ | ||
43 | fatal "awk failed" | ||
44 | fgrep "$_kpub" $OBJ/known_hosts > /dev/null | ||
45 | } | ||
46 | |||
47 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy | ||
48 | |||
49 | # Connect to sshd with StrictHostkeyChecking=no | ||
50 | verbose "learn hostkey with StrictHostKeyChecking=no" | ||
51 | >$OBJ/known_hosts | ||
52 | dossh -oHostKeyAlgorithms=ssh-ed25519 -oStrictHostKeyChecking=no | ||
53 | # Verify no additional keys learned | ||
54 | expect_nkeys 1 "unstrict connect keys" | ||
55 | check_key_present ssh-ed25519 || fail "unstrict didn't learn key" | ||
56 | |||
57 | # Connect to sshd as usual | ||
58 | verbose "learn additional hostkeys" | ||
59 | dossh -oStrictHostKeyChecking=yes | ||
60 | # Check that other keys learned | ||
61 | expect_nkeys $nkeys "learn hostkeys" | ||
62 | check_key_present ssh-rsa || fail "didn't learn keys" | ||
63 | |||
64 | # Check each key type | ||
65 | for k in `ssh -Q key-plain` ; do | ||
66 | verbose "learn additional hostkeys, type=$k" | ||
67 | dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs | ||
68 | expect_nkeys $nkeys "learn hostkeys $k" | ||
69 | check_key_present $k || fail "didn't learn $k" | ||
70 | done | ||
71 | |||
72 | # Change one hostkey (non primary) and relearn | ||
73 | verbose "learn changed non-primary hostkey" | ||
74 | mv $OBJ/hkr.ssh-rsa.pub $OBJ/hkr.ssh-rsa.pub.old | ||
75 | rm -f $OBJ/hkr.ssh-rsa | ||
76 | ${SSHKEYGEN} -qt ssh-rsa -f $OBJ/hkr.ssh-rsa -N '' || fatal "ssh-keygen $k" | ||
77 | dossh -oStrictHostKeyChecking=yes | ||
78 | # Check that the key was replaced | ||
79 | expect_nkeys $nkeys "learn hostkeys" | ||
80 | check_key_present ssh-rsa $OBJ/hkr.ssh-rsa.pub.old && fail "old key present" | ||
81 | check_key_present ssh-rsa || fail "didn't learn changed key" | ||
82 | |||
83 | # Add new hostkey (primary type) to sshd and connect | ||
84 | verbose "learn new primary hostkey" | ||
85 | ${SSHKEYGEN} -qt ssh-rsa -f $OBJ/hkr.ssh-rsa-new -N '' || fatal "ssh-keygen $k" | ||
86 | ( cat $OBJ/sshd_proxy.orig ; echo HostKey $OBJ/hkr.ssh-rsa-new ) \ | ||
87 | > $OBJ/sshd_proxy | ||
88 | # Check new hostkey added | ||
89 | dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs | ||
90 | expect_nkeys `expr $nkeys + 1` "learn hostkeys" | ||
91 | check_key_present ssh-rsa || fail "current key missing" | ||
92 | check_key_present ssh-rsa $OBJ/hkr.ssh-rsa-new.pub || fail "new key missing" | ||
93 | |||
94 | # Remove old hostkey (primary type) from sshd | ||
95 | verbose "rotate primary hostkey" | ||
96 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy | ||
97 | mv $OBJ/hkr.ssh-rsa.pub $OBJ/hkr.ssh-rsa.pub.old | ||
98 | mv $OBJ/hkr.ssh-rsa-new.pub $OBJ/hkr.ssh-rsa.pub | ||
99 | mv $OBJ/hkr.ssh-rsa-new $OBJ/hkr.ssh-rsa | ||
100 | # Check old hostkey removed | ||
101 | dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs | ||
102 | expect_nkeys $nkeys "learn hostkeys" | ||
103 | check_key_present ssh-rsa $OBJ/hkr.ssh-rsa.pub.old && fail "old key present" | ||
104 | check_key_present ssh-rsa || fail "didn't learn changed key" | ||
105 | |||
106 | # Connect again, forcing rotated key | ||
107 | verbose "check rotate primary hostkey" | ||
108 | dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa | ||
109 | expect_nkeys 1 "learn hostkeys" | ||
110 | check_key_present ssh-rsa || fail "didn't learn changed key" | ||
111 | |||
112 | # $OpenBSD: hostkey-rotate.sh,v 1.2 2015/03/03 17:53:40 djm Exp $ | ||
113 | # Placed in the Public Domain. | ||
114 | |||
115 | tid="hostkey rotate" | ||
116 | |||
117 | # Prepare hostkeys file with one key | ||
118 | |||
119 | # Connect to sshd | ||
120 | |||
121 | # Check that other keys learned | ||
122 | |||
123 | # Change one hostkey (non primary) | ||
124 | |||
125 | # Connect to sshd | ||
126 | |||
127 | # Check that the key was replaced | ||
128 | |||
diff --git a/regress/integrity.sh b/regress/integrity.sh index d3a489ff7..2ff8b3f17 100644 --- a/regress/integrity.sh +++ b/regress/integrity.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: integrity.sh,v 1.14 2014/05/21 07:04:21 djm Exp $ | 1 | # $OpenBSD: integrity.sh,v 1.15 2015/01/19 20:42:31 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="integrity" | 4 | tid="integrity" |
@@ -20,7 +20,7 @@ echo "KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" \ | |||
20 | >> $OBJ/ssh_proxy | 20 | >> $OBJ/ssh_proxy |
21 | 21 | ||
22 | # sshd-command for proxy (see test-exec.sh) | 22 | # sshd-command for proxy (see test-exec.sh) |
23 | cmd="$SUDO sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSHD_LOGFILE} -i -f $OBJ/sshd_proxy" | 23 | cmd="$SUDO sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" |
24 | 24 | ||
25 | for m in $macs; do | 25 | for m in $macs; do |
26 | trace "test $tid: mac $m" | 26 | trace "test $tid: mac $m" |
@@ -58,7 +58,7 @@ for m in $macs; do | |||
58 | tr -s '\r\n' '.') | 58 | tr -s '\r\n' '.') |
59 | case "$out" in | 59 | case "$out" in |
60 | Bad?packet*) elen=`expr $elen + 1`; skip=3;; | 60 | Bad?packet*) elen=`expr $elen + 1`; skip=3;; |
61 | Corrupted?MAC* | Decryption?integrity?check?failed*) | 61 | Corrupted?MAC* | *message?authentication?code?incorrect*) |
62 | emac=`expr $emac + 1`; skip=0;; | 62 | emac=`expr $emac + 1`; skip=0;; |
63 | padding*) epad=`expr $epad + 1`; skip=0;; | 63 | padding*) epad=`expr $epad + 1`; skip=0;; |
64 | *) fail "unexpected error mac $m at $off: $out";; | 64 | *) fail "unexpected error mac $m at $off: $out";; |
diff --git a/regress/key-options.sh b/regress/key-options.sh index f98d78b30..7a68ad358 100644 --- a/regress/key-options.sh +++ b/regress/key-options.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: key-options.sh,v 1.2 2008/06/30 08:07:34 djm Exp $ | 1 | # $OpenBSD: key-options.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="key options" | 4 | tid="key options" |
@@ -8,7 +8,7 @@ authkeys="$OBJ/authorized_keys_${USER}" | |||
8 | cp $authkeys $origkeys | 8 | cp $authkeys $origkeys |
9 | 9 | ||
10 | # Test command= forced command | 10 | # Test command= forced command |
11 | for p in 1 2; do | 11 | for p in ${SSH_PROTOCOLS}; do |
12 | for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do | 12 | for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do |
13 | sed "s/.*/$c &/" $origkeys >$authkeys | 13 | sed "s/.*/$c &/" $origkeys >$authkeys |
14 | verbose "key option proto $p $c" | 14 | verbose "key option proto $p $c" |
@@ -24,7 +24,7 @@ done | |||
24 | 24 | ||
25 | # Test no-pty | 25 | # Test no-pty |
26 | sed 's/.*/no-pty &/' $origkeys >$authkeys | 26 | sed 's/.*/no-pty &/' $origkeys >$authkeys |
27 | for p in 1 2; do | 27 | for p in ${SSH_PROTOCOLS}; do |
28 | verbose "key option proto $p no-pty" | 28 | verbose "key option proto $p no-pty" |
29 | r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost tty` | 29 | r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost tty` |
30 | if [ -f "$r" ]; then | 30 | if [ -f "$r" ]; then |
@@ -35,7 +35,7 @@ done | |||
35 | # Test environment= | 35 | # Test environment= |
36 | echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy | 36 | echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy |
37 | sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys | 37 | sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys |
38 | for p in 1 2; do | 38 | for p in ${SSH_PROTOCOLS}; do |
39 | verbose "key option proto $p environment" | 39 | verbose "key option proto $p environment" |
40 | r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo $FOO'` | 40 | r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo $FOO'` |
41 | if [ "$r" != "bar" ]; then | 41 | if [ "$r" != "bar" ]; then |
@@ -45,7 +45,7 @@ done | |||
45 | 45 | ||
46 | # Test from= restriction | 46 | # Test from= restriction |
47 | start_sshd | 47 | start_sshd |
48 | for p in 1 2; do | 48 | for p in ${SSH_PROTOCOLS}; do |
49 | for f in 127.0.0.1 '127.0.0.0\/8'; do | 49 | for f in 127.0.0.1 '127.0.0.0\/8'; do |
50 | cat $origkeys >$authkeys | 50 | cat $origkeys >$authkeys |
51 | ${SSH} -$p -q -F $OBJ/ssh_proxy somehost true | 51 | ${SSH} -$p -q -F $OBJ/ssh_proxy somehost true |
diff --git a/regress/keygen-change.sh b/regress/keygen-change.sh index 08d359023..e56185050 100644 --- a/regress/keygen-change.sh +++ b/regress/keygen-change.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: keygen-change.sh,v 1.2 2002/07/16 09:15:55 markus Exp $ | 1 | # $OpenBSD: keygen-change.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="change passphrase for key" | 4 | tid="change passphrase for key" |
@@ -6,7 +6,12 @@ tid="change passphrase for key" | |||
6 | S1="secret1" | 6 | S1="secret1" |
7 | S2="2secret" | 7 | S2="2secret" |
8 | 8 | ||
9 | for t in rsa dsa rsa1; do | 9 | KEYTYPES=`${SSH} -Q key-plain` |
10 | if ssh_version 1; then | ||
11 | KEYTYPES="${KEYTYPES} rsa1" | ||
12 | fi | ||
13 | |||
14 | for t in $KEYTYPES; do | ||
10 | # generate user key for agent | 15 | # generate user key for agent |
11 | trace "generating $t key" | 16 | trace "generating $t key" |
12 | rm -f $OBJ/$t-key | 17 | rm -f $OBJ/$t-key |
diff --git a/regress/keygen-knownhosts.sh b/regress/keygen-knownhosts.sh new file mode 100644 index 000000000..085aac650 --- /dev/null +++ b/regress/keygen-knownhosts.sh | |||
@@ -0,0 +1,197 @@ | |||
1 | # $OpenBSD: keygen-knownhosts.sh,v 1.2 2015/01/27 12:01:36 djm Exp $ | ||
2 | # Placed in the Public Domain. | ||
3 | |||
4 | tid="ssh-keygen known_hosts" | ||
5 | |||
6 | rm -f $OBJ/kh.* | ||
7 | |||
8 | # Generate some keys for testing (just ed25519 for speed) and make a hosts file. | ||
9 | for 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 | ||
28 | done | ||
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. | ||
33 | cat $OBJ/kh.hosts >> $OBJ/kh.invalid | ||
34 | echo "host-i " >> $OBJ/kh.invalid | ||
35 | |||
36 | cp $OBJ/kh.invalid $OBJ/kh.invalid.orig | ||
37 | cp $OBJ/kh.hosts $OBJ/kh.hosts.orig | ||
38 | |||
39 | expect_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 | |||
55 | check_find() { | ||
56 | _host=$1 | ||
57 | _name=$2 | ||
58 | _keygenopt=$3 | ||
59 | ${SSHKEYGEN} $_keygenopt -f $OBJ/kh.invalid -F $_host > $OBJ/kh.result | ||
60 | if ! diff -uw $OBJ/kh.expect $OBJ/kh.result ; then | ||
61 | fail "didn't find $_name" | ||
62 | fi | ||
63 | } | ||
64 | |||
65 | # Find key | ||
66 | rm -f $OBJ/kh.expect | ||
67 | expect_key host-a host-a host-a 2 | ||
68 | expect_key host-a host-a host-a2 20 | ||
69 | check_find host-a "simple find" | ||
70 | |||
71 | # find CA key | ||
72 | rm -f $OBJ/kh.expect | ||
73 | expect_key host-c host-c host-c 8 CA | ||
74 | check_find host-c "find CA key" | ||
75 | |||
76 | # find revoked key | ||
77 | rm -f $OBJ/kh.expect | ||
78 | expect_key host-d host-d host-d 11 REVOKED | ||
79 | check_find host-d "find revoked key" | ||
80 | |||
81 | # find key with wildcard | ||
82 | rm -f $OBJ/kh.expect | ||
83 | expect_key host-e.somedomain "host-e*" host-e 14 | ||
84 | check_find host-e.somedomain "find wildcard key" | ||
85 | |||
86 | # find key among multiple hosts | ||
87 | rm -f $OBJ/kh.expect | ||
88 | expect_key host-h "host-f,host-g,host-h " host-f 17 | ||
89 | check_find host-h "find multiple hosts" | ||
90 | |||
91 | check_hashed_find() { | ||
92 | _host=$1 | ||
93 | _name=$2 | ||
94 | _file=$3 | ||
95 | test "x$_file" = "x" && _file=$OBJ/kh.invalid | ||
96 | ${SSHKEYGEN} -f $_file -HF $_host | grep '|1|' | \ | ||
97 | sed "s/^[^ ]*/$_host/" > $OBJ/kh.result | ||
98 | if ! diff -uw $OBJ/kh.expect $OBJ/kh.result ; then | ||
99 | fail "didn't find $_name" | ||
100 | fi | ||
101 | } | ||
102 | |||
103 | # Find key and hash | ||
104 | rm -f $OBJ/kh.expect | ||
105 | expect_key host-a host-a host-a | ||
106 | expect_key host-a host-a host-a2 | ||
107 | check_hashed_find host-a "find simple and hash" | ||
108 | |||
109 | # Find CA key and hash | ||
110 | rm -f $OBJ/kh.expect | ||
111 | expect_key host-c host-c host-c "" CA | ||
112 | # CA key output is not hashed. | ||
113 | check_find host-c "find simple and hash" -H | ||
114 | |||
115 | # Find revoked key and hash | ||
116 | rm -f $OBJ/kh.expect | ||
117 | expect_key host-d host-d host-d "" REVOKED | ||
118 | # Revoked key output is not hashed. | ||
119 | check_find host-d "find simple and hash" -H | ||
120 | |||
121 | # find key with wildcard and hash | ||
122 | rm -f $OBJ/kh.expect | ||
123 | expect_key host-e "host-e*" host-e "" | ||
124 | # Key with wildcard hostname should not be hashed. | ||
125 | check_find host-e "find wildcard key" -H | ||
126 | |||
127 | # find key among multiple hosts | ||
128 | rm -f $OBJ/kh.expect | ||
129 | # Comma-separated hostnames should be expanded and hashed. | ||
130 | expect_key host-f "host-h " host-f | ||
131 | expect_key host-g "host-h " host-f | ||
132 | expect_key host-h "host-h " host-f | ||
133 | check_hashed_find host-h "find multiple hosts" | ||
134 | |||
135 | # Attempt remove key on invalid file. | ||
136 | cp $OBJ/kh.invalid.orig $OBJ/kh.invalid | ||
137 | ${SSHKEYGEN} -qf $OBJ/kh.invalid -R host-a 2>/dev/null | ||
138 | diff -u $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "remove on invalid succeeded" | ||
139 | |||
140 | # Remove key | ||
141 | cp $OBJ/kh.hosts.orig $OBJ/kh.hosts | ||
142 | ${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-a 2>/dev/null | ||
143 | grep -v "^host-a " $OBJ/kh.hosts.orig > $OBJ/kh.expect | ||
144 | diff -u $OBJ/kh.hosts $OBJ/kh.expect || fail "remove simple" | ||
145 | |||
146 | # Remove CA key | ||
147 | cp $OBJ/kh.hosts.orig $OBJ/kh.hosts | ||
148 | ${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-c 2>/dev/null | ||
149 | # CA key should not be removed. | ||
150 | diff -u $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove CA" | ||
151 | |||
152 | # Remove revoked key | ||
153 | cp $OBJ/kh.hosts.orig $OBJ/kh.hosts | ||
154 | ${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-d 2>/dev/null | ||
155 | # revoked key should not be removed. | ||
156 | diff -u $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove revoked" | ||
157 | |||
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 -u $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" | ||
163 | |||
164 | # Remove multiple | ||
165 | cp $OBJ/kh.hosts.orig $OBJ/kh.hosts | ||
166 | ${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-h 2>/dev/null | ||
167 | grep -v "^host-f," $OBJ/kh.hosts.orig > $OBJ/kh.expect | ||
168 | diff -u $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" | ||
169 | |||
170 | # Attempt hash on invalid file | ||
171 | cp $OBJ/kh.invalid.orig $OBJ/kh.invalid | ||
172 | ${SSHKEYGEN} -qf $OBJ/kh.invalid -H 2>/dev/null && fail "hash invalid succeeded" | ||
173 | diff -u $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "invalid file modified" | ||
174 | |||
175 | # Hash valid file | ||
176 | cp $OBJ/kh.hosts.orig $OBJ/kh.hosts | ||
177 | ${SSHKEYGEN} -qf $OBJ/kh.hosts -H 2>/dev/null || fail "hash failed" | ||
178 | diff -u $OBJ/kh.hosts.old $OBJ/kh.hosts.orig || fail "backup differs" | ||
179 | grep "^host-[abfgh]" $OBJ/kh.hosts && fail "original hostnames persist" | ||
180 | |||
181 | cp $OBJ/kh.hosts $OBJ/kh.hashed.orig | ||
182 | |||
183 | # Test lookup | ||
184 | rm -f $OBJ/kh.expect | ||
185 | expect_key host-a host-a host-a | ||
186 | expect_key host-a host-a host-a2 | ||
187 | check_hashed_find host-a "find simple in hashed" $OBJ/kh.hosts | ||
188 | |||
189 | # Test multiple expanded | ||
190 | rm -f $OBJ/kh.expect | ||
191 | expect_key host-h host-h host-f | ||
192 | check_hashed_find host-h "find simple in hashed" $OBJ/kh.hosts | ||
193 | |||
194 | # Test remove | ||
195 | cp $OBJ/kh.hashed.orig $OBJ/kh.hashed | ||
196 | ${SSHKEYGEN} -qf $OBJ/kh.hashed -R host-a 2>/dev/null | ||
197 | ${SSHKEYGEN} -qf $OBJ/kh.hashed -F host-a && fail "found key after hashed remove" | ||
diff --git a/regress/keyscan.sh b/regress/keyscan.sh index 33f14f0fc..886f3295a 100644 --- a/regress/keyscan.sh +++ b/regress/keyscan.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: keyscan.sh,v 1.3 2002/03/15 13:08:56 markus Exp $ | 1 | # $OpenBSD: keyscan.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="keyscan" | 4 | tid="keyscan" |
@@ -8,7 +8,12 @@ rm -f ${OBJ}/host.dsa | |||
8 | 8 | ||
9 | start_sshd | 9 | start_sshd |
10 | 10 | ||
11 | for t in rsa1 rsa dsa; do | 11 | KEYTYPES="rsa dsa" |
12 | if ssh_version 1; then | ||
13 | KEYTYPES="${KEYTYPES} rsa1" | ||
14 | fi | ||
15 | |||
16 | for t in $KEYTYPES; do | ||
12 | trace "keyscan type $t" | 17 | trace "keyscan type $t" |
13 | ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \ | 18 | ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \ |
14 | > /dev/null 2>&1 | 19 | > /dev/null 2>&1 |
diff --git a/regress/krl.sh b/regress/krl.sh index 287384b4a..1077358ff 100644 --- a/regress/krl.sh +++ b/regress/krl.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: krl.sh,v 1.3 2014/06/24 01:04:43 djm Exp $ | 1 | # $OpenBSD: krl.sh,v 1.6 2015/01/30 01:11:39 djm Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="key revocation lists" | 4 | tid="key revocation lists" |
@@ -17,6 +17,8 @@ rm -f $OBJ/revoked-* $OBJ/krl-* | |||
17 | # Generate a CA key | 17 | # Generate a CA key |
18 | $SSHKEYGEN -t $ECDSA -f $OBJ/revoked-ca -C "" -N "" > /dev/null || | 18 | $SSHKEYGEN -t $ECDSA -f $OBJ/revoked-ca -C "" -N "" > /dev/null || |
19 | fatal "$SSHKEYGEN CA failed" | 19 | fatal "$SSHKEYGEN CA failed" |
20 | $SSHKEYGEN -t ed25519 -f $OBJ/revoked-ca2 -C "" -N "" > /dev/null || | ||
21 | fatal "$SSHKEYGEN CA2 failed" | ||
20 | 22 | ||
21 | # A specification that revokes some certificates by serial numbers | 23 | # A specification that revokes some certificates by serial numbers |
22 | # The serial pattern is chosen to ensure the KRL includes list, range and | 24 | # The serial pattern is chosen to ensure the KRL includes list, range and |
@@ -45,6 +47,7 @@ EOF | |||
45 | # A specification that revokes some certificated by key ID. | 47 | # A specification that revokes some certificated by key ID. |
46 | touch $OBJ/revoked-keyid | 48 | touch $OBJ/revoked-keyid |
47 | for n in 1 2 3 4 10 15 30 50 `jot 500 300` 999 1000 1001 1002; do | 49 | for n in 1 2 3 4 10 15 30 50 `jot 500 300` 999 1000 1001 1002; do |
50 | test "x$n" = "x499" && continue | ||
48 | # Fill in by-ID revocation spec. | 51 | # Fill in by-ID revocation spec. |
49 | echo "id: revoked $n" >> $OBJ/revoked-keyid | 52 | echo "id: revoked $n" >> $OBJ/revoked-keyid |
50 | done | 53 | done |
@@ -56,7 +59,7 @@ keygen() { | |||
56 | keytype=$ECDSA | 59 | keytype=$ECDSA |
57 | case $N in | 60 | case $N in |
58 | 2 | 10 | 510 | 1001) keytype=rsa;; | 61 | 2 | 10 | 510 | 1001) keytype=rsa;; |
59 | 4 | 30 | 520 | 1002) keytype=dsa;; | 62 | 4 | 30 | 520 | 1002) keytype=ed25519;; |
60 | esac | 63 | esac |
61 | $SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \ | 64 | $SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \ |
62 | || fatal "$SSHKEYGEN failed" | 65 | || fatal "$SSHKEYGEN failed" |
@@ -71,37 +74,48 @@ verbose "$tid: generating test keys" | |||
71 | REVOKED_SERIALS="1 4 10 50 500 510 520 799 999" | 74 | REVOKED_SERIALS="1 4 10 50 500 510 520 799 999" |
72 | for n in $REVOKED_SERIALS ; do | 75 | for n in $REVOKED_SERIALS ; do |
73 | f=`keygen $n` | 76 | f=`keygen $n` |
74 | REVOKED_KEYS="$REVOKED_KEYS ${f}.pub" | 77 | RKEYS="$RKEYS ${f}.pub" |
75 | REVOKED_CERTS="$REVOKED_CERTS ${f}-cert.pub" | 78 | RCERTS="$RCERTS ${f}-cert.pub" |
76 | done | 79 | done |
77 | NOTREVOKED_SERIALS="5 9 14 16 29 30 49 51 499 800 1000 1001" | 80 | UNREVOKED_SERIALS="5 9 14 16 29 49 51 499 800 1010 1011" |
78 | NOTREVOKED="" | 81 | UNREVOKED="" |
79 | for n in $NOTREVOKED_SERIALS ; do | 82 | for n in $UNREVOKED_SERIALS ; do |
80 | NOTREVOKED_KEYS="$NOTREVOKED_KEYS ${f}.pub" | 83 | f=`keygen $n` |
81 | NOTREVOKED_CERTS="$NOTREVOKED_CERTS ${f}-cert.pub" | 84 | UKEYS="$UKEYS ${f}.pub" |
85 | UCERTS="$UCERTS ${f}-cert.pub" | ||
82 | done | 86 | done |
83 | 87 | ||
84 | genkrls() { | 88 | genkrls() { |
85 | OPTS=$1 | 89 | OPTS=$1 |
86 | $SSHKEYGEN $OPTS -kf $OBJ/krl-empty - </dev/null \ | 90 | $SSHKEYGEN $OPTS -kf $OBJ/krl-empty - </dev/null \ |
87 | >/dev/null || fatal "$SSHKEYGEN KRL failed" | 91 | >/dev/null || fatal "$SSHKEYGEN KRL failed" |
88 | $SSHKEYGEN $OPTS -kf $OBJ/krl-keys $REVOKED_KEYS \ | 92 | $SSHKEYGEN $OPTS -kf $OBJ/krl-keys $RKEYS \ |
89 | >/dev/null || fatal "$SSHKEYGEN KRL failed" | 93 | >/dev/null || fatal "$SSHKEYGEN KRL failed" |
90 | $SSHKEYGEN $OPTS -kf $OBJ/krl-cert $REVOKED_CERTS \ | 94 | $SSHKEYGEN $OPTS -kf $OBJ/krl-cert $RCERTS \ |
91 | >/dev/null || fatal "$SSHKEYGEN KRL failed" | 95 | >/dev/null || fatal "$SSHKEYGEN KRL failed" |
92 | $SSHKEYGEN $OPTS -kf $OBJ/krl-all $REVOKED_KEYS $REVOKED_CERTS \ | 96 | $SSHKEYGEN $OPTS -kf $OBJ/krl-all $RKEYS $RCERTS \ |
93 | >/dev/null || fatal "$SSHKEYGEN KRL failed" | 97 | >/dev/null || fatal "$SSHKEYGEN KRL failed" |
94 | $SSHKEYGEN $OPTS -kf $OBJ/krl-ca $OBJ/revoked-ca.pub \ | 98 | $SSHKEYGEN $OPTS -kf $OBJ/krl-ca $OBJ/revoked-ca.pub \ |
95 | >/dev/null || fatal "$SSHKEYGEN KRL failed" | 99 | >/dev/null || fatal "$SSHKEYGEN KRL failed" |
96 | # KRLs from serial/key-id spec need the CA specified. | 100 | # This should fail as KRLs from serial/key-id spec need the CA specified. |
97 | $SSHKEYGEN $OPTS -kf $OBJ/krl-serial $OBJ/revoked-serials \ | 101 | $SSHKEYGEN $OPTS -kf $OBJ/krl-serial $OBJ/revoked-serials \ |
98 | >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" | 102 | >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" |
99 | $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid $OBJ/revoked-keyid \ | 103 | $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid $OBJ/revoked-keyid \ |
100 | >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" | 104 | >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" |
101 | $SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca $OBJ/revoked-serials \ | 105 | # These should succeed; they specify an explicit CA key. |
106 | $SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca \ | ||
107 | $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" | ||
108 | $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub \ | ||
109 | $OBJ/revoked-keyid >/dev/null || fatal "$SSHKEYGEN KRL failed" | ||
110 | # These should succeed; they specify an wildcard CA key. | ||
111 | $SSHKEYGEN $OPTS -kf $OBJ/krl-serial-wild -s NONE $OBJ/revoked-serials \ | ||
102 | >/dev/null || fatal "$SSHKEYGEN KRL failed" | 112 | >/dev/null || fatal "$SSHKEYGEN KRL failed" |
103 | $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub $OBJ/revoked-keyid \ | 113 | $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid-wild -s NONE $OBJ/revoked-keyid \ |
104 | >/dev/null || fatal "$SSHKEYGEN KRL failed" | 114 | >/dev/null || fatal "$SSHKEYGEN KRL failed" |
115 | # Revoke the same serials with the second CA key to ensure a multi-CA | ||
116 | # KRL is generated. | ||
117 | $SSHKEYGEN $OPTS -kf $OBJ/krl-serial -u -s $OBJ/revoked-ca2 \ | ||
118 | $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" | ||
105 | } | 119 | } |
106 | 120 | ||
107 | ## XXX dump with trace and grep for set cert serials | 121 | ## XXX dump with trace and grep for set cert serials |
@@ -123,7 +137,7 @@ check_krl() { | |||
123 | fatal "key $KEY unexpectedly revoked by KRL $KRL: $TAG" | 137 | fatal "key $KEY unexpectedly revoked by KRL $KRL: $TAG" |
124 | fi | 138 | fi |
125 | } | 139 | } |
126 | test_all() { | 140 | test_rev() { |
127 | FILES=$1 | 141 | FILES=$1 |
128 | TAG=$2 | 142 | TAG=$2 |
129 | KEYS_RESULT=$3 | 143 | KEYS_RESULT=$3 |
@@ -132,32 +146,40 @@ test_all() { | |||
132 | KEYID_RESULT=$6 | 146 | KEYID_RESULT=$6 |
133 | CERTS_RESULT=$7 | 147 | CERTS_RESULT=$7 |
134 | CA_RESULT=$8 | 148 | CA_RESULT=$8 |
149 | SERIAL_WRESULT=$9 | ||
150 | KEYID_WRESULT=$10 | ||
135 | verbose "$tid: checking revocations for $TAG" | 151 | verbose "$tid: checking revocations for $TAG" |
136 | for f in $FILES ; do | 152 | for f in $FILES ; do |
137 | check_krl $f $OBJ/krl-empty no "$TAG" | 153 | check_krl $f $OBJ/krl-empty no "$TAG" |
138 | check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG" | 154 | check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG" |
139 | check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG" | 155 | check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG" |
140 | check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG" | 156 | check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG" |
141 | check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG" | 157 | check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG" |
142 | check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG" | 158 | check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG" |
143 | check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG" | 159 | check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG" |
160 | check_krl $f $OBJ/krl-serial-wild $SERIAL_WRESULT "$TAG" | ||
161 | check_krl $f $OBJ/krl-keyid-wild $KEYID_WRESULT "$TAG" | ||
144 | done | 162 | done |
145 | } | 163 | } |
146 | # keys all serial keyid certs CA | 164 | |
147 | test_all "$REVOKED_KEYS" "revoked keys" yes yes no no no no | 165 | test_all() { |
148 | test_all "$UNREVOKED_KEYS" "unrevoked keys" no no no no no no | 166 | # wildcard |
149 | test_all "$REVOKED_CERTS" "revoked certs" yes yes yes yes yes yes | 167 | # keys all sr# k.ID cert CA sr.# k.ID |
150 | test_all "$UNREVOKED_CERTS" "unrevoked certs" no no no no no yes | 168 | test_rev "$RKEYS" "revoked keys" yes yes no no no no no no |
169 | test_rev "$UKEYS" "unrevoked keys" no no no no no no no no | ||
170 | test_rev "$RCERTS" "revoked certs" yes yes yes yes yes yes yes yes | ||
171 | test_rev "$UCERTS" "unrevoked certs" no no no no no yes no no | ||
172 | } | ||
173 | |||
174 | test_all | ||
151 | 175 | ||
152 | # Check update. Results should be identical. | 176 | # Check update. Results should be identical. |
153 | verbose "$tid: testing KRL update" | 177 | verbose "$tid: testing KRL update" |
154 | for f in $OBJ/krl-keys $OBJ/krl-cert $OBJ/krl-all \ | 178 | for f in $OBJ/krl-keys $OBJ/krl-cert $OBJ/krl-all \ |
155 | $OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid ; do | 179 | $OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid \ |
180 | $OBJ/krl-serial-wild $OBJ/krl-keyid-wild; do | ||
156 | cp -f $OBJ/krl-empty $f | 181 | cp -f $OBJ/krl-empty $f |
157 | genkrls -u | 182 | genkrls -u |
158 | done | 183 | done |
159 | # keys all serial keyid certs CA | 184 | |
160 | test_all "$REVOKED_KEYS" "revoked keys" yes yes no no no no | 185 | test_all |
161 | test_all "$UNREVOKED_KEYS" "unrevoked keys" no no no no no no | ||
162 | test_all "$REVOKED_CERTS" "revoked certs" yes yes yes yes yes yes | ||
163 | test_all "$UNREVOKED_CERTS" "unrevoked certs" no no no no no yes | ||
diff --git a/regress/limit-keytype.sh b/regress/limit-keytype.sh new file mode 100644 index 000000000..2de037bd1 --- /dev/null +++ b/regress/limit-keytype.sh | |||
@@ -0,0 +1,80 @@ | |||
1 | # $OpenBSD: limit-keytype.sh,v 1.1 2015/01/13 07:49:49 djm Exp $ | ||
2 | # Placed in the Public Domain. | ||
3 | |||
4 | tid="restrict pubkey type" | ||
5 | |||
6 | rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* | ||
7 | rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* | ||
8 | |||
9 | mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig | ||
10 | mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig | ||
11 | |||
12 | # Create a CA key | ||
13 | ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key ||\ | ||
14 | fatal "ssh-keygen failed" | ||
15 | |||
16 | # Make some keys and a certificate. | ||
17 | ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \ | ||
18 | fatal "ssh-keygen failed" | ||
19 | ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key2 || \ | ||
20 | fatal "ssh-keygen failed" | ||
21 | ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key3 || \ | ||
22 | fatal "ssh-keygen failed" | ||
23 | ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ | ||
24 | -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key3 || | ||
25 | fatal "couldn't sign user_key1" | ||
26 | # Copy the private key alongside the cert to allow better control of when | ||
27 | # it is offered. | ||
28 | mv $OBJ/user_key3-cert.pub $OBJ/cert_user_key3.pub | ||
29 | cp -p $OBJ/user_key3 $OBJ/cert_user_key3 | ||
30 | |||
31 | grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy | ||
32 | |||
33 | opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" | ||
34 | fullopts="$opts -i $OBJ/cert_user_key3 -i $OBJ/user_key1 -i $OBJ/user_key2" | ||
35 | |||
36 | echo mekmitasdigoat > $OBJ/authorized_principals_$USER | ||
37 | cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER | ||
38 | cat $OBJ/user_key2.pub >> $OBJ/authorized_keys_$USER | ||
39 | |||
40 | prepare_config() { | ||
41 | ( | ||
42 | grep -v "Protocol" $OBJ/sshd_proxy.orig | ||
43 | echo "Protocol 2" | ||
44 | echo "AuthenticationMethods publickey" | ||
45 | echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" | ||
46 | echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" | ||
47 | for x in "$@" ; do | ||
48 | echo "$x" | ||
49 | done | ||
50 | ) > $OBJ/sshd_proxy | ||
51 | } | ||
52 | |||
53 | prepare_config | ||
54 | |||
55 | # Check we can log in with all key types. | ||
56 | ${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed" | ||
57 | ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" | ||
58 | ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" | ||
59 | |||
60 | # Allow plain Ed25519 and RSA. The certificate should fail. | ||
61 | verbose "privsep=$privsep allow rsa,ed25519" | ||
62 | prepare_config "PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519" | ||
63 | ${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded" | ||
64 | ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" | ||
65 | ${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" | ||
66 | |||
67 | # Allow Ed25519 only. | ||
68 | verbose "privsep=$privsep allow ed25519" | ||
69 | prepare_config "PubkeyAcceptedKeyTypes ssh-ed25519" | ||
70 | ${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded" | ||
71 | ${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" | ||
72 | ${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" | ||
73 | |||
74 | # Allow all certs. Plain keys should fail. | ||
75 | verbose "privsep=$privsep allow cert only" | ||
76 | prepare_config "PubkeyAcceptedKeyTypes ssh-*-cert-v01@openssh.com" | ||
77 | ${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed" | ||
78 | ${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" | ||
79 | ${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" | ||
80 | |||
diff --git a/regress/localcommand.sh b/regress/localcommand.sh index 8a9b56971..220f19a4d 100644 --- a/regress/localcommand.sh +++ b/regress/localcommand.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: localcommand.sh,v 1.2 2013/05/17 10:24:48 dtucker Exp $ | 1 | # $OpenBSD: localcommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="localcommand" | 4 | tid="localcommand" |
@@ -6,7 +6,7 @@ tid="localcommand" | |||
6 | echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy | 6 | echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy |
7 | echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy | 7 | echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy |
8 | 8 | ||
9 | for p in 1 2; do | 9 | for p in ${SSH_PROTOCOLS}; do |
10 | verbose "test $tid: proto $p localcommand" | 10 | verbose "test $tid: proto $p localcommand" |
11 | a=`${SSH} -F $OBJ/ssh_proxy -$p somehost true` | 11 | a=`${SSH} -F $OBJ/ssh_proxy -$p somehost true` |
12 | if [ "$a" != "foo" ] ; then | 12 | if [ "$a" != "foo" ] ; then |
diff --git a/regress/multiplex.sh b/regress/multiplex.sh index 8ee140be6..acb9234d9 100644 --- a/regress/multiplex.sh +++ b/regress/multiplex.sh | |||
@@ -1,24 +1,11 @@ | |||
1 | # $OpenBSD: multiplex.sh,v 1.25 2014/07/22 01:32:12 djm Exp $ | 1 | # $OpenBSD: multiplex.sh,v 1.27 2014/12/22 06:14:29 djm Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | CTL=/tmp/openssh.regress.ctl-sock.$$ | 4 | CTL=/tmp/openssh.regress.ctl-sock.$$ |
5 | 5 | ||
6 | tid="connection multiplexing" | 6 | tid="connection multiplexing" |
7 | 7 | ||
8 | if have_prog nc ; then | 8 | NC=$OBJ/netcat |
9 | if nc -h 2>&1 | grep -- -N >/dev/null; then | ||
10 | NC="nc -N"; | ||
11 | elif nc -h 2>&1 | grep -- "-U.*Use UNIX" >/dev/null ; then | ||
12 | NC="nc" | ||
13 | else | ||
14 | echo "nc is incompatible" | ||
15 | fi | ||
16 | fi | ||
17 | |||
18 | if test -z "$NC" ; then | ||
19 | echo "skipped (no compatible nc found)" | ||
20 | exit 0 | ||
21 | fi | ||
22 | 9 | ||
23 | trace "will use ProxyCommand $proxycmd" | 10 | trace "will use ProxyCommand $proxycmd" |
24 | if config_defined DISABLE_FD_PASSING ; then | 11 | if config_defined DISABLE_FD_PASSING ; then |
@@ -90,20 +77,20 @@ cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}" | |||
90 | rm -f ${COPY} | 77 | rm -f ${COPY} |
91 | verbose "test $tid: forward" | 78 | verbose "test $tid: forward" |
92 | trace "forward over TCP/IP and check result" | 79 | trace "forward over TCP/IP and check result" |
93 | $NC -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} & | 80 | $NC -N -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} > /dev/null & |
94 | netcat_pid=$! | 81 | netcat_pid=$! |
95 | ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L127.0.0.1:$((${PORT} + 2)):127.0.0.1:$((${PORT} + 1)) otherhost >>$TEST_SSH_LOGFILE 2>&1 | 82 | ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L127.0.0.1:$((${PORT} + 2)):127.0.0.1:$((${PORT} + 1)) otherhost >>$TEST_SSH_LOGFILE 2>&1 |
96 | $NC -d 127.0.0.1 $((${PORT} + 2)) > ${COPY} < /dev/null | 83 | $NC 127.0.0.1 $((${PORT} + 2)) < /dev/null > ${COPY} |
97 | cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" | 84 | cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" |
98 | kill $netcat_pid 2>/dev/null | 85 | kill $netcat_pid 2>/dev/null |
99 | rm -f ${COPY} $OBJ/unix-[123].fwd | 86 | rm -f ${COPY} $OBJ/unix-[123].fwd |
100 | 87 | ||
101 | trace "forward over UNIX and check result" | 88 | trace "forward over UNIX and check result" |
102 | $NC -Ul $OBJ/unix-1.fwd < ${DATA} & | 89 | $NC -N -Ul $OBJ/unix-1.fwd < ${DATA} > /dev/null & |
103 | netcat_pid=$! | 90 | netcat_pid=$! |
104 | ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 | 91 | ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 |
105 | ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 | 92 | ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 |
106 | $NC -d -U $OBJ/unix-3.fwd > ${COPY} </dev/null | 93 | $NC -U $OBJ/unix-3.fwd < /dev/null > ${COPY} 2>/dev/null |
107 | cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" | 94 | cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" |
108 | kill $netcat_pid 2>/dev/null | 95 | kill $netcat_pid 2>/dev/null |
109 | rm -f ${COPY} $OBJ/unix-[123].fwd | 96 | rm -f ${COPY} $OBJ/unix-[123].fwd |
diff --git a/regress/multipubkey.sh b/regress/multipubkey.sh new file mode 100644 index 000000000..e9d15306f --- /dev/null +++ b/regress/multipubkey.sh | |||
@@ -0,0 +1,66 @@ | |||
1 | # $OpenBSD: multipubkey.sh,v 1.1 2014/12/22 08:06:03 djm Exp $ | ||
2 | # Placed in the Public Domain. | ||
3 | |||
4 | tid="multiple pubkey" | ||
5 | |||
6 | rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* | ||
7 | rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* | ||
8 | |||
9 | mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig | ||
10 | mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig | ||
11 | |||
12 | # Create a CA key | ||
13 | ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key ||\ | ||
14 | fatal "ssh-keygen failed" | ||
15 | |||
16 | # Make some keys and a certificate. | ||
17 | ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \ | ||
18 | fatal "ssh-keygen failed" | ||
19 | ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key2 || \ | ||
20 | fatal "ssh-keygen failed" | ||
21 | ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ | ||
22 | -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key1 || | ||
23 | fail "couldn't sign user_key1" | ||
24 | # Copy the private key alongside the cert to allow better control of when | ||
25 | # it is offered. | ||
26 | mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1.pub | ||
27 | cp -p $OBJ/user_key1 $OBJ/cert_user_key1 | ||
28 | |||
29 | grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy | ||
30 | |||
31 | opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" | ||
32 | opts="$opts -i $OBJ/cert_user_key1 -i $OBJ/user_key1 -i $OBJ/user_key2" | ||
33 | |||
34 | for privsep in no yes; do | ||
35 | ( | ||
36 | grep -v "Protocol" $OBJ/sshd_proxy.orig | ||
37 | echo "Protocol 2" | ||
38 | echo "UsePrivilegeSeparation $privsep" | ||
39 | echo "AuthenticationMethods publickey,publickey" | ||
40 | echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" | ||
41 | echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" | ||
42 | ) > $OBJ/sshd_proxy | ||
43 | |||
44 | # Single key should fail. | ||
45 | rm -f $OBJ/authorized_principals_$USER | ||
46 | cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER | ||
47 | ${SSH} $opts proxy true && fail "ssh succeeded with key" | ||
48 | |||
49 | # Single key with same-public cert should fail. | ||
50 | echo mekmitasdigoat > $OBJ/authorized_principals_$USER | ||
51 | cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER | ||
52 | ${SSH} $opts proxy true && fail "ssh succeeded with key+cert" | ||
53 | |||
54 | # Multiple plain keys should succeed. | ||
55 | rm -f $OBJ/authorized_principals_$USER | ||
56 | cat $OBJ/user_key1.pub $OBJ/user_key2.pub > \ | ||
57 | $OBJ/authorized_keys_$USER | ||
58 | ${SSH} $opts proxy true || fail "ssh failed with multiple keys" | ||
59 | # Cert and different key should succeed | ||
60 | |||
61 | # Key and different-public cert should succeed. | ||
62 | echo mekmitasdigoat > $OBJ/authorized_principals_$USER | ||
63 | cat $OBJ/user_key2.pub > $OBJ/authorized_keys_$USER | ||
64 | ${SSH} $opts proxy true || fail "ssh failed with key/cert" | ||
65 | done | ||
66 | |||
diff --git a/regress/netcat.c b/regress/netcat.c new file mode 100644 index 000000000..1a9fc8730 --- /dev/null +++ b/regress/netcat.c | |||
@@ -0,0 +1,1690 @@ | |||
1 | /* $OpenBSD: netcat.c,v 1.126 2014/10/30 16:08:31 tedu Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. The name of the author may not be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | */ | ||
28 | |||
29 | /* | ||
30 | * Re-written nc(1) for OpenBSD. Original implementation by | ||
31 | * *Hobbit* <hobbit@avian.org>. | ||
32 | */ | ||
33 | |||
34 | #include "includes.h" | ||
35 | |||
36 | #include <sys/types.h> | ||
37 | #include <sys/socket.h> | ||
38 | #include <sys/time.h> | ||
39 | #include <sys/uio.h> | ||
40 | #include <sys/un.h> | ||
41 | |||
42 | #include <netinet/in.h> | ||
43 | #include <netinet/tcp.h> | ||
44 | #include <netinet/ip.h> | ||
45 | #include <arpa/telnet.h> | ||
46 | |||
47 | #include <errno.h> | ||
48 | #include <netdb.h> | ||
49 | #include <stdarg.h> | ||
50 | #include <stdio.h> | ||
51 | #include <stdlib.h> | ||
52 | #include <string.h> | ||
53 | #include <unistd.h> | ||
54 | #include <fcntl.h> | ||
55 | #include <limits.h> | ||
56 | #include "atomicio.h" | ||
57 | |||
58 | #ifdef HAVE_POLL_H | ||
59 | #include <poll.h> | ||
60 | #else | ||
61 | # ifdef HAVE_SYS_POLL_H | ||
62 | # include <sys/poll.h> | ||
63 | # endif | ||
64 | #endif | ||
65 | |||
66 | #ifndef SUN_LEN | ||
67 | #define SUN_LEN(su) \ | ||
68 | (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) | ||
69 | #endif | ||
70 | |||
71 | #define PORT_MAX 65535 | ||
72 | #define PORT_MAX_LEN 6 | ||
73 | #define UNIX_DG_TMP_SOCKET_SIZE 19 | ||
74 | |||
75 | #define POLL_STDIN 0 | ||
76 | #define POLL_NETOUT 1 | ||
77 | #define POLL_NETIN 2 | ||
78 | #define POLL_STDOUT 3 | ||
79 | #define BUFSIZE 16384 | ||
80 | |||
81 | /* Command Line Options */ | ||
82 | int dflag; /* detached, no stdin */ | ||
83 | int Fflag; /* fdpass sock to stdout */ | ||
84 | unsigned int iflag; /* Interval Flag */ | ||
85 | int kflag; /* More than one connect */ | ||
86 | int lflag; /* Bind to local port */ | ||
87 | int Nflag; /* shutdown() network socket */ | ||
88 | int nflag; /* Don't do name look up */ | ||
89 | char *Pflag; /* Proxy username */ | ||
90 | char *pflag; /* Localport flag */ | ||
91 | int rflag; /* Random ports flag */ | ||
92 | char *sflag; /* Source Address */ | ||
93 | int tflag; /* Telnet Emulation */ | ||
94 | int uflag; /* UDP - Default to TCP */ | ||
95 | int vflag; /* Verbosity */ | ||
96 | int xflag; /* Socks proxy */ | ||
97 | int zflag; /* Port Scan Flag */ | ||
98 | int Dflag; /* sodebug */ | ||
99 | int Iflag; /* TCP receive buffer size */ | ||
100 | int Oflag; /* TCP send buffer size */ | ||
101 | int Sflag; /* TCP MD5 signature option */ | ||
102 | int Tflag = -1; /* IP Type of Service */ | ||
103 | int rtableid = -1; | ||
104 | |||
105 | int timeout = -1; | ||
106 | int family = AF_UNSPEC; | ||
107 | char *portlist[PORT_MAX+1]; | ||
108 | char *unix_dg_tmp_socket; | ||
109 | |||
110 | void atelnet(int, unsigned char *, unsigned int); | ||
111 | void build_ports(char *); | ||
112 | void help(void); | ||
113 | int local_listen(char *, char *, struct addrinfo); | ||
114 | void readwrite(int); | ||
115 | void fdpass(int nfd) __attribute__((noreturn)); | ||
116 | int remote_connect(const char *, const char *, struct addrinfo); | ||
117 | int timeout_connect(int, const struct sockaddr *, socklen_t); | ||
118 | int socks_connect(const char *, const char *, struct addrinfo, | ||
119 | const char *, const char *, struct addrinfo, int, const char *); | ||
120 | int udptest(int); | ||
121 | int unix_bind(char *); | ||
122 | int unix_connect(char *); | ||
123 | int unix_listen(char *); | ||
124 | void set_common_sockopts(int); | ||
125 | int map_tos(char *, int *); | ||
126 | void report_connect(const struct sockaddr *, socklen_t); | ||
127 | void usage(int); | ||
128 | ssize_t drainbuf(int, unsigned char *, size_t *); | ||
129 | ssize_t fillbuf(int, unsigned char *, size_t *); | ||
130 | |||
131 | static void err(int, const char *, ...) __attribute__((format(printf, 2, 3))); | ||
132 | static void errx(int, const char *, ...) __attribute__((format(printf, 2, 3))); | ||
133 | static void warn(const char *, ...) __attribute__((format(printf, 1, 2))); | ||
134 | |||
135 | static void | ||
136 | err(int r, const char *fmt, ...) | ||
137 | { | ||
138 | va_list args; | ||
139 | |||
140 | va_start(args, fmt); | ||
141 | fprintf(stderr, "%s: ", strerror(errno)); | ||
142 | vfprintf(stderr, fmt, args); | ||
143 | fputc('\n', stderr); | ||
144 | va_end(args); | ||
145 | exit(r); | ||
146 | } | ||
147 | |||
148 | static void | ||
149 | errx(int r, const char *fmt, ...) | ||
150 | { | ||
151 | va_list args; | ||
152 | |||
153 | va_start(args, fmt); | ||
154 | vfprintf(stderr, fmt, args); | ||
155 | fputc('\n', stderr); | ||
156 | va_end(args); | ||
157 | exit(r); | ||
158 | } | ||
159 | |||
160 | static void | ||
161 | warn(const char *fmt, ...) | ||
162 | { | ||
163 | va_list args; | ||
164 | |||
165 | va_start(args, fmt); | ||
166 | fprintf(stderr, "%s: ", strerror(errno)); | ||
167 | vfprintf(stderr, fmt, args); | ||
168 | fputc('\n', stderr); | ||
169 | va_end(args); | ||
170 | } | ||
171 | |||
172 | int | ||
173 | main(int argc, char *argv[]) | ||
174 | { | ||
175 | int ch, s, ret, socksv; | ||
176 | char *host, *uport; | ||
177 | struct addrinfo hints; | ||
178 | struct servent *sv; | ||
179 | socklen_t len; | ||
180 | struct sockaddr_storage cliaddr; | ||
181 | char *proxy = NULL; | ||
182 | const char *errstr, *proxyhost = "", *proxyport = NULL; | ||
183 | struct addrinfo proxyhints; | ||
184 | char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; | ||
185 | |||
186 | ret = 1; | ||
187 | s = 0; | ||
188 | socksv = 5; | ||
189 | host = NULL; | ||
190 | uport = NULL; | ||
191 | sv = NULL; | ||
192 | |||
193 | while ((ch = getopt(argc, argv, | ||
194 | "46DdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { | ||
195 | switch (ch) { | ||
196 | case '4': | ||
197 | family = AF_INET; | ||
198 | break; | ||
199 | case '6': | ||
200 | family = AF_INET6; | ||
201 | break; | ||
202 | case 'U': | ||
203 | family = AF_UNIX; | ||
204 | break; | ||
205 | case 'X': | ||
206 | if (strcasecmp(optarg, "connect") == 0) | ||
207 | socksv = -1; /* HTTP proxy CONNECT */ | ||
208 | else if (strcmp(optarg, "4") == 0) | ||
209 | socksv = 4; /* SOCKS v.4 */ | ||
210 | else if (strcmp(optarg, "5") == 0) | ||
211 | socksv = 5; /* SOCKS v.5 */ | ||
212 | else | ||
213 | errx(1, "unsupported proxy protocol"); | ||
214 | break; | ||
215 | case 'd': | ||
216 | dflag = 1; | ||
217 | break; | ||
218 | case 'F': | ||
219 | Fflag = 1; | ||
220 | break; | ||
221 | case 'h': | ||
222 | help(); | ||
223 | break; | ||
224 | case 'i': | ||
225 | iflag = strtonum(optarg, 0, UINT_MAX, &errstr); | ||
226 | if (errstr) | ||
227 | errx(1, "interval %s: %s", errstr, optarg); | ||
228 | break; | ||
229 | case 'k': | ||
230 | kflag = 1; | ||
231 | break; | ||
232 | case 'l': | ||
233 | lflag = 1; | ||
234 | break; | ||
235 | case 'N': | ||
236 | Nflag = 1; | ||
237 | break; | ||
238 | case 'n': | ||
239 | nflag = 1; | ||
240 | break; | ||
241 | case 'P': | ||
242 | Pflag = optarg; | ||
243 | break; | ||
244 | case 'p': | ||
245 | pflag = optarg; | ||
246 | break; | ||
247 | case 'r': | ||
248 | rflag = 1; | ||
249 | break; | ||
250 | case 's': | ||
251 | sflag = optarg; | ||
252 | break; | ||
253 | case 't': | ||
254 | tflag = 1; | ||
255 | break; | ||
256 | case 'u': | ||
257 | uflag = 1; | ||
258 | break; | ||
259 | #ifdef SO_RTABLE | ||
260 | case 'V': | ||
261 | rtableid = (int)strtonum(optarg, 0, | ||
262 | RT_TABLEID_MAX, &errstr); | ||
263 | if (errstr) | ||
264 | errx(1, "rtable %s: %s", errstr, optarg); | ||
265 | break; | ||
266 | #endif | ||
267 | case 'v': | ||
268 | vflag = 1; | ||
269 | break; | ||
270 | case 'w': | ||
271 | timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); | ||
272 | if (errstr) | ||
273 | errx(1, "timeout %s: %s", errstr, optarg); | ||
274 | timeout *= 1000; | ||
275 | break; | ||
276 | case 'x': | ||
277 | xflag = 1; | ||
278 | if ((proxy = strdup(optarg)) == NULL) | ||
279 | errx(1, "strdup"); | ||
280 | break; | ||
281 | case 'z': | ||
282 | zflag = 1; | ||
283 | break; | ||
284 | case 'D': | ||
285 | Dflag = 1; | ||
286 | break; | ||
287 | case 'I': | ||
288 | Iflag = strtonum(optarg, 1, 65536 << 14, &errstr); | ||
289 | if (errstr != NULL) | ||
290 | errx(1, "TCP receive window %s: %s", | ||
291 | errstr, optarg); | ||
292 | break; | ||
293 | case 'O': | ||
294 | Oflag = strtonum(optarg, 1, 65536 << 14, &errstr); | ||
295 | if (errstr != NULL) | ||
296 | errx(1, "TCP send window %s: %s", | ||
297 | errstr, optarg); | ||
298 | break; | ||
299 | case 'S': | ||
300 | Sflag = 1; | ||
301 | break; | ||
302 | case 'T': | ||
303 | errstr = NULL; | ||
304 | errno = 0; | ||
305 | if (map_tos(optarg, &Tflag)) | ||
306 | break; | ||
307 | if (strlen(optarg) > 1 && optarg[0] == '0' && | ||
308 | optarg[1] == 'x') | ||
309 | Tflag = (int)strtol(optarg, NULL, 16); | ||
310 | else | ||
311 | Tflag = (int)strtonum(optarg, 0, 255, | ||
312 | &errstr); | ||
313 | if (Tflag < 0 || Tflag > 255 || errstr || errno) | ||
314 | errx(1, "illegal tos value %s", optarg); | ||
315 | break; | ||
316 | default: | ||
317 | usage(1); | ||
318 | } | ||
319 | } | ||
320 | argc -= optind; | ||
321 | argv += optind; | ||
322 | |||
323 | /* Cruft to make sure options are clean, and used properly. */ | ||
324 | if (argv[0] && !argv[1] && family == AF_UNIX) { | ||
325 | host = argv[0]; | ||
326 | uport = NULL; | ||
327 | } else if (argv[0] && !argv[1]) { | ||
328 | if (!lflag) | ||
329 | usage(1); | ||
330 | uport = argv[0]; | ||
331 | host = NULL; | ||
332 | } else if (argv[0] && argv[1]) { | ||
333 | host = argv[0]; | ||
334 | uport = argv[1]; | ||
335 | } else | ||
336 | usage(1); | ||
337 | |||
338 | if (lflag && sflag) | ||
339 | errx(1, "cannot use -s and -l"); | ||
340 | if (lflag && pflag) | ||
341 | errx(1, "cannot use -p and -l"); | ||
342 | if (lflag && zflag) | ||
343 | errx(1, "cannot use -z and -l"); | ||
344 | if (!lflag && kflag) | ||
345 | errx(1, "must use -l with -k"); | ||
346 | |||
347 | /* Get name of temporary socket for unix datagram client */ | ||
348 | if ((family == AF_UNIX) && uflag && !lflag) { | ||
349 | if (sflag) { | ||
350 | unix_dg_tmp_socket = sflag; | ||
351 | } else { | ||
352 | strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", | ||
353 | UNIX_DG_TMP_SOCKET_SIZE); | ||
354 | if (mktemp(unix_dg_tmp_socket_buf) == NULL) | ||
355 | err(1, "mktemp"); | ||
356 | unix_dg_tmp_socket = unix_dg_tmp_socket_buf; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | /* Initialize addrinfo structure. */ | ||
361 | if (family != AF_UNIX) { | ||
362 | memset(&hints, 0, sizeof(struct addrinfo)); | ||
363 | hints.ai_family = family; | ||
364 | hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; | ||
365 | hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; | ||
366 | if (nflag) | ||
367 | hints.ai_flags |= AI_NUMERICHOST; | ||
368 | } | ||
369 | |||
370 | if (xflag) { | ||
371 | if (uflag) | ||
372 | errx(1, "no proxy support for UDP mode"); | ||
373 | |||
374 | if (lflag) | ||
375 | errx(1, "no proxy support for listen"); | ||
376 | |||
377 | if (family == AF_UNIX) | ||
378 | errx(1, "no proxy support for unix sockets"); | ||
379 | |||
380 | /* XXX IPv6 transport to proxy would probably work */ | ||
381 | if (family == AF_INET6) | ||
382 | errx(1, "no proxy support for IPv6"); | ||
383 | |||
384 | if (sflag) | ||
385 | errx(1, "no proxy support for local source address"); | ||
386 | |||
387 | proxyhost = strsep(&proxy, ":"); | ||
388 | proxyport = proxy; | ||
389 | |||
390 | memset(&proxyhints, 0, sizeof(struct addrinfo)); | ||
391 | proxyhints.ai_family = family; | ||
392 | proxyhints.ai_socktype = SOCK_STREAM; | ||
393 | proxyhints.ai_protocol = IPPROTO_TCP; | ||
394 | if (nflag) | ||
395 | proxyhints.ai_flags |= AI_NUMERICHOST; | ||
396 | } | ||
397 | |||
398 | if (lflag) { | ||
399 | int connfd; | ||
400 | ret = 0; | ||
401 | |||
402 | if (family == AF_UNIX) { | ||
403 | if (uflag) | ||
404 | s = unix_bind(host); | ||
405 | else | ||
406 | s = unix_listen(host); | ||
407 | } | ||
408 | |||
409 | /* Allow only one connection at a time, but stay alive. */ | ||
410 | for (;;) { | ||
411 | if (family != AF_UNIX) | ||
412 | s = local_listen(host, uport, hints); | ||
413 | if (s < 0) | ||
414 | err(1, "local_listen"); | ||
415 | /* | ||
416 | * For UDP and -k, don't connect the socket, let it | ||
417 | * receive datagrams from multiple socket pairs. | ||
418 | */ | ||
419 | if (uflag && kflag) | ||
420 | readwrite(s); | ||
421 | /* | ||
422 | * For UDP and not -k, we will use recvfrom() initially | ||
423 | * to wait for a caller, then use the regular functions | ||
424 | * to talk to the caller. | ||
425 | */ | ||
426 | else if (uflag && !kflag) { | ||
427 | int rv, plen; | ||
428 | char buf[16384]; | ||
429 | struct sockaddr_storage z; | ||
430 | |||
431 | len = sizeof(z); | ||
432 | plen = 2048; | ||
433 | rv = recvfrom(s, buf, plen, MSG_PEEK, | ||
434 | (struct sockaddr *)&z, &len); | ||
435 | if (rv < 0) | ||
436 | err(1, "recvfrom"); | ||
437 | |||
438 | rv = connect(s, (struct sockaddr *)&z, len); | ||
439 | if (rv < 0) | ||
440 | err(1, "connect"); | ||
441 | |||
442 | if (vflag) | ||
443 | report_connect((struct sockaddr *)&z, len); | ||
444 | |||
445 | readwrite(s); | ||
446 | } else { | ||
447 | len = sizeof(cliaddr); | ||
448 | connfd = accept(s, (struct sockaddr *)&cliaddr, | ||
449 | &len); | ||
450 | if (connfd == -1) { | ||
451 | /* For now, all errnos are fatal */ | ||
452 | err(1, "accept"); | ||
453 | } | ||
454 | if (vflag) | ||
455 | report_connect((struct sockaddr *)&cliaddr, len); | ||
456 | |||
457 | readwrite(connfd); | ||
458 | close(connfd); | ||
459 | } | ||
460 | |||
461 | if (family != AF_UNIX) | ||
462 | close(s); | ||
463 | else if (uflag) { | ||
464 | if (connect(s, NULL, 0) < 0) | ||
465 | err(1, "connect"); | ||
466 | } | ||
467 | |||
468 | if (!kflag) | ||
469 | break; | ||
470 | } | ||
471 | } else if (family == AF_UNIX) { | ||
472 | ret = 0; | ||
473 | |||
474 | if ((s = unix_connect(host)) > 0 && !zflag) { | ||
475 | readwrite(s); | ||
476 | close(s); | ||
477 | } else | ||
478 | ret = 1; | ||
479 | |||
480 | if (uflag) | ||
481 | unlink(unix_dg_tmp_socket); | ||
482 | exit(ret); | ||
483 | |||
484 | } else { | ||
485 | int i = 0; | ||
486 | |||
487 | /* Construct the portlist[] array. */ | ||
488 | build_ports(uport); | ||
489 | |||
490 | /* Cycle through portlist, connecting to each port. */ | ||
491 | for (i = 0; portlist[i] != NULL; i++) { | ||
492 | if (s) | ||
493 | close(s); | ||
494 | |||
495 | if (xflag) | ||
496 | s = socks_connect(host, portlist[i], hints, | ||
497 | proxyhost, proxyport, proxyhints, socksv, | ||
498 | Pflag); | ||
499 | else | ||
500 | s = remote_connect(host, portlist[i], hints); | ||
501 | |||
502 | if (s < 0) | ||
503 | continue; | ||
504 | |||
505 | ret = 0; | ||
506 | if (vflag || zflag) { | ||
507 | /* For UDP, make sure we are connected. */ | ||
508 | if (uflag) { | ||
509 | if (udptest(s) == -1) { | ||
510 | ret = 1; | ||
511 | continue; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /* Don't look up port if -n. */ | ||
516 | if (nflag) | ||
517 | sv = NULL; | ||
518 | else { | ||
519 | sv = getservbyport( | ||
520 | ntohs(atoi(portlist[i])), | ||
521 | uflag ? "udp" : "tcp"); | ||
522 | } | ||
523 | |||
524 | fprintf(stderr, | ||
525 | "Connection to %s %s port [%s/%s] " | ||
526 | "succeeded!\n", host, portlist[i], | ||
527 | uflag ? "udp" : "tcp", | ||
528 | sv ? sv->s_name : "*"); | ||
529 | } | ||
530 | if (Fflag) | ||
531 | fdpass(s); | ||
532 | else if (!zflag) | ||
533 | readwrite(s); | ||
534 | } | ||
535 | } | ||
536 | |||
537 | if (s) | ||
538 | close(s); | ||
539 | |||
540 | exit(ret); | ||
541 | } | ||
542 | |||
543 | /* | ||
544 | * unix_bind() | ||
545 | * Returns a unix socket bound to the given path | ||
546 | */ | ||
547 | int | ||
548 | unix_bind(char *path) | ||
549 | { | ||
550 | struct sockaddr_un sun_sa; | ||
551 | int s; | ||
552 | |||
553 | /* Create unix domain socket. */ | ||
554 | if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM, | ||
555 | 0)) < 0) | ||
556 | return (-1); | ||
557 | |||
558 | memset(&sun_sa, 0, sizeof(struct sockaddr_un)); | ||
559 | sun_sa.sun_family = AF_UNIX; | ||
560 | |||
561 | if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >= | ||
562 | sizeof(sun_sa.sun_path)) { | ||
563 | close(s); | ||
564 | errno = ENAMETOOLONG; | ||
565 | return (-1); | ||
566 | } | ||
567 | |||
568 | if (bind(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) { | ||
569 | close(s); | ||
570 | return (-1); | ||
571 | } | ||
572 | return (s); | ||
573 | } | ||
574 | |||
575 | /* | ||
576 | * unix_connect() | ||
577 | * Returns a socket connected to a local unix socket. Returns -1 on failure. | ||
578 | */ | ||
579 | int | ||
580 | unix_connect(char *path) | ||
581 | { | ||
582 | struct sockaddr_un sun_sa; | ||
583 | int s; | ||
584 | |||
585 | if (uflag) { | ||
586 | if ((s = unix_bind(unix_dg_tmp_socket)) < 0) | ||
587 | return (-1); | ||
588 | } else { | ||
589 | if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) | ||
590 | return (-1); | ||
591 | } | ||
592 | (void)fcntl(s, F_SETFD, FD_CLOEXEC); | ||
593 | |||
594 | memset(&sun_sa, 0, sizeof(struct sockaddr_un)); | ||
595 | sun_sa.sun_family = AF_UNIX; | ||
596 | |||
597 | if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >= | ||
598 | sizeof(sun_sa.sun_path)) { | ||
599 | close(s); | ||
600 | errno = ENAMETOOLONG; | ||
601 | return (-1); | ||
602 | } | ||
603 | if (connect(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) { | ||
604 | close(s); | ||
605 | return (-1); | ||
606 | } | ||
607 | return (s); | ||
608 | |||
609 | } | ||
610 | |||
611 | /* | ||
612 | * unix_listen() | ||
613 | * Create a unix domain socket, and listen on it. | ||
614 | */ | ||
615 | int | ||
616 | unix_listen(char *path) | ||
617 | { | ||
618 | int s; | ||
619 | if ((s = unix_bind(path)) < 0) | ||
620 | return (-1); | ||
621 | |||
622 | if (listen(s, 5) < 0) { | ||
623 | close(s); | ||
624 | return (-1); | ||
625 | } | ||
626 | return (s); | ||
627 | } | ||
628 | |||
629 | /* | ||
630 | * remote_connect() | ||
631 | * Returns a socket connected to a remote host. Properly binds to a local | ||
632 | * port or source address if needed. Returns -1 on failure. | ||
633 | */ | ||
634 | int | ||
635 | remote_connect(const char *host, const char *port, struct addrinfo hints) | ||
636 | { | ||
637 | struct addrinfo *res, *res0; | ||
638 | int s, error; | ||
639 | #if defined(SO_RTABLE) || defined(SO_BINDANY) | ||
640 | int on = 1; | ||
641 | #endif | ||
642 | |||
643 | if ((error = getaddrinfo(host, port, &hints, &res))) | ||
644 | errx(1, "getaddrinfo: %s", gai_strerror(error)); | ||
645 | |||
646 | res0 = res; | ||
647 | do { | ||
648 | if ((s = socket(res0->ai_family, res0->ai_socktype, | ||
649 | res0->ai_protocol)) < 0) | ||
650 | continue; | ||
651 | |||
652 | #ifdef SO_RTABLE | ||
653 | if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE, | ||
654 | &rtableid, sizeof(rtableid)) == -1)) | ||
655 | err(1, "setsockopt SO_RTABLE"); | ||
656 | #endif | ||
657 | /* Bind to a local port or source address if specified. */ | ||
658 | if (sflag || pflag) { | ||
659 | struct addrinfo ahints, *ares; | ||
660 | |||
661 | #ifdef SO_BINDANY | ||
662 | /* try SO_BINDANY, but don't insist */ | ||
663 | setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); | ||
664 | #endif | ||
665 | memset(&ahints, 0, sizeof(struct addrinfo)); | ||
666 | ahints.ai_family = res0->ai_family; | ||
667 | ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; | ||
668 | ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; | ||
669 | ahints.ai_flags = AI_PASSIVE; | ||
670 | if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) | ||
671 | errx(1, "getaddrinfo: %s", gai_strerror(error)); | ||
672 | |||
673 | if (bind(s, (struct sockaddr *)ares->ai_addr, | ||
674 | ares->ai_addrlen) < 0) | ||
675 | err(1, "bind failed"); | ||
676 | freeaddrinfo(ares); | ||
677 | } | ||
678 | |||
679 | set_common_sockopts(s); | ||
680 | |||
681 | if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) | ||
682 | break; | ||
683 | else if (vflag) | ||
684 | warn("connect to %s port %s (%s) failed", host, port, | ||
685 | uflag ? "udp" : "tcp"); | ||
686 | |||
687 | close(s); | ||
688 | s = -1; | ||
689 | } while ((res0 = res0->ai_next) != NULL); | ||
690 | |||
691 | freeaddrinfo(res); | ||
692 | |||
693 | return (s); | ||
694 | } | ||
695 | |||
696 | int | ||
697 | timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) | ||
698 | { | ||
699 | struct pollfd pfd; | ||
700 | socklen_t optlen; | ||
701 | int flags = 0, optval; | ||
702 | int ret; | ||
703 | |||
704 | if (timeout != -1) { | ||
705 | flags = fcntl(s, F_GETFL, 0); | ||
706 | if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) | ||
707 | err(1, "set non-blocking mode"); | ||
708 | } | ||
709 | |||
710 | if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { | ||
711 | pfd.fd = s; | ||
712 | pfd.events = POLLOUT; | ||
713 | if ((ret = poll(&pfd, 1, timeout)) == 1) { | ||
714 | optlen = sizeof(optval); | ||
715 | if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, | ||
716 | &optval, &optlen)) == 0) { | ||
717 | errno = optval; | ||
718 | ret = optval == 0 ? 0 : -1; | ||
719 | } | ||
720 | } else if (ret == 0) { | ||
721 | errno = ETIMEDOUT; | ||
722 | ret = -1; | ||
723 | } else | ||
724 | err(1, "poll failed"); | ||
725 | } | ||
726 | |||
727 | if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) | ||
728 | err(1, "restoring flags"); | ||
729 | |||
730 | return (ret); | ||
731 | } | ||
732 | |||
733 | /* | ||
734 | * local_listen() | ||
735 | * Returns a socket listening on a local port, binds to specified source | ||
736 | * address. Returns -1 on failure. | ||
737 | */ | ||
738 | int | ||
739 | local_listen(char *host, char *port, struct addrinfo hints) | ||
740 | { | ||
741 | struct addrinfo *res, *res0; | ||
742 | int s, ret, x = 1; | ||
743 | int error; | ||
744 | |||
745 | /* Allow nodename to be null. */ | ||
746 | hints.ai_flags |= AI_PASSIVE; | ||
747 | |||
748 | /* | ||
749 | * In the case of binding to a wildcard address | ||
750 | * default to binding to an ipv4 address. | ||
751 | */ | ||
752 | if (host == NULL && hints.ai_family == AF_UNSPEC) | ||
753 | hints.ai_family = AF_INET; | ||
754 | |||
755 | if ((error = getaddrinfo(host, port, &hints, &res))) | ||
756 | errx(1, "getaddrinfo: %s", gai_strerror(error)); | ||
757 | |||
758 | res0 = res; | ||
759 | do { | ||
760 | if ((s = socket(res0->ai_family, res0->ai_socktype, | ||
761 | res0->ai_protocol)) < 0) | ||
762 | continue; | ||
763 | |||
764 | #ifdef SO_RTABLE | ||
765 | if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE, | ||
766 | &rtableid, sizeof(rtableid)) == -1)) | ||
767 | err(1, "setsockopt SO_RTABLE"); | ||
768 | #endif | ||
769 | #ifdef SO_REUSEPORT | ||
770 | ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); | ||
771 | if (ret == -1) | ||
772 | err(1, "setsockopt"); | ||
773 | #endif | ||
774 | set_common_sockopts(s); | ||
775 | |||
776 | if (bind(s, (struct sockaddr *)res0->ai_addr, | ||
777 | res0->ai_addrlen) == 0) | ||
778 | break; | ||
779 | |||
780 | close(s); | ||
781 | s = -1; | ||
782 | } while ((res0 = res0->ai_next) != NULL); | ||
783 | |||
784 | if (!uflag && s != -1) { | ||
785 | if (listen(s, 1) < 0) | ||
786 | err(1, "listen"); | ||
787 | } | ||
788 | |||
789 | freeaddrinfo(res); | ||
790 | |||
791 | return (s); | ||
792 | } | ||
793 | |||
794 | /* | ||
795 | * readwrite() | ||
796 | * Loop that polls on the network file descriptor and stdin. | ||
797 | */ | ||
798 | void | ||
799 | readwrite(int net_fd) | ||
800 | { | ||
801 | struct pollfd pfd[4]; | ||
802 | int stdin_fd = STDIN_FILENO; | ||
803 | int stdout_fd = STDOUT_FILENO; | ||
804 | unsigned char netinbuf[BUFSIZE]; | ||
805 | size_t netinbufpos = 0; | ||
806 | unsigned char stdinbuf[BUFSIZE]; | ||
807 | size_t stdinbufpos = 0; | ||
808 | int n, num_fds; | ||
809 | ssize_t ret; | ||
810 | |||
811 | /* don't read from stdin if requested */ | ||
812 | if (dflag) | ||
813 | stdin_fd = -1; | ||
814 | |||
815 | /* stdin */ | ||
816 | pfd[POLL_STDIN].fd = stdin_fd; | ||
817 | pfd[POLL_STDIN].events = POLLIN; | ||
818 | |||
819 | /* network out */ | ||
820 | pfd[POLL_NETOUT].fd = net_fd; | ||
821 | pfd[POLL_NETOUT].events = 0; | ||
822 | |||
823 | /* network in */ | ||
824 | pfd[POLL_NETIN].fd = net_fd; | ||
825 | pfd[POLL_NETIN].events = POLLIN; | ||
826 | |||
827 | /* stdout */ | ||
828 | pfd[POLL_STDOUT].fd = stdout_fd; | ||
829 | pfd[POLL_STDOUT].events = 0; | ||
830 | |||
831 | while (1) { | ||
832 | /* both inputs are gone, buffers are empty, we are done */ | ||
833 | if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 | ||
834 | && stdinbufpos == 0 && netinbufpos == 0) { | ||
835 | close(net_fd); | ||
836 | return; | ||
837 | } | ||
838 | /* both outputs are gone, we can't continue */ | ||
839 | if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) { | ||
840 | close(net_fd); | ||
841 | return; | ||
842 | } | ||
843 | /* listen and net in gone, queues empty, done */ | ||
844 | if (lflag && pfd[POLL_NETIN].fd == -1 | ||
845 | && stdinbufpos == 0 && netinbufpos == 0) { | ||
846 | close(net_fd); | ||
847 | return; | ||
848 | } | ||
849 | |||
850 | /* help says -i is for "wait between lines sent". We read and | ||
851 | * write arbitrary amounts of data, and we don't want to start | ||
852 | * scanning for newlines, so this is as good as it gets */ | ||
853 | if (iflag) | ||
854 | sleep(iflag); | ||
855 | |||
856 | /* poll */ | ||
857 | num_fds = poll(pfd, 4, timeout); | ||
858 | |||
859 | /* treat poll errors */ | ||
860 | if (num_fds == -1) { | ||
861 | close(net_fd); | ||
862 | err(1, "polling error"); | ||
863 | } | ||
864 | |||
865 | /* timeout happened */ | ||
866 | if (num_fds == 0) | ||
867 | return; | ||
868 | |||
869 | /* treat socket error conditions */ | ||
870 | for (n = 0; n < 4; n++) { | ||
871 | if (pfd[n].revents & (POLLERR|POLLNVAL)) { | ||
872 | pfd[n].fd = -1; | ||
873 | } | ||
874 | } | ||
875 | /* reading is possible after HUP */ | ||
876 | if (pfd[POLL_STDIN].events & POLLIN && | ||
877 | pfd[POLL_STDIN].revents & POLLHUP && | ||
878 | ! (pfd[POLL_STDIN].revents & POLLIN)) | ||
879 | pfd[POLL_STDIN].fd = -1; | ||
880 | |||
881 | if (pfd[POLL_NETIN].events & POLLIN && | ||
882 | pfd[POLL_NETIN].revents & POLLHUP && | ||
883 | ! (pfd[POLL_NETIN].revents & POLLIN)) | ||
884 | pfd[POLL_NETIN].fd = -1; | ||
885 | |||
886 | if (pfd[POLL_NETOUT].revents & POLLHUP) { | ||
887 | if (Nflag) | ||
888 | shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); | ||
889 | pfd[POLL_NETOUT].fd = -1; | ||
890 | } | ||
891 | /* if HUP, stop watching stdout */ | ||
892 | if (pfd[POLL_STDOUT].revents & POLLHUP) | ||
893 | pfd[POLL_STDOUT].fd = -1; | ||
894 | /* if no net out, stop watching stdin */ | ||
895 | if (pfd[POLL_NETOUT].fd == -1) | ||
896 | pfd[POLL_STDIN].fd = -1; | ||
897 | /* if no stdout, stop watching net in */ | ||
898 | if (pfd[POLL_STDOUT].fd == -1) { | ||
899 | if (pfd[POLL_NETIN].fd != -1) | ||
900 | shutdown(pfd[POLL_NETIN].fd, SHUT_RD); | ||
901 | pfd[POLL_NETIN].fd = -1; | ||
902 | } | ||
903 | |||
904 | /* try to read from stdin */ | ||
905 | if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) { | ||
906 | ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf, | ||
907 | &stdinbufpos); | ||
908 | /* error or eof on stdin - remove from pfd */ | ||
909 | if (ret == 0 || ret == -1) | ||
910 | pfd[POLL_STDIN].fd = -1; | ||
911 | /* read something - poll net out */ | ||
912 | if (stdinbufpos > 0) | ||
913 | pfd[POLL_NETOUT].events = POLLOUT; | ||
914 | /* filled buffer - remove self from polling */ | ||
915 | if (stdinbufpos == BUFSIZE) | ||
916 | pfd[POLL_STDIN].events = 0; | ||
917 | } | ||
918 | /* try to write to network */ | ||
919 | if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) { | ||
920 | ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf, | ||
921 | &stdinbufpos); | ||
922 | if (ret == -1) | ||
923 | pfd[POLL_NETOUT].fd = -1; | ||
924 | /* buffer empty - remove self from polling */ | ||
925 | if (stdinbufpos == 0) | ||
926 | pfd[POLL_NETOUT].events = 0; | ||
927 | /* buffer no longer full - poll stdin again */ | ||
928 | if (stdinbufpos < BUFSIZE) | ||
929 | pfd[POLL_STDIN].events = POLLIN; | ||
930 | } | ||
931 | /* try to read from network */ | ||
932 | if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) { | ||
933 | ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf, | ||
934 | &netinbufpos); | ||
935 | if (ret == -1) | ||
936 | pfd[POLL_NETIN].fd = -1; | ||
937 | /* eof on net in - remove from pfd */ | ||
938 | if (ret == 0) { | ||
939 | shutdown(pfd[POLL_NETIN].fd, SHUT_RD); | ||
940 | pfd[POLL_NETIN].fd = -1; | ||
941 | } | ||
942 | /* read something - poll stdout */ | ||
943 | if (netinbufpos > 0) | ||
944 | pfd[POLL_STDOUT].events = POLLOUT; | ||
945 | /* filled buffer - remove self from polling */ | ||
946 | if (netinbufpos == BUFSIZE) | ||
947 | pfd[POLL_NETIN].events = 0; | ||
948 | /* handle telnet */ | ||
949 | if (tflag) | ||
950 | atelnet(pfd[POLL_NETIN].fd, netinbuf, | ||
951 | netinbufpos); | ||
952 | } | ||
953 | /* try to write to stdout */ | ||
954 | if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) { | ||
955 | ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf, | ||
956 | &netinbufpos); | ||
957 | if (ret == -1) | ||
958 | pfd[POLL_STDOUT].fd = -1; | ||
959 | /* buffer empty - remove self from polling */ | ||
960 | if (netinbufpos == 0) | ||
961 | pfd[POLL_STDOUT].events = 0; | ||
962 | /* buffer no longer full - poll net in again */ | ||
963 | if (netinbufpos < BUFSIZE) | ||
964 | pfd[POLL_NETIN].events = POLLIN; | ||
965 | } | ||
966 | |||
967 | /* stdin gone and queue empty? */ | ||
968 | if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) { | ||
969 | if (pfd[POLL_NETOUT].fd != -1 && Nflag) | ||
970 | shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); | ||
971 | pfd[POLL_NETOUT].fd = -1; | ||
972 | } | ||
973 | /* net in gone and queue empty? */ | ||
974 | if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) { | ||
975 | pfd[POLL_STDOUT].fd = -1; | ||
976 | } | ||
977 | } | ||
978 | } | ||
979 | |||
980 | ssize_t | ||
981 | drainbuf(int fd, unsigned char *buf, size_t *bufpos) | ||
982 | { | ||
983 | ssize_t n; | ||
984 | ssize_t adjust; | ||
985 | |||
986 | n = write(fd, buf, *bufpos); | ||
987 | /* don't treat EAGAIN, EINTR as error */ | ||
988 | if (n == -1 && (errno == EAGAIN || errno == EINTR)) | ||
989 | n = -2; | ||
990 | if (n <= 0) | ||
991 | return n; | ||
992 | /* adjust buffer */ | ||
993 | adjust = *bufpos - n; | ||
994 | if (adjust > 0) | ||
995 | memmove(buf, buf + n, adjust); | ||
996 | *bufpos -= n; | ||
997 | return n; | ||
998 | } | ||
999 | |||
1000 | |||
1001 | ssize_t | ||
1002 | fillbuf(int fd, unsigned char *buf, size_t *bufpos) | ||
1003 | { | ||
1004 | size_t num = BUFSIZE - *bufpos; | ||
1005 | ssize_t n; | ||
1006 | |||
1007 | n = read(fd, buf + *bufpos, num); | ||
1008 | /* don't treat EAGAIN, EINTR as error */ | ||
1009 | if (n == -1 && (errno == EAGAIN || errno == EINTR)) | ||
1010 | n = -2; | ||
1011 | if (n <= 0) | ||
1012 | return n; | ||
1013 | *bufpos += n; | ||
1014 | return n; | ||
1015 | } | ||
1016 | |||
1017 | /* | ||
1018 | * fdpass() | ||
1019 | * Pass the connected file descriptor to stdout and exit. | ||
1020 | */ | ||
1021 | void | ||
1022 | fdpass(int nfd) | ||
1023 | { | ||
1024 | #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) | ||
1025 | struct msghdr msg; | ||
1026 | #ifndef HAVE_ACCRIGHTS_IN_MSGHDR | ||
1027 | union { | ||
1028 | struct cmsghdr hdr; | ||
1029 | char buf[CMSG_SPACE(sizeof(int))]; | ||
1030 | } cmsgbuf; | ||
1031 | struct cmsghdr *cmsg; | ||
1032 | #endif | ||
1033 | struct iovec vec; | ||
1034 | char ch = '\0'; | ||
1035 | struct pollfd pfd; | ||
1036 | ssize_t r; | ||
1037 | |||
1038 | memset(&msg, 0, sizeof(msg)); | ||
1039 | #ifdef HAVE_ACCRIGHTS_IN_MSGHDR | ||
1040 | msg.msg_accrights = (caddr_t)&nfd; | ||
1041 | msg.msg_accrightslen = sizeof(nfd); | ||
1042 | #else | ||
1043 | memset(&cmsgbuf, 0, sizeof(cmsgbuf)); | ||
1044 | msg.msg_control = (caddr_t)&cmsgbuf.buf; | ||
1045 | msg.msg_controllen = sizeof(cmsgbuf.buf); | ||
1046 | cmsg = CMSG_FIRSTHDR(&msg); | ||
1047 | cmsg->cmsg_len = CMSG_LEN(sizeof(int)); | ||
1048 | cmsg->cmsg_level = SOL_SOCKET; | ||
1049 | cmsg->cmsg_type = SCM_RIGHTS; | ||
1050 | *(int *)CMSG_DATA(cmsg) = nfd; | ||
1051 | #endif | ||
1052 | |||
1053 | vec.iov_base = &ch; | ||
1054 | vec.iov_len = 1; | ||
1055 | msg.msg_iov = &vec; | ||
1056 | msg.msg_iovlen = 1; | ||
1057 | |||
1058 | bzero(&pfd, sizeof(pfd)); | ||
1059 | pfd.fd = STDOUT_FILENO; | ||
1060 | for (;;) { | ||
1061 | r = sendmsg(STDOUT_FILENO, &msg, 0); | ||
1062 | if (r == -1) { | ||
1063 | if (errno == EAGAIN || errno == EINTR) { | ||
1064 | pfd.events = POLLOUT; | ||
1065 | if (poll(&pfd, 1, -1) == -1) | ||
1066 | err(1, "poll"); | ||
1067 | continue; | ||
1068 | } | ||
1069 | err(1, "sendmsg"); | ||
1070 | } else if (r == -1) | ||
1071 | errx(1, "sendmsg: unexpected return value %zd", r); | ||
1072 | else | ||
1073 | break; | ||
1074 | } | ||
1075 | exit(0); | ||
1076 | #else | ||
1077 | errx(1, "%s: file descriptor passing not supported", __func__); | ||
1078 | #endif | ||
1079 | } | ||
1080 | |||
1081 | /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ | ||
1082 | void | ||
1083 | atelnet(int nfd, unsigned char *buf, unsigned int size) | ||
1084 | { | ||
1085 | unsigned char *p, *end; | ||
1086 | unsigned char obuf[4]; | ||
1087 | |||
1088 | if (size < 3) | ||
1089 | return; | ||
1090 | end = buf + size - 2; | ||
1091 | |||
1092 | for (p = buf; p < end; p++) { | ||
1093 | if (*p != IAC) | ||
1094 | continue; | ||
1095 | |||
1096 | obuf[0] = IAC; | ||
1097 | p++; | ||
1098 | if ((*p == WILL) || (*p == WONT)) | ||
1099 | obuf[1] = DONT; | ||
1100 | else if ((*p == DO) || (*p == DONT)) | ||
1101 | obuf[1] = WONT; | ||
1102 | else | ||
1103 | continue; | ||
1104 | |||
1105 | p++; | ||
1106 | obuf[2] = *p; | ||
1107 | if (atomicio(vwrite, nfd, obuf, 3) != 3) | ||
1108 | warn("Write Error!"); | ||
1109 | } | ||
1110 | } | ||
1111 | |||
1112 | /* | ||
1113 | * build_ports() | ||
1114 | * Build an array of ports in portlist[], listing each port | ||
1115 | * that we should try to connect to. | ||
1116 | */ | ||
1117 | void | ||
1118 | build_ports(char *p) | ||
1119 | { | ||
1120 | const char *errstr; | ||
1121 | char *n; | ||
1122 | int hi, lo, cp; | ||
1123 | int x = 0; | ||
1124 | |||
1125 | if ((n = strchr(p, '-')) != NULL) { | ||
1126 | *n = '\0'; | ||
1127 | n++; | ||
1128 | |||
1129 | /* Make sure the ports are in order: lowest->highest. */ | ||
1130 | hi = strtonum(n, 1, PORT_MAX, &errstr); | ||
1131 | if (errstr) | ||
1132 | errx(1, "port number %s: %s", errstr, n); | ||
1133 | lo = strtonum(p, 1, PORT_MAX, &errstr); | ||
1134 | if (errstr) | ||
1135 | errx(1, "port number %s: %s", errstr, p); | ||
1136 | |||
1137 | if (lo > hi) { | ||
1138 | cp = hi; | ||
1139 | hi = lo; | ||
1140 | lo = cp; | ||
1141 | } | ||
1142 | |||
1143 | /* Load ports sequentially. */ | ||
1144 | for (cp = lo; cp <= hi; cp++) { | ||
1145 | portlist[x] = calloc(1, PORT_MAX_LEN); | ||
1146 | if (portlist[x] == NULL) | ||
1147 | errx(1, "calloc"); | ||
1148 | snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); | ||
1149 | x++; | ||
1150 | } | ||
1151 | |||
1152 | /* Randomly swap ports. */ | ||
1153 | if (rflag) { | ||
1154 | int y; | ||
1155 | char *c; | ||
1156 | |||
1157 | for (x = 0; x <= (hi - lo); x++) { | ||
1158 | y = (arc4random() & 0xFFFF) % (hi - lo); | ||
1159 | c = portlist[x]; | ||
1160 | portlist[x] = portlist[y]; | ||
1161 | portlist[y] = c; | ||
1162 | } | ||
1163 | } | ||
1164 | } else { | ||
1165 | hi = strtonum(p, 1, PORT_MAX, &errstr); | ||
1166 | if (errstr) | ||
1167 | errx(1, "port number %s: %s", errstr, p); | ||
1168 | portlist[0] = strdup(p); | ||
1169 | if (portlist[0] == NULL) | ||
1170 | errx(1, "strdup"); | ||
1171 | } | ||
1172 | } | ||
1173 | |||
1174 | /* | ||
1175 | * udptest() | ||
1176 | * Do a few writes to see if the UDP port is there. | ||
1177 | * Fails once PF state table is full. | ||
1178 | */ | ||
1179 | int | ||
1180 | udptest(int s) | ||
1181 | { | ||
1182 | int i, ret; | ||
1183 | |||
1184 | for (i = 0; i <= 3; i++) { | ||
1185 | if (write(s, "X", 1) == 1) | ||
1186 | ret = 1; | ||
1187 | else | ||
1188 | ret = -1; | ||
1189 | } | ||
1190 | return (ret); | ||
1191 | } | ||
1192 | |||
1193 | void | ||
1194 | set_common_sockopts(int s) | ||
1195 | { | ||
1196 | int x = 1; | ||
1197 | |||
1198 | #ifdef TCP_MD5SIG | ||
1199 | if (Sflag) { | ||
1200 | if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, | ||
1201 | &x, sizeof(x)) == -1) | ||
1202 | err(1, "setsockopt"); | ||
1203 | } | ||
1204 | #endif | ||
1205 | if (Dflag) { | ||
1206 | if (setsockopt(s, SOL_SOCKET, SO_DEBUG, | ||
1207 | &x, sizeof(x)) == -1) | ||
1208 | err(1, "setsockopt"); | ||
1209 | } | ||
1210 | if (Tflag != -1) { | ||
1211 | if (setsockopt(s, IPPROTO_IP, IP_TOS, | ||
1212 | &Tflag, sizeof(Tflag)) == -1) | ||
1213 | err(1, "set IP ToS"); | ||
1214 | } | ||
1215 | if (Iflag) { | ||
1216 | if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, | ||
1217 | &Iflag, sizeof(Iflag)) == -1) | ||
1218 | err(1, "set TCP receive buffer size"); | ||
1219 | } | ||
1220 | if (Oflag) { | ||
1221 | if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, | ||
1222 | &Oflag, sizeof(Oflag)) == -1) | ||
1223 | err(1, "set TCP send buffer size"); | ||
1224 | } | ||
1225 | } | ||
1226 | |||
1227 | int | ||
1228 | map_tos(char *s, int *val) | ||
1229 | { | ||
1230 | /* DiffServ Codepoints and other TOS mappings */ | ||
1231 | const struct toskeywords { | ||
1232 | const char *keyword; | ||
1233 | int val; | ||
1234 | } *t, toskeywords[] = { | ||
1235 | { "af11", IPTOS_DSCP_AF11 }, | ||
1236 | { "af12", IPTOS_DSCP_AF12 }, | ||
1237 | { "af13", IPTOS_DSCP_AF13 }, | ||
1238 | { "af21", IPTOS_DSCP_AF21 }, | ||
1239 | { "af22", IPTOS_DSCP_AF22 }, | ||
1240 | { "af23", IPTOS_DSCP_AF23 }, | ||
1241 | { "af31", IPTOS_DSCP_AF31 }, | ||
1242 | { "af32", IPTOS_DSCP_AF32 }, | ||
1243 | { "af33", IPTOS_DSCP_AF33 }, | ||
1244 | { "af41", IPTOS_DSCP_AF41 }, | ||
1245 | { "af42", IPTOS_DSCP_AF42 }, | ||
1246 | { "af43", IPTOS_DSCP_AF43 }, | ||
1247 | { "critical", IPTOS_PREC_CRITIC_ECP }, | ||
1248 | { "cs0", IPTOS_DSCP_CS0 }, | ||
1249 | { "cs1", IPTOS_DSCP_CS1 }, | ||
1250 | { "cs2", IPTOS_DSCP_CS2 }, | ||
1251 | { "cs3", IPTOS_DSCP_CS3 }, | ||
1252 | { "cs4", IPTOS_DSCP_CS4 }, | ||
1253 | { "cs5", IPTOS_DSCP_CS5 }, | ||
1254 | { "cs6", IPTOS_DSCP_CS6 }, | ||
1255 | { "cs7", IPTOS_DSCP_CS7 }, | ||
1256 | { "ef", IPTOS_DSCP_EF }, | ||
1257 | { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, | ||
1258 | { "lowdelay", IPTOS_LOWDELAY }, | ||
1259 | { "netcontrol", IPTOS_PREC_NETCONTROL }, | ||
1260 | { "reliability", IPTOS_RELIABILITY }, | ||
1261 | { "throughput", IPTOS_THROUGHPUT }, | ||
1262 | { NULL, -1 }, | ||
1263 | }; | ||
1264 | |||
1265 | for (t = toskeywords; t->keyword != NULL; t++) { | ||
1266 | if (strcmp(s, t->keyword) == 0) { | ||
1267 | *val = t->val; | ||
1268 | return (1); | ||
1269 | } | ||
1270 | } | ||
1271 | |||
1272 | return (0); | ||
1273 | } | ||
1274 | |||
1275 | void | ||
1276 | report_connect(const struct sockaddr *sa, socklen_t salen) | ||
1277 | { | ||
1278 | char remote_host[NI_MAXHOST]; | ||
1279 | char remote_port[NI_MAXSERV]; | ||
1280 | int herr; | ||
1281 | int flags = NI_NUMERICSERV; | ||
1282 | |||
1283 | if (nflag) | ||
1284 | flags |= NI_NUMERICHOST; | ||
1285 | |||
1286 | if ((herr = getnameinfo(sa, salen, | ||
1287 | remote_host, sizeof(remote_host), | ||
1288 | remote_port, sizeof(remote_port), | ||
1289 | flags)) != 0) { | ||
1290 | if (herr == EAI_SYSTEM) | ||
1291 | err(1, "getnameinfo"); | ||
1292 | else | ||
1293 | errx(1, "getnameinfo: %s", gai_strerror(herr)); | ||
1294 | } | ||
1295 | |||
1296 | fprintf(stderr, | ||
1297 | "Connection from %s %s " | ||
1298 | "received!\n", remote_host, remote_port); | ||
1299 | } | ||
1300 | |||
1301 | void | ||
1302 | help(void) | ||
1303 | { | ||
1304 | usage(0); | ||
1305 | fprintf(stderr, "\tCommand Summary:\n\ | ||
1306 | \t-4 Use IPv4\n\ | ||
1307 | \t-6 Use IPv6\n\ | ||
1308 | \t-D Enable the debug socket option\n\ | ||
1309 | \t-d Detach from stdin\n\ | ||
1310 | \t-F Pass socket fd\n\ | ||
1311 | \t-h This help text\n\ | ||
1312 | \t-I length TCP receive buffer length\n\ | ||
1313 | \t-i secs\t Delay interval for lines sent, ports scanned\n\ | ||
1314 | \t-k Keep inbound sockets open for multiple connects\n\ | ||
1315 | \t-l Listen mode, for inbound connects\n\ | ||
1316 | \t-N Shutdown the network socket after EOF on stdin\n\ | ||
1317 | \t-n Suppress name/port resolutions\n\ | ||
1318 | \t-O length TCP send buffer length\n\ | ||
1319 | \t-P proxyuser\tUsername for proxy authentication\n\ | ||
1320 | \t-p port\t Specify local port for remote connects\n\ | ||
1321 | \t-r Randomize remote ports\n\ | ||
1322 | \t-S Enable the TCP MD5 signature option\n\ | ||
1323 | \t-s addr\t Local source address\n\ | ||
1324 | \t-T toskeyword\tSet IP Type of Service\n\ | ||
1325 | \t-t Answer TELNET negotiation\n\ | ||
1326 | \t-U Use UNIX domain socket\n\ | ||
1327 | \t-u UDP mode\n\ | ||
1328 | \t-V rtable Specify alternate routing table\n\ | ||
1329 | \t-v Verbose\n\ | ||
1330 | \t-w secs\t Timeout for connects and final net reads\n\ | ||
1331 | \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ | ||
1332 | \t-x addr[:port]\tSpecify proxy address and port\n\ | ||
1333 | \t-z Zero-I/O mode [used for scanning]\n\ | ||
1334 | Port numbers can be individual or ranges: lo-hi [inclusive]\n"); | ||
1335 | exit(1); | ||
1336 | } | ||
1337 | |||
1338 | void | ||
1339 | usage(int ret) | ||
1340 | { | ||
1341 | fprintf(stderr, | ||
1342 | "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n" | ||
1343 | "\t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n" | ||
1344 | "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" | ||
1345 | "\t [-x proxy_address[:port]] [destination] [port]\n"); | ||
1346 | if (ret) | ||
1347 | exit(1); | ||
1348 | } | ||
1349 | |||
1350 | /* *** src/usr.bin/nc/socks.c *** */ | ||
1351 | |||
1352 | |||
1353 | /* $OpenBSD: socks.c,v 1.20 2012/03/08 09:56:28 espie Exp $ */ | ||
1354 | |||
1355 | /* | ||
1356 | * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. | ||
1357 | * Copyright (c) 2004, 2005 Damien Miller. All rights reserved. | ||
1358 | * | ||
1359 | * Redistribution and use in source and binary forms, with or without | ||
1360 | * modification, are permitted provided that the following conditions | ||
1361 | * are met: | ||
1362 | * 1. Redistributions of source code must retain the above copyright | ||
1363 | * notice, this list of conditions and the following disclaimer. | ||
1364 | * 2. Redistributions in binary form must reproduce the above copyright | ||
1365 | * notice, this list of conditions and the following disclaimer in the | ||
1366 | * documentation and/or other materials provided with the distribution. | ||
1367 | * | ||
1368 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
1369 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
1370 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
1371 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
1372 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
1373 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
1374 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
1375 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
1376 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
1377 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
1378 | */ | ||
1379 | |||
1380 | #include <sys/types.h> | ||
1381 | #include <sys/socket.h> | ||
1382 | #include <netinet/in.h> | ||
1383 | #include <arpa/inet.h> | ||
1384 | |||
1385 | #include <errno.h> | ||
1386 | #include <netdb.h> | ||
1387 | #include <stdio.h> | ||
1388 | #include <stdlib.h> | ||
1389 | #include <string.h> | ||
1390 | #include <unistd.h> | ||
1391 | #include <resolv.h> | ||
1392 | |||
1393 | #define SOCKS_PORT "1080" | ||
1394 | #define HTTP_PROXY_PORT "3128" | ||
1395 | #define HTTP_MAXHDRS 64 | ||
1396 | #define SOCKS_V5 5 | ||
1397 | #define SOCKS_V4 4 | ||
1398 | #define SOCKS_NOAUTH 0 | ||
1399 | #define SOCKS_NOMETHOD 0xff | ||
1400 | #define SOCKS_CONNECT 1 | ||
1401 | #define SOCKS_IPV4 1 | ||
1402 | #define SOCKS_DOMAIN 3 | ||
1403 | #define SOCKS_IPV6 4 | ||
1404 | |||
1405 | int remote_connect(const char *, const char *, struct addrinfo); | ||
1406 | int socks_connect(const char *, const char *, struct addrinfo, | ||
1407 | const char *, const char *, struct addrinfo, int, | ||
1408 | const char *); | ||
1409 | |||
1410 | static int | ||
1411 | decode_addrport(const char *h, const char *p, struct sockaddr *addr, | ||
1412 | socklen_t addrlen, int v4only, int numeric) | ||
1413 | { | ||
1414 | int r; | ||
1415 | struct addrinfo hints, *res; | ||
1416 | |||
1417 | bzero(&hints, sizeof(hints)); | ||
1418 | hints.ai_family = v4only ? PF_INET : PF_UNSPEC; | ||
1419 | hints.ai_flags = numeric ? AI_NUMERICHOST : 0; | ||
1420 | hints.ai_socktype = SOCK_STREAM; | ||
1421 | r = getaddrinfo(h, p, &hints, &res); | ||
1422 | /* Don't fatal when attempting to convert a numeric address */ | ||
1423 | if (r != 0) { | ||
1424 | if (!numeric) { | ||
1425 | errx(1, "getaddrinfo(\"%.64s\", \"%.64s\"): %s", h, p, | ||
1426 | gai_strerror(r)); | ||
1427 | } | ||
1428 | return (-1); | ||
1429 | } | ||
1430 | if (addrlen < res->ai_addrlen) { | ||
1431 | freeaddrinfo(res); | ||
1432 | errx(1, "internal error: addrlen < res->ai_addrlen"); | ||
1433 | } | ||
1434 | memcpy(addr, res->ai_addr, res->ai_addrlen); | ||
1435 | freeaddrinfo(res); | ||
1436 | return (0); | ||
1437 | } | ||
1438 | |||
1439 | static int | ||
1440 | proxy_read_line(int fd, char *buf, size_t bufsz) | ||
1441 | { | ||
1442 | size_t off; | ||
1443 | |||
1444 | for(off = 0;;) { | ||
1445 | if (off >= bufsz) | ||
1446 | errx(1, "proxy read too long"); | ||
1447 | if (atomicio(read, fd, buf + off, 1) != 1) | ||
1448 | err(1, "proxy read"); | ||
1449 | /* Skip CR */ | ||
1450 | if (buf[off] == '\r') | ||
1451 | continue; | ||
1452 | if (buf[off] == '\n') { | ||
1453 | buf[off] = '\0'; | ||
1454 | break; | ||
1455 | } | ||
1456 | off++; | ||
1457 | } | ||
1458 | return (off); | ||
1459 | } | ||
1460 | |||
1461 | static const char * | ||
1462 | getproxypass(const char *proxyuser, const char *proxyhost) | ||
1463 | { | ||
1464 | char prompt[512]; | ||
1465 | static char pw[256]; | ||
1466 | |||
1467 | snprintf(prompt, sizeof(prompt), "Proxy password for %s@%s: ", | ||
1468 | proxyuser, proxyhost); | ||
1469 | if (readpassphrase(prompt, pw, sizeof(pw), RPP_REQUIRE_TTY) == NULL) | ||
1470 | errx(1, "Unable to read proxy passphrase"); | ||
1471 | return (pw); | ||
1472 | } | ||
1473 | |||
1474 | int | ||
1475 | socks_connect(const char *host, const char *port, | ||
1476 | struct addrinfo hints __attribute__ ((__unused__)), | ||
1477 | const char *proxyhost, const char *proxyport, struct addrinfo proxyhints, | ||
1478 | int socksv, const char *proxyuser) | ||
1479 | { | ||
1480 | int proxyfd, r, authretry = 0; | ||
1481 | size_t hlen, wlen = 0; | ||
1482 | unsigned char buf[1024]; | ||
1483 | size_t cnt; | ||
1484 | struct sockaddr_storage addr; | ||
1485 | struct sockaddr_in *in4 = (struct sockaddr_in *)&addr; | ||
1486 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr; | ||
1487 | in_port_t serverport; | ||
1488 | const char *proxypass = NULL; | ||
1489 | |||
1490 | if (proxyport == NULL) | ||
1491 | proxyport = (socksv == -1) ? HTTP_PROXY_PORT : SOCKS_PORT; | ||
1492 | |||
1493 | /* Abuse API to lookup port */ | ||
1494 | if (decode_addrport("0.0.0.0", port, (struct sockaddr *)&addr, | ||
1495 | sizeof(addr), 1, 1) == -1) | ||
1496 | errx(1, "unknown port \"%.64s\"", port); | ||
1497 | serverport = in4->sin_port; | ||
1498 | |||
1499 | again: | ||
1500 | if (authretry++ > 3) | ||
1501 | errx(1, "Too many authentication failures"); | ||
1502 | |||
1503 | proxyfd = remote_connect(proxyhost, proxyport, proxyhints); | ||
1504 | |||
1505 | if (proxyfd < 0) | ||
1506 | return (-1); | ||
1507 | |||
1508 | if (socksv == 5) { | ||
1509 | if (decode_addrport(host, port, (struct sockaddr *)&addr, | ||
1510 | sizeof(addr), 0, 1) == -1) | ||
1511 | addr.ss_family = 0; /* used in switch below */ | ||
1512 | |||
1513 | /* Version 5, one method: no authentication */ | ||
1514 | buf[0] = SOCKS_V5; | ||
1515 | buf[1] = 1; | ||
1516 | buf[2] = SOCKS_NOAUTH; | ||
1517 | cnt = atomicio(vwrite, proxyfd, buf, 3); | ||
1518 | if (cnt != 3) | ||
1519 | err(1, "write failed (%zu/3)", cnt); | ||
1520 | |||
1521 | cnt = atomicio(read, proxyfd, buf, 2); | ||
1522 | if (cnt != 2) | ||
1523 | err(1, "read failed (%zu/3)", cnt); | ||
1524 | |||
1525 | if (buf[1] == SOCKS_NOMETHOD) | ||
1526 | errx(1, "authentication method negotiation failed"); | ||
1527 | |||
1528 | switch (addr.ss_family) { | ||
1529 | case 0: | ||
1530 | /* Version 5, connect: domain name */ | ||
1531 | |||
1532 | /* Max domain name length is 255 bytes */ | ||
1533 | hlen = strlen(host); | ||
1534 | if (hlen > 255) | ||
1535 | errx(1, "host name too long for SOCKS5"); | ||
1536 | buf[0] = SOCKS_V5; | ||
1537 | buf[1] = SOCKS_CONNECT; | ||
1538 | buf[2] = 0; | ||
1539 | buf[3] = SOCKS_DOMAIN; | ||
1540 | buf[4] = hlen; | ||
1541 | memcpy(buf + 5, host, hlen); | ||
1542 | memcpy(buf + 5 + hlen, &serverport, sizeof serverport); | ||
1543 | wlen = 7 + hlen; | ||
1544 | break; | ||
1545 | case AF_INET: | ||
1546 | /* Version 5, connect: IPv4 address */ | ||
1547 | buf[0] = SOCKS_V5; | ||
1548 | buf[1] = SOCKS_CONNECT; | ||
1549 | buf[2] = 0; | ||
1550 | buf[3] = SOCKS_IPV4; | ||
1551 | memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); | ||
1552 | memcpy(buf + 8, &in4->sin_port, sizeof in4->sin_port); | ||
1553 | wlen = 10; | ||
1554 | break; | ||
1555 | case AF_INET6: | ||
1556 | /* Version 5, connect: IPv6 address */ | ||
1557 | buf[0] = SOCKS_V5; | ||
1558 | buf[1] = SOCKS_CONNECT; | ||
1559 | buf[2] = 0; | ||
1560 | buf[3] = SOCKS_IPV6; | ||
1561 | memcpy(buf + 4, &in6->sin6_addr, sizeof in6->sin6_addr); | ||
1562 | memcpy(buf + 20, &in6->sin6_port, | ||
1563 | sizeof in6->sin6_port); | ||
1564 | wlen = 22; | ||
1565 | break; | ||
1566 | default: | ||
1567 | errx(1, "internal error: silly AF"); | ||
1568 | } | ||
1569 | |||
1570 | cnt = atomicio(vwrite, proxyfd, buf, wlen); | ||
1571 | if (cnt != wlen) | ||
1572 | err(1, "write failed (%zu/%zu)", cnt, wlen); | ||
1573 | |||
1574 | cnt = atomicio(read, proxyfd, buf, 4); | ||
1575 | if (cnt != 4) | ||
1576 | err(1, "read failed (%zu/4)", cnt); | ||
1577 | if (buf[1] != 0) | ||
1578 | errx(1, "connection failed, SOCKS error %d", buf[1]); | ||
1579 | switch (buf[3]) { | ||
1580 | case SOCKS_IPV4: | ||
1581 | cnt = atomicio(read, proxyfd, buf + 4, 6); | ||
1582 | if (cnt != 6) | ||
1583 | err(1, "read failed (%zu/6)", cnt); | ||
1584 | break; | ||
1585 | case SOCKS_IPV6: | ||
1586 | cnt = atomicio(read, proxyfd, buf + 4, 18); | ||
1587 | if (cnt != 18) | ||
1588 | err(1, "read failed (%zu/18)", cnt); | ||
1589 | break; | ||
1590 | default: | ||
1591 | errx(1, "connection failed, unsupported address type"); | ||
1592 | } | ||
1593 | } else if (socksv == 4) { | ||
1594 | /* This will exit on lookup failure */ | ||
1595 | decode_addrport(host, port, (struct sockaddr *)&addr, | ||
1596 | sizeof(addr), 1, 0); | ||
1597 | |||
1598 | /* Version 4 */ | ||
1599 | buf[0] = SOCKS_V4; | ||
1600 | buf[1] = SOCKS_CONNECT; /* connect */ | ||
1601 | memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); | ||
1602 | memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); | ||
1603 | buf[8] = 0; /* empty username */ | ||
1604 | wlen = 9; | ||
1605 | |||
1606 | cnt = atomicio(vwrite, proxyfd, buf, wlen); | ||
1607 | if (cnt != wlen) | ||
1608 | err(1, "write failed (%zu/%zu)", cnt, wlen); | ||
1609 | |||
1610 | cnt = atomicio(read, proxyfd, buf, 8); | ||
1611 | if (cnt != 8) | ||
1612 | err(1, "read failed (%zu/8)", cnt); | ||
1613 | if (buf[1] != 90) | ||
1614 | errx(1, "connection failed, SOCKS error %d", buf[1]); | ||
1615 | } else if (socksv == -1) { | ||
1616 | /* HTTP proxy CONNECT */ | ||
1617 | |||
1618 | /* Disallow bad chars in hostname */ | ||
1619 | if (strcspn(host, "\r\n\t []:") != strlen(host)) | ||
1620 | errx(1, "Invalid hostname"); | ||
1621 | |||
1622 | /* Try to be sane about numeric IPv6 addresses */ | ||
1623 | if (strchr(host, ':') != NULL) { | ||
1624 | r = snprintf(buf, sizeof(buf), | ||
1625 | "CONNECT [%s]:%d HTTP/1.0\r\n", | ||
1626 | host, ntohs(serverport)); | ||
1627 | } else { | ||
1628 | r = snprintf(buf, sizeof(buf), | ||
1629 | "CONNECT %s:%d HTTP/1.0\r\n", | ||
1630 | host, ntohs(serverport)); | ||
1631 | } | ||
1632 | if (r == -1 || (size_t)r >= sizeof(buf)) | ||
1633 | errx(1, "hostname too long"); | ||
1634 | r = strlen(buf); | ||
1635 | |||
1636 | cnt = atomicio(vwrite, proxyfd, buf, r); | ||
1637 | if (cnt != (size_t)r) | ||
1638 | err(1, "write failed (%zu/%d)", cnt, r); | ||
1639 | |||
1640 | if (authretry > 1) { | ||
1641 | char resp[1024]; | ||
1642 | |||
1643 | proxypass = getproxypass(proxyuser, proxyhost); | ||
1644 | r = snprintf(buf, sizeof(buf), "%s:%s", | ||
1645 | proxyuser, proxypass); | ||
1646 | if (r == -1 || (size_t)r >= sizeof(buf) || | ||
1647 | b64_ntop(buf, strlen(buf), resp, | ||
1648 | sizeof(resp)) == -1) | ||
1649 | errx(1, "Proxy username/password too long"); | ||
1650 | r = snprintf(buf, sizeof(buf), "Proxy-Authorization: " | ||
1651 | "Basic %s\r\n", resp); | ||
1652 | if (r == -1 || (size_t)r >= sizeof(buf)) | ||
1653 | errx(1, "Proxy auth response too long"); | ||
1654 | r = strlen(buf); | ||
1655 | if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != (size_t)r) | ||
1656 | err(1, "write failed (%zu/%d)", cnt, r); | ||
1657 | } | ||
1658 | |||
1659 | /* Terminate headers */ | ||
1660 | if ((r = atomicio(vwrite, proxyfd, "\r\n", 2)) != 2) | ||
1661 | err(1, "write failed (2/%d)", r); | ||
1662 | |||
1663 | /* Read status reply */ | ||
1664 | proxy_read_line(proxyfd, buf, sizeof(buf)); | ||
1665 | if (proxyuser != NULL && | ||
1666 | strncmp(buf, "HTTP/1.0 407 ", 12) == 0) { | ||
1667 | if (authretry > 1) { | ||
1668 | fprintf(stderr, "Proxy authentication " | ||
1669 | "failed\n"); | ||
1670 | } | ||
1671 | close(proxyfd); | ||
1672 | goto again; | ||
1673 | } else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 && | ||
1674 | strncmp(buf, "HTTP/1.1 200 ", 12) != 0) | ||
1675 | errx(1, "Proxy error: \"%s\"", buf); | ||
1676 | |||
1677 | /* Headers continue until we hit an empty line */ | ||
1678 | for (r = 0; r < HTTP_MAXHDRS; r++) { | ||
1679 | proxy_read_line(proxyfd, buf, sizeof(buf)); | ||
1680 | if (*buf == '\0') | ||
1681 | break; | ||
1682 | } | ||
1683 | if (*buf != '\0') | ||
1684 | errx(1, "Too many proxy headers received"); | ||
1685 | } else | ||
1686 | errx(1, "Unknown proxy protocol %d", socksv); | ||
1687 | |||
1688 | return (proxyfd); | ||
1689 | } | ||
1690 | |||
diff --git a/regress/proto-mismatch.sh b/regress/proto-mismatch.sh index fb521f214..9e8024beb 100644 --- a/regress/proto-mismatch.sh +++ b/regress/proto-mismatch.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: proto-mismatch.sh,v 1.3 2002/03/15 13:08:56 markus Exp $ | 1 | # $OpenBSD: proto-mismatch.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="protocol version mismatch" | 4 | tid="protocol version mismatch" |
@@ -16,4 +16,6 @@ mismatch () | |||
16 | } | 16 | } |
17 | 17 | ||
18 | mismatch 2 SSH-1.5-HALLO | 18 | mismatch 2 SSH-1.5-HALLO |
19 | mismatch 1 SSH-2.0-HALLO | 19 | if ssh_version 1; then |
20 | mismatch 1 SSH-2.0-HALLO | ||
21 | fi | ||
diff --git a/regress/proto-version.sh b/regress/proto-version.sh index b876dd7ec..cf4946115 100644 --- a/regress/proto-version.sh +++ b/regress/proto-version.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: proto-version.sh,v 1.4 2013/05/17 00:37:40 dtucker Exp $ | 1 | # $OpenBSD: proto-version.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="sshd version with different protocol combinations" | 4 | tid="sshd version with different protocol combinations" |
@@ -28,7 +28,9 @@ check_version () | |||
28 | fi | 28 | fi |
29 | } | 29 | } |
30 | 30 | ||
31 | check_version 2,1 199 | ||
32 | check_version 1,2 199 | ||
33 | check_version 2 20 | 31 | check_version 2 20 |
34 | check_version 1 15 | 32 | if ssh_version 1; then |
33 | check_version 2,1 199 | ||
34 | check_version 1,2 199 | ||
35 | check_version 1 15 | ||
36 | fi | ||
diff --git a/regress/proxy-connect.sh b/regress/proxy-connect.sh index 023ba7367..f816962b5 100644 --- a/regress/proxy-connect.sh +++ b/regress/proxy-connect.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: proxy-connect.sh,v 1.7 2014/05/03 18:46:14 dtucker Exp $ | 1 | # $OpenBSD: proxy-connect.sh,v 1.8 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="proxy connect" | 4 | tid="proxy connect" |
@@ -9,7 +9,7 @@ for ps in no yes; do | |||
9 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy | 9 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy |
10 | echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy | 10 | echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy |
11 | 11 | ||
12 | for p in 1 2; do | 12 | for p in ${SSH_PROTOCOLS}; do |
13 | for c in no yes; do | 13 | for c in no yes; do |
14 | verbose "plain username protocol $p privsep=$ps comp=$c" | 14 | verbose "plain username protocol $p privsep=$ps comp=$c" |
15 | opts="-$p -oCompression=$c -F $OBJ/ssh_proxy" | 15 | opts="-$p -oCompression=$c -F $OBJ/ssh_proxy" |
@@ -24,7 +24,7 @@ for ps in no yes; do | |||
24 | done | 24 | done |
25 | done | 25 | done |
26 | 26 | ||
27 | for p in 1 2; do | 27 | for p in ${SSH_PROTOCOLS}; do |
28 | verbose "username with style protocol $p" | 28 | verbose "username with style protocol $p" |
29 | ${SSH} -$p -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \ | 29 | ${SSH} -$p -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \ |
30 | fail "ssh proxyconnect protocol $p failed" | 30 | fail "ssh proxyconnect protocol $p failed" |
diff --git a/regress/reconfigure.sh b/regress/reconfigure.sh index 9fd289531..eecddd3c7 100644 --- a/regress/reconfigure.sh +++ b/regress/reconfigure.sh | |||
@@ -1,20 +1,30 @@ | |||
1 | # $OpenBSD: reconfigure.sh,v 1.2 2003/06/21 09:14:05 markus Exp $ | 1 | # $OpenBSD: reconfigure.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="simple connect after reconfigure" | 4 | tid="simple connect after reconfigure" |
5 | 5 | ||
6 | # we need the full path to sshd for -HUP | 6 | # we need the full path to sshd for -HUP |
7 | case $SSHD in | 7 | if test "x$USE_VALGRIND" = "x" ; then |
8 | /*) | 8 | case $SSHD in |
9 | # full path is OK | 9 | /*) |
10 | ;; | 10 | # full path is OK |
11 | *) | 11 | ;; |
12 | # otherwise make fully qualified | 12 | *) |
13 | SSHD=$OBJ/$SSHD | 13 | # otherwise make fully qualified |
14 | esac | 14 | SSHD=$OBJ/$SSHD |
15 | esac | ||
16 | fi | ||
15 | 17 | ||
16 | start_sshd | 18 | start_sshd |
17 | 19 | ||
20 | trace "connect before restart" | ||
21 | for p in ${SSH_PROTOCOLS} ; do | ||
22 | ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true | ||
23 | if [ $? -ne 0 ]; then | ||
24 | fail "ssh connect with protocol $p failed before reconfigure" | ||
25 | fi | ||
26 | done | ||
27 | |||
18 | PID=`$SUDO cat $PIDFILE` | 28 | PID=`$SUDO cat $PIDFILE` |
19 | rm -f $PIDFILE | 29 | rm -f $PIDFILE |
20 | $SUDO kill -HUP $PID | 30 | $SUDO kill -HUP $PID |
@@ -28,7 +38,8 @@ done | |||
28 | 38 | ||
29 | test -f $PIDFILE || fatal "sshd did not restart" | 39 | test -f $PIDFILE || fatal "sshd did not restart" |
30 | 40 | ||
31 | for p in 1 2; do | 41 | trace "connect after restart" |
42 | for p in ${SSH_PROTOCOLS} ; do | ||
32 | ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true | 43 | ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true |
33 | if [ $? -ne 0 ]; then | 44 | if [ $? -ne 0 ]; then |
34 | fail "ssh connect with protocol $p failed after reconfigure" | 45 | fail "ssh connect with protocol $p failed after reconfigure" |
diff --git a/regress/reexec.sh b/regress/reexec.sh index 433573f06..5c0a7b46f 100644 --- a/regress/reexec.sh +++ b/regress/reexec.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: reexec.sh,v 1.7 2013/05/17 10:23:52 dtucker Exp $ | 1 | # $OpenBSD: reexec.sh,v 1.8 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="reexec tests" | 4 | tid="reexec tests" |
@@ -19,7 +19,7 @@ start_sshd_copy () | |||
19 | copy_tests () | 19 | copy_tests () |
20 | { | 20 | { |
21 | rm -f ${COPY} | 21 | rm -f ${COPY} |
22 | for p in 1 2; do | 22 | for p in ${SSH_PROTOCOLS} ; do |
23 | verbose "$tid: proto $p" | 23 | verbose "$tid: proto $p" |
24 | ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \ | 24 | ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \ |
25 | cat ${DATA} > ${COPY} | 25 | cat ${DATA} > ${COPY} |
diff --git a/regress/rekey.sh b/regress/rekey.sh index fd452b034..0d4444d03 100644 --- a/regress/rekey.sh +++ b/regress/rekey.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: rekey.sh,v 1.15 2014/04/21 22:15:37 djm Exp $ | 1 | # $OpenBSD: rekey.sh,v 1.16 2015/02/14 12:43:16 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="rekey" | 4 | tid="rekey" |
@@ -100,9 +100,29 @@ for s in 5 10; do | |||
100 | fi | 100 | fi |
101 | done | 101 | done |
102 | 102 | ||
103 | echo "rekeylimit default 5" >>$OBJ/sshd_proxy | 103 | for s in 16 1k 128k 256k; do |
104 | verbose "server rekeylimit ${s}" | ||
105 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy | ||
106 | echo "rekeylimit ${s}" >>$OBJ/sshd_proxy | ||
107 | rm -f ${COPY} ${LOG} | ||
108 | ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "cat ${DATA}" \ | ||
109 | > ${COPY} | ||
110 | if [ $? -ne 0 ]; then | ||
111 | fail "ssh failed" | ||
112 | fi | ||
113 | cmp ${DATA} ${COPY} || fail "corrupted copy" | ||
114 | n=`grep 'NEWKEYS sent' ${LOG} | wc -l` | ||
115 | n=`expr $n - 1` | ||
116 | trace "$n rekeying(s)" | ||
117 | if [ $n -lt 1 ]; then | ||
118 | fail "no rekeying occured" | ||
119 | fi | ||
120 | done | ||
121 | |||
104 | for s in 5 10; do | 122 | for s in 5 10; do |
105 | verbose "server rekeylimit default ${s} no data" | 123 | verbose "server rekeylimit default ${s} no data" |
124 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy | ||
125 | echo "rekeylimit default ${s}" >>$OBJ/sshd_proxy | ||
106 | rm -f ${COPY} ${LOG} | 126 | rm -f ${COPY} ${LOG} |
107 | ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "sleep $s;sleep 3" | 127 | ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "sleep $s;sleep 3" |
108 | if [ $? -ne 0 ]; then | 128 | if [ $? -ne 0 ]; then |
diff --git a/regress/sshd-log-wrapper.sh b/regress/sshd-log-wrapper.sh index a9386be4d..c00934c78 100644 --- a/regress/sshd-log-wrapper.sh +++ b/regress/sshd-log-wrapper.sh | |||
@@ -3,11 +3,9 @@ | |||
3 | # Placed in the Public Domain. | 3 | # Placed in the Public Domain. |
4 | # | 4 | # |
5 | # simple wrapper for sshd proxy mode to catch stderr output | 5 | # simple wrapper for sshd proxy mode to catch stderr output |
6 | # sh sshd-log-wrapper.sh /path/to/sshd /path/to/logfile | 6 | # sh sshd-log-wrapper.sh /path/to/logfile /path/to/sshd [args...] |
7 | 7 | ||
8 | sshd=$1 | 8 | log=$1 |
9 | log=$2 | ||
10 | shift | ||
11 | shift | 9 | shift |
12 | 10 | ||
13 | exec $sshd -E$log $@ | 11 | exec "$@" -E$log |
diff --git a/regress/stderr-data.sh b/regress/stderr-data.sh index b0bd2355c..8c8149a73 100644 --- a/regress/stderr-data.sh +++ b/regress/stderr-data.sh | |||
@@ -1,10 +1,10 @@ | |||
1 | # $OpenBSD: stderr-data.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $ | 1 | # $OpenBSD: stderr-data.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="stderr data transfer" | 4 | tid="stderr data transfer" |
5 | 5 | ||
6 | for n in '' -n; do | 6 | for n in '' -n; do |
7 | for p in 1 2; do | 7 | for p in ${SSH_PROTOCOLS}; do |
8 | verbose "test $tid: proto $p ($n)" | 8 | verbose "test $tid: proto $p ($n)" |
9 | ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ | 9 | ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ |
10 | exec sh -c \'"exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ | 10 | exec sh -c \'"exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ |
diff --git a/regress/t11.ok b/regress/t11.ok new file mode 100644 index 000000000..1925bb470 --- /dev/null +++ b/regress/t11.ok | |||
@@ -0,0 +1 @@ | |||
SHA256:4w1rnrek3klTJOTVhwuCIFd5k+pq9Bfo5KTxxb8BqbY | |||
diff --git a/regress/t4.ok b/regress/t4.ok index 8c4942bf1..4631ea8c7 100644 --- a/regress/t4.ok +++ b/regress/t4.ok | |||
@@ -1 +1 @@ | |||
3b:dd:44:e9:49:18:84:95:f1:e7:33:6b:9d:93:b1:36 | MD5:3b:dd:44:e9:49:18:84:95:f1:e7:33:6b:9d:93:b1:36 | ||
diff --git a/regress/test-exec.sh b/regress/test-exec.sh index a1bab832f..0f766620d 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: test-exec.sh,v 1.48 2014/07/06 07:42:03 djm Exp $ | 1 | # $OpenBSD: test-exec.sh,v 1.51 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | #SUDO=sudo | 4 | #SUDO=sudo |
@@ -130,6 +130,11 @@ if [ "x$TEST_SSH_CONCH" != "x" ]; then | |||
130 | esac | 130 | esac |
131 | fi | 131 | fi |
132 | 132 | ||
133 | SSH_PROTOCOLS=`$SSH -Q protocol-version` | ||
134 | if [ "x$TEST_SSH_PROTOCOLS" != "x" ]; then | ||
135 | SSH_PROTOCOLS="${TEST_SSH_PROTOCOLS}" | ||
136 | fi | ||
137 | |||
133 | # Path to sshd must be absolute for rexec | 138 | # Path to sshd must be absolute for rexec |
134 | case "$SSHD" in | 139 | case "$SSHD" in |
135 | /*) ;; | 140 | /*) ;; |
@@ -141,6 +146,55 @@ case "$SSHAGENT" in | |||
141 | *) SSHAGENT=`which $SSHAGENT` ;; | 146 | *) SSHAGENT=`which $SSHAGENT` ;; |
142 | esac | 147 | esac |
143 | 148 | ||
149 | # Record the actual binaries used. | ||
150 | SSH_BIN=${SSH} | ||
151 | SSHD_BIN=${SSHD} | ||
152 | SSHAGENT_BIN=${SSHAGENT} | ||
153 | SSHADD_BIN=${SSHADD} | ||
154 | SSHKEYGEN_BIN=${SSHKEYGEN} | ||
155 | SSHKEYSCAN_BIN=${SSHKEYSCAN} | ||
156 | SFTP_BIN=${SFTP} | ||
157 | SFTPSERVER_BIN=${SFTPSERVER} | ||
158 | SCP_BIN=${SCP} | ||
159 | |||
160 | if [ "x$USE_VALGRIND" != "x" ]; then | ||
161 | mkdir -p $OBJ/valgrind-out | ||
162 | VG_TEST=`basename $SCRIPT .sh` | ||
163 | |||
164 | # Some tests are difficult to fix. | ||
165 | case "$VG_TEST" in | ||
166 | connect-privsep|reexec) | ||
167 | VG_SKIP=1 ;; | ||
168 | esac | ||
169 | |||
170 | if [ x"$VG_SKIP" = "x" ]; then | ||
171 | VG_IGNORE="/bin/*,/sbin/*,/usr/*,/var/*" | ||
172 | VG_LOG="$OBJ/valgrind-out/${VG_TEST}." | ||
173 | VG_OPTS="--track-origins=yes --leak-check=full" | ||
174 | VG_OPTS="$VG_OPTS --trace-children=yes" | ||
175 | VG_OPTS="$VG_OPTS --trace-children-skip=${VG_IGNORE}" | ||
176 | VG_PATH="valgrind" | ||
177 | if [ "x$VALGRIND_PATH" != "x" ]; then | ||
178 | VG_PATH="$VALGRIND_PATH" | ||
179 | fi | ||
180 | VG="$VG_PATH $VG_OPTS" | ||
181 | SSH="$VG --log-file=${VG_LOG}ssh.%p $SSH" | ||
182 | SSHD="$VG --log-file=${VG_LOG}sshd.%p $SSHD" | ||
183 | SSHAGENT="$VG --log-file=${VG_LOG}ssh-agent.%p $SSHAGENT" | ||
184 | SSHADD="$VG --log-file=${VG_LOG}ssh-add.%p $SSHADD" | ||
185 | SSHKEYGEN="$VG --log-file=${VG_LOG}ssh-keygen.%p $SSHKEYGEN" | ||
186 | SSHKEYSCAN="$VG --log-file=${VG_LOG}ssh-keyscan.%p $SSHKEYSCAN" | ||
187 | SFTP="$VG --log-file=${VG_LOG}sftp.%p ${SFTP}" | ||
188 | SCP="$VG --log-file=${VG_LOG}scp.%p $SCP" | ||
189 | cat > $OBJ/valgrind-sftp-server.sh << EOF | ||
190 | #!/bin/sh | ||
191 | exec $VG --log-file=${VG_LOG}sftp-server.%p $SFTPSERVER "\$@" | ||
192 | EOF | ||
193 | chmod a+rx $OBJ/valgrind-sftp-server.sh | ||
194 | SFTPSERVER="$OBJ/valgrind-sftp-server.sh" | ||
195 | fi | ||
196 | fi | ||
197 | |||
144 | # Logfiles. | 198 | # Logfiles. |
145 | # SSH_LOGFILE should be the debug output of ssh(1) only | 199 | # SSH_LOGFILE should be the debug output of ssh(1) only |
146 | # SSHD_LOGFILE should be the debug output of sshd(8) only | 200 | # SSHD_LOGFILE should be the debug output of sshd(8) only |
@@ -175,7 +229,7 @@ SSH="$SSHLOGWRAP" | |||
175 | # [kbytes] to ensure the file is at least that large. | 229 | # [kbytes] to ensure the file is at least that large. |
176 | DATANAME=data | 230 | DATANAME=data |
177 | DATA=$OBJ/${DATANAME} | 231 | DATA=$OBJ/${DATANAME} |
178 | cat ${SSHAGENT} >${DATA} | 232 | cat ${SSHAGENT_BIN} >${DATA} |
179 | chmod u+w ${DATA} | 233 | chmod u+w ${DATA} |
180 | COPY=$OBJ/copy | 234 | COPY=$OBJ/copy |
181 | rm -f ${COPY} | 235 | rm -f ${COPY} |
@@ -183,7 +237,7 @@ rm -f ${COPY} | |||
183 | increase_datafile_size() | 237 | increase_datafile_size() |
184 | { | 238 | { |
185 | while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do | 239 | while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do |
186 | cat ${SSHAGENT} >>${DATA} | 240 | cat ${SSHAGENT_BIN} >>${DATA} |
187 | done | 241 | done |
188 | } | 242 | } |
189 | 243 | ||
@@ -325,16 +379,27 @@ fatal () | |||
325 | exit $RESULT | 379 | exit $RESULT |
326 | } | 380 | } |
327 | 381 | ||
382 | ssh_version () | ||
383 | { | ||
384 | echo ${SSH_PROTOCOLS} | grep "$1" >/dev/null | ||
385 | } | ||
386 | |||
328 | RESULT=0 | 387 | RESULT=0 |
329 | PIDFILE=$OBJ/pidfile | 388 | PIDFILE=$OBJ/pidfile |
330 | 389 | ||
331 | trap fatal 3 2 | 390 | trap fatal 3 2 |
332 | 391 | ||
392 | if ssh_version 1; then | ||
393 | PROTO="2,1" | ||
394 | else | ||
395 | PROTO="2" | ||
396 | fi | ||
397 | |||
333 | # create server config | 398 | # create server config |
334 | cat << EOF > $OBJ/sshd_config | 399 | cat << EOF > $OBJ/sshd_config |
335 | StrictModes no | 400 | StrictModes no |
336 | Port $PORT | 401 | Port $PORT |
337 | Protocol 2,1 | 402 | Protocol $PROTO |
338 | AddressFamily inet | 403 | AddressFamily inet |
339 | ListenAddress 127.0.0.1 | 404 | ListenAddress 127.0.0.1 |
340 | #ListenAddress ::1 | 405 | #ListenAddress ::1 |
@@ -360,7 +425,7 @@ echo 'StrictModes no' >> $OBJ/sshd_proxy | |||
360 | # create client config | 425 | # create client config |
361 | cat << EOF > $OBJ/ssh_config | 426 | cat << EOF > $OBJ/ssh_config |
362 | Host * | 427 | Host * |
363 | Protocol 2,1 | 428 | Protocol $PROTO |
364 | Hostname 127.0.0.1 | 429 | Hostname 127.0.0.1 |
365 | HostKeyAlias localhost-with-alias | 430 | HostKeyAlias localhost-with-alias |
366 | Port $PORT | 431 | Port $PORT |
@@ -385,10 +450,15 @@ fi | |||
385 | 450 | ||
386 | rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER | 451 | rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER |
387 | 452 | ||
453 | if ssh_version 1; then | ||
454 | SSH_KEYTYPES="rsa rsa1" | ||
455 | else | ||
456 | SSH_KEYTYPES="rsa ed25519" | ||
457 | fi | ||
388 | trace "generate keys" | 458 | trace "generate keys" |
389 | for t in rsa rsa1; do | 459 | for t in ${SSH_KEYTYPES}; do |
390 | # generate user key | 460 | # generate user key |
391 | if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN} -nt $OBJ/$t ]; then | 461 | if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then |
392 | rm -f $OBJ/$t | 462 | rm -f $OBJ/$t |
393 | ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\ | 463 | ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\ |
394 | fail "ssh-keygen for $t failed" | 464 | fail "ssh-keygen for $t failed" |
@@ -451,7 +521,7 @@ if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then | |||
451 | echo "Hostname=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy | 521 | echo "Hostname=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy |
452 | echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy | 522 | echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy |
453 | echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy | 523 | echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy |
454 | echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSHD_LOGFILE} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy | 524 | echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy |
455 | 525 | ||
456 | REGRESS_INTEROP_PUTTY=yes | 526 | REGRESS_INTEROP_PUTTY=yes |
457 | fi | 527 | fi |
@@ -459,7 +529,7 @@ fi | |||
459 | # create a proxy version of the client config | 529 | # create a proxy version of the client config |
460 | ( | 530 | ( |
461 | cat $OBJ/ssh_config | 531 | cat $OBJ/ssh_config |
462 | echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSHD_LOGFILE} -i -f $OBJ/sshd_proxy | 532 | echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy |
463 | ) > $OBJ/ssh_proxy | 533 | ) > $OBJ/ssh_proxy |
464 | 534 | ||
465 | # check proxy config | 535 | # check proxy config |
diff --git a/regress/transfer.sh b/regress/transfer.sh index 1ae3ef5bf..36c14634a 100644 --- a/regress/transfer.sh +++ b/regress/transfer.sh | |||
@@ -1,9 +1,9 @@ | |||
1 | # $OpenBSD: transfer.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $ | 1 | # $OpenBSD: transfer.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="transfer data" | 4 | tid="transfer data" |
5 | 5 | ||
6 | for p in 1 2; do | 6 | for p in ${SSH_PROTOCOLS}; do |
7 | verbose "$tid: proto $p" | 7 | verbose "$tid: proto $p" |
8 | rm -f ${COPY} | 8 | rm -f ${COPY} |
9 | ${SSH} -n -q -$p -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY} | 9 | ${SSH} -n -q -$p -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY} |
diff --git a/regress/try-ciphers.sh b/regress/try-ciphers.sh index 2881ce16c..4165c7b88 100644 --- a/regress/try-ciphers.sh +++ b/regress/try-ciphers.sh | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: try-ciphers.sh,v 1.23 2014/04/21 22:15:37 djm Exp $ | 1 | # $OpenBSD: try-ciphers.sh,v 1.24 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="try ciphers" | 4 | tid="try ciphers" |
@@ -26,7 +26,11 @@ for c in `${SSH} -Q cipher`; do | |||
26 | done | 26 | done |
27 | done | 27 | done |
28 | 28 | ||
29 | ciphers="3des blowfish" | 29 | if ssh_version 1; then |
30 | ciphers="3des blowfish" | ||
31 | else | ||
32 | ciphers="" | ||
33 | fi | ||
30 | for c in $ciphers; do | 34 | for c in $ciphers; do |
31 | trace "proto 1 cipher $c" | 35 | trace "proto 1 cipher $c" |
32 | verbose "test $tid: proto 1 cipher $c" | 36 | verbose "test $tid: proto 1 cipher $c" |
diff --git a/regress/unittests/Makefile b/regress/unittests/Makefile index bdb4574e2..d3d90823f 100644 --- a/regress/unittests/Makefile +++ b/regress/unittests/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | # $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $ | 1 | # $OpenBSD: Makefile,v 1.5 2015/02/16 22:21:03 djm Exp $ |
2 | 2 | REGRESS_FAIL_EARLY= yes | |
3 | SUBDIR= test_helper sshbuf sshkey | 3 | SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys |
4 | 4 | ||
5 | .include <bsd.subdir.mk> | 5 | .include <bsd.subdir.mk> |
diff --git a/regress/unittests/Makefile.inc b/regress/unittests/Makefile.inc index 4c3363749..c55d00c61 100644 --- a/regress/unittests/Makefile.inc +++ b/regress/unittests/Makefile.inc | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile.inc,v 1.1 2014/04/30 05:32:00 djm Exp $ | 1 | # $OpenBSD: Makefile.inc,v 1.3 2015/01/23 21:21:23 miod Exp $ |
2 | 2 | ||
3 | .include <bsd.own.mk> | 3 | .include <bsd.own.mk> |
4 | .include <bsd.obj.mk> | 4 | .include <bsd.obj.mk> |
@@ -21,7 +21,6 @@ CDIAGFLAGS+= -Wmissing-declarations | |||
21 | CDIAGFLAGS+= -Wmissing-prototypes | 21 | CDIAGFLAGS+= -Wmissing-prototypes |
22 | CDIAGFLAGS+= -Wparentheses | 22 | CDIAGFLAGS+= -Wparentheses |
23 | CDIAGFLAGS+= -Wpointer-arith | 23 | CDIAGFLAGS+= -Wpointer-arith |
24 | CDIAGFLAGS+= -Wpointer-sign | ||
25 | CDIAGFLAGS+= -Wreturn-type | 24 | CDIAGFLAGS+= -Wreturn-type |
26 | CDIAGFLAGS+= -Wshadow | 25 | CDIAGFLAGS+= -Wshadow |
27 | CDIAGFLAGS+= -Wsign-compare | 26 | CDIAGFLAGS+= -Wsign-compare |
@@ -32,6 +31,7 @@ CDIAGFLAGS+= -Wtrigraphs | |||
32 | CDIAGFLAGS+= -Wuninitialized | 31 | CDIAGFLAGS+= -Wuninitialized |
33 | CDIAGFLAGS+= -Wunused | 32 | CDIAGFLAGS+= -Wunused |
34 | .if ${COMPILER_VERSION} == "gcc4" | 33 | .if ${COMPILER_VERSION} == "gcc4" |
34 | CDIAGFLAGS+= -Wpointer-sign | ||
35 | CDIAGFLAGS+= -Wold-style-definition | 35 | CDIAGFLAGS+= -Wold-style-definition |
36 | .endif | 36 | .endif |
37 | 37 | ||
diff --git a/regress/unittests/bitmap/Makefile b/regress/unittests/bitmap/Makefile new file mode 100644 index 000000000..b704d22d6 --- /dev/null +++ b/regress/unittests/bitmap/Makefile | |||
@@ -0,0 +1,12 @@ | |||
1 | # $OpenBSD: Makefile,v 1.1 2015/01/15 07:36:28 djm Exp $ | ||
2 | |||
3 | TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" | ||
4 | |||
5 | PROG=test_bitmap | ||
6 | SRCS=tests.c | ||
7 | REGRESS_TARGETS=run-regress-${PROG} | ||
8 | |||
9 | run-regress-${PROG}: ${PROG} | ||
10 | env ${TEST_ENV} ./${PROG} | ||
11 | |||
12 | .include <bsd.regress.mk> | ||
diff --git a/regress/unittests/bitmap/tests.c b/regress/unittests/bitmap/tests.c new file mode 100644 index 000000000..23025f90a --- /dev/null +++ b/regress/unittests/bitmap/tests.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* $OpenBSD: tests.c,v 1.1 2015/01/15 07:36:28 djm Exp $ */ | ||
2 | /* | ||
3 | * Regress test for bitmap.h bitmap API | ||
4 | * | ||
5 | * Placed in the public domain | ||
6 | */ | ||
7 | |||
8 | #include "includes.h" | ||
9 | |||
10 | #include <sys/types.h> | ||
11 | #include <sys/param.h> | ||
12 | #include <stdio.h> | ||
13 | #ifdef HAVE_STDINT_H | ||
14 | #include <stdint.h> | ||
15 | #endif | ||
16 | #include <stdlib.h> | ||
17 | #include <string.h> | ||
18 | |||
19 | #include <openssl/bn.h> | ||
20 | |||
21 | #include "../test_helper/test_helper.h" | ||
22 | |||
23 | #include "bitmap.h" | ||
24 | |||
25 | #define NTESTS 131 | ||
26 | |||
27 | void | ||
28 | tests(void) | ||
29 | { | ||
30 | struct bitmap *b; | ||
31 | BIGNUM *bn; | ||
32 | size_t len; | ||
33 | int i, j, k, n; | ||
34 | u_char bbuf[1024], bnbuf[1024]; | ||
35 | int r; | ||
36 | |||
37 | TEST_START("bitmap_new"); | ||
38 | b = bitmap_new(); | ||
39 | ASSERT_PTR_NE(b, NULL); | ||
40 | bn = BN_new(); | ||
41 | ASSERT_PTR_NE(bn, NULL); | ||
42 | TEST_DONE(); | ||
43 | |||
44 | TEST_START("bitmap_set_bit / bitmap_test_bit"); | ||
45 | for (i = -1; i < NTESTS; i++) { | ||
46 | for (j = -1; j < NTESTS; j++) { | ||
47 | for (k = -1; k < NTESTS; k++) { | ||
48 | bitmap_zero(b); | ||
49 | BN_clear(bn); | ||
50 | |||
51 | test_subtest_info("set %d/%d/%d", i, j, k); | ||
52 | /* Set bits */ | ||
53 | if (i >= 0) { | ||
54 | ASSERT_INT_EQ(bitmap_set_bit(b, i), 0); | ||
55 | ASSERT_INT_EQ(BN_set_bit(bn, i), 1); | ||
56 | } | ||
57 | if (j >= 0) { | ||
58 | ASSERT_INT_EQ(bitmap_set_bit(b, j), 0); | ||
59 | ASSERT_INT_EQ(BN_set_bit(bn, j), 1); | ||
60 | } | ||
61 | if (k >= 0) { | ||
62 | ASSERT_INT_EQ(bitmap_set_bit(b, k), 0); | ||
63 | ASSERT_INT_EQ(BN_set_bit(bn, k), 1); | ||
64 | } | ||
65 | |||
66 | /* Check perfect match between bitmap and bn */ | ||
67 | test_subtest_info("match %d/%d/%d", i, j, k); | ||
68 | for (n = 0; n < NTESTS; n++) { | ||
69 | ASSERT_INT_EQ(BN_is_bit_set(bn, n), | ||
70 | bitmap_test_bit(b, n)); | ||
71 | } | ||
72 | |||
73 | /* Test length calculations */ | ||
74 | test_subtest_info("length %d/%d/%d", i, j, k); | ||
75 | ASSERT_INT_EQ(BN_num_bits(bn), | ||
76 | (int)bitmap_nbits(b)); | ||
77 | ASSERT_INT_EQ(BN_num_bytes(bn), | ||
78 | (int)bitmap_nbytes(b)); | ||
79 | |||
80 | /* Test serialisation */ | ||
81 | test_subtest_info("serialise %d/%d/%d", | ||
82 | i, j, k); | ||
83 | len = bitmap_nbytes(b); | ||
84 | memset(bbuf, 0xfc, sizeof(bbuf)); | ||
85 | ASSERT_INT_EQ(bitmap_to_string(b, bbuf, | ||
86 | sizeof(bbuf)), 0); | ||
87 | for (n = len; n < (int)sizeof(bbuf); n++) | ||
88 | ASSERT_U8_EQ(bbuf[n], 0xfc); | ||
89 | r = BN_bn2bin(bn, bnbuf); | ||
90 | ASSERT_INT_GE(r, 0); | ||
91 | ASSERT_INT_EQ(r, (int)len); | ||
92 | ASSERT_MEM_EQ(bbuf, bnbuf, len); | ||
93 | |||
94 | /* Test deserialisation */ | ||
95 | test_subtest_info("deserialise %d/%d/%d", | ||
96 | i, j, k); | ||
97 | bitmap_zero(b); | ||
98 | ASSERT_INT_EQ(bitmap_from_string(b, bnbuf, | ||
99 | len), 0); | ||
100 | for (n = 0; n < NTESTS; n++) { | ||
101 | ASSERT_INT_EQ(BN_is_bit_set(bn, n), | ||
102 | bitmap_test_bit(b, n)); | ||
103 | } | ||
104 | |||
105 | /* Test clearing bits */ | ||
106 | test_subtest_info("clear %d/%d/%d", | ||
107 | i, j, k); | ||
108 | for (n = 0; n < NTESTS; n++) { | ||
109 | ASSERT_INT_EQ(bitmap_set_bit(b, n), 0); | ||
110 | ASSERT_INT_EQ(BN_set_bit(bn, n), 1); | ||
111 | } | ||
112 | if (i >= 0) { | ||
113 | bitmap_clear_bit(b, i); | ||
114 | BN_clear_bit(bn, i); | ||
115 | } | ||
116 | if (j >= 0) { | ||
117 | bitmap_clear_bit(b, j); | ||
118 | BN_clear_bit(bn, j); | ||
119 | } | ||
120 | if (k >= 0) { | ||
121 | bitmap_clear_bit(b, k); | ||
122 | BN_clear_bit(bn, k); | ||
123 | } | ||
124 | for (n = 0; n < NTESTS; n++) { | ||
125 | ASSERT_INT_EQ(BN_is_bit_set(bn, n), | ||
126 | bitmap_test_bit(b, n)); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | } | ||
131 | bitmap_free(b); | ||
132 | BN_free(bn); | ||
133 | TEST_DONE(); | ||
134 | } | ||
135 | |||
diff --git a/regress/unittests/hostkeys/Makefile b/regress/unittests/hostkeys/Makefile new file mode 100644 index 000000000..f52a85fb1 --- /dev/null +++ b/regress/unittests/hostkeys/Makefile | |||
@@ -0,0 +1,12 @@ | |||
1 | # $OpenBSD: Makefile,v 1.1 2015/02/16 22:18:34 djm Exp $ | ||
2 | |||
3 | TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" | ||
4 | |||
5 | PROG=test_hostkeys | ||
6 | SRCS=tests.c test_iterate.c | ||
7 | REGRESS_TARGETS=run-regress-${PROG} | ||
8 | |||
9 | run-regress-${PROG}: ${PROG} | ||
10 | env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata | ||
11 | |||
12 | .include <bsd.regress.mk> | ||
diff --git a/regress/unittests/hostkeys/mktestdata.sh b/regress/unittests/hostkeys/mktestdata.sh new file mode 100644 index 000000000..36890ba11 --- /dev/null +++ b/regress/unittests/hostkeys/mktestdata.sh | |||
@@ -0,0 +1,94 @@ | |||
1 | #!/bin/sh | ||
2 | # $OpenBSD: mktestdata.sh,v 1.1 2015/02/16 22:18:34 djm Exp $ | ||
3 | |||
4 | set -ex | ||
5 | |||
6 | cd testdata | ||
7 | |||
8 | rm -f rsa1* rsa* dsa* ecdsa* ed25519* | ||
9 | rm -f known_hosts* | ||
10 | |||
11 | gen_all() { | ||
12 | _n=$1 | ||
13 | _ecdsa_bits=256 | ||
14 | test "x$_n" = "x1" && _ecdsa_bits=384 | ||
15 | test "x$_n" = "x2" && _ecdsa_bits=521 | ||
16 | ssh-keygen -qt rsa1 -b 1024 -C "RSA1 #$_n" -N "" -f rsa1_$_n | ||
17 | ssh-keygen -qt rsa -b 1024 -C "RSA #$_n" -N "" -f rsa_$_n | ||
18 | ssh-keygen -qt dsa -b 1024 -C "DSA #$_n" -N "" -f dsa_$_n | ||
19 | ssh-keygen -qt ecdsa -b $_ecdsa_bits -C "ECDSA #$_n" -N "" -f ecdsa_$_n | ||
20 | ssh-keygen -qt ed25519 -C "ED25519 #$_n" -N "" -f ed25519_$_n | ||
21 | # Don't need private keys | ||
22 | rm -f rsa1_$_n rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n | ||
23 | } | ||
24 | |||
25 | hentries() { | ||
26 | _preamble=$1 | ||
27 | _kspec=$2 | ||
28 | for k in `ls -1 $_kspec | sort` ; do | ||
29 | printf "$_preamble " | ||
30 | cat $k | ||
31 | done | ||
32 | echo | ||
33 | } | ||
34 | |||
35 | gen_all 1 | ||
36 | gen_all 2 | ||
37 | gen_all 3 | ||
38 | gen_all 4 | ||
39 | gen_all 5 | ||
40 | gen_all 6 | ||
41 | |||
42 | # A section of known_hosts with hashed hostnames. | ||
43 | ( | ||
44 | hentries "sisyphus.example.com" "*_5.pub" | ||
45 | hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_6.pub" | ||
46 | ) > known_hosts_hash_frag | ||
47 | ssh-keygen -Hf known_hosts_hash_frag | ||
48 | rm -f known_hosts_hash_frag.old | ||
49 | |||
50 | # Populated known_hosts, including comments, hashed names and invalid lines | ||
51 | ( | ||
52 | echo "# Plain host keys, plain host names" | ||
53 | hentries "sisyphus.example.com" "*_1.pub" | ||
54 | |||
55 | echo "# Plain host keys, hostnames + addresses" | ||
56 | hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_2.pub" | ||
57 | |||
58 | echo "# Some hosts with wildcard names / IPs" | ||
59 | hentries "*.example.com,192.0.2.*,2001:*" "*_3.pub" | ||
60 | |||
61 | echo "# Hashed hostname and address entries" | ||
62 | cat known_hosts_hash_frag | ||
63 | rm -f known_hosts_hash_frag | ||
64 | echo | ||
65 | |||
66 | echo "# Revoked and CA keys" | ||
67 | printf "@revoked sisyphus.example.com " ; cat rsa1_4.pub | ||
68 | printf "@revoked sisyphus.example.com " ; cat ed25519_4.pub | ||
69 | printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub | ||
70 | printf "@cert-authority *.example.com " ; cat dsa_4.pub | ||
71 | |||
72 | printf "\n" | ||
73 | echo "# Some invalid lines" | ||
74 | # Invalid marker | ||
75 | printf "@what sisyphus.example.com " ; cat rsa1_1.pub | ||
76 | # Key missing | ||
77 | echo "sisyphus.example.com " | ||
78 | # Key blob missing | ||
79 | echo "prometheus.example.com ssh-ed25519 " | ||
80 | # Key blob truncated | ||
81 | echo "sisyphus.example.com ssh-dsa AAAATgAAAAdz" | ||
82 | # RSA1 key truncated after key bits | ||
83 | echo "prometheus.example.com 1024 " | ||
84 | # RSA1 key truncated after exponent | ||
85 | echo "sisyphus.example.com 1024 65535 " | ||
86 | # RSA1 key incorrect key bits | ||
87 | printf "prometheus.example.com 1025 " ; cut -d' ' -f2- < rsa1_1.pub | ||
88 | # Invalid type | ||
89 | echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" | ||
90 | # Type mismatch with blob | ||
91 | echo "prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" | ||
92 | ) > known_hosts | ||
93 | |||
94 | echo OK | ||
diff --git a/regress/unittests/hostkeys/test_iterate.c b/regress/unittests/hostkeys/test_iterate.c new file mode 100644 index 000000000..d81291b68 --- /dev/null +++ b/regress/unittests/hostkeys/test_iterate.c | |||
@@ -0,0 +1,1171 @@ | |||
1 | /* $OpenBSD: test_iterate.c,v 1.3 2015/03/07 04:41:48 djm Exp $ */ | ||
2 | /* | ||
3 | * Regress test for hostfile.h hostkeys_foreach() | ||
4 | * | ||
5 | * Placed in the public domain | ||
6 | */ | ||
7 | |||
8 | #include "includes.h" | ||
9 | |||
10 | #include <sys/types.h> | ||
11 | #include <sys/param.h> | ||
12 | #include <stdio.h> | ||
13 | #ifdef HAVE_STDINT_H | ||
14 | #include <stdint.h> | ||
15 | #endif | ||
16 | #include <stdlib.h> | ||
17 | #include <string.h> | ||
18 | |||
19 | #include "../test_helper/test_helper.h" | ||
20 | |||
21 | #include "sshkey.h" | ||
22 | #include "authfile.h" | ||
23 | #include "hostfile.h" | ||
24 | |||
25 | struct expected { | ||
26 | const char *key_file; /* Path for key, NULL for none */ | ||
27 | int no_parse_status; /* Expected status w/o key parsing */ | ||
28 | int no_parse_keytype; /* Expected keytype w/o key parsing */ | ||
29 | int match_host_p; /* Match 'prometheus.example.com' */ | ||
30 | int match_host_s; /* Match 'sisyphus.example.com' */ | ||
31 | int match_ipv4; /* Match '192.0.2.1' */ | ||
32 | int match_ipv6; /* Match '2001:db8::1' */ | ||
33 | int match_flags; /* Expected flags from match */ | ||
34 | struct hostkey_foreach_line l; /* Expected line contents */ | ||
35 | }; | ||
36 | |||
37 | struct cbctx { | ||
38 | const struct expected *expected; | ||
39 | size_t nexpected; | ||
40 | size_t i; | ||
41 | int flags; | ||
42 | int match_host_p; | ||
43 | int match_host_s; | ||
44 | int match_ipv4; | ||
45 | int match_ipv6; | ||
46 | }; | ||
47 | |||
48 | /* | ||
49 | * hostkeys_foreach() iterator callback that verifies the line passed | ||
50 | * against an array of expected entries. | ||
51 | */ | ||
52 | static int | ||
53 | check(struct hostkey_foreach_line *l, void *_ctx) | ||
54 | { | ||
55 | struct cbctx *ctx = (struct cbctx *)_ctx; | ||
56 | const struct expected *expected; | ||
57 | int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0; | ||
58 | const int matching = (ctx->flags & HKF_WANT_MATCH) != 0; | ||
59 | u_int expected_status, expected_match; | ||
60 | int expected_keytype; | ||
61 | |||
62 | test_subtest_info("entry %zu/%zu, file line %ld", | ||
63 | ctx->i + 1, ctx->nexpected, l->linenum); | ||
64 | |||
65 | for (;;) { | ||
66 | ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected); | ||
67 | expected = ctx->expected + ctx->i++; | ||
68 | /* If we are matching host/IP then skip entries that don't */ | ||
69 | if (!matching) | ||
70 | break; | ||
71 | if (ctx->match_host_p && expected->match_host_p) | ||
72 | break; | ||
73 | if (ctx->match_host_s && expected->match_host_s) | ||
74 | break; | ||
75 | if (ctx->match_ipv4 && expected->match_ipv4) | ||
76 | break; | ||
77 | if (ctx->match_ipv6 && expected->match_ipv6) | ||
78 | break; | ||
79 | } | ||
80 | expected_status = (parse_key || expected->no_parse_status < 0) ? | ||
81 | expected->l.status : (u_int)expected->no_parse_status; | ||
82 | expected_match = expected->l.match; | ||
83 | #define UPDATE_MATCH_STATUS(x) do { \ | ||
84 | if (ctx->x && expected->x) { \ | ||
85 | expected_match |= expected->x; \ | ||
86 | if (expected_status == HKF_STATUS_OK) \ | ||
87 | expected_status = HKF_STATUS_MATCHED; \ | ||
88 | } \ | ||
89 | } while (0) | ||
90 | expected_keytype = (parse_key || expected->no_parse_keytype < 0) ? | ||
91 | expected->l.keytype : expected->no_parse_keytype; | ||
92 | |||
93 | #ifndef WITH_SSH1 | ||
94 | if (expected->l.keytype == KEY_RSA1 || | ||
95 | expected->no_parse_keytype == KEY_RSA1) { | ||
96 | expected_status = HKF_STATUS_INVALID; | ||
97 | expected_keytype = KEY_UNSPEC; | ||
98 | parse_key = 0; | ||
99 | } | ||
100 | #endif | ||
101 | #ifndef OPENSSL_HAS_ECC | ||
102 | if (expected->l.keytype == KEY_ECDSA || | ||
103 | expected->no_parse_keytype == KEY_ECDSA) { | ||
104 | expected_status = HKF_STATUS_INVALID; | ||
105 | expected_keytype = KEY_UNSPEC; | ||
106 | parse_key = 0; | ||
107 | } | ||
108 | #endif | ||
109 | |||
110 | UPDATE_MATCH_STATUS(match_host_p); | ||
111 | UPDATE_MATCH_STATUS(match_host_s); | ||
112 | UPDATE_MATCH_STATUS(match_ipv4); | ||
113 | UPDATE_MATCH_STATUS(match_ipv6); | ||
114 | |||
115 | ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */ | ||
116 | ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum); | ||
117 | ASSERT_U_INT_EQ(l->status, expected_status); | ||
118 | ASSERT_U_INT_EQ(l->match, expected_match); | ||
119 | /* Not all test entries contain fulltext */ | ||
120 | if (expected->l.line != NULL) | ||
121 | ASSERT_STRING_EQ(l->line, expected->l.line); | ||
122 | ASSERT_INT_EQ(l->marker, expected->l.marker); | ||
123 | /* XXX we skip hashed hostnames for now; implement checking */ | ||
124 | if (expected->l.hosts != NULL) | ||
125 | ASSERT_STRING_EQ(l->hosts, expected->l.hosts); | ||
126 | /* Not all test entries contain raw keys */ | ||
127 | if (expected->l.rawkey != NULL) | ||
128 | ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey); | ||
129 | /* XXX synthesise raw key for cases lacking and compare */ | ||
130 | ASSERT_INT_EQ(l->keytype, expected_keytype); | ||
131 | if (parse_key) { | ||
132 | if (expected->l.key == NULL) | ||
133 | ASSERT_PTR_EQ(l->key, NULL); | ||
134 | if (expected->l.key != NULL) { | ||
135 | ASSERT_PTR_NE(l->key, NULL); | ||
136 | ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1); | ||
137 | } | ||
138 | } | ||
139 | if (parse_key && !(l->comment == NULL && expected->l.comment == NULL)) | ||
140 | ASSERT_STRING_EQ(l->comment, expected->l.comment); | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | /* Loads public keys for a set of expected results */ | ||
145 | static void | ||
146 | prepare_expected(struct expected *expected, size_t n) | ||
147 | { | ||
148 | size_t i; | ||
149 | |||
150 | for (i = 0; i < n; i++) { | ||
151 | if (expected[i].key_file == NULL) | ||
152 | continue; | ||
153 | #ifndef WITH_SSH1 | ||
154 | if (expected[i].l.keytype == KEY_RSA1) | ||
155 | continue; | ||
156 | #endif | ||
157 | #ifndef OPENSSL_HAS_ECC | ||
158 | if (expected[i].l.keytype == KEY_ECDSA) | ||
159 | continue; | ||
160 | #endif | ||
161 | ASSERT_INT_EQ(sshkey_load_public( | ||
162 | test_data_file(expected[i].key_file), &expected[i].l.key, | ||
163 | NULL), 0); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | struct expected expected_full[] = { | ||
168 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
169 | NULL, /* path, don't care */ | ||
170 | 1, /* line number */ | ||
171 | HKF_STATUS_COMMENT, /* status */ | ||
172 | 0, /* match flags */ | ||
173 | "# Plain host keys, plain host names", /* full line, optional */ | ||
174 | MRK_NONE, /* marker (CA / revoked) */ | ||
175 | NULL, /* hosts text */ | ||
176 | NULL, /* raw key, optional */ | ||
177 | KEY_UNSPEC, /* key type */ | ||
178 | NULL, /* deserialised key */ | ||
179 | NULL, /* comment */ | ||
180 | } }, | ||
181 | { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
182 | NULL, | ||
183 | 2, | ||
184 | HKF_STATUS_OK, | ||
185 | 0, | ||
186 | NULL, | ||
187 | MRK_NONE, | ||
188 | "sisyphus.example.com", | ||
189 | NULL, | ||
190 | KEY_DSA, | ||
191 | NULL, /* filled at runtime */ | ||
192 | "DSA #1", | ||
193 | } }, | ||
194 | { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
195 | NULL, | ||
196 | 3, | ||
197 | HKF_STATUS_OK, | ||
198 | 0, | ||
199 | NULL, | ||
200 | MRK_NONE, | ||
201 | "sisyphus.example.com", | ||
202 | NULL, | ||
203 | KEY_ECDSA, | ||
204 | NULL, /* filled at runtime */ | ||
205 | "ECDSA #1", | ||
206 | } }, | ||
207 | { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
208 | NULL, | ||
209 | 4, | ||
210 | HKF_STATUS_OK, | ||
211 | 0, | ||
212 | NULL, | ||
213 | MRK_NONE, | ||
214 | "sisyphus.example.com", | ||
215 | NULL, | ||
216 | KEY_ED25519, | ||
217 | NULL, /* filled at runtime */ | ||
218 | "ED25519 #1", | ||
219 | } }, | ||
220 | { "rsa1_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
221 | NULL, | ||
222 | 5, | ||
223 | HKF_STATUS_OK, | ||
224 | 0, | ||
225 | NULL, | ||
226 | MRK_NONE, | ||
227 | "sisyphus.example.com", | ||
228 | NULL, | ||
229 | KEY_RSA1, | ||
230 | NULL, /* filled at runtime */ | ||
231 | "RSA1 #1", | ||
232 | } }, | ||
233 | { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
234 | NULL, | ||
235 | 6, | ||
236 | HKF_STATUS_OK, | ||
237 | 0, | ||
238 | NULL, | ||
239 | MRK_NONE, | ||
240 | "sisyphus.example.com", | ||
241 | NULL, | ||
242 | KEY_RSA, | ||
243 | NULL, /* filled at runtime */ | ||
244 | "RSA #1", | ||
245 | } }, | ||
246 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
247 | NULL, | ||
248 | 7, | ||
249 | HKF_STATUS_COMMENT, | ||
250 | 0, | ||
251 | "", | ||
252 | MRK_NONE, | ||
253 | NULL, | ||
254 | NULL, | ||
255 | KEY_UNSPEC, | ||
256 | NULL, | ||
257 | NULL, | ||
258 | } }, | ||
259 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
260 | NULL, | ||
261 | 8, | ||
262 | HKF_STATUS_COMMENT, | ||
263 | 0, | ||
264 | "# Plain host keys, hostnames + addresses", | ||
265 | MRK_NONE, | ||
266 | NULL, | ||
267 | NULL, | ||
268 | KEY_UNSPEC, | ||
269 | NULL, | ||
270 | NULL, | ||
271 | } }, | ||
272 | { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
273 | NULL, | ||
274 | 9, | ||
275 | HKF_STATUS_OK, | ||
276 | 0, | ||
277 | NULL, | ||
278 | MRK_NONE, | ||
279 | "prometheus.example.com,192.0.2.1,2001:db8::1", | ||
280 | NULL, | ||
281 | KEY_DSA, | ||
282 | NULL, /* filled at runtime */ | ||
283 | "DSA #2", | ||
284 | } }, | ||
285 | { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
286 | NULL, | ||
287 | 10, | ||
288 | HKF_STATUS_OK, | ||
289 | 0, | ||
290 | NULL, | ||
291 | MRK_NONE, | ||
292 | "prometheus.example.com,192.0.2.1,2001:db8::1", | ||
293 | NULL, | ||
294 | KEY_ECDSA, | ||
295 | NULL, /* filled at runtime */ | ||
296 | "ECDSA #2", | ||
297 | } }, | ||
298 | { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
299 | NULL, | ||
300 | 11, | ||
301 | HKF_STATUS_OK, | ||
302 | 0, | ||
303 | NULL, | ||
304 | MRK_NONE, | ||
305 | "prometheus.example.com,192.0.2.1,2001:db8::1", | ||
306 | NULL, | ||
307 | KEY_ED25519, | ||
308 | NULL, /* filled at runtime */ | ||
309 | "ED25519 #2", | ||
310 | } }, | ||
311 | { "rsa1_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
312 | NULL, | ||
313 | 12, | ||
314 | HKF_STATUS_OK, | ||
315 | 0, | ||
316 | NULL, | ||
317 | MRK_NONE, | ||
318 | "prometheus.example.com,192.0.2.1,2001:db8::1", | ||
319 | NULL, | ||
320 | KEY_RSA1, | ||
321 | NULL, /* filled at runtime */ | ||
322 | "RSA1 #2", | ||
323 | } }, | ||
324 | { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
325 | NULL, | ||
326 | 13, | ||
327 | HKF_STATUS_OK, | ||
328 | 0, | ||
329 | NULL, | ||
330 | MRK_NONE, | ||
331 | "prometheus.example.com,192.0.2.1,2001:db8::1", | ||
332 | NULL, | ||
333 | KEY_RSA, | ||
334 | NULL, /* filled at runtime */ | ||
335 | "RSA #2", | ||
336 | } }, | ||
337 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
338 | NULL, | ||
339 | 14, | ||
340 | HKF_STATUS_COMMENT, | ||
341 | 0, | ||
342 | "", | ||
343 | MRK_NONE, | ||
344 | NULL, | ||
345 | NULL, | ||
346 | KEY_UNSPEC, | ||
347 | NULL, | ||
348 | NULL, | ||
349 | } }, | ||
350 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
351 | NULL, | ||
352 | 15, | ||
353 | HKF_STATUS_COMMENT, | ||
354 | 0, | ||
355 | "# Some hosts with wildcard names / IPs", | ||
356 | MRK_NONE, | ||
357 | NULL, | ||
358 | NULL, | ||
359 | KEY_UNSPEC, | ||
360 | NULL, | ||
361 | NULL, | ||
362 | } }, | ||
363 | { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
364 | NULL, | ||
365 | 16, | ||
366 | HKF_STATUS_OK, | ||
367 | 0, | ||
368 | NULL, | ||
369 | MRK_NONE, | ||
370 | "*.example.com,192.0.2.*,2001:*", | ||
371 | NULL, | ||
372 | KEY_DSA, | ||
373 | NULL, /* filled at runtime */ | ||
374 | "DSA #3", | ||
375 | } }, | ||
376 | { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
377 | NULL, | ||
378 | 17, | ||
379 | HKF_STATUS_OK, | ||
380 | 0, | ||
381 | NULL, | ||
382 | MRK_NONE, | ||
383 | "*.example.com,192.0.2.*,2001:*", | ||
384 | NULL, | ||
385 | KEY_ECDSA, | ||
386 | NULL, /* filled at runtime */ | ||
387 | "ECDSA #3", | ||
388 | } }, | ||
389 | { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
390 | NULL, | ||
391 | 18, | ||
392 | HKF_STATUS_OK, | ||
393 | 0, | ||
394 | NULL, | ||
395 | MRK_NONE, | ||
396 | "*.example.com,192.0.2.*,2001:*", | ||
397 | NULL, | ||
398 | KEY_ED25519, | ||
399 | NULL, /* filled at runtime */ | ||
400 | "ED25519 #3", | ||
401 | } }, | ||
402 | { "rsa1_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
403 | NULL, | ||
404 | 19, | ||
405 | HKF_STATUS_OK, | ||
406 | 0, | ||
407 | NULL, | ||
408 | MRK_NONE, | ||
409 | "*.example.com,192.0.2.*,2001:*", | ||
410 | NULL, | ||
411 | KEY_RSA1, | ||
412 | NULL, /* filled at runtime */ | ||
413 | "RSA1 #3", | ||
414 | } }, | ||
415 | { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { | ||
416 | NULL, | ||
417 | 20, | ||
418 | HKF_STATUS_OK, | ||
419 | 0, | ||
420 | NULL, | ||
421 | MRK_NONE, | ||
422 | "*.example.com,192.0.2.*,2001:*", | ||
423 | NULL, | ||
424 | KEY_RSA, | ||
425 | NULL, /* filled at runtime */ | ||
426 | "RSA #3", | ||
427 | } }, | ||
428 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
429 | NULL, | ||
430 | 21, | ||
431 | HKF_STATUS_COMMENT, | ||
432 | 0, | ||
433 | "", | ||
434 | MRK_NONE, | ||
435 | NULL, | ||
436 | NULL, | ||
437 | KEY_UNSPEC, | ||
438 | NULL, | ||
439 | NULL, | ||
440 | } }, | ||
441 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
442 | NULL, | ||
443 | 22, | ||
444 | HKF_STATUS_COMMENT, | ||
445 | 0, | ||
446 | "# Hashed hostname and address entries", | ||
447 | MRK_NONE, | ||
448 | NULL, | ||
449 | NULL, | ||
450 | KEY_UNSPEC, | ||
451 | NULL, | ||
452 | NULL, | ||
453 | } }, | ||
454 | { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { | ||
455 | NULL, | ||
456 | 23, | ||
457 | HKF_STATUS_OK, | ||
458 | 0, | ||
459 | NULL, | ||
460 | MRK_NONE, | ||
461 | NULL, | ||
462 | NULL, | ||
463 | KEY_DSA, | ||
464 | NULL, /* filled at runtime */ | ||
465 | "DSA #5", | ||
466 | } }, | ||
467 | { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { | ||
468 | NULL, | ||
469 | 24, | ||
470 | HKF_STATUS_OK, | ||
471 | 0, | ||
472 | NULL, | ||
473 | MRK_NONE, | ||
474 | NULL, | ||
475 | NULL, | ||
476 | KEY_ECDSA, | ||
477 | NULL, /* filled at runtime */ | ||
478 | "ECDSA #5", | ||
479 | } }, | ||
480 | { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { | ||
481 | NULL, | ||
482 | 25, | ||
483 | HKF_STATUS_OK, | ||
484 | 0, | ||
485 | NULL, | ||
486 | MRK_NONE, | ||
487 | NULL, | ||
488 | NULL, | ||
489 | KEY_ED25519, | ||
490 | NULL, /* filled at runtime */ | ||
491 | "ED25519 #5", | ||
492 | } }, | ||
493 | { "rsa1_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { | ||
494 | NULL, | ||
495 | 26, | ||
496 | HKF_STATUS_OK, | ||
497 | 0, | ||
498 | NULL, | ||
499 | MRK_NONE, | ||
500 | NULL, | ||
501 | NULL, | ||
502 | KEY_RSA1, | ||
503 | NULL, /* filled at runtime */ | ||
504 | "RSA1 #5", | ||
505 | } }, | ||
506 | { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { | ||
507 | NULL, | ||
508 | 27, | ||
509 | HKF_STATUS_OK, | ||
510 | 0, | ||
511 | NULL, | ||
512 | MRK_NONE, | ||
513 | NULL, | ||
514 | NULL, | ||
515 | KEY_RSA, | ||
516 | NULL, /* filled at runtime */ | ||
517 | "RSA #5", | ||
518 | } }, | ||
519 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
520 | NULL, | ||
521 | 28, | ||
522 | HKF_STATUS_COMMENT, | ||
523 | 0, | ||
524 | "", | ||
525 | MRK_NONE, | ||
526 | NULL, | ||
527 | NULL, | ||
528 | KEY_UNSPEC, | ||
529 | NULL, | ||
530 | NULL, | ||
531 | } }, | ||
532 | /* | ||
533 | * The next series have each key listed multiple times, as the | ||
534 | * hostname and addresses in the pre-hashed known_hosts are split | ||
535 | * to separate lines. | ||
536 | */ | ||
537 | { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { | ||
538 | NULL, | ||
539 | 29, | ||
540 | HKF_STATUS_OK, | ||
541 | 0, | ||
542 | NULL, | ||
543 | MRK_NONE, | ||
544 | NULL, | ||
545 | NULL, | ||
546 | KEY_DSA, | ||
547 | NULL, /* filled at runtime */ | ||
548 | "DSA #6", | ||
549 | } }, | ||
550 | { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { | ||
551 | NULL, | ||
552 | 30, | ||
553 | HKF_STATUS_OK, | ||
554 | 0, | ||
555 | NULL, | ||
556 | MRK_NONE, | ||
557 | NULL, | ||
558 | NULL, | ||
559 | KEY_DSA, | ||
560 | NULL, /* filled at runtime */ | ||
561 | "DSA #6", | ||
562 | } }, | ||
563 | { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { | ||
564 | NULL, | ||
565 | 31, | ||
566 | HKF_STATUS_OK, | ||
567 | 0, | ||
568 | NULL, | ||
569 | MRK_NONE, | ||
570 | NULL, | ||
571 | NULL, | ||
572 | KEY_DSA, | ||
573 | NULL, /* filled at runtime */ | ||
574 | "DSA #6", | ||
575 | } }, | ||
576 | { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { | ||
577 | NULL, | ||
578 | 32, | ||
579 | HKF_STATUS_OK, | ||
580 | 0, | ||
581 | NULL, | ||
582 | MRK_NONE, | ||
583 | NULL, | ||
584 | NULL, | ||
585 | KEY_ECDSA, | ||
586 | NULL, /* filled at runtime */ | ||
587 | "ECDSA #6", | ||
588 | } }, | ||
589 | { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { | ||
590 | NULL, | ||
591 | 33, | ||
592 | HKF_STATUS_OK, | ||
593 | 0, | ||
594 | NULL, | ||
595 | MRK_NONE, | ||
596 | NULL, | ||
597 | NULL, | ||
598 | KEY_ECDSA, | ||
599 | NULL, /* filled at runtime */ | ||
600 | "ECDSA #6", | ||
601 | } }, | ||
602 | { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { | ||
603 | NULL, | ||
604 | 34, | ||
605 | HKF_STATUS_OK, | ||
606 | 0, | ||
607 | NULL, | ||
608 | MRK_NONE, | ||
609 | NULL, | ||
610 | NULL, | ||
611 | KEY_ECDSA, | ||
612 | NULL, /* filled at runtime */ | ||
613 | "ECDSA #6", | ||
614 | } }, | ||
615 | { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { | ||
616 | NULL, | ||
617 | 35, | ||
618 | HKF_STATUS_OK, | ||
619 | 0, | ||
620 | NULL, | ||
621 | MRK_NONE, | ||
622 | NULL, | ||
623 | NULL, | ||
624 | KEY_ED25519, | ||
625 | NULL, /* filled at runtime */ | ||
626 | "ED25519 #6", | ||
627 | } }, | ||
628 | { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { | ||
629 | NULL, | ||
630 | 36, | ||
631 | HKF_STATUS_OK, | ||
632 | 0, | ||
633 | NULL, | ||
634 | MRK_NONE, | ||
635 | NULL, | ||
636 | NULL, | ||
637 | KEY_ED25519, | ||
638 | NULL, /* filled at runtime */ | ||
639 | "ED25519 #6", | ||
640 | } }, | ||
641 | { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { | ||
642 | NULL, | ||
643 | 37, | ||
644 | HKF_STATUS_OK, | ||
645 | 0, | ||
646 | NULL, | ||
647 | MRK_NONE, | ||
648 | NULL, | ||
649 | NULL, | ||
650 | KEY_ED25519, | ||
651 | NULL, /* filled at runtime */ | ||
652 | "ED25519 #6", | ||
653 | } }, | ||
654 | { "rsa1_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { | ||
655 | NULL, | ||
656 | 38, | ||
657 | HKF_STATUS_OK, | ||
658 | 0, | ||
659 | NULL, | ||
660 | MRK_NONE, | ||
661 | NULL, | ||
662 | NULL, | ||
663 | KEY_RSA1, | ||
664 | NULL, /* filled at runtime */ | ||
665 | "RSA1 #6", | ||
666 | } }, | ||
667 | { "rsa1_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { | ||
668 | NULL, | ||
669 | 39, | ||
670 | HKF_STATUS_OK, | ||
671 | 0, | ||
672 | NULL, | ||
673 | MRK_NONE, | ||
674 | NULL, | ||
675 | NULL, | ||
676 | KEY_RSA1, | ||
677 | NULL, /* filled at runtime */ | ||
678 | "RSA1 #6", | ||
679 | } }, | ||
680 | { "rsa1_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { | ||
681 | NULL, | ||
682 | 40, | ||
683 | HKF_STATUS_OK, | ||
684 | 0, | ||
685 | NULL, | ||
686 | MRK_NONE, | ||
687 | NULL, | ||
688 | NULL, | ||
689 | KEY_RSA1, | ||
690 | NULL, /* filled at runtime */ | ||
691 | "RSA1 #6", | ||
692 | } }, | ||
693 | { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { | ||
694 | NULL, | ||
695 | 41, | ||
696 | HKF_STATUS_OK, | ||
697 | 0, | ||
698 | NULL, | ||
699 | MRK_NONE, | ||
700 | NULL, | ||
701 | NULL, | ||
702 | KEY_RSA, | ||
703 | NULL, /* filled at runtime */ | ||
704 | "RSA #6", | ||
705 | } }, | ||
706 | { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { | ||
707 | NULL, | ||
708 | 42, | ||
709 | HKF_STATUS_OK, | ||
710 | 0, | ||
711 | NULL, | ||
712 | MRK_NONE, | ||
713 | NULL, | ||
714 | NULL, | ||
715 | KEY_RSA, | ||
716 | NULL, /* filled at runtime */ | ||
717 | "RSA #6", | ||
718 | } }, | ||
719 | { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { | ||
720 | NULL, | ||
721 | 43, | ||
722 | HKF_STATUS_OK, | ||
723 | 0, | ||
724 | NULL, | ||
725 | MRK_NONE, | ||
726 | NULL, | ||
727 | NULL, | ||
728 | KEY_RSA, | ||
729 | NULL, /* filled at runtime */ | ||
730 | "RSA #6", | ||
731 | } }, | ||
732 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
733 | NULL, | ||
734 | 44, | ||
735 | HKF_STATUS_COMMENT, | ||
736 | 0, | ||
737 | "", | ||
738 | MRK_NONE, | ||
739 | NULL, | ||
740 | NULL, | ||
741 | KEY_UNSPEC, | ||
742 | NULL, | ||
743 | NULL, | ||
744 | } }, | ||
745 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
746 | NULL, | ||
747 | 45, | ||
748 | HKF_STATUS_COMMENT, | ||
749 | 0, | ||
750 | "", | ||
751 | MRK_NONE, | ||
752 | NULL, | ||
753 | NULL, | ||
754 | KEY_UNSPEC, | ||
755 | NULL, | ||
756 | NULL, | ||
757 | } }, | ||
758 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
759 | NULL, | ||
760 | 46, | ||
761 | HKF_STATUS_COMMENT, | ||
762 | 0, | ||
763 | "# Revoked and CA keys", | ||
764 | MRK_NONE, | ||
765 | NULL, | ||
766 | NULL, | ||
767 | KEY_UNSPEC, | ||
768 | NULL, | ||
769 | NULL, | ||
770 | } }, | ||
771 | { "rsa1_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
772 | NULL, | ||
773 | 47, | ||
774 | HKF_STATUS_OK, | ||
775 | 0, | ||
776 | NULL, | ||
777 | MRK_REVOKE, | ||
778 | "sisyphus.example.com", | ||
779 | NULL, | ||
780 | KEY_RSA1, | ||
781 | NULL, /* filled at runtime */ | ||
782 | "RSA1 #4", | ||
783 | } }, | ||
784 | { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
785 | NULL, | ||
786 | 48, | ||
787 | HKF_STATUS_OK, | ||
788 | 0, | ||
789 | NULL, | ||
790 | MRK_REVOKE, | ||
791 | "sisyphus.example.com", | ||
792 | NULL, | ||
793 | KEY_ED25519, | ||
794 | NULL, /* filled at runtime */ | ||
795 | "ED25519 #4", | ||
796 | } }, | ||
797 | { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { | ||
798 | NULL, | ||
799 | 49, | ||
800 | HKF_STATUS_OK, | ||
801 | 0, | ||
802 | NULL, | ||
803 | MRK_CA, | ||
804 | "prometheus.example.com", | ||
805 | NULL, | ||
806 | KEY_ECDSA, | ||
807 | NULL, /* filled at runtime */ | ||
808 | "ECDSA #4", | ||
809 | } }, | ||
810 | { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, { | ||
811 | NULL, | ||
812 | 50, | ||
813 | HKF_STATUS_OK, | ||
814 | 0, | ||
815 | NULL, | ||
816 | MRK_CA, | ||
817 | "*.example.com", | ||
818 | NULL, | ||
819 | KEY_DSA, | ||
820 | NULL, /* filled at runtime */ | ||
821 | "DSA #4", | ||
822 | } }, | ||
823 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
824 | NULL, | ||
825 | 51, | ||
826 | HKF_STATUS_COMMENT, | ||
827 | 0, | ||
828 | "", | ||
829 | MRK_NONE, | ||
830 | NULL, | ||
831 | NULL, | ||
832 | KEY_UNSPEC, | ||
833 | NULL, | ||
834 | NULL, | ||
835 | } }, | ||
836 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
837 | NULL, | ||
838 | 52, | ||
839 | HKF_STATUS_COMMENT, | ||
840 | 0, | ||
841 | "# Some invalid lines", | ||
842 | MRK_NONE, | ||
843 | NULL, | ||
844 | NULL, | ||
845 | KEY_UNSPEC, | ||
846 | NULL, | ||
847 | NULL, | ||
848 | } }, | ||
849 | { NULL, -1, -1, 0, 0, 0, 0, -1, { | ||
850 | NULL, | ||
851 | 53, | ||
852 | HKF_STATUS_INVALID, | ||
853 | 0, | ||
854 | NULL, | ||
855 | MRK_ERROR, | ||
856 | NULL, | ||
857 | NULL, | ||
858 | KEY_UNSPEC, | ||
859 | NULL, | ||
860 | NULL, | ||
861 | } }, | ||
862 | { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
863 | NULL, | ||
864 | 54, | ||
865 | HKF_STATUS_INVALID, | ||
866 | 0, | ||
867 | NULL, | ||
868 | MRK_NONE, | ||
869 | "sisyphus.example.com", | ||
870 | NULL, | ||
871 | KEY_UNSPEC, | ||
872 | NULL, | ||
873 | NULL, | ||
874 | } }, | ||
875 | { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { | ||
876 | NULL, | ||
877 | 55, | ||
878 | HKF_STATUS_INVALID, | ||
879 | 0, | ||
880 | NULL, | ||
881 | MRK_NONE, | ||
882 | "prometheus.example.com", | ||
883 | NULL, | ||
884 | KEY_UNSPEC, | ||
885 | NULL, | ||
886 | NULL, | ||
887 | } }, | ||
888 | { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
889 | NULL, | ||
890 | 56, | ||
891 | HKF_STATUS_INVALID, /* Would be ok if key not parsed */ | ||
892 | 0, | ||
893 | NULL, | ||
894 | MRK_NONE, | ||
895 | "sisyphus.example.com", | ||
896 | NULL, | ||
897 | KEY_UNSPEC, | ||
898 | NULL, | ||
899 | NULL, | ||
900 | } }, | ||
901 | { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { | ||
902 | NULL, | ||
903 | 57, | ||
904 | HKF_STATUS_INVALID, /* Would be ok if key not parsed */ | ||
905 | 0, | ||
906 | NULL, | ||
907 | MRK_NONE, | ||
908 | "prometheus.example.com", | ||
909 | NULL, | ||
910 | KEY_UNSPEC, | ||
911 | NULL, | ||
912 | NULL, | ||
913 | } }, | ||
914 | { NULL, HKF_STATUS_OK, KEY_RSA1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
915 | NULL, | ||
916 | 58, | ||
917 | HKF_STATUS_INVALID, /* Would be ok if key not parsed */ | ||
918 | 0, | ||
919 | NULL, | ||
920 | MRK_NONE, | ||
921 | "sisyphus.example.com", | ||
922 | NULL, | ||
923 | KEY_UNSPEC, | ||
924 | NULL, | ||
925 | NULL, | ||
926 | } }, | ||
927 | { NULL, HKF_STATUS_OK, KEY_RSA1, HKF_MATCH_HOST, 0, 0, 0, -1, { | ||
928 | NULL, | ||
929 | 59, | ||
930 | HKF_STATUS_INVALID, /* Would be ok if key not parsed */ | ||
931 | 0, | ||
932 | NULL, | ||
933 | MRK_NONE, | ||
934 | "prometheus.example.com", | ||
935 | NULL, | ||
936 | KEY_UNSPEC, | ||
937 | NULL, /* filled at runtime */ | ||
938 | NULL, | ||
939 | } }, | ||
940 | { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { | ||
941 | NULL, | ||
942 | 60, | ||
943 | HKF_STATUS_INVALID, | ||
944 | 0, | ||
945 | NULL, | ||
946 | MRK_NONE, | ||
947 | "sisyphus.example.com", | ||
948 | NULL, | ||
949 | KEY_UNSPEC, | ||
950 | NULL, /* filled at runtime */ | ||
951 | NULL, | ||
952 | } }, | ||
953 | { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, { | ||
954 | NULL, | ||
955 | 61, | ||
956 | HKF_STATUS_INVALID, /* Would be ok if key not parsed */ | ||
957 | 0, | ||
958 | NULL, | ||
959 | MRK_NONE, | ||
960 | "prometheus.example.com", | ||
961 | NULL, | ||
962 | KEY_UNSPEC, | ||
963 | NULL, /* filled at runtime */ | ||
964 | NULL, | ||
965 | } }, | ||
966 | }; | ||
967 | |||
968 | void test_iterate(void); | ||
969 | |||
970 | void | ||
971 | test_iterate(void) | ||
972 | { | ||
973 | struct cbctx ctx; | ||
974 | |||
975 | TEST_START("hostkeys_iterate all with key parse"); | ||
976 | memset(&ctx, 0, sizeof(ctx)); | ||
977 | ctx.expected = expected_full; | ||
978 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
979 | ctx.flags = HKF_WANT_PARSE_KEY; | ||
980 | prepare_expected(expected_full, ctx.nexpected); | ||
981 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
982 | check, &ctx, NULL, NULL, ctx.flags), 0); | ||
983 | TEST_DONE(); | ||
984 | |||
985 | TEST_START("hostkeys_iterate all without key parse"); | ||
986 | memset(&ctx, 0, sizeof(ctx)); | ||
987 | ctx.expected = expected_full; | ||
988 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
989 | ctx.flags = 0; | ||
990 | prepare_expected(expected_full, ctx.nexpected); | ||
991 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
992 | check, &ctx, NULL, NULL, ctx.flags), 0); | ||
993 | TEST_DONE(); | ||
994 | |||
995 | TEST_START("hostkeys_iterate specify host 1"); | ||
996 | memset(&ctx, 0, sizeof(ctx)); | ||
997 | ctx.expected = expected_full; | ||
998 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
999 | ctx.flags = 0; | ||
1000 | ctx.match_host_p = 1; | ||
1001 | prepare_expected(expected_full, ctx.nexpected); | ||
1002 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1003 | check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0); | ||
1004 | TEST_DONE(); | ||
1005 | |||
1006 | TEST_START("hostkeys_iterate specify host 2"); | ||
1007 | memset(&ctx, 0, sizeof(ctx)); | ||
1008 | ctx.expected = expected_full; | ||
1009 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1010 | ctx.flags = 0; | ||
1011 | ctx.match_host_s = 1; | ||
1012 | prepare_expected(expected_full, ctx.nexpected); | ||
1013 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1014 | check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0); | ||
1015 | TEST_DONE(); | ||
1016 | |||
1017 | TEST_START("hostkeys_iterate match host 1"); | ||
1018 | memset(&ctx, 0, sizeof(ctx)); | ||
1019 | ctx.expected = expected_full; | ||
1020 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1021 | ctx.flags = HKF_WANT_MATCH; | ||
1022 | ctx.match_host_p = 1; | ||
1023 | prepare_expected(expected_full, ctx.nexpected); | ||
1024 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1025 | check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0); | ||
1026 | TEST_DONE(); | ||
1027 | |||
1028 | TEST_START("hostkeys_iterate match host 2"); | ||
1029 | memset(&ctx, 0, sizeof(ctx)); | ||
1030 | ctx.expected = expected_full; | ||
1031 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1032 | ctx.flags = HKF_WANT_MATCH; | ||
1033 | ctx.match_host_s = 1; | ||
1034 | prepare_expected(expected_full, ctx.nexpected); | ||
1035 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1036 | check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0); | ||
1037 | TEST_DONE(); | ||
1038 | |||
1039 | TEST_START("hostkeys_iterate specify host missing"); | ||
1040 | memset(&ctx, 0, sizeof(ctx)); | ||
1041 | ctx.expected = expected_full; | ||
1042 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1043 | ctx.flags = 0; | ||
1044 | prepare_expected(expected_full, ctx.nexpected); | ||
1045 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1046 | check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0); | ||
1047 | TEST_DONE(); | ||
1048 | |||
1049 | TEST_START("hostkeys_iterate match host missing"); | ||
1050 | memset(&ctx, 0, sizeof(ctx)); | ||
1051 | ctx.expected = expected_full; | ||
1052 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1053 | ctx.flags = HKF_WANT_MATCH; | ||
1054 | prepare_expected(expected_full, ctx.nexpected); | ||
1055 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1056 | check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0); | ||
1057 | TEST_DONE(); | ||
1058 | |||
1059 | TEST_START("hostkeys_iterate specify IPv4"); | ||
1060 | memset(&ctx, 0, sizeof(ctx)); | ||
1061 | ctx.expected = expected_full; | ||
1062 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1063 | ctx.flags = 0; | ||
1064 | ctx.match_ipv4 = 1; | ||
1065 | prepare_expected(expected_full, ctx.nexpected); | ||
1066 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1067 | check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0); | ||
1068 | TEST_DONE(); | ||
1069 | |||
1070 | TEST_START("hostkeys_iterate specify IPv6"); | ||
1071 | memset(&ctx, 0, sizeof(ctx)); | ||
1072 | ctx.expected = expected_full; | ||
1073 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1074 | ctx.flags = 0; | ||
1075 | ctx.match_ipv6 = 1; | ||
1076 | prepare_expected(expected_full, ctx.nexpected); | ||
1077 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1078 | check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0); | ||
1079 | TEST_DONE(); | ||
1080 | |||
1081 | TEST_START("hostkeys_iterate match IPv4"); | ||
1082 | memset(&ctx, 0, sizeof(ctx)); | ||
1083 | ctx.expected = expected_full; | ||
1084 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1085 | ctx.flags = HKF_WANT_MATCH; | ||
1086 | ctx.match_ipv4 = 1; | ||
1087 | prepare_expected(expected_full, ctx.nexpected); | ||
1088 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1089 | check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0); | ||
1090 | TEST_DONE(); | ||
1091 | |||
1092 | TEST_START("hostkeys_iterate match IPv6"); | ||
1093 | memset(&ctx, 0, sizeof(ctx)); | ||
1094 | ctx.expected = expected_full; | ||
1095 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1096 | ctx.flags = HKF_WANT_MATCH; | ||
1097 | ctx.match_ipv6 = 1; | ||
1098 | prepare_expected(expected_full, ctx.nexpected); | ||
1099 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1100 | check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0); | ||
1101 | TEST_DONE(); | ||
1102 | |||
1103 | TEST_START("hostkeys_iterate specify addr missing"); | ||
1104 | memset(&ctx, 0, sizeof(ctx)); | ||
1105 | ctx.expected = expected_full; | ||
1106 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1107 | ctx.flags = 0; | ||
1108 | prepare_expected(expected_full, ctx.nexpected); | ||
1109 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1110 | check, &ctx, "tiresias.example.org", "192.168.0.1", ctx.flags), 0); | ||
1111 | TEST_DONE(); | ||
1112 | |||
1113 | TEST_START("hostkeys_iterate match addr missing"); | ||
1114 | memset(&ctx, 0, sizeof(ctx)); | ||
1115 | ctx.expected = expected_full; | ||
1116 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1117 | ctx.flags = HKF_WANT_MATCH; | ||
1118 | prepare_expected(expected_full, ctx.nexpected); | ||
1119 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1120 | check, &ctx, "tiresias.example.org", "::1", ctx.flags), 0); | ||
1121 | TEST_DONE(); | ||
1122 | |||
1123 | TEST_START("hostkeys_iterate specify host 2 and IPv4"); | ||
1124 | memset(&ctx, 0, sizeof(ctx)); | ||
1125 | ctx.expected = expected_full; | ||
1126 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1127 | ctx.flags = 0; | ||
1128 | ctx.match_host_s = 1; | ||
1129 | ctx.match_ipv4 = 1; | ||
1130 | prepare_expected(expected_full, ctx.nexpected); | ||
1131 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1132 | check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0); | ||
1133 | TEST_DONE(); | ||
1134 | |||
1135 | TEST_START("hostkeys_iterate match host 1 and IPv6"); | ||
1136 | memset(&ctx, 0, sizeof(ctx)); | ||
1137 | ctx.expected = expected_full; | ||
1138 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1139 | ctx.flags = HKF_WANT_MATCH; | ||
1140 | ctx.match_host_p = 1; | ||
1141 | ctx.match_ipv6 = 1; | ||
1142 | prepare_expected(expected_full, ctx.nexpected); | ||
1143 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1144 | check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0); | ||
1145 | TEST_DONE(); | ||
1146 | |||
1147 | TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse"); | ||
1148 | memset(&ctx, 0, sizeof(ctx)); | ||
1149 | ctx.expected = expected_full; | ||
1150 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1151 | ctx.flags = HKF_WANT_PARSE_KEY; | ||
1152 | ctx.match_host_s = 1; | ||
1153 | ctx.match_ipv4 = 1; | ||
1154 | prepare_expected(expected_full, ctx.nexpected); | ||
1155 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1156 | check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0); | ||
1157 | TEST_DONE(); | ||
1158 | |||
1159 | TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse"); | ||
1160 | memset(&ctx, 0, sizeof(ctx)); | ||
1161 | ctx.expected = expected_full; | ||
1162 | ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); | ||
1163 | ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY; | ||
1164 | ctx.match_host_p = 1; | ||
1165 | ctx.match_ipv6 = 1; | ||
1166 | prepare_expected(expected_full, ctx.nexpected); | ||
1167 | ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), | ||
1168 | check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0); | ||
1169 | TEST_DONE(); | ||
1170 | } | ||
1171 | |||
diff --git a/regress/unittests/hostkeys/testdata/dsa_1.pub b/regress/unittests/hostkeys/testdata/dsa_1.pub new file mode 100644 index 000000000..56e1e3714 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/dsa_1.pub | |||
@@ -0,0 +1 @@ | |||
ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 | |||
diff --git a/regress/unittests/hostkeys/testdata/dsa_2.pub b/regress/unittests/hostkeys/testdata/dsa_2.pub new file mode 100644 index 000000000..394e0bf00 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/dsa_2.pub | |||
@@ -0,0 +1 @@ | |||
ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 | |||
diff --git a/regress/unittests/hostkeys/testdata/dsa_3.pub b/regress/unittests/hostkeys/testdata/dsa_3.pub new file mode 100644 index 000000000..e506ea422 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/dsa_3.pub | |||
@@ -0,0 +1 @@ | |||
ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 | |||
diff --git a/regress/unittests/hostkeys/testdata/dsa_4.pub b/regress/unittests/hostkeys/testdata/dsa_4.pub new file mode 100644 index 000000000..8552c3819 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/dsa_4.pub | |||
@@ -0,0 +1 @@ | |||
ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 | |||
diff --git a/regress/unittests/hostkeys/testdata/dsa_5.pub b/regress/unittests/hostkeys/testdata/dsa_5.pub new file mode 100644 index 000000000..149e1efd1 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/dsa_5.pub | |||
@@ -0,0 +1 @@ | |||
ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 | |||
diff --git a/regress/unittests/hostkeys/testdata/dsa_6.pub b/regress/unittests/hostkeys/testdata/dsa_6.pub new file mode 100644 index 000000000..edbb97643 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/dsa_6.pub | |||
@@ -0,0 +1 @@ | |||
ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 | |||
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_1.pub b/regress/unittests/hostkeys/testdata/ecdsa_1.pub new file mode 100644 index 000000000..16a535bcc --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ecdsa_1.pub | |||
@@ -0,0 +1 @@ | |||
ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 | |||
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_2.pub b/regress/unittests/hostkeys/testdata/ecdsa_2.pub new file mode 100644 index 000000000..d2bad11e2 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ecdsa_2.pub | |||
@@ -0,0 +1 @@ | |||
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 | |||
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_3.pub b/regress/unittests/hostkeys/testdata/ecdsa_3.pub new file mode 100644 index 000000000..e3ea9254e --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ecdsa_3.pub | |||
@@ -0,0 +1 @@ | |||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 | |||
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_4.pub b/regress/unittests/hostkeys/testdata/ecdsa_4.pub new file mode 100644 index 000000000..2d616f5c6 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ecdsa_4.pub | |||
@@ -0,0 +1 @@ | |||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 | |||
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_5.pub b/regress/unittests/hostkeys/testdata/ecdsa_5.pub new file mode 100644 index 000000000..a3df9b3f4 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ecdsa_5.pub | |||
@@ -0,0 +1 @@ | |||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 | |||
diff --git a/regress/unittests/hostkeys/testdata/ecdsa_6.pub b/regress/unittests/hostkeys/testdata/ecdsa_6.pub new file mode 100644 index 000000000..139f5a7bf --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ecdsa_6.pub | |||
@@ -0,0 +1 @@ | |||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 | |||
diff --git a/regress/unittests/hostkeys/testdata/ed25519_1.pub b/regress/unittests/hostkeys/testdata/ed25519_1.pub new file mode 100644 index 000000000..0b12efedb --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ed25519_1.pub | |||
@@ -0,0 +1 @@ | |||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 | |||
diff --git a/regress/unittests/hostkeys/testdata/ed25519_2.pub b/regress/unittests/hostkeys/testdata/ed25519_2.pub new file mode 100644 index 000000000..78e262bcc --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ed25519_2.pub | |||
@@ -0,0 +1 @@ | |||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 | |||
diff --git a/regress/unittests/hostkeys/testdata/ed25519_3.pub b/regress/unittests/hostkeys/testdata/ed25519_3.pub new file mode 100644 index 000000000..64e5f12a6 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ed25519_3.pub | |||
@@ -0,0 +1 @@ | |||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 | |||
diff --git a/regress/unittests/hostkeys/testdata/ed25519_4.pub b/regress/unittests/hostkeys/testdata/ed25519_4.pub new file mode 100644 index 000000000..47b6724ec --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ed25519_4.pub | |||
@@ -0,0 +1 @@ | |||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 | |||
diff --git a/regress/unittests/hostkeys/testdata/ed25519_5.pub b/regress/unittests/hostkeys/testdata/ed25519_5.pub new file mode 100644 index 000000000..72ccae6fe --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ed25519_5.pub | |||
@@ -0,0 +1 @@ | |||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 | |||
diff --git a/regress/unittests/hostkeys/testdata/ed25519_6.pub b/regress/unittests/hostkeys/testdata/ed25519_6.pub new file mode 100644 index 000000000..0f719731d --- /dev/null +++ b/regress/unittests/hostkeys/testdata/ed25519_6.pub | |||
@@ -0,0 +1 @@ | |||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 | |||
diff --git a/regress/unittests/hostkeys/testdata/known_hosts b/regress/unittests/hostkeys/testdata/known_hosts new file mode 100644 index 000000000..3740f674b --- /dev/null +++ b/regress/unittests/hostkeys/testdata/known_hosts | |||
@@ -0,0 +1,61 @@ | |||
1 | # Plain host keys, plain host names | ||
2 | sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 | ||
3 | sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 | ||
4 | sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 | ||
5 | sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 | ||
6 | sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 | ||
7 | |||
8 | # Plain host keys, hostnames + addresses | ||
9 | prometheus.example.com,192.0.2.1,2001:db8::1 ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 | ||
10 | prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 | ||
11 | prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 | ||
12 | prometheus.example.com,192.0.2.1,2001:db8::1 1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 | ||
13 | prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 | ||
14 | |||
15 | # Some hosts with wildcard names / IPs | ||
16 | *.example.com,192.0.2.*,2001:* ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 | ||
17 | *.example.com,192.0.2.*,2001:* ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 | ||
18 | *.example.com,192.0.2.*,2001:* ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 | ||
19 | *.example.com,192.0.2.*,2001:* 1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3 | ||
20 | *.example.com,192.0.2.*,2001:* ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 | ||
21 | |||
22 | # Hashed hostname and address entries | ||
23 | |1|6FWxoqTCAfm8sZ7T/q73OmxCFGM=|S4eQmusok4cbyDzzGEFGIAthDbw= ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 | ||
24 | |1|hTrfD0CuuB9ZbOa1CHFYvIk/gKE=|tPmW50t7flncm1UyM+DR97ubDNU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 | ||
25 | |1|fOGqe75X5ZpTz4c7DitP4E8/y30=|Lmcch2fh54bUYoV//S2VqDFVeiY= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 | ||
26 | |1|0RVzLjY3lwE3MRweguaAXaCCWk8=|DbcIgJQcRZJMYI6NYDOM6oJycPk= 1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 | ||
27 | |1|4q79XnHpKBNQhyMLAqbPPDN+JKo=|k1Wvjjb52zDdrXWM801+wX5oH8U= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 | ||
28 | |||
29 | |1|0M6PIx6THA3ipIOvTl3fcgn2z+A=|bwEJAOwJz+Sm7orFdgj170mD/zY= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 | ||
30 | |1|a6WGHcL+9gX3e96tMlgDSDJwtSg=|5Dqlb/yqNEf7jgfllrp/ygLmRV8= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 | ||
31 | |1|OeCpi7Pn5Q6c8la4fPf9G8YctT8=|sC6D7lDXTafIpokZJ1+1xWg2R6Q= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 | ||
32 | |1|BHESVyiJ7G2NN0lxrw7vT109jmk=|TKof+015J77bXqibsh0N1Lp0MKk= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 | ||
33 | |1|wY53mZNASDJ5/P3JYCJ4FUNa6WQ=|v8p0MfV5lqlZB2J0yLxl/gsWVQo= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 | ||
34 | |1|horeoyFPwfKhyFN+zJZ5LCfOo/I=|2ofvp0tNwCbKsV8FuiFA4gQG2Z8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 | ||
35 | |1|Aw4fXumZfx6jEIJuDGIyeEMd81A=|5FdLtdm2JeKNsS8IQeQlGYIadOE= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 | ||
36 | |1|+dGUNpv6GblrDd5fgHLlOWpSbEo=|He/pQ1yJjtiCyTNWpGwjBD4sZFI= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 | ||
37 | |1|E/PACGl8m1T7QnPedOoooozstP0=|w6DQAFT8yZgj0Hlkz5R1TppYHCA= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 | ||
38 | |1|SaoyMStgxpYfwedSXBAghi8Zo0s=|Gz78k69GaE6iViV3OOvbStKqyTA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 | ||
39 | |1|8qfGeiT5WTCzWYbXPQ+lsLg7km4=|1sIBwiSUr8IGkvrUGm3/9QYurmA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 | ||
40 | |1|87M1OtyHg1BZiDY3rT6lYsZFnAU=|eddAQVcMNbn2OB87XWXFQnYo6R4= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 | ||
41 | |1|60w3wFfC0XWI+rRmRlxIRhh8lwE=|yMhsGrzBJKiesAdSQ/PVgkCrDKk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 | ||
42 | |1|5gdEMmLUJC7grqWhRJPy2OTaSyE=|/XTfmLMa/B8npcVCGFRdaHl+d/0= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 | ||
43 | |1|6FGCWUr42GHdMB/eifnHNCuwgdk=|ONJvYZ/ANmi59R5HrOhLPmvYENM= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 | ||
44 | |||
45 | |||
46 | # Revoked and CA keys | ||
47 | @revoked sisyphus.example.com 1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4 | ||
48 | @revoked sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 | ||
49 | @cert-authority prometheus.example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 | ||
50 | @cert-authority *.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 | ||
51 | |||
52 | # Some invalid lines | ||
53 | @what sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 | ||
54 | sisyphus.example.com | ||
55 | prometheus.example.com ssh-ed25519 | ||
56 | sisyphus.example.com ssh-dsa AAAATgAAAAdz | ||
57 | prometheus.example.com 1024 | ||
58 | sisyphus.example.com 1024 65535 | ||
59 | prometheus.example.com 1025 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 | ||
60 | sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== | ||
61 | prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== | ||
diff --git a/regress/unittests/hostkeys/testdata/rsa1_1.pub b/regress/unittests/hostkeys/testdata/rsa1_1.pub new file mode 100644 index 000000000..772ce9c05 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa1_1.pub | |||
@@ -0,0 +1 @@ | |||
1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa1_2.pub b/regress/unittests/hostkeys/testdata/rsa1_2.pub new file mode 100644 index 000000000..78794b941 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa1_2.pub | |||
@@ -0,0 +1 @@ | |||
1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa1_3.pub b/regress/unittests/hostkeys/testdata/rsa1_3.pub new file mode 100644 index 000000000..0c035fe0a --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa1_3.pub | |||
@@ -0,0 +1 @@ | |||
1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa1_4.pub b/regress/unittests/hostkeys/testdata/rsa1_4.pub new file mode 100644 index 000000000..00064423e --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa1_4.pub | |||
@@ -0,0 +1 @@ | |||
1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa1_5.pub b/regress/unittests/hostkeys/testdata/rsa1_5.pub new file mode 100644 index 000000000..bb53c2642 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa1_5.pub | |||
@@ -0,0 +1 @@ | |||
1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa1_6.pub b/regress/unittests/hostkeys/testdata/rsa1_6.pub new file mode 100644 index 000000000..85d6576b5 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa1_6.pub | |||
@@ -0,0 +1 @@ | |||
1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa_1.pub b/regress/unittests/hostkeys/testdata/rsa_1.pub new file mode 100644 index 000000000..2b87885a1 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa_1.pub | |||
@@ -0,0 +1 @@ | |||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa_2.pub b/regress/unittests/hostkeys/testdata/rsa_2.pub new file mode 100644 index 000000000..33f1fd93b --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa_2.pub | |||
@@ -0,0 +1 @@ | |||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa_3.pub b/regress/unittests/hostkeys/testdata/rsa_3.pub new file mode 100644 index 000000000..c2f6b208c --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa_3.pub | |||
@@ -0,0 +1 @@ | |||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa_4.pub b/regress/unittests/hostkeys/testdata/rsa_4.pub new file mode 100644 index 000000000..35545a713 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa_4.pub | |||
@@ -0,0 +1 @@ | |||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDI8AdjBAozcdRnIikVlt69iyDHKyrtxmpdkbRy9bWaL86OH+PTmLUk5e+T/ufiakpeE2pm0hkE3e4Sh/FsY+rsQdRoraWVNFfchcMeVlKvuy5RZN0ElvmaQebOJUeNeBn2LLw8aL8bJ4CP/bQRKrmrSSqjz3+4H9YNVyyk1OGBPQ== RSA #4 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa_5.pub b/regress/unittests/hostkeys/testdata/rsa_5.pub new file mode 100644 index 000000000..befbaa7d9 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa_5.pub | |||
@@ -0,0 +1 @@ | |||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 | |||
diff --git a/regress/unittests/hostkeys/testdata/rsa_6.pub b/regress/unittests/hostkeys/testdata/rsa_6.pub new file mode 100644 index 000000000..393e11672 --- /dev/null +++ b/regress/unittests/hostkeys/testdata/rsa_6.pub | |||
@@ -0,0 +1 @@ | |||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 | |||
diff --git a/regress/unittests/hostkeys/tests.c b/regress/unittests/hostkeys/tests.c new file mode 100644 index 000000000..92c7646ad --- /dev/null +++ b/regress/unittests/hostkeys/tests.c | |||
@@ -0,0 +1,16 @@ | |||
1 | /* $OpenBSD: tests.c,v 1.1 2015/02/16 22:18:34 djm Exp $ */ | ||
2 | /* | ||
3 | * Regress test for known_hosts-related API. | ||
4 | * | ||
5 | * Placed in the public domain | ||
6 | */ | ||
7 | |||
8 | void tests(void); | ||
9 | void test_iterate(void); /* test_iterate.c */ | ||
10 | |||
11 | void | ||
12 | tests(void) | ||
13 | { | ||
14 | test_iterate(); | ||
15 | } | ||
16 | |||
diff --git a/regress/unittests/kex/Makefile b/regress/unittests/kex/Makefile new file mode 100644 index 000000000..6532cb00a --- /dev/null +++ b/regress/unittests/kex/Makefile | |||
@@ -0,0 +1,14 @@ | |||
1 | # $OpenBSD: Makefile,v 1.2 2015/01/24 10:39:21 miod Exp $ | ||
2 | |||
3 | TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" | ||
4 | |||
5 | PROG=test_kex | ||
6 | SRCS=tests.c test_kex.c | ||
7 | REGRESS_TARGETS=run-regress-${PROG} | ||
8 | |||
9 | run-regress-${PROG}: ${PROG} | ||
10 | env ${TEST_ENV} ./${PROG} | ||
11 | |||
12 | .include <bsd.regress.mk> | ||
13 | |||
14 | LDADD+=-lz | ||
diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c new file mode 100644 index 000000000..c61e2bdbb --- /dev/null +++ b/regress/unittests/kex/test_kex.c | |||
@@ -0,0 +1,197 @@ | |||
1 | /* $OpenBSD: test_kex.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */ | ||
2 | /* | ||
3 | * Regress test KEX | ||
4 | * | ||
5 | * Placed in the public domain | ||
6 | */ | ||
7 | |||
8 | #include "includes.h" | ||
9 | |||
10 | #include <sys/types.h> | ||
11 | #include <sys/param.h> | ||
12 | #include <stdio.h> | ||
13 | #ifdef HAVE_STDINT_H | ||
14 | #include <stdint.h> | ||
15 | #endif | ||
16 | #include <stdlib.h> | ||
17 | #include <string.h> | ||
18 | |||
19 | #include "../test_helper/test_helper.h" | ||
20 | |||
21 | #include "ssherr.h" | ||
22 | #include "ssh_api.h" | ||
23 | #include "sshbuf.h" | ||
24 | #include "packet.h" | ||
25 | #include "myproposal.h" | ||
26 | |||
27 | struct ssh *active_state = NULL; /* XXX - needed for linking */ | ||
28 | |||
29 | void kex_tests(void); | ||
30 | static int do_debug = 0; | ||
31 | |||
32 | static int | ||
33 | do_send_and_receive(struct ssh *from, struct ssh *to) | ||
34 | { | ||
35 | u_char type; | ||
36 | size_t len; | ||
37 | const u_char *buf; | ||
38 | int r; | ||
39 | |||
40 | for (;;) { | ||
41 | if ((r = ssh_packet_next(from, &type)) != 0) { | ||
42 | fprintf(stderr, "ssh_packet_next: %s\n", ssh_err(r)); | ||
43 | return r; | ||
44 | } | ||
45 | if (type != 0) | ||
46 | return 0; | ||
47 | buf = ssh_output_ptr(from, &len); | ||
48 | if (do_debug) | ||
49 | printf("%zu", len); | ||
50 | if (len == 0) | ||
51 | return 0; | ||
52 | if ((r = ssh_output_consume(from, len)) != 0 || | ||
53 | (r = ssh_input_append(to, buf, len)) != 0) | ||
54 | return r; | ||
55 | } | ||
56 | } | ||
57 | |||
58 | static void | ||
59 | run_kex(struct ssh *client, struct ssh *server) | ||
60 | { | ||
61 | int r = 0; | ||
62 | |||
63 | while (!server->kex->done || !client->kex->done) { | ||
64 | if (do_debug) | ||
65 | printf(" S:"); | ||
66 | if ((r = do_send_and_receive(server, client))) | ||
67 | break; | ||
68 | if (do_debug) | ||
69 | printf(" C:"); | ||
70 | if ((r = do_send_and_receive(client, server))) | ||
71 | break; | ||
72 | } | ||
73 | if (do_debug) | ||
74 | printf("done: %s\n", ssh_err(r)); | ||
75 | ASSERT_INT_EQ(r, 0); | ||
76 | ASSERT_INT_EQ(server->kex->done, 1); | ||
77 | ASSERT_INT_EQ(client->kex->done, 1); | ||
78 | } | ||
79 | |||
80 | static void | ||
81 | do_kex_with_key(char *kex, int keytype, int bits) | ||
82 | { | ||
83 | struct ssh *client = NULL, *server = NULL, *server2 = NULL; | ||
84 | struct sshkey *private, *public; | ||
85 | struct sshbuf *state; | ||
86 | struct kex_params kex_params; | ||
87 | char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; | ||
88 | |||
89 | TEST_START("sshkey_generate"); | ||
90 | ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0); | ||
91 | TEST_DONE(); | ||
92 | |||
93 | TEST_START("sshkey_from_private"); | ||
94 | ASSERT_INT_EQ(sshkey_from_private(private, &public), 0); | ||
95 | TEST_DONE(); | ||
96 | |||
97 | TEST_START("ssh_init"); | ||
98 | memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); | ||
99 | if (kex != NULL) | ||
100 | kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; | ||
101 | ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0); | ||
102 | ASSERT_INT_EQ(ssh_init(&server, 1, &kex_params), 0); | ||
103 | ASSERT_PTR_NE(client, NULL); | ||
104 | ASSERT_PTR_NE(server, NULL); | ||
105 | TEST_DONE(); | ||
106 | |||
107 | TEST_START("ssh_add_hostkey"); | ||
108 | ASSERT_INT_EQ(ssh_add_hostkey(server, private), 0); | ||
109 | ASSERT_INT_EQ(ssh_add_hostkey(client, public), 0); | ||
110 | TEST_DONE(); | ||
111 | |||
112 | TEST_START("kex"); | ||
113 | run_kex(client, server); | ||
114 | TEST_DONE(); | ||
115 | |||
116 | TEST_START("rekeying client"); | ||
117 | ASSERT_INT_EQ(kex_send_kexinit(client), 0); | ||
118 | run_kex(client, server); | ||
119 | TEST_DONE(); | ||
120 | |||
121 | TEST_START("rekeying server"); | ||
122 | ASSERT_INT_EQ(kex_send_kexinit(server), 0); | ||
123 | run_kex(client, server); | ||
124 | TEST_DONE(); | ||
125 | |||
126 | TEST_START("ssh_packet_get_state"); | ||
127 | state = sshbuf_new(); | ||
128 | ASSERT_PTR_NE(state, NULL); | ||
129 | ASSERT_INT_EQ(ssh_packet_get_state(server, state), 0); | ||
130 | ASSERT_INT_GE(sshbuf_len(state), 1); | ||
131 | TEST_DONE(); | ||
132 | |||
133 | TEST_START("ssh_packet_set_state"); | ||
134 | server2 = NULL; | ||
135 | ASSERT_INT_EQ(ssh_init(&server2, 1, NULL), 0); | ||
136 | ASSERT_PTR_NE(server2, NULL); | ||
137 | ASSERT_INT_EQ(ssh_add_hostkey(server2, private), 0); | ||
138 | kex_free(server2->kex); /* XXX or should ssh_packet_set_state()? */ | ||
139 | ASSERT_INT_EQ(ssh_packet_set_state(server2, state), 0); | ||
140 | ASSERT_INT_EQ(sshbuf_len(state), 0); | ||
141 | sshbuf_free(state); | ||
142 | ASSERT_PTR_NE(server2->kex, NULL); | ||
143 | /* XXX we need to set the callbacks */ | ||
144 | server2->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; | ||
145 | server2->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; | ||
146 | server2->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; | ||
147 | server2->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; | ||
148 | #ifdef OPENSSL_HAS_ECC | ||
149 | server2->kex->kex[KEX_ECDH_SHA2] = kexecdh_server; | ||
150 | #endif | ||
151 | server2->kex->kex[KEX_C25519_SHA256] = kexc25519_server; | ||
152 | server2->kex->load_host_public_key = server->kex->load_host_public_key; | ||
153 | server2->kex->load_host_private_key = server->kex->load_host_private_key; | ||
154 | server2->kex->sign = server->kex->sign; | ||
155 | TEST_DONE(); | ||
156 | |||
157 | TEST_START("rekeying server2"); | ||
158 | ASSERT_INT_EQ(kex_send_kexinit(server2), 0); | ||
159 | run_kex(client, server2); | ||
160 | ASSERT_INT_EQ(kex_send_kexinit(client), 0); | ||
161 | run_kex(client, server2); | ||
162 | TEST_DONE(); | ||
163 | |||
164 | TEST_START("cleanup"); | ||
165 | sshkey_free(private); | ||
166 | sshkey_free(public); | ||
167 | ssh_free(client); | ||
168 | ssh_free(server); | ||
169 | ssh_free(server2); | ||
170 | TEST_DONE(); | ||
171 | } | ||
172 | |||
173 | static void | ||
174 | do_kex(char *kex) | ||
175 | { | ||
176 | do_kex_with_key(kex, KEY_RSA, 2048); | ||
177 | do_kex_with_key(kex, KEY_DSA, 1024); | ||
178 | #ifdef OPENSSL_HAS_ECC | ||
179 | do_kex_with_key(kex, KEY_ECDSA, 256); | ||
180 | #endif | ||
181 | do_kex_with_key(kex, KEY_ED25519, 256); | ||
182 | } | ||
183 | |||
184 | void | ||
185 | kex_tests(void) | ||
186 | { | ||
187 | do_kex("curve25519-sha256@libssh.org"); | ||
188 | #ifdef OPENSSL_HAS_ECC | ||
189 | do_kex("ecdh-sha2-nistp256"); | ||
190 | do_kex("ecdh-sha2-nistp384"); | ||
191 | do_kex("ecdh-sha2-nistp521"); | ||
192 | #endif | ||
193 | do_kex("diffie-hellman-group-exchange-sha256"); | ||
194 | do_kex("diffie-hellman-group-exchange-sha1"); | ||
195 | do_kex("diffie-hellman-group14-sha1"); | ||
196 | do_kex("diffie-hellman-group1-sha1"); | ||
197 | } | ||
diff --git a/regress/unittests/kex/tests.c b/regress/unittests/kex/tests.c new file mode 100644 index 000000000..e7036ec17 --- /dev/null +++ b/regress/unittests/kex/tests.c | |||
@@ -0,0 +1,14 @@ | |||
1 | /* $OpenBSD: tests.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */ | ||
2 | /* | ||
3 | * Placed in the public domain | ||
4 | */ | ||
5 | |||
6 | #include "../test_helper/test_helper.h" | ||
7 | |||
8 | void kex_tests(void); | ||
9 | |||
10 | void | ||
11 | tests(void) | ||
12 | { | ||
13 | kex_tests(); | ||
14 | } | ||
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c index 0c4c71ecd..a68e1329e 100644 --- a/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c +++ b/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c | |||
@@ -32,8 +32,6 @@ void | |||
32 | sshbuf_getput_crypto_tests(void) | 32 | sshbuf_getput_crypto_tests(void) |
33 | { | 33 | { |
34 | struct sshbuf *p1; | 34 | struct sshbuf *p1; |
35 | const u_char *d; | ||
36 | size_t s; | ||
37 | BIGNUM *bn, *bn2; | 35 | BIGNUM *bn, *bn2; |
38 | /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */ | 36 | /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */ |
39 | const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10"; | 37 | const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10"; |
@@ -48,7 +46,9 @@ sshbuf_getput_crypto_tests(void) | |||
48 | 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, | 46 | 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, |
49 | 0x7f, 0xff, 0x11 | 47 | 0x7f, 0xff, 0x11 |
50 | }; | 48 | }; |
51 | #ifdef OPENSSL_HAS_NISTP256 | 49 | #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) |
50 | const u_char *d; | ||
51 | size_t s; | ||
52 | BIGNUM *bn_x, *bn_y; | 52 | BIGNUM *bn_x, *bn_y; |
53 | int ec256_nid = NID_X9_62_prime256v1; | 53 | int ec256_nid = NID_X9_62_prime256v1; |
54 | char *ec256_x = "0C828004839D0106AA59575216191357" | 54 | char *ec256_x = "0C828004839D0106AA59575216191357" |
@@ -352,7 +352,7 @@ sshbuf_getput_crypto_tests(void) | |||
352 | sshbuf_free(p1); | 352 | sshbuf_free(p1); |
353 | TEST_DONE(); | 353 | TEST_DONE(); |
354 | 354 | ||
355 | #ifdef OPENSSL_HAS_NISTP256 | 355 | #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) |
356 | TEST_START("sshbuf_put_ec"); | 356 | TEST_START("sshbuf_put_ec"); |
357 | eck = EC_KEY_new_by_curve_name(ec256_nid); | 357 | eck = EC_KEY_new_by_curve_name(ec256_nid); |
358 | ASSERT_PTR_NE(eck, NULL); | 358 | ASSERT_PTR_NE(eck, NULL); |
diff --git a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c index 8c3269b13..c6b5c29d1 100644 --- a/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c +++ b/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c | |||
@@ -33,7 +33,7 @@ attempt_parse_blob(u_char *blob, size_t len) | |||
33 | { | 33 | { |
34 | struct sshbuf *p1; | 34 | struct sshbuf *p1; |
35 | BIGNUM *bn; | 35 | BIGNUM *bn; |
36 | #ifdef OPENSSL_HAS_NISTP256 | 36 | #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) |
37 | EC_KEY *eck; | 37 | EC_KEY *eck; |
38 | #endif | 38 | #endif |
39 | u_char *s; | 39 | u_char *s; |
@@ -60,7 +60,7 @@ attempt_parse_blob(u_char *blob, size_t len) | |||
60 | bn = BN_new(); | 60 | bn = BN_new(); |
61 | sshbuf_get_bignum2(p1, bn); | 61 | sshbuf_get_bignum2(p1, bn); |
62 | BN_clear_free(bn); | 62 | BN_clear_free(bn); |
63 | #ifdef OPENSSL_HAS_NISTP256 | 63 | #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) |
64 | eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); | 64 | eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); |
65 | ASSERT_PTR_NE(eck, NULL); | 65 | ASSERT_PTR_NE(eck, NULL); |
66 | sshbuf_get_eckey(p1, eck); | 66 | sshbuf_get_eckey(p1, eck); |
diff --git a/regress/unittests/sshkey/common.c b/regress/unittests/sshkey/common.c index 0a4b3a90c..b598f05cb 100644 --- a/regress/unittests/sshkey/common.c +++ b/regress/unittests/sshkey/common.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: common.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ | 1 | /* $OpenBSD: common.c,v 1.2 2015/01/08 13:10:58 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Helpers for key API tests | 3 | * Helpers for key API tests |
4 | * | 4 | * |
@@ -44,7 +44,7 @@ load_file(const char *name) | |||
44 | 44 | ||
45 | ASSERT_PTR_NE(ret = sshbuf_new(), NULL); | 45 | ASSERT_PTR_NE(ret = sshbuf_new(), NULL); |
46 | ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1); | 46 | ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1); |
47 | ASSERT_INT_EQ(sshkey_load_file(fd, name, ret), 0); | 47 | ASSERT_INT_EQ(sshkey_load_file(fd, ret), 0); |
48 | close(fd); | 48 | close(fd); |
49 | return ret; | 49 | return ret; |
50 | } | 50 | } |
diff --git a/regress/unittests/sshkey/mktestdata.sh b/regress/unittests/sshkey/mktestdata.sh index ee1fe3962..09165af02 100755 --- a/regress/unittests/sshkey/mktestdata.sh +++ b/regress/unittests/sshkey/mktestdata.sh | |||
@@ -1,5 +1,5 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # $OpenBSD: mktestdata.sh,v 1.3 2014/07/22 23:57:40 dtucker Exp $ | 2 | # $OpenBSD: mktestdata.sh,v 1.4 2015/01/18 19:54:46 djm Exp $ |
3 | 3 | ||
4 | PW=mekmitasdigoat | 4 | PW=mekmitasdigoat |
5 | 5 | ||
@@ -187,4 +187,6 @@ ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb | |||
187 | ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb | 187 | ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb |
188 | ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb | 188 | ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb |
189 | 189 | ||
190 | # XXX Extend ssh-keygen to do detached signatures (better to test/fuzz against) | ||
191 | |||
190 | echo "$PW" > pw | 192 | echo "$PW" > pw |
diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c index 764f7fb76..fa95212bf 100644 --- a/regress/unittests/sshkey/test_file.c +++ b/regress/unittests/sshkey/test_file.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: test_file.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ | 1 | /* $OpenBSD: test_file.c,v 1.3 2015/03/04 23:22:35 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Regress test for sshkey.h key management API | 3 | * Regress test for sshkey.h key management API |
4 | * | 4 | * |
@@ -33,6 +33,7 @@ | |||
33 | #include "authfile.h" | 33 | #include "authfile.h" |
34 | #include "sshkey.h" | 34 | #include "sshkey.h" |
35 | #include "sshbuf.h" | 35 | #include "sshbuf.h" |
36 | #include "digest.h" | ||
36 | 37 | ||
37 | #include "common.h" | 38 | #include "common.h" |
38 | 39 | ||
@@ -50,6 +51,7 @@ sshkey_file_tests(void) | |||
50 | pw = load_text_file("pw"); | 51 | pw = load_text_file("pw"); |
51 | TEST_DONE(); | 52 | TEST_DONE(); |
52 | 53 | ||
54 | #ifdef WITH_SSH1 | ||
53 | TEST_START("parse RSA1 from private"); | 55 | TEST_START("parse RSA1 from private"); |
54 | buf = load_file("rsa1_1"); | 56 | buf = load_file("rsa1_1"); |
55 | ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1", | 57 | ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1", |
@@ -81,7 +83,7 @@ sshkey_file_tests(void) | |||
81 | 83 | ||
82 | TEST_START("RSA1 key hex fingerprint"); | 84 | TEST_START("RSA1 key hex fingerprint"); |
83 | buf = load_text_file("rsa1_1.fp"); | 85 | buf = load_text_file("rsa1_1.fp"); |
84 | cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); | 86 | cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); |
85 | ASSERT_PTR_NE(cp, NULL); | 87 | ASSERT_PTR_NE(cp, NULL); |
86 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 88 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
87 | sshbuf_free(buf); | 89 | sshbuf_free(buf); |
@@ -90,7 +92,7 @@ sshkey_file_tests(void) | |||
90 | 92 | ||
91 | TEST_START("RSA1 key bubblebabble fingerprint"); | 93 | TEST_START("RSA1 key bubblebabble fingerprint"); |
92 | buf = load_text_file("rsa1_1.fp.bb"); | 94 | buf = load_text_file("rsa1_1.fp.bb"); |
93 | cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); | 95 | cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); |
94 | ASSERT_PTR_NE(cp, NULL); | 96 | ASSERT_PTR_NE(cp, NULL); |
95 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 97 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
96 | sshbuf_free(buf); | 98 | sshbuf_free(buf); |
@@ -98,6 +100,7 @@ sshkey_file_tests(void) | |||
98 | TEST_DONE(); | 100 | TEST_DONE(); |
99 | 101 | ||
100 | sshkey_free(k1); | 102 | sshkey_free(k1); |
103 | #endif | ||
101 | 104 | ||
102 | TEST_START("parse RSA from private"); | 105 | TEST_START("parse RSA from private"); |
103 | buf = load_file("rsa_1"); | 106 | buf = load_file("rsa_1"); |
@@ -164,7 +167,7 @@ sshkey_file_tests(void) | |||
164 | 167 | ||
165 | TEST_START("RSA key hex fingerprint"); | 168 | TEST_START("RSA key hex fingerprint"); |
166 | buf = load_text_file("rsa_1.fp"); | 169 | buf = load_text_file("rsa_1.fp"); |
167 | cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); | 170 | cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); |
168 | ASSERT_PTR_NE(cp, NULL); | 171 | ASSERT_PTR_NE(cp, NULL); |
169 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 172 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
170 | sshbuf_free(buf); | 173 | sshbuf_free(buf); |
@@ -173,7 +176,7 @@ sshkey_file_tests(void) | |||
173 | 176 | ||
174 | TEST_START("RSA cert hex fingerprint"); | 177 | TEST_START("RSA cert hex fingerprint"); |
175 | buf = load_text_file("rsa_1-cert.fp"); | 178 | buf = load_text_file("rsa_1-cert.fp"); |
176 | cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); | 179 | cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX); |
177 | ASSERT_PTR_NE(cp, NULL); | 180 | ASSERT_PTR_NE(cp, NULL); |
178 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 181 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
179 | sshbuf_free(buf); | 182 | sshbuf_free(buf); |
@@ -183,7 +186,7 @@ sshkey_file_tests(void) | |||
183 | 186 | ||
184 | TEST_START("RSA key bubblebabble fingerprint"); | 187 | TEST_START("RSA key bubblebabble fingerprint"); |
185 | buf = load_text_file("rsa_1.fp.bb"); | 188 | buf = load_text_file("rsa_1.fp.bb"); |
186 | cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); | 189 | cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); |
187 | ASSERT_PTR_NE(cp, NULL); | 190 | ASSERT_PTR_NE(cp, NULL); |
188 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 191 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
189 | sshbuf_free(buf); | 192 | sshbuf_free(buf); |
@@ -257,7 +260,7 @@ sshkey_file_tests(void) | |||
257 | 260 | ||
258 | TEST_START("DSA key hex fingerprint"); | 261 | TEST_START("DSA key hex fingerprint"); |
259 | buf = load_text_file("dsa_1.fp"); | 262 | buf = load_text_file("dsa_1.fp"); |
260 | cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); | 263 | cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); |
261 | ASSERT_PTR_NE(cp, NULL); | 264 | ASSERT_PTR_NE(cp, NULL); |
262 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 265 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
263 | sshbuf_free(buf); | 266 | sshbuf_free(buf); |
@@ -266,7 +269,7 @@ sshkey_file_tests(void) | |||
266 | 269 | ||
267 | TEST_START("DSA cert hex fingerprint"); | 270 | TEST_START("DSA cert hex fingerprint"); |
268 | buf = load_text_file("dsa_1-cert.fp"); | 271 | buf = load_text_file("dsa_1-cert.fp"); |
269 | cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); | 272 | cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX); |
270 | ASSERT_PTR_NE(cp, NULL); | 273 | ASSERT_PTR_NE(cp, NULL); |
271 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 274 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
272 | sshbuf_free(buf); | 275 | sshbuf_free(buf); |
@@ -276,7 +279,7 @@ sshkey_file_tests(void) | |||
276 | 279 | ||
277 | TEST_START("DSA key bubblebabble fingerprint"); | 280 | TEST_START("DSA key bubblebabble fingerprint"); |
278 | buf = load_text_file("dsa_1.fp.bb"); | 281 | buf = load_text_file("dsa_1.fp.bb"); |
279 | cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); | 282 | cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); |
280 | ASSERT_PTR_NE(cp, NULL); | 283 | ASSERT_PTR_NE(cp, NULL); |
281 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 284 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
282 | sshbuf_free(buf); | 285 | sshbuf_free(buf); |
@@ -357,7 +360,7 @@ sshkey_file_tests(void) | |||
357 | 360 | ||
358 | TEST_START("ECDSA key hex fingerprint"); | 361 | TEST_START("ECDSA key hex fingerprint"); |
359 | buf = load_text_file("ecdsa_1.fp"); | 362 | buf = load_text_file("ecdsa_1.fp"); |
360 | cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); | 363 | cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); |
361 | ASSERT_PTR_NE(cp, NULL); | 364 | ASSERT_PTR_NE(cp, NULL); |
362 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 365 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
363 | sshbuf_free(buf); | 366 | sshbuf_free(buf); |
@@ -366,7 +369,7 @@ sshkey_file_tests(void) | |||
366 | 369 | ||
367 | TEST_START("ECDSA cert hex fingerprint"); | 370 | TEST_START("ECDSA cert hex fingerprint"); |
368 | buf = load_text_file("ecdsa_1-cert.fp"); | 371 | buf = load_text_file("ecdsa_1-cert.fp"); |
369 | cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); | 372 | cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX); |
370 | ASSERT_PTR_NE(cp, NULL); | 373 | ASSERT_PTR_NE(cp, NULL); |
371 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 374 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
372 | sshbuf_free(buf); | 375 | sshbuf_free(buf); |
@@ -376,7 +379,7 @@ sshkey_file_tests(void) | |||
376 | 379 | ||
377 | TEST_START("ECDSA key bubblebabble fingerprint"); | 380 | TEST_START("ECDSA key bubblebabble fingerprint"); |
378 | buf = load_text_file("ecdsa_1.fp.bb"); | 381 | buf = load_text_file("ecdsa_1.fp.bb"); |
379 | cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); | 382 | cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); |
380 | ASSERT_PTR_NE(cp, NULL); | 383 | ASSERT_PTR_NE(cp, NULL); |
381 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 384 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
382 | sshbuf_free(buf); | 385 | sshbuf_free(buf); |
@@ -424,7 +427,7 @@ sshkey_file_tests(void) | |||
424 | 427 | ||
425 | TEST_START("Ed25519 key hex fingerprint"); | 428 | TEST_START("Ed25519 key hex fingerprint"); |
426 | buf = load_text_file("ed25519_1.fp"); | 429 | buf = load_text_file("ed25519_1.fp"); |
427 | cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); | 430 | cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); |
428 | ASSERT_PTR_NE(cp, NULL); | 431 | ASSERT_PTR_NE(cp, NULL); |
429 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 432 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
430 | sshbuf_free(buf); | 433 | sshbuf_free(buf); |
@@ -433,7 +436,7 @@ sshkey_file_tests(void) | |||
433 | 436 | ||
434 | TEST_START("Ed25519 cert hex fingerprint"); | 437 | TEST_START("Ed25519 cert hex fingerprint"); |
435 | buf = load_text_file("ed25519_1-cert.fp"); | 438 | buf = load_text_file("ed25519_1-cert.fp"); |
436 | cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); | 439 | cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX); |
437 | ASSERT_PTR_NE(cp, NULL); | 440 | ASSERT_PTR_NE(cp, NULL); |
438 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 441 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
439 | sshbuf_free(buf); | 442 | sshbuf_free(buf); |
@@ -443,7 +446,7 @@ sshkey_file_tests(void) | |||
443 | 446 | ||
444 | TEST_START("Ed25519 key bubblebabble fingerprint"); | 447 | TEST_START("Ed25519 key bubblebabble fingerprint"); |
445 | buf = load_text_file("ed25519_1.fp.bb"); | 448 | buf = load_text_file("ed25519_1.fp.bb"); |
446 | cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); | 449 | cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); |
447 | ASSERT_PTR_NE(cp, NULL); | 450 | ASSERT_PTR_NE(cp, NULL); |
448 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); | 451 | ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); |
449 | sshbuf_free(buf); | 452 | sshbuf_free(buf); |
diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c index a3f61a6df..1f08a2e43 100644 --- a/regress/unittests/sshkey/test_fuzz.c +++ b/regress/unittests/sshkey/test_fuzz.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: test_fuzz.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ | 1 | /* $OpenBSD: test_fuzz.c,v 1.4 2015/03/04 23:22:35 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Fuzz tests for key parsing | 3 | * Fuzz tests for key parsing |
4 | * | 4 | * |
@@ -53,7 +53,7 @@ public_fuzz(struct sshkey *k) | |||
53 | struct fuzz *fuzz; | 53 | struct fuzz *fuzz; |
54 | 54 | ||
55 | ASSERT_PTR_NE(buf = sshbuf_new(), NULL); | 55 | ASSERT_PTR_NE(buf = sshbuf_new(), NULL); |
56 | ASSERT_INT_EQ(sshkey_to_blob_buf(k, buf), 0); | 56 | ASSERT_INT_EQ(sshkey_putb(k, buf), 0); |
57 | /* XXX need a way to run the tests in "slow, but complete" mode */ | 57 | /* XXX need a way to run the tests in "slow, but complete" mode */ |
58 | fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */ | 58 | fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */ |
59 | FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */ | 59 | FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */ |
@@ -87,8 +87,11 @@ sig_fuzz(struct sshkey *k) | |||
87 | free(sig); | 87 | free(sig); |
88 | TEST_ONERROR(onerror, fuzz); | 88 | TEST_ONERROR(onerror, fuzz); |
89 | for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { | 89 | for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { |
90 | sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz), | 90 | /* Ensure 1-bit difference at least */ |
91 | c, sizeof(c), 0); | 91 | if (fuzz_matches_original(fuzz)) |
92 | continue; | ||
93 | ASSERT_INT_NE(sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz), | ||
94 | c, sizeof(c), 0), 0); | ||
92 | } | 95 | } |
93 | fuzz_cleanup(fuzz); | 96 | fuzz_cleanup(fuzz); |
94 | } | 97 | } |
@@ -101,6 +104,7 @@ sshkey_fuzz_tests(void) | |||
101 | struct fuzz *fuzz; | 104 | struct fuzz *fuzz; |
102 | int r; | 105 | int r; |
103 | 106 | ||
107 | #ifdef WITH_SSH1 | ||
104 | TEST_START("fuzz RSA1 private"); | 108 | TEST_START("fuzz RSA1 private"); |
105 | buf = load_file("rsa1_1"); | 109 | buf = load_file("rsa1_1"); |
106 | fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | | 110 | fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | |
@@ -144,6 +148,7 @@ sshkey_fuzz_tests(void) | |||
144 | sshbuf_free(fuzzed); | 148 | sshbuf_free(fuzzed); |
145 | fuzz_cleanup(fuzz); | 149 | fuzz_cleanup(fuzz); |
146 | TEST_DONE(); | 150 | TEST_DONE(); |
151 | #endif | ||
147 | 152 | ||
148 | TEST_START("fuzz RSA private"); | 153 | TEST_START("fuzz RSA private"); |
149 | buf = load_file("rsa_1"); | 154 | buf = load_file("rsa_1"); |
diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c index ef0c67956..ad10c9be2 100644 --- a/regress/unittests/sshkey/test_sshkey.c +++ b/regress/unittests/sshkey/test_sshkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ | 1 | /* $OpenBSD: test_sshkey.c,v 1.3 2015/01/26 06:11:28 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Regress test for sshkey.h key management API | 3 | * Regress test for sshkey.h key management API |
4 | * | 4 | * |
@@ -19,7 +19,7 @@ | |||
19 | #include <openssl/bn.h> | 19 | #include <openssl/bn.h> |
20 | #include <openssl/rsa.h> | 20 | #include <openssl/rsa.h> |
21 | #include <openssl/dsa.h> | 21 | #include <openssl/dsa.h> |
22 | #ifdef OPENSSL_HAS_NISTP256 | 22 | #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) |
23 | # include <openssl/ec.h> | 23 | # include <openssl/ec.h> |
24 | #endif | 24 | #endif |
25 | 25 | ||
@@ -37,6 +37,20 @@ | |||
37 | void sshkey_tests(void); | 37 | void sshkey_tests(void); |
38 | 38 | ||
39 | static void | 39 | static void |
40 | put_opt(struct sshbuf *b, const char *name, const char *value) | ||
41 | { | ||
42 | struct sshbuf *sect; | ||
43 | |||
44 | sect = sshbuf_new(); | ||
45 | ASSERT_PTR_NE(sect, NULL); | ||
46 | ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0); | ||
47 | if (value != NULL) | ||
48 | ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0); | ||
49 | ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0); | ||
50 | sshbuf_free(sect); | ||
51 | } | ||
52 | |||
53 | static void | ||
40 | build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, | 54 | build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, |
41 | const struct sshkey *sign_key, const struct sshkey *ca_key) | 55 | const struct sshkey *sign_key, const struct sshkey *ca_key) |
42 | { | 56 | { |
@@ -45,25 +59,31 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, | |||
45 | size_t siglen; | 59 | size_t siglen; |
46 | 60 | ||
47 | ca_buf = sshbuf_new(); | 61 | ca_buf = sshbuf_new(); |
48 | ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0); | 62 | ASSERT_PTR_NE(ca_buf, NULL); |
63 | ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); | ||
49 | 64 | ||
50 | /* | 65 | /* |
51 | * Get the public key serialisation by rendering the key and skipping | 66 | * Get the public key serialisation by rendering the key and skipping |
52 | * the type string. This is a bit of a hack :/ | 67 | * the type string. This is a bit of a hack :/ |
53 | */ | 68 | */ |
54 | pk = sshbuf_new(); | 69 | pk = sshbuf_new(); |
55 | ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0); | 70 | ASSERT_PTR_NE(pk, NULL); |
71 | ASSERT_INT_EQ(sshkey_putb_plain(k, pk), 0); | ||
56 | ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); | 72 | ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); |
57 | 73 | ||
58 | principals = sshbuf_new(); | 74 | principals = sshbuf_new(); |
75 | ASSERT_PTR_NE(principals, NULL); | ||
59 | ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); | 76 | ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); |
60 | ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); | 77 | ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); |
61 | 78 | ||
62 | critopts = sshbuf_new(); | 79 | critopts = sshbuf_new(); |
63 | /* XXX fill this in */ | 80 | ASSERT_PTR_NE(critopts, NULL); |
81 | put_opt(critopts, "force-command", "/usr/local/bin/nethack"); | ||
82 | put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1"); | ||
64 | 83 | ||
65 | exts = sshbuf_new(); | 84 | exts = sshbuf_new(); |
66 | /* XXX fill this in */ | 85 | ASSERT_PTR_NE(exts, NULL); |
86 | put_opt(critopts, "permit-X11-forwarding", NULL); | ||
67 | 87 | ||
68 | ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); | 88 | ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); |
69 | ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ | 89 | ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ |
@@ -90,10 +110,74 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, | |||
90 | sshbuf_free(pk); | 110 | sshbuf_free(pk); |
91 | } | 111 | } |
92 | 112 | ||
113 | static void | ||
114 | signature_test(struct sshkey *k, struct sshkey *bad, const u_char *d, size_t l) | ||
115 | { | ||
116 | size_t len; | ||
117 | u_char *sig; | ||
118 | |||
119 | ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, 0), 0); | ||
120 | ASSERT_SIZE_T_GT(len, 8); | ||
121 | ASSERT_PTR_NE(sig, NULL); | ||
122 | ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0); | ||
123 | ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, 0), 0); | ||
124 | /* Fuzz test is more comprehensive, this is just a smoke test */ | ||
125 | sig[len - 5] ^= 0x10; | ||
126 | ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, 0), 0); | ||
127 | free(sig); | ||
128 | } | ||
129 | |||
130 | static void | ||
131 | banana(u_char *s, size_t l) | ||
132 | { | ||
133 | size_t o; | ||
134 | const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' }; | ||
135 | |||
136 | for (o = 0; o < l; o += sizeof(the_banana)) { | ||
137 | if (l - o < sizeof(the_banana)) { | ||
138 | memcpy(s + o, "nanananana", l - o); | ||
139 | break; | ||
140 | } | ||
141 | memcpy(s + o, banana, sizeof(the_banana)); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static void | ||
146 | signature_tests(struct sshkey *k, struct sshkey *bad) | ||
147 | { | ||
148 | u_char i, buf[2049]; | ||
149 | size_t lens[] = { | ||
150 | 1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129, | ||
151 | 255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049 | ||
152 | }; | ||
153 | |||
154 | for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) { | ||
155 | test_subtest_info("%s key, banana length %zu", | ||
156 | sshkey_type(k), lens[i]); | ||
157 | banana(buf, lens[i]); | ||
158 | signature_test(k, bad, buf, lens[i]); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | static struct sshkey * | ||
163 | get_private(const char *n) | ||
164 | { | ||
165 | struct sshbuf *b; | ||
166 | struct sshkey *ret; | ||
167 | |||
168 | b = load_file(n); | ||
169 | ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", n, &ret, NULL), 0); | ||
170 | sshbuf_free(b); | ||
171 | return ret; | ||
172 | } | ||
173 | |||
93 | void | 174 | void |
94 | sshkey_tests(void) | 175 | sshkey_tests(void) |
95 | { | 176 | { |
96 | struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf; | 177 | struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf; |
178 | #ifdef OPENSSL_HAS_ECC | ||
179 | struct sshkey *ke; | ||
180 | #endif | ||
97 | struct sshbuf *b; | 181 | struct sshbuf *b; |
98 | 182 | ||
99 | TEST_START("new invalid"); | 183 | TEST_START("new invalid"); |
@@ -136,12 +220,14 @@ sshkey_tests(void) | |||
136 | sshkey_free(k1); | 220 | sshkey_free(k1); |
137 | TEST_DONE(); | 221 | TEST_DONE(); |
138 | 222 | ||
223 | #ifdef OPENSSL_HAS_ECC | ||
139 | TEST_START("new/free KEY_ECDSA"); | 224 | TEST_START("new/free KEY_ECDSA"); |
140 | k1 = sshkey_new(KEY_ECDSA); | 225 | k1 = sshkey_new(KEY_ECDSA); |
141 | ASSERT_PTR_NE(k1, NULL); | 226 | ASSERT_PTR_NE(k1, NULL); |
142 | ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ | 227 | ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ |
143 | sshkey_free(k1); | 228 | sshkey_free(k1); |
144 | TEST_DONE(); | 229 | TEST_DONE(); |
230 | #endif | ||
145 | 231 | ||
146 | TEST_START("new/free KEY_ED25519"); | 232 | TEST_START("new/free KEY_ED25519"); |
147 | k1 = sshkey_new(KEY_ED25519); | 233 | k1 = sshkey_new(KEY_ED25519); |
@@ -192,12 +278,14 @@ sshkey_tests(void) | |||
192 | sshkey_free(k1); | 278 | sshkey_free(k1); |
193 | TEST_DONE(); | 279 | TEST_DONE(); |
194 | 280 | ||
281 | #ifdef OPENSSL_HAS_ECC | ||
195 | TEST_START("generate KEY_ECDSA wrong bits"); | 282 | TEST_START("generate KEY_ECDSA wrong bits"); |
196 | ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), | 283 | ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), |
197 | SSH_ERR_INVALID_ARGUMENT); | 284 | SSH_ERR_INVALID_ARGUMENT); |
198 | ASSERT_PTR_EQ(k1, NULL); | 285 | ASSERT_PTR_EQ(k1, NULL); |
199 | sshkey_free(k1); | 286 | sshkey_free(k1); |
200 | TEST_DONE(); | 287 | TEST_DONE(); |
288 | #endif | ||
201 | 289 | ||
202 | TEST_START("generate KEY_RSA"); | 290 | TEST_START("generate KEY_RSA"); |
203 | ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0); | 291 | ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0); |
@@ -332,26 +420,100 @@ sshkey_tests(void) | |||
332 | #endif | 420 | #endif |
333 | sshkey_free(kf); | 421 | sshkey_free(kf); |
334 | 422 | ||
335 | /* XXX certify test */ | 423 | TEST_START("certify key"); |
336 | /* XXX sign test */ | 424 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), |
337 | /* XXX verify test */ | 425 | &k1, NULL), 0); |
426 | k2 = get_private("ed25519_2"); | ||
427 | ASSERT_INT_EQ(sshkey_to_certified(k1, 0), 0); | ||
428 | ASSERT_PTR_NE(k1->cert, NULL); | ||
429 | k1->cert->type = SSH2_CERT_TYPE_USER; | ||
430 | k1->cert->serial = 1234; | ||
431 | k1->cert->key_id = strdup("estragon"); | ||
432 | ASSERT_PTR_NE(k1->cert->key_id, NULL); | ||
433 | k1->cert->principals = calloc(4, sizeof(*k1->cert->principals)); | ||
434 | ASSERT_PTR_NE(k1->cert->principals, NULL); | ||
435 | k1->cert->principals[0] = strdup("estragon"); | ||
436 | k1->cert->principals[1] = strdup("vladimir"); | ||
437 | k1->cert->principals[2] = strdup("pozzo"); | ||
438 | k1->cert->principals[3] = strdup("lucky"); | ||
439 | ASSERT_PTR_NE(k1->cert->principals[0], NULL); | ||
440 | ASSERT_PTR_NE(k1->cert->principals[1], NULL); | ||
441 | ASSERT_PTR_NE(k1->cert->principals[2], NULL); | ||
442 | ASSERT_PTR_NE(k1->cert->principals[3], NULL); | ||
443 | k1->cert->valid_after = 0; | ||
444 | k1->cert->valid_before = (u_int64_t)-1; | ||
445 | k1->cert->critical = sshbuf_new(); | ||
446 | ASSERT_PTR_NE(k1->cert->critical, NULL); | ||
447 | k1->cert->extensions = sshbuf_new(); | ||
448 | ASSERT_PTR_NE(k1->cert->extensions, NULL); | ||
449 | put_opt(k1->cert->critical, "force-command", "/usr/bin/true"); | ||
450 | put_opt(k1->cert->critical, "source-address", "127.0.0.1"); | ||
451 | put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL); | ||
452 | put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL); | ||
453 | ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0); | ||
454 | ASSERT_INT_EQ(sshkey_certify(k1, k2), 0); | ||
455 | b = sshbuf_new(); | ||
456 | ASSERT_PTR_NE(b, NULL); | ||
457 | ASSERT_INT_EQ(sshkey_putb(k1, b), 0); | ||
458 | ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0); | ||
459 | |||
460 | sshkey_free(k1); | ||
461 | sshkey_free(k2); | ||
462 | sshkey_free(k3); | ||
463 | sshbuf_reset(b); | ||
464 | TEST_DONE(); | ||
465 | |||
466 | TEST_START("sign and verify RSA"); | ||
467 | k1 = get_private("rsa_1"); | ||
468 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, | ||
469 | NULL), 0); | ||
470 | signature_tests(k1, k2); | ||
471 | sshkey_free(k1); | ||
472 | sshkey_free(k2); | ||
473 | TEST_DONE(); | ||
474 | |||
475 | TEST_START("sign and verify DSA"); | ||
476 | k1 = get_private("dsa_1"); | ||
477 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2, | ||
478 | NULL), 0); | ||
479 | signature_tests(k1, k2); | ||
480 | sshkey_free(k1); | ||
481 | sshkey_free(k2); | ||
482 | TEST_DONE(); | ||
483 | |||
484 | #ifdef OPENSSL_HAS_ECC | ||
485 | TEST_START("sign and verify ECDSA"); | ||
486 | k1 = get_private("ecdsa_1"); | ||
487 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2, | ||
488 | NULL), 0); | ||
489 | signature_tests(k1, k2); | ||
490 | sshkey_free(k1); | ||
491 | sshkey_free(k2); | ||
492 | TEST_DONE(); | ||
493 | #endif | ||
494 | |||
495 | TEST_START("sign and verify ED25519"); | ||
496 | k1 = get_private("ed25519_1"); | ||
497 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2, | ||
498 | NULL), 0); | ||
499 | signature_tests(k1, k2); | ||
500 | sshkey_free(k1); | ||
501 | sshkey_free(k2); | ||
502 | TEST_DONE(); | ||
338 | 503 | ||
339 | TEST_START("nested certificate"); | 504 | TEST_START("nested certificate"); |
340 | ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); | 505 | ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); |
341 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, | 506 | ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, |
342 | NULL), 0); | 507 | NULL), 0); |
343 | b = load_file("rsa_2"); | 508 | k3 = get_private("ed25519_2"); |
344 | ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1", | ||
345 | &k3, NULL), 0); | ||
346 | sshbuf_reset(b); | ||
347 | build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); | 509 | build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); |
348 | ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), | 510 | ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), |
349 | SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); | 511 | SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); |
350 | ASSERT_PTR_EQ(k4, NULL); | 512 | ASSERT_PTR_EQ(k4, NULL); |
351 | sshbuf_free(b); | ||
352 | sshkey_free(k1); | 513 | sshkey_free(k1); |
353 | sshkey_free(k2); | 514 | sshkey_free(k2); |
354 | sshkey_free(k3); | 515 | sshkey_free(k3); |
516 | sshbuf_free(b); | ||
355 | TEST_DONE(); | 517 | TEST_DONE(); |
356 | 518 | ||
357 | } | 519 | } |
diff --git a/regress/unittests/sshkey/testdata/dsa_1-cert.fp b/regress/unittests/sshkey/testdata/dsa_1-cert.fp index 56ee1f89b..b26145b24 100644 --- a/regress/unittests/sshkey/testdata/dsa_1-cert.fp +++ b/regress/unittests/sshkey/testdata/dsa_1-cert.fp | |||
@@ -1 +1 @@ | |||
5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74 | MD5:5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74 | ||
diff --git a/regress/unittests/sshkey/testdata/dsa_1.fp b/regress/unittests/sshkey/testdata/dsa_1.fp index 56ee1f89b..b26145b24 100644 --- a/regress/unittests/sshkey/testdata/dsa_1.fp +++ b/regress/unittests/sshkey/testdata/dsa_1.fp | |||
@@ -1 +1 @@ | |||
5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74 | MD5:5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74 | ||
diff --git a/regress/unittests/sshkey/testdata/dsa_2.fp b/regress/unittests/sshkey/testdata/dsa_2.fp index ba9de82a8..822657403 100644 --- a/regress/unittests/sshkey/testdata/dsa_2.fp +++ b/regress/unittests/sshkey/testdata/dsa_2.fp | |||
@@ -1 +1 @@ | |||
72:5f:50:6b:e5:64:c5:62:21:92:3f:8b:10:9b:9f:1a | MD5:72:5f:50:6b:e5:64:c5:62:21:92:3f:8b:10:9b:9f:1a | ||
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp b/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp index a56dbc8d0..c3d747aff 100644 --- a/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp +++ b/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp | |||
@@ -1 +1 @@ | |||
f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44 | MD5:f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44 | ||
diff --git a/regress/unittests/sshkey/testdata/ecdsa_1.fp b/regress/unittests/sshkey/testdata/ecdsa_1.fp index a56dbc8d0..c3d747aff 100644 --- a/regress/unittests/sshkey/testdata/ecdsa_1.fp +++ b/regress/unittests/sshkey/testdata/ecdsa_1.fp | |||
@@ -1 +1 @@ | |||
f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44 | MD5:f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44 | ||
diff --git a/regress/unittests/sshkey/testdata/ecdsa_2.fp b/regress/unittests/sshkey/testdata/ecdsa_2.fp index eb4bbdf03..fe7526b92 100644 --- a/regress/unittests/sshkey/testdata/ecdsa_2.fp +++ b/regress/unittests/sshkey/testdata/ecdsa_2.fp | |||
@@ -1 +1 @@ | |||
51:bd:ff:2b:6d:26:9b:90:f9:e1:4a:ca:a0:29:8e:70 | MD5:51:bd:ff:2b:6d:26:9b:90:f9:e1:4a:ca:a0:29:8e:70 | ||
diff --git a/regress/unittests/sshkey/testdata/ed25519_1-cert.fp b/regress/unittests/sshkey/testdata/ed25519_1-cert.fp index e6d23d0b8..fbde87af0 100644 --- a/regress/unittests/sshkey/testdata/ed25519_1-cert.fp +++ b/regress/unittests/sshkey/testdata/ed25519_1-cert.fp | |||
@@ -1 +1 @@ | |||
19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f | MD5:19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f | ||
diff --git a/regress/unittests/sshkey/testdata/ed25519_1.fp b/regress/unittests/sshkey/testdata/ed25519_1.fp index e6d23d0b8..fbde87af0 100644 --- a/regress/unittests/sshkey/testdata/ed25519_1.fp +++ b/regress/unittests/sshkey/testdata/ed25519_1.fp | |||
@@ -1 +1 @@ | |||
19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f | MD5:19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f | ||
diff --git a/regress/unittests/sshkey/testdata/ed25519_2.fp b/regress/unittests/sshkey/testdata/ed25519_2.fp index 02c684f36..ec1cdbb94 100644 --- a/regress/unittests/sshkey/testdata/ed25519_2.fp +++ b/regress/unittests/sshkey/testdata/ed25519_2.fp | |||
@@ -1 +1 @@ | |||
5c:c9:ae:a3:0c:aa:28:29:b8:fc:7c:64:ba:6e:e9:c9 | MD5:5c:c9:ae:a3:0c:aa:28:29:b8:fc:7c:64:ba:6e:e9:c9 | ||
diff --git a/regress/unittests/sshkey/testdata/rsa1_1.fp b/regress/unittests/sshkey/testdata/rsa1_1.fp index 782ece0db..2e1068c64 100644 --- a/regress/unittests/sshkey/testdata/rsa1_1.fp +++ b/regress/unittests/sshkey/testdata/rsa1_1.fp | |||
@@ -1 +1 @@ | |||
a8:82:9b:98:c5:e6:19:d6:83:39:9f:4d:3a:8f:7c:80 | MD5:a8:82:9b:98:c5:e6:19:d6:83:39:9f:4d:3a:8f:7c:80 | ||
diff --git a/regress/unittests/sshkey/testdata/rsa1_2.fp b/regress/unittests/sshkey/testdata/rsa1_2.fp index c3325371d..cd0039306 100644 --- a/regress/unittests/sshkey/testdata/rsa1_2.fp +++ b/regress/unittests/sshkey/testdata/rsa1_2.fp | |||
@@ -1 +1 @@ | |||
c0:83:1c:97:5f:32:77:7e:e4:e3:e9:29:b9:eb:76:9c | MD5:c0:83:1c:97:5f:32:77:7e:e4:e3:e9:29:b9:eb:76:9c | ||
diff --git a/regress/unittests/sshkey/testdata/rsa_1-cert.fp b/regress/unittests/sshkey/testdata/rsa_1-cert.fp index bf9c2e362..1cf780dd9 100644 --- a/regress/unittests/sshkey/testdata/rsa_1-cert.fp +++ b/regress/unittests/sshkey/testdata/rsa_1-cert.fp | |||
@@ -1 +1 @@ | |||
be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b | MD5:be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b | ||
diff --git a/regress/unittests/sshkey/testdata/rsa_1.fp b/regress/unittests/sshkey/testdata/rsa_1.fp index bf9c2e362..1cf780dd9 100644 --- a/regress/unittests/sshkey/testdata/rsa_1.fp +++ b/regress/unittests/sshkey/testdata/rsa_1.fp | |||
@@ -1 +1 @@ | |||
be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b | MD5:be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b | ||
diff --git a/regress/unittests/sshkey/testdata/rsa_2.fp b/regress/unittests/sshkey/testdata/rsa_2.fp index 53939f413..8d4367610 100644 --- a/regress/unittests/sshkey/testdata/rsa_2.fp +++ b/regress/unittests/sshkey/testdata/rsa_2.fp | |||
@@ -1 +1 @@ | |||
fb:8f:7b:26:3d:42:40:ef:ed:f1:ed:ee:66:9e:ba:b0 | MD5:fb:8f:7b:26:3d:42:40:ef:ed:f1:ed:ee:66:9e:ba:b0 | ||
diff --git a/regress/unittests/test_helper/Makefile b/regress/unittests/test_helper/Makefile index 3e90903ef..5b3894cbf 100644 --- a/regress/unittests/test_helper/Makefile +++ b/regress/unittests/test_helper/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $ | 1 | # $OpenBSD: Makefile,v 1.2 2015/01/20 22:58:57 djm Exp $ |
2 | 2 | ||
3 | LIB= test_helper | 3 | LIB= test_helper |
4 | SRCS= test_helper.c fuzz.c | 4 | SRCS= test_helper.c fuzz.c |
@@ -7,6 +7,9 @@ DEBUGLIBS= no | |||
7 | NOPROFILE= yes | 7 | NOPROFILE= yes |
8 | NOPIC= yes | 8 | NOPIC= yes |
9 | 9 | ||
10 | # Hack to allow building with SUBDIR in ../../Makefile | ||
11 | regress: all | ||
12 | |||
10 | install: | 13 | install: |
11 | @echo -n | 14 | @echo -n |
12 | 15 | ||
diff --git a/regress/unittests/test_helper/fuzz.c b/regress/unittests/test_helper/fuzz.c index 77c6e7cad..99f1d036c 100644 --- a/regress/unittests/test_helper/fuzz.c +++ b/regress/unittests/test_helper/fuzz.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: fuzz.c,v 1.3 2014/05/02 09:41:32 andre Exp $ */ | 1 | /* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -20,6 +20,7 @@ | |||
20 | #include "includes.h" | 20 | #include "includes.h" |
21 | 21 | ||
22 | #include <sys/types.h> | 22 | #include <sys/types.h> |
23 | #include <sys/uio.h> | ||
23 | 24 | ||
24 | #include <assert.h> | 25 | #include <assert.h> |
25 | #include <ctype.h> | 26 | #include <ctype.h> |
@@ -29,9 +30,11 @@ | |||
29 | #endif | 30 | #endif |
30 | #include <stdlib.h> | 31 | #include <stdlib.h> |
31 | #include <string.h> | 32 | #include <string.h> |
32 | #include <assert.h> | 33 | #include <signal.h> |
34 | #include <unistd.h> | ||
33 | 35 | ||
34 | #include "test_helper.h" | 36 | #include "test_helper.h" |
37 | #include "atomicio.h" | ||
35 | 38 | ||
36 | /* #define FUZZ_DEBUG */ | 39 | /* #define FUZZ_DEBUG */ |
37 | 40 | ||
@@ -96,60 +99,66 @@ fuzz_ntop(u_int n) | |||
96 | } | 99 | } |
97 | } | 100 | } |
98 | 101 | ||
99 | void | 102 | static int |
100 | fuzz_dump(struct fuzz *fuzz) | 103 | fuzz_fmt(struct fuzz *fuzz, char *s, size_t n) |
101 | { | 104 | { |
102 | u_char *p = fuzz_ptr(fuzz); | 105 | if (fuzz == NULL) |
103 | size_t i, j, len = fuzz_len(fuzz); | 106 | return -1; |
104 | 107 | ||
105 | switch (fuzz->strategy) { | 108 | switch (fuzz->strategy) { |
106 | case FUZZ_1_BIT_FLIP: | 109 | case FUZZ_1_BIT_FLIP: |
107 | fprintf(stderr, "%s case %zu of %zu (bit: %zu)\n", | 110 | snprintf(s, n, "%s case %zu of %zu (bit: %zu)\n", |
108 | fuzz_ntop(fuzz->strategy), | 111 | fuzz_ntop(fuzz->strategy), |
109 | fuzz->o1, fuzz->slen * 8, fuzz->o1); | 112 | fuzz->o1, fuzz->slen * 8, fuzz->o1); |
110 | break; | 113 | return 0; |
111 | case FUZZ_2_BIT_FLIP: | 114 | case FUZZ_2_BIT_FLIP: |
112 | fprintf(stderr, "%s case %llu of %llu (bits: %zu, %zu)\n", | 115 | snprintf(s, n, "%s case %llu of %llu (bits: %zu, %zu)\n", |
113 | fuzz_ntop(fuzz->strategy), | 116 | fuzz_ntop(fuzz->strategy), |
114 | (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1, | 117 | (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1, |
115 | ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8, | 118 | ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8, |
116 | fuzz->o1, fuzz->o2); | 119 | fuzz->o1, fuzz->o2); |
117 | break; | 120 | return 0; |
118 | case FUZZ_1_BYTE_FLIP: | 121 | case FUZZ_1_BYTE_FLIP: |
119 | fprintf(stderr, "%s case %zu of %zu (byte: %zu)\n", | 122 | snprintf(s, n, "%s case %zu of %zu (byte: %zu)\n", |
120 | fuzz_ntop(fuzz->strategy), | 123 | fuzz_ntop(fuzz->strategy), |
121 | fuzz->o1, fuzz->slen, fuzz->o1); | 124 | fuzz->o1, fuzz->slen, fuzz->o1); |
122 | break; | 125 | return 0; |
123 | case FUZZ_2_BYTE_FLIP: | 126 | case FUZZ_2_BYTE_FLIP: |
124 | fprintf(stderr, "%s case %llu of %llu (bytes: %zu, %zu)\n", | 127 | snprintf(s, n, "%s case %llu of %llu (bytes: %zu, %zu)\n", |
125 | fuzz_ntop(fuzz->strategy), | 128 | fuzz_ntop(fuzz->strategy), |
126 | (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1, | 129 | (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1, |
127 | ((fuzz_ullong)fuzz->slen) * fuzz->slen, | 130 | ((fuzz_ullong)fuzz->slen) * fuzz->slen, |
128 | fuzz->o1, fuzz->o2); | 131 | fuzz->o1, fuzz->o2); |
129 | break; | 132 | return 0; |
130 | case FUZZ_TRUNCATE_START: | 133 | case FUZZ_TRUNCATE_START: |
131 | fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n", | 134 | snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", |
132 | fuzz_ntop(fuzz->strategy), | 135 | fuzz_ntop(fuzz->strategy), |
133 | fuzz->o1, fuzz->slen, fuzz->o1); | 136 | fuzz->o1, fuzz->slen, fuzz->o1); |
134 | break; | 137 | return 0; |
135 | case FUZZ_TRUNCATE_END: | 138 | case FUZZ_TRUNCATE_END: |
136 | fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n", | 139 | snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", |
137 | fuzz_ntop(fuzz->strategy), | 140 | fuzz_ntop(fuzz->strategy), |
138 | fuzz->o1, fuzz->slen, fuzz->o1); | 141 | fuzz->o1, fuzz->slen, fuzz->o1); |
139 | break; | 142 | return 0; |
140 | case FUZZ_BASE64: | 143 | case FUZZ_BASE64: |
141 | assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); | 144 | assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); |
142 | fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n", | 145 | snprintf(s, n, "%s case %llu of %llu (offset: %zu char: %c)\n", |
143 | fuzz_ntop(fuzz->strategy), | 146 | fuzz_ntop(fuzz->strategy), |
144 | (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2, | 147 | (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2, |
145 | fuzz->slen * (fuzz_ullong)64, fuzz->o1, | 148 | fuzz->slen * (fuzz_ullong)64, fuzz->o1, |
146 | fuzz_b64chars[fuzz->o2]); | 149 | fuzz_b64chars[fuzz->o2]); |
147 | break; | 150 | return 0; |
148 | default: | 151 | default: |
152 | return -1; | ||
149 | abort(); | 153 | abort(); |
150 | } | 154 | } |
155 | } | ||
156 | |||
157 | static void | ||
158 | dump(u_char *p, size_t len) | ||
159 | { | ||
160 | size_t i, j; | ||
151 | 161 | ||
152 | fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, len); | ||
153 | for (i = 0; i < len; i += 16) { | 162 | for (i = 0; i < len; i += 16) { |
154 | fprintf(stderr, "%.4zd: ", i); | 163 | fprintf(stderr, "%.4zd: ", i); |
155 | for (j = i; j < i + 16; j++) { | 164 | for (j = i; j < i + 16; j++) { |
@@ -171,6 +180,39 @@ fuzz_dump(struct fuzz *fuzz) | |||
171 | } | 180 | } |
172 | } | 181 | } |
173 | 182 | ||
183 | void | ||
184 | fuzz_dump(struct fuzz *fuzz) | ||
185 | { | ||
186 | char buf[256]; | ||
187 | |||
188 | if (fuzz_fmt(fuzz, buf, sizeof(buf)) != 0) { | ||
189 | fprintf(stderr, "%s: fuzz invalid\n", __func__); | ||
190 | abort(); | ||
191 | } | ||
192 | fputs(buf, stderr); | ||
193 | fprintf(stderr, "fuzz original %p len = %zu\n", fuzz->seed, fuzz->slen); | ||
194 | dump(fuzz->seed, fuzz->slen); | ||
195 | fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, fuzz_len(fuzz)); | ||
196 | dump(fuzz_ptr(fuzz), fuzz_len(fuzz)); | ||
197 | } | ||
198 | |||
199 | #ifdef SIGINFO | ||
200 | static struct fuzz *last_fuzz; | ||
201 | |||
202 | static void | ||
203 | siginfo(int unused __attribute__((__unused__))) | ||
204 | { | ||
205 | char buf[256]; | ||
206 | |||
207 | test_info(buf, sizeof(buf)); | ||
208 | atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); | ||
209 | if (last_fuzz != NULL) { | ||
210 | fuzz_fmt(last_fuzz, buf, sizeof(buf)); | ||
211 | atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); | ||
212 | } | ||
213 | } | ||
214 | #endif | ||
215 | |||
174 | struct fuzz * | 216 | struct fuzz * |
175 | fuzz_begin(u_int strategies, const void *p, size_t l) | 217 | fuzz_begin(u_int strategies, const void *p, size_t l) |
176 | { | 218 | { |
@@ -190,6 +232,12 @@ fuzz_begin(u_int strategies, const void *p, size_t l) | |||
190 | FUZZ_DBG(("begin, ret = %p", ret)); | 232 | FUZZ_DBG(("begin, ret = %p", ret)); |
191 | 233 | ||
192 | fuzz_next(ret); | 234 | fuzz_next(ret); |
235 | |||
236 | #ifdef SIGINFO | ||
237 | last_fuzz = ret; | ||
238 | signal(SIGINFO, siginfo); | ||
239 | #endif | ||
240 | |||
193 | return ret; | 241 | return ret; |
194 | } | 242 | } |
195 | 243 | ||
@@ -197,6 +245,10 @@ void | |||
197 | fuzz_cleanup(struct fuzz *fuzz) | 245 | fuzz_cleanup(struct fuzz *fuzz) |
198 | { | 246 | { |
199 | FUZZ_DBG(("cleanup, fuzz = %p", fuzz)); | 247 | FUZZ_DBG(("cleanup, fuzz = %p", fuzz)); |
248 | #ifdef SIGINFO | ||
249 | last_fuzz = NULL; | ||
250 | signal(SIGINFO, SIG_DFL); | ||
251 | #endif | ||
200 | assert(fuzz != NULL); | 252 | assert(fuzz != NULL); |
201 | assert(fuzz->seed != NULL); | 253 | assert(fuzz->seed != NULL); |
202 | assert(fuzz->fuzzed != NULL); | 254 | assert(fuzz->fuzzed != NULL); |
@@ -326,6 +378,14 @@ fuzz_next(struct fuzz *fuzz) | |||
326 | } | 378 | } |
327 | 379 | ||
328 | int | 380 | int |
381 | fuzz_matches_original(struct fuzz *fuzz) | ||
382 | { | ||
383 | if (fuzz_len(fuzz) != fuzz->slen) | ||
384 | return 0; | ||
385 | return memcmp(fuzz_ptr(fuzz), fuzz->seed, fuzz->slen) == 0; | ||
386 | } | ||
387 | |||
388 | int | ||
329 | fuzz_done(struct fuzz *fuzz) | 389 | fuzz_done(struct fuzz *fuzz) |
330 | { | 390 | { |
331 | FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz, | 391 | FUZZ_DBG(("fuzz = %p, strategies = 0x%lx", fuzz, |
diff --git a/regress/unittests/test_helper/test_helper.c b/regress/unittests/test_helper/test_helper.c index d0bc67833..26ca26b5e 100644 --- a/regress/unittests/test_helper/test_helper.c +++ b/regress/unittests/test_helper/test_helper.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */ | 1 | /* $OpenBSD: test_helper.c,v 1.6 2015/03/03 20:42:49 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <sys/types.h> | 22 | #include <sys/types.h> |
23 | #include <sys/param.h> | 23 | #include <sys/param.h> |
24 | #include <sys/uio.h> | ||
24 | 25 | ||
25 | #include <fcntl.h> | 26 | #include <fcntl.h> |
26 | #include <stdio.h> | 27 | #include <stdio.h> |
@@ -31,6 +32,7 @@ | |||
31 | #include <string.h> | 32 | #include <string.h> |
32 | #include <assert.h> | 33 | #include <assert.h> |
33 | #include <unistd.h> | 34 | #include <unistd.h> |
35 | #include <signal.h> | ||
34 | 36 | ||
35 | #include <openssl/bn.h> | 37 | #include <openssl/bn.h> |
36 | 38 | ||
@@ -39,6 +41,7 @@ | |||
39 | #endif | 41 | #endif |
40 | 42 | ||
41 | #include "test_helper.h" | 43 | #include "test_helper.h" |
44 | #include "atomicio.h" | ||
42 | 45 | ||
43 | #define TEST_CHECK_INT(r, pred) do { \ | 46 | #define TEST_CHECK_INT(r, pred) do { \ |
44 | switch (pred) { \ | 47 | switch (pred) { \ |
@@ -111,6 +114,7 @@ static u_int test_number = 0; | |||
111 | static test_onerror_func_t *test_onerror = NULL; | 114 | static test_onerror_func_t *test_onerror = NULL; |
112 | static void *onerror_ctx = NULL; | 115 | static void *onerror_ctx = NULL; |
113 | static const char *data_dir = NULL; | 116 | static const char *data_dir = NULL; |
117 | static char subtest_info[512]; | ||
114 | 118 | ||
115 | int | 119 | int |
116 | main(int argc, char **argv) | 120 | main(int argc, char **argv) |
@@ -180,13 +184,36 @@ test_data_file(const char *name) | |||
180 | } | 184 | } |
181 | 185 | ||
182 | void | 186 | void |
187 | test_info(char *s, size_t len) | ||
188 | { | ||
189 | snprintf(s, len, "In test %u: \"%s\"%s%s\n", test_number, | ||
190 | active_test_name == NULL ? "<none>" : active_test_name, | ||
191 | *subtest_info != '\0' ? " - " : "", subtest_info); | ||
192 | } | ||
193 | |||
194 | #ifdef SIGINFO | ||
195 | static void | ||
196 | siginfo(int unused __attribute__((__unused__))) | ||
197 | { | ||
198 | char buf[256]; | ||
199 | |||
200 | test_info(buf, sizeof(buf)); | ||
201 | atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); | ||
202 | } | ||
203 | #endif | ||
204 | |||
205 | void | ||
183 | test_start(const char *n) | 206 | test_start(const char *n) |
184 | { | 207 | { |
185 | assert(active_test_name == NULL); | 208 | assert(active_test_name == NULL); |
186 | assert((active_test_name = strdup(n)) != NULL); | 209 | assert((active_test_name = strdup(n)) != NULL); |
210 | *subtest_info = '\0'; | ||
187 | if (verbose_mode) | 211 | if (verbose_mode) |
188 | printf("test %u - \"%s\": ", test_number, active_test_name); | 212 | printf("test %u - \"%s\": ", test_number, active_test_name); |
189 | test_number++; | 213 | test_number++; |
214 | #ifdef SIGINFO | ||
215 | signal(SIGINFO, siginfo); | ||
216 | #endif | ||
190 | } | 217 | } |
191 | 218 | ||
192 | void | 219 | void |
@@ -199,6 +226,7 @@ set_onerror_func(test_onerror_func_t *f, void *ctx) | |||
199 | void | 226 | void |
200 | test_done(void) | 227 | test_done(void) |
201 | { | 228 | { |
229 | *subtest_info = '\0'; | ||
202 | assert(active_test_name != NULL); | 230 | assert(active_test_name != NULL); |
203 | free(active_test_name); | 231 | free(active_test_name); |
204 | active_test_name = NULL; | 232 | active_test_name = NULL; |
@@ -211,6 +239,16 @@ test_done(void) | |||
211 | } | 239 | } |
212 | 240 | ||
213 | void | 241 | void |
242 | test_subtest_info(const char *fmt, ...) | ||
243 | { | ||
244 | va_list ap; | ||
245 | |||
246 | va_start(ap, fmt); | ||
247 | vsnprintf(subtest_info, sizeof(subtest_info), fmt, ap); | ||
248 | va_end(ap); | ||
249 | } | ||
250 | |||
251 | void | ||
214 | ssl_err_check(const char *file, int line) | 252 | ssl_err_check(const char *file, int line) |
215 | { | 253 | { |
216 | long openssl_error = ERR_get_error(); | 254 | long openssl_error = ERR_get_error(); |
@@ -256,8 +294,9 @@ static void | |||
256 | test_header(const char *file, int line, const char *a1, const char *a2, | 294 | test_header(const char *file, int line, const char *a1, const char *a2, |
257 | const char *name, enum test_predicate pred) | 295 | const char *name, enum test_predicate pred) |
258 | { | 296 | { |
259 | fprintf(stderr, "\n%s:%d test #%u \"%s\"\n", | 297 | fprintf(stderr, "\n%s:%d test #%u \"%s\"%s%s\n", |
260 | file, line, test_number, active_test_name); | 298 | file, line, test_number, active_test_name, |
299 | *subtest_info != '\0' ? " - " : "", subtest_info); | ||
261 | fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", | 300 | fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", |
262 | name, pred_name(pred), a1, | 301 | name, pred_name(pred), a1, |
263 | a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); | 302 | a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); |
@@ -280,8 +319,13 @@ void | |||
280 | assert_string(const char *file, int line, const char *a1, const char *a2, | 319 | assert_string(const char *file, int line, const char *a1, const char *a2, |
281 | const char *aa1, const char *aa2, enum test_predicate pred) | 320 | const char *aa1, const char *aa2, enum test_predicate pred) |
282 | { | 321 | { |
283 | int r = strcmp(aa1, aa2); | 322 | int r; |
284 | 323 | ||
324 | /* Verify pointers are not NULL */ | ||
325 | assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); | ||
326 | assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); | ||
327 | |||
328 | r = strcmp(aa1, aa2); | ||
285 | TEST_CHECK_INT(r, pred); | 329 | TEST_CHECK_INT(r, pred); |
286 | test_header(file, line, a1, a2, "STRING", pred); | 330 | test_header(file, line, a1, a2, "STRING", pred); |
287 | fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); | 331 | fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); |
@@ -310,8 +354,15 @@ void | |||
310 | assert_mem(const char *file, int line, const char *a1, const char *a2, | 354 | assert_mem(const char *file, int line, const char *a1, const char *a2, |
311 | const void *aa1, const void *aa2, size_t l, enum test_predicate pred) | 355 | const void *aa1, const void *aa2, size_t l, enum test_predicate pred) |
312 | { | 356 | { |
313 | int r = memcmp(aa1, aa2, l); | 357 | int r; |
314 | 358 | ||
359 | if (l == 0) | ||
360 | return; | ||
361 | /* If length is >0, then verify pointers are not NULL */ | ||
362 | assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); | ||
363 | assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); | ||
364 | |||
365 | r = memcmp(aa1, aa2, l); | ||
315 | TEST_CHECK_INT(r, pred); | 366 | TEST_CHECK_INT(r, pred); |
316 | test_header(file, line, a1, a2, "STRING", pred); | 367 | test_header(file, line, a1, a2, "STRING", pred); |
317 | fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l); | 368 | fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l); |
@@ -338,11 +389,15 @@ assert_mem_filled(const char *file, int line, const char *a1, | |||
338 | const void *aa1, u_char v, size_t l, enum test_predicate pred) | 389 | const void *aa1, u_char v, size_t l, enum test_predicate pred) |
339 | { | 390 | { |
340 | size_t where = -1; | 391 | size_t where = -1; |
341 | int r = memvalcmp(aa1, v, l, &where); | 392 | int r; |
342 | char tmp[64]; | 393 | char tmp[64]; |
343 | 394 | ||
344 | if (l == 0) | 395 | if (l == 0) |
345 | return; | 396 | return; |
397 | /* If length is >0, then verify the pointer is not NULL */ | ||
398 | assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); | ||
399 | |||
400 | r = memvalcmp(aa1, v, l, &where); | ||
346 | TEST_CHECK_INT(r, pred); | 401 | TEST_CHECK_INT(r, pred); |
347 | test_header(file, line, a1, NULL, "MEM_ZERO", pred); | 402 | test_header(file, line, a1, NULL, "MEM_ZERO", pred); |
348 | fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, | 403 | fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, |
diff --git a/regress/unittests/test_helper/test_helper.h b/regress/unittests/test_helper/test_helper.h index a398c615f..1d9c66986 100644 --- a/regress/unittests/test_helper/test_helper.h +++ b/regress/unittests/test_helper/test_helper.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: test_helper.h,v 1.3 2014/05/02 09:41:32 andre Exp $ */ | 1 | /* $OpenBSD: test_helper.h,v 1.6 2015/01/18 19:52:44 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2011 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -40,8 +40,11 @@ void tests(void); | |||
40 | 40 | ||
41 | const char *test_data_file(const char *name); | 41 | const char *test_data_file(const char *name); |
42 | void test_start(const char *n); | 42 | void test_start(const char *n); |
43 | void test_info(char *s, size_t len); | ||
43 | void set_onerror_func(test_onerror_func_t *f, void *ctx); | 44 | void set_onerror_func(test_onerror_func_t *f, void *ctx); |
44 | void test_done(void); | 45 | void test_done(void); |
46 | void test_subtest_info(const char *fmt, ...) | ||
47 | __attribute__((format(printf, 1, 2))); | ||
45 | void ssl_err_check(const char *file, int line); | 48 | void ssl_err_check(const char *file, int line); |
46 | void assert_bignum(const char *file, int line, | 49 | void assert_bignum(const char *file, int line, |
47 | const char *a1, const char *a2, | 50 | const char *a1, const char *a2, |
@@ -280,6 +283,13 @@ void fuzz_cleanup(struct fuzz *fuzz); | |||
280 | /* Prepare the next fuzz case in the series */ | 283 | /* Prepare the next fuzz case in the series */ |
281 | void fuzz_next(struct fuzz *fuzz); | 284 | void fuzz_next(struct fuzz *fuzz); |
282 | 285 | ||
286 | /* | ||
287 | * Check whether this fuzz case is identical to the original | ||
288 | * This is slow, but useful if the caller needs to ensure that all tests | ||
289 | * generated change the input (e.g. when fuzzing signatures). | ||
290 | */ | ||
291 | int fuzz_matches_original(struct fuzz *fuzz); | ||
292 | |||
283 | /* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */ | 293 | /* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */ |
284 | int fuzz_done(struct fuzz *fuzz); | 294 | int fuzz_done(struct fuzz *fuzz); |
285 | 295 | ||
@@ -289,4 +299,5 @@ u_char *fuzz_ptr(struct fuzz *fuzz); | |||
289 | 299 | ||
290 | /* Dump the current fuzz case to stderr */ | 300 | /* Dump the current fuzz case to stderr */ |
291 | void fuzz_dump(struct fuzz *fuzz); | 301 | void fuzz_dump(struct fuzz *fuzz); |
302 | |||
292 | #endif /* _TEST_HELPER_H */ | 303 | #endif /* _TEST_HELPER_H */ |
diff --git a/regress/valgrind-unit.sh b/regress/valgrind-unit.sh new file mode 100755 index 000000000..433cb069a --- /dev/null +++ b/regress/valgrind-unit.sh | |||
@@ -0,0 +1,20 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | UNIT_BINARY="$1" | ||
4 | shift | ||
5 | UNIT_ARGS="$@" | ||
6 | |||
7 | test "x$OBJ" = "x" && OBJ=$PWD | ||
8 | |||
9 | # This mostly replicates the logic in test-exec.sh for running the | ||
10 | # regress tests under valgrind. | ||
11 | VG_TEST=`basename $UNIT_BINARY` | ||
12 | VG_LOG="$OBJ/valgrind-out/${VG_TEST}.%p" | ||
13 | VG_OPTS="--track-origins=yes --leak-check=full --log-file=${VG_LOG}" | ||
14 | VG_OPTS="$VG_OPTS --trace-children=yes" | ||
15 | VG_PATH="valgrind" | ||
16 | if [ "x$VALGRIND_PATH" != "x" ]; then | ||
17 | VG_PATH="$VALGRIND_PATH" | ||
18 | fi | ||
19 | |||
20 | exec $VG_PATH $VG_OPTS $UNIT_BINARY $UNIT_ARGS | ||
diff --git a/regress/yes-head.sh b/regress/yes-head.sh index a8e6bc800..1fc754211 100644 --- a/regress/yes-head.sh +++ b/regress/yes-head.sh | |||
@@ -1,9 +1,9 @@ | |||
1 | # $OpenBSD: yes-head.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ | 1 | # $OpenBSD: yes-head.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ |
2 | # Placed in the Public Domain. | 2 | # Placed in the Public Domain. |
3 | 3 | ||
4 | tid="yes pipe head" | 4 | tid="yes pipe head" |
5 | 5 | ||
6 | for p in 1 2; do | 6 | for p in ${SSH_PROTOCOLS}; do |
7 | lines=`${SSH} -$p -F $OBJ/ssh_proxy thishost 'sh -c "while true;do echo yes;done | _POSIX2_VERSION=199209 head -2000"' | (sleep 3 ; wc -l)` | 7 | lines=`${SSH} -$p -F $OBJ/ssh_proxy thishost 'sh -c "while true;do echo yes;done | _POSIX2_VERSION=199209 head -2000"' | (sleep 3 ; wc -l)` |
8 | if [ $? -ne 0 ]; then | 8 | if [ $? -ne 0 ]; then |
9 | fail "yes|head test failed" | 9 | fail "yes|head test failed" |