summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2017-10-04 11:23:58 +0100
committerColin Watson <cjwatson@debian.org>2017-10-04 11:23:58 +0100
commit62f54f20bf351468e0124f63cc2902ee40d9b0e9 (patch)
tree3e090f2711b94ca5029d3fa3e8047b1ed1448b1f
parent6fabaf6fd9b07cc8bc6a17c9c4a5b76849cfc874 (diff)
parent66bf74a92131b7effe49fb0eefe5225151869dc5 (diff)
Import openssh_7.6p1.orig.tar.gz
-rw-r--r--.gitignore28
-rw-r--r--.skipped-commit-ids10
-rw-r--r--ChangeLog5065
-rw-r--r--INSTALL2
-rw-r--r--LICENCE23
-rw-r--r--Makefile.in31
-rw-r--r--PROTOCOL6
-rw-r--r--PROTOCOL.agent585
-rw-r--r--PROTOCOL.certkeys21
-rw-r--r--README10
-rw-r--r--auth-options.c14
-rw-r--r--auth-options.h4
-rw-r--r--auth-pam.c47
-rw-r--r--auth.c165
-rw-r--r--auth.h81
-rw-r--r--auth2-chall.c37
-rw-r--r--auth2-gss.c77
-rw-r--r--auth2-hostbased.c111
-rw-r--r--auth2-kbdint.c6
-rw-r--r--auth2-none.c14
-rw-r--r--auth2-passwd.c32
-rw-r--r--auth2-pubkey.c580
-rw-r--r--auth2.c173
-rw-r--r--authfd.c174
-rw-r--r--authfd.h7
-rw-r--r--authfile.c113
-rw-r--r--bitmap.c9
-rw-r--r--bufbn.c42
-rw-r--r--buffer.h6
-rw-r--r--channels.c3885
-rw-r--r--channels.h228
-rw-r--r--cipher-3des1.c158
-rw-r--r--cipher-bf1.c106
-rw-r--r--cipher.c299
-rw-r--r--cipher.h29
-rw-r--r--clientloop.c855
-rw-r--r--clientloop.h31
-rw-r--r--compat.c34
-rw-r--r--compat.h6
-rw-r--r--config.h.in42
-rwxr-xr-xconfigure335
-rw-r--r--configure.ac106
-rw-r--r--contrib/aix/README2
-rw-r--r--contrib/redhat/openssh.spec2
-rw-r--r--contrib/ssh-copy-id15
-rw-r--r--contrib/suse/openssh.spec2
-rw-r--r--deattack.c165
-rw-r--r--deattack.h38
-rw-r--r--defines.h29
-rw-r--r--digest-libc.c12
-rw-r--r--digest-openssl.c3
-rw-r--r--digest.h13
-rw-r--r--dispatch.c21
-rw-r--r--dispatch.h14
-rw-r--r--dns.c2
-rw-r--r--dns.h2
-rw-r--r--gss-serv.c11
-rw-r--r--hostfile.c33
-rw-r--r--includes.h3
-rw-r--r--kex.c81
-rw-r--r--kex.h9
-rw-r--r--kexc25519c.c7
-rw-r--r--kexc25519s.c5
-rw-r--r--kexdhc.c7
-rw-r--r--kexdhs.c7
-rw-r--r--kexecdhc.c7
-rw-r--r--kexecdhs.c7
-rw-r--r--kexgexc.c16
-rw-r--r--kexgexs.c12
-rw-r--r--key.c177
-rw-r--r--key.h36
-rw-r--r--krl.c4
-rw-r--r--log.c35
-rw-r--r--log.h4
-rw-r--r--mac.c9
-rw-r--r--md-sha256.c86
-rw-r--r--misc.c473
-rw-r--r--misc.h22
-rw-r--r--moduli.02
-rw-r--r--monitor.c103
-rw-r--r--monitor_wrap.c31
-rw-r--r--monitor_wrap.h17
-rw-r--r--mux.c239
-rw-r--r--myproposal.h5
-rw-r--r--nchan.c369
-rw-r--r--opacket.c20
-rw-r--r--opacket.h10
-rw-r--r--openbsd-compat/Makefile.in4
-rw-r--r--openbsd-compat/bsd-err.c6
-rw-r--r--openbsd-compat/bsd-getpagesize.c23
-rw-r--r--openbsd-compat/bsd-malloc.c55
-rw-r--r--openbsd-compat/bsd-misc.c10
-rw-r--r--openbsd-compat/bsd-misc.h4
-rw-r--r--openbsd-compat/explicit_bzero.c4
-rw-r--r--openbsd-compat/fmt_scaled.c18
-rw-r--r--openbsd-compat/freezero.c29
-rw-r--r--openbsd-compat/openbsd-compat.h12
-rw-r--r--openbsd-compat/port-tun.c93
-rw-r--r--openbsd-compat/port-tun.h5
-rw-r--r--openbsd-compat/recallocarray.c90
-rw-r--r--packet.c802
-rw-r--r--packet.h18
-rw-r--r--pathnames.h4
-rw-r--r--platform-misc.c35
-rw-r--r--platform.c16
-rw-r--r--readconf.c202
-rw-r--r--readconf.h16
-rw-r--r--regress/Makefile38
-rw-r--r--regress/agent-getpeereid.sh2
-rw-r--r--regress/agent-pkcs11.sh4
-rw-r--r--regress/agent.sh38
-rw-r--r--regress/authinfo.sh17
-rw-r--r--regress/banner.sh8
-rw-r--r--regress/broken-pipe.sh17
-rw-r--r--regress/brokenkeys.sh6
-rw-r--r--regress/cert-file.sh131
-rw-r--r--regress/cert-hostkey.sh14
-rw-r--r--regress/cert-userkey.sh36
-rw-r--r--regress/cfgmatch.sh76
-rw-r--r--regress/cipher-speed.sh27
-rw-r--r--regress/connect-privsep.sh30
-rw-r--r--regress/connect.sh12
-rw-r--r--regress/dhgex.sh3
-rw-r--r--regress/dynamic-forward.sh20
-rw-r--r--regress/exit-status.sh34
-rw-r--r--regress/forcecommand.sh23
-rw-r--r--regress/forward-control.sh109
-rw-r--r--regress/forwarding.sh174
-rw-r--r--regress/host-expand.sh9
-rw-r--r--regress/hostkey-agent.sh4
-rw-r--r--regress/integrity.sh10
-rw-r--r--regress/key-options.sh52
-rw-r--r--regress/keygen-change.sh5
-rw-r--r--regress/keyscan.sh6
-rw-r--r--regress/keytype.sh15
-rw-r--r--regress/localcommand.sh14
-rw-r--r--regress/login-timeout.sh20
-rw-r--r--regress/misc/fuzz-harness/Makefile22
-rw-r--r--regress/misc/fuzz-harness/README1
-rw-r--r--regress/misc/fuzz-harness/pubkey_fuzz.cc18
-rw-r--r--regress/misc/fuzz-harness/sig_fuzz.cc50
-rw-r--r--regress/misc/kexfuzz/Makefile4
-rw-r--r--regress/misc/kexfuzz/kexfuzz.c4
-rw-r--r--regress/multiplex.sh6
-rw-r--r--regress/principals-command.sh18
-rw-r--r--regress/proto-mismatch.sh12
-rw-r--r--regress/proto-version.sh16
-rw-r--r--regress/proxy-connect.sh41
-rw-r--r--regress/putty-ciphers.sh4
-rw-r--r--regress/putty-transfer.sh45
-rw-r--r--regress/reconfigure.sh22
-rw-r--r--regress/reexec.sh32
-rw-r--r--regress/ssh-com.sh4
-rw-r--r--regress/stderr-after-eof.sh4
-rw-r--r--regress/stderr-data.sh14
-rw-r--r--regress/test-exec.sh37
-rw-r--r--regress/transfer.sh29
-rw-r--r--regress/try-ciphers.sh24
-rw-r--r--regress/unittests/Makefile.inc4
-rw-r--r--regress/unittests/hostkeys/mktestdata.sh16
-rw-r--r--regress/unittests/hostkeys/test_iterate.c249
-rw-r--r--regress/unittests/hostkeys/testdata/known_hosts45
-rwxr-xr-xregress/unittests/sshkey/mktestdata.sh35
-rw-r--r--regress/unittests/sshkey/test_file.c51
-rw-r--r--regress/unittests/sshkey/test_fuzz.c45
-rw-r--r--regress/unittests/sshkey/test_sshkey.c22
-rw-r--r--regress/yes-head.sh18
-rw-r--r--rsa.c188
-rw-r--r--rsa.h26
-rw-r--r--sandbox-capsicum.c2
-rw-r--r--sandbox-seccomp-filter.c6
-rw-r--r--sandbox-solaris.c6
-rw-r--r--scp.013
-rw-r--r--scp.119
-rw-r--r--scp.c42
-rw-r--r--servconf.c117
-rw-r--r--servconf.h15
-rw-r--r--serverloop.c133
-rw-r--r--serverloop.h6
-rw-r--r--session.c377
-rw-r--r--session.h18
-rw-r--r--sftp-client.c4
-rw-r--r--sftp-common.c25
-rw-r--r--sftp-server.02
-rw-r--r--sftp-server.c6
-rw-r--r--sftp.019
-rw-r--r--sftp.120
-rw-r--r--sftp.c58
-rw-r--r--ssh-add.032
-rw-r--r--ssh-add.121
-rw-r--r--ssh-add.c109
-rw-r--r--ssh-agent.02
-rw-r--r--ssh-agent.c744
-rw-r--r--ssh-gss.h3
-rw-r--r--ssh-keygen.0161
-rw-r--r--ssh-keygen.1120
-rw-r--r--ssh-keygen.c292
-rw-r--r--ssh-keyscan.013
-rw-r--r--ssh-keyscan.114
-rw-r--r--ssh-keyscan.c129
-rw-r--r--ssh-keysign.02
-rw-r--r--ssh-pkcs11-client.c6
-rw-r--r--ssh-pkcs11-helper.02
-rw-r--r--ssh-pkcs11-helper.c14
-rw-r--r--ssh-pkcs11.c9
-rw-r--r--ssh-rsa.c45
-rw-r--r--ssh.081
-rw-r--r--ssh.192
-rw-r--r--ssh.c362
-rw-r--r--ssh.h9
-rw-r--r--ssh1.h91
-rw-r--r--ssh_api.c3
-rw-r--r--ssh_config10
-rw-r--r--ssh_config.0147
-rw-r--r--ssh_config.5137
-rw-r--r--sshbuf-getput-basic.c4
-rw-r--r--sshbuf.c17
-rw-r--r--sshbuf.h3
-rw-r--r--sshconnect.c339
-rw-r--r--sshconnect.h18
-rw-r--r--sshconnect1.c774
-rw-r--r--sshconnect2.c141
-rw-r--r--sshd.024
-rw-r--r--sshd.826
-rw-r--r--sshd.c87
-rw-r--r--sshd_config.042
-rw-r--r--sshd_config.545
-rw-r--r--ssherr.c6
-rw-r--r--ssherr.h4
-rw-r--r--sshkey.c609
-rw-r--r--sshkey.h19
-rw-r--r--ttymodes.c125
-rw-r--r--ttymodes.h21
-rw-r--r--umac.c8
-rw-r--r--utf8.c7
-rw-r--r--version.h4
-rw-r--r--xmalloc.c14
-rw-r--r--xmalloc.h3
238 files changed, 10526 insertions, 14612 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..650eb3c3c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,28 @@
1Makefile
2buildpkg.sh
3config.h
4config.h.in
5config.status
6configure
7openbsd-compat/Makefile
8openbsd-compat/regress/Makefile
9openssh.xml
10opensshd.init
11survey.sh
12**/*.0
13**/*.o
14**/*.out
15**/*.a
16autom4te.cache/
17scp
18sftp
19sftp-server
20ssh
21ssh-add
22ssh-agent
23ssh-keygen
24ssh-keyscan
25ssh-keysign
26ssh-pkcs11-helper
27sshd
28!regress/misc/fuzz-harness/Makefile
diff --git a/.skipped-commit-ids b/.skipped-commit-ids
index ee8241fb3..7c03c9db8 100644
--- a/.skipped-commit-ids
+++ b/.skipped-commit-ids
@@ -11,3 +11,13 @@ f6ae971186ba68d066cd102e57d5b0b2c211a5ee systrace is dead.
1196c5054e3e1f170c6276902d5bc65bb3b87a2603 remove DEBUGLIBS from Makefile 1196c5054e3e1f170c6276902d5bc65bb3b87a2603 remove DEBUGLIBS from Makefile
126da9a37f74aef9f9cc639004345ad893cad582d8 Update moduli file 126da9a37f74aef9f9cc639004345ad893cad582d8 Update moduli file
1377bcb50e47b68c7209c7f0a5a020d73761e5143b unset REGRESS_FAIL_EARLY 1377bcb50e47b68c7209c7f0a5a020d73761e5143b unset REGRESS_FAIL_EARLY
1438c2133817cbcae75c88c63599ac54228f0fa384 Change COMPILER_VERSION tests
1530c20180c87cbc99fa1020489fe7fd8245b6420c resync integrity.sh shell
161e6b51ddf767cbad0a4e63eb08026c127e654308 integrity.sh reliability
17fe5b31f69a60d47171836911f144acff77810217 Makefile.inc bits
185781670c0578fe89663c9085ed3ba477cf7e7913 Delete sshconnect1.c
19ea80f445e819719ccdcb237022cacfac990fdc5c Makefile.inc warning flags
20b92c93266d8234d493857bb822260dacf4366157 moduli-gen.sh tweak
21b25bf747544265b39af74fe0716dc8d9f5b63b95 Updated moduli
221bd41cba06a7752de4df304305a8153ebfb6b0ac rsa.[ch] already removed
23e39b3902fe1d6c4a7ba6a3c58e072219f3c1e604 Makefile changes
diff --git a/ChangeLog b/ChangeLog
index 48f648d78..e008ec9f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,2514 @@
1commit 66bf74a92131b7effe49fb0eefe5225151869dc5
2Author: djm@openbsd.org <djm@openbsd.org>
3Date: Mon Oct 2 19:33:20 2017 +0000
4
5 upstream commit
6
7 Fix PermitOpen crash; spotted by benno@, ok dtucker@ deraadt@
8
9 Upstream-ID: c2cc84ffac070d2e1ff76182c70ca230a387983c
10
11commit d63b38160a59039708fd952adc75a0b3da141560
12Author: Damien Miller <djm@mindrot.org>
13Date: Sun Oct 1 10:32:25 2017 +1100
14
15 update URL again
16
17 I spotted a typo in the draft so uploaded a new version...
18
19commit 6f64f596430cd3576c529f07acaaf2800aa17d58
20Author: Damien Miller <djm@mindrot.org>
21Date: Sun Oct 1 10:01:56 2017 +1100
22
23 sync release notes URL
24
25commit 35ff70a04dd71663a5ac1e73b90d16d270a06e0d
26Author: Damien Miller <djm@mindrot.org>
27Date: Sun Oct 1 10:01:25 2017 +1100
28
29 sync contrib/ssh-copy-id with upstream
30
31commit 290843b8ede85f8b30bf29cd7dceb805c3ea5b66
32Author: Damien Miller <djm@mindrot.org>
33Date: Sun Oct 1 09:59:19 2017 +1100
34
35 update version in RPM spec files
36
37commit 4e4e0bb223c5be88d87d5798c75cc6b0d4fef31d
38Author: Damien Miller <djm@mindrot.org>
39Date: Sun Oct 1 09:58:24 2017 +1100
40
41 update agent draft URL
42
43commit e4a798f001d2ecd8bf025c1d07658079f27cc604
44Author: djm@openbsd.org <djm@openbsd.org>
45Date: Sat Sep 30 22:26:33 2017 +0000
46
47 upstream commit
48
49 openssh-7.6; ok deraadt@
50
51 Upstream-ID: a39c3a5b63a1baae109ae1ae4c7c34c2a59acde0
52
53commit 5fa1407e16e7e5fda9769d53b626ce39d5588d4d
54Author: jmc@openbsd.org <jmc@openbsd.org>
55Date: Wed Sep 27 06:45:53 2017 +0000
56
57 upstream commit
58
59 tweak EposeAuthinfo; diff from lars nooden
60
61 tweaked by sthen; ok djm dtucker
62
63 Upstream-ID: 8f2ea5d2065184363e8be7a0ba24d98a3b259748
64
65commit bba69c246f0331f657fd6ec97724df99fc1ad174
66Author: Damien Miller <djm@mindrot.org>
67Date: Thu Sep 28 16:06:21 2017 -0700
68
69 don't fatal ./configure for LibreSSL
70
71commit 04dc070e8b4507d9d829f910b29be7e3b2414913
72Author: Damien Miller <djm@mindrot.org>
73Date: Thu Sep 28 14:54:34 2017 -0700
74
75 abort in configure when only openssl-1.1.x found
76
77 We don't support openssl-1.1.x yet (see multiple threads on the
78 openssh-unix-dev@ mailing list for the reason), but previously
79 ./configure would accept it and the compilation would subsequently
80 fail. This makes ./configure display an explicit error message and
81 abort.
82
83 ok dtucker@
84
85commit 74c1c3660acf996d9dc329e819179418dc115f2c
86Author: Darren Tucker <dtucker@zip.com.au>
87Date: Wed Sep 27 07:44:41 2017 +1000
88
89 Check for and handle calloc(p, 0) = NULL.
90
91 On some platforms (AIX, maybe others) allocating zero bytes of memory
92 via the various *alloc functions returns NULL, which is permitted
93 by the standards. Autoconf has some macros for detecting this (with
94 the exception of calloc for some reason) so use these and if necessary
95 activate shims for them. ok djm@
96
97commit 6a9481258a77b0b54b2a313d1761c87360c5f1f5
98Author: markus@openbsd.org <markus@openbsd.org>
99Date: Thu Sep 21 19:18:12 2017 +0000
100
101 upstream commit
102
103 test reverse dynamic forwarding with SOCKS
104
105 Upstream-Regress-ID: 95cf290470f7e5e2f691e4bc6ba19b91eced2f79
106
107commit 1b9f321605733754df60fac8c1d3283c89b74455
108Author: Damien Miller <djm@mindrot.org>
109Date: Tue Sep 26 16:55:55 2017 +1000
110
111 sync missing changes in dynamic-forward.sh
112
113commit 44fc334c7a9ebdd08addb6d5fa005369897fddeb
114Author: Darren Tucker <dtucker@zip.com.au>
115Date: Mon Sep 25 09:48:10 2017 +1000
116
117 Add minimal strsignal for platforms without it.
118
119commit 218e6f98df566fb9bd363f6aa47018cb65ede196
120Author: djm@openbsd.org <djm@openbsd.org>
121Date: Sun Sep 24 13:45:34 2017 +0000
122
123 upstream commit
124
125 fix inverted test on channel open failure path that
126 "upgraded" a transient failure into a fatal error; reported by sthen and also
127 seen by benno@; ok sthen@
128
129 Upstream-ID: b58b3fbb79ba224599c6cd6b60c934fc46c68472
130
131commit c704f641f7b8777497dc82e81f2ac89afec7e401
132Author: djm@openbsd.org <djm@openbsd.org>
133Date: Sun Sep 24 09:50:01 2017 +0000
134
135 upstream commit
136
137 write the correct buffer when tunnel forwarding; doesn't
138 matter on OpenBSD (they are the same) but does matter on portable where we
139 use an output filter to translate os-specific tun/tap headers
140
141 Upstream-ID: f1ca94eff48404827b12e1d12f6139ee99a72284
142
143commit 55486f5cef117354f0c64f991895835077b7c7f7
144Author: djm@openbsd.org <djm@openbsd.org>
145Date: Sat Sep 23 22:04:07 2017 +0000
146
147 upstream commit
148
149 fix tunnel forwarding problem introduced in refactor;
150 reported by stsp@ ok markus@
151
152 Upstream-ID: 81a731cdae1122c8522134095d1a8b60fa9dcd04
153
154commit 609d7a66ce578abf259da2d5f6f68795c2bda731
155Author: markus@openbsd.org <markus@openbsd.org>
156Date: Thu Sep 21 19:16:53 2017 +0000
157
158 upstream commit
159
160 Add 'reverse' dynamic forwarding which combines dynamic
161 forwarding (-D) with remote forwarding (-R) where the remote-forwarded port
162 expects SOCKS-requests.
163
164 The SSH server code is unchanged and the parsing happens at the SSH
165 clients side. Thus the full SOCKS-request is sent over the forwarded
166 channel and the client parses c->output. Parsing happens in
167 channel_before_prepare_select(), _before_ the select bitmask is
168 computed in the pre[] handlers, but after network input processing
169 in the post[] handlers.
170
171 help and ok djm@
172
173 Upstream-ID: aa25a6a3851064f34fe719e0bf15656ad5a64b89
174
175commit 36945fa103176c00b39731e1fc1919a0d0808b81
176Author: dtucker@openbsd.org <dtucker@openbsd.org>
177Date: Wed Sep 20 05:19:00 2017 +0000
178
179 upstream commit
180
181 Use strsignal in debug message instead of casting for the
182 benefit of portable where sig_atomic_t might not be int. "much nicer"
183 deraadt@
184
185 Upstream-ID: 2dac6c1e40511c700bd90664cd263ed2299dcf79
186
187commit 3e8d185af326bf183b6f78597d5e3d2eeb2dc40e
188Author: millert@openbsd.org <millert@openbsd.org>
189Date: Tue Sep 19 12:10:30 2017 +0000
190
191 upstream commit
192
193 Use explicit_bzero() instead of bzero() before free() to
194 prevent the compiler from optimizing away the bzero() call. OK djm@
195
196 Upstream-ID: cdc6197e64c9684c7250e23d60863ee1b53cef1d
197
198commit 5b8da1f53854c0923ec6e927e86709e4d72737b6
199Author: djm@openbsd.org <djm@openbsd.org>
200Date: Tue Sep 19 04:24:22 2017 +0000
201
202 upstream commit
203
204 fix use-after-free in ~^Z escape handler path, introduced
205 in channels.c refactor; spotted by millert@ "makes sense" deraadt@
206
207 Upstream-ID: 8fa2cdc65c23ad6420c1e59444b0c955b0589b22
208
209commit a3839d8d2b89ff1a80cadd4dd654336710de2c9e
210Author: dtucker@openbsd.org <dtucker@openbsd.org>
211Date: Mon Sep 18 12:03:24 2017 +0000
212
213 upstream commit
214
215 Prevent type mismatch warning in debug on platforms where
216 sig_atomic_t != int. ok djm@
217
218 Upstream-ID: 306e2375eb0364a4c68e48f091739bea4f4892ed
219
220commit 30484e5e5f0b63d2c6ba32c6b85f06b6c6fa55fc
221Author: dtucker@openbsd.org <dtucker@openbsd.org>
222Date: Mon Sep 18 09:41:52 2017 +0000
223
224 upstream commit
225
226 Add braces missing after channels refactor. ok markus@
227
228 Upstream-ID: 72ab325c84e010680dbc88f226e2aa96b11a3980
229
230commit b79569190b9b76dfacc6d996faa482f16e8fc026
231Author: Damien Miller <djm@mindrot.org>
232Date: Tue Sep 19 12:29:23 2017 +1000
233
234 add freezero(3) replacement
235
236 ok dtucker@
237
238commit 161af8f5ec0961b10cc032efb5cc1b44ced5a92e
239Author: Damien Miller <djm@mindrot.org>
240Date: Tue Sep 19 10:18:56 2017 +1000
241
242 move FORTIFY_SOURCE into hardening options group
243
244 It's still on by default, but now it's possible to turn it off using
245 --without-hardening. This is useful since it's known to cause problems
246 with some -fsanitize options. ok dtucker@
247
248commit 09eacf856e0fe1a6e3fe597ec8032b7046292914
249Author: bluhm@openbsd.org <bluhm@openbsd.org>
250Date: Wed Sep 13 14:58:26 2017 +0000
251
252 upstream commit
253
254 Print SKIPPED if sudo and doas configuration is missing.
255 Prevents that running the regression test with wrong environment is reported
256 as failure. Keep the fatal there to avoid interfering with other setups for
257 portable ssh. OK dtucker@
258
259 Upstream-Regress-ID: f0dc60023caef496ded341ac5aade2a606fa234e
260
261commit cdede10899892f25f1ccdccd7a3fe5e5ef0aa49a
262Author: dtucker@openbsd.org <dtucker@openbsd.org>
263Date: Mon Aug 7 03:52:55 2017 +0000
264
265 upstream commit
266
267 Remove obsolete privsep=no fallback test.
268
269 Upstream-Regress-ID: 7d6e1baa1678ac6be50c2a1555662eb1047638df
270
271commit ec218c105daa9f5b192f7aa890fdb2d4fdc4e9d8
272Author: dtucker@openbsd.org <dtucker@openbsd.org>
273Date: Mon Aug 7 00:53:51 2017 +0000
274
275 upstream commit
276
277 Remove non-privsep test since disabling privsep is now
278 deprecated.
279
280 Upstream-Regress-ID: 77ad3f3d8d52e87f514a80f285c6c1229b108ce8
281
282commit 239c57d5bc2253e27e3e6ad7ac52ec8c377ee24e
283Author: dtucker@openbsd.org <dtucker@openbsd.org>
284Date: Fri Jul 28 10:32:08 2017 +0000
285
286 upstream commit
287
288 Don't call fatal from stop_sshd since it calls cleanup
289 which calls stop_sshd which will probably fail in the same way. Instead,
290 just bail. Differentiate between sshd dying without cleanup and not shutting
291 down.
292
293 Upstream-Regress-ID: f97315f538618b349e2b0bea02d6b0c9196c6bc4
294
295commit aea59a0d9f120f2a87c7f494a0d9c51eaa79b8ba
296Author: djm@openbsd.org <djm@openbsd.org>
297Date: Thu Sep 14 04:32:21 2017 +0000
298
299 upstream commit
300
301 Revert commitid: gJtIN6rRTS3CHy9b.
302
303 -------------
304 identify the case where SSHFP records are missing but other DNS RR
305 types are present and display a more useful error message for this
306 case; patch by Thordur Bjornsson; bz#2501; ok dtucker@
307 -------------
308
309 This caused unexpected failures when VerifyHostKeyDNS=yes, SSHFP results
310 are missing but the user already has the key in known_hosts
311
312 Spotted by dtucker@
313
314 Upstream-ID: 97e31742fddaf72046f6ffef091ec0d823299920
315
316commit 871f1e4374420b07550041b329627c474abc3010
317Author: Damien Miller <djm@mindrot.org>
318Date: Tue Sep 12 18:01:35 2017 +1000
319
320 adapt portable to channels API changes
321
322commit 4ec0bb9f9ad7b4eb0af110fa8eddf8fa199e46bb
323Author: djm@openbsd.org <djm@openbsd.org>
324Date: Tue Sep 12 07:55:48 2017 +0000
325
326 upstream commit
327
328 unused variable
329
330 Upstream-ID: 2f9ba09f2708993d35eac5aa71df910dcc52bac1
331
332commit 9145a73ce2ba30c82bbf91d7205bfd112529449f
333Author: djm@openbsd.org <djm@openbsd.org>
334Date: Tue Sep 12 07:32:04 2017 +0000
335
336 upstream commit
337
338 fix tun/tap forwarding case in previous
339
340 Upstream-ID: 43ebe37a930320e24bca6900dccc39857840bc53
341
342commit 9f53229c2ac97dbc6f5a03657de08a1150a9ac7e
343Author: djm@openbsd.org <djm@openbsd.org>
344Date: Tue Sep 12 06:35:31 2017 +0000
345
346 upstream commit
347
348 Make remote channel ID a u_int
349
350 Previously we tracked the remote channel IDs in an int, but this is
351 strictly incorrect: the wire protocol uses uint32 and there is nothing
352 in-principle stopping a SSH implementation from sending, say, 0xffff0000.
353
354 In practice everyone numbers their channels sequentially, so this has
355 never been a problem.
356
357 ok markus@
358
359 Upstream-ID: b9f4cd3dc53155b4a5c995c0adba7da760d03e73
360
361commit dbee4119b502e3f8b6cd3282c69c537fd01d8e16
362Author: djm@openbsd.org <djm@openbsd.org>
363Date: Tue Sep 12 06:32:07 2017 +0000
364
365 upstream commit
366
367 refactor channels.c
368
369 Move static state to a "struct ssh_channels" that is allocated at
370 runtime and tracked as a member of struct ssh.
371
372 Explicitly pass "struct ssh" to all channels functions.
373
374 Replace use of the legacy packet APIs in channels.c.
375
376 Rework sshd_config PermitOpen handling: previously the configuration
377 parser would call directly into the channels layer. After the refactor
378 this is not possible, as the channels structures are allocated at
379 connection time and aren't available when the configuration is parsed.
380 The server config parser now tracks PermitOpen itself and explicitly
381 configures the channels code later.
382
383 ok markus@
384
385 Upstream-ID: 11828f161656b965cc306576422613614bea2d8f
386
387commit abd59663df37a42152e37980113ccaa405b9a282
388Author: djm@openbsd.org <djm@openbsd.org>
389Date: Thu Sep 7 23:48:09 2017 +0000
390
391 upstream commit
392
393 typo in comment
394
395 Upstream-ID: a93b1e6f30f1f9b854b5b964b9fd092d0c422c47
396
397commit 149a8cd24ce9dd47c36f571738681df5f31a326c
398Author: jmc@openbsd.org <jmc@openbsd.org>
399Date: Mon Sep 4 06:34:43 2017 +0000
400
401 upstream commit
402
403 tweak previous;
404
405 Upstream-ID: bb8cc40b61b15f6a13d81da465ac5bfc65cbfc4b
406
407commit ec9d22cc251cc5acfe7b2bcef9cc7a1fe0e949d8
408Author: Damien Miller <djm@mindrot.org>
409Date: Fri Sep 8 12:44:13 2017 +1000
410
411 Fuzzer harnesses for sig verify and pubkey parsing
412
413 These are some basic clang libfuzzer harnesses for signature
414 verification and public key parsing. Some assembly (metaphorical)
415 required.
416
417commit de35c382894964a896a63ecd5607d3a3b93af75d
418Author: Damien Miller <djm@mindrot.org>
419Date: Fri Sep 8 12:38:31 2017 +1000
420
421 Give configure ability to set CFLAGS/LDFLAGS later
422
423 Some CFLAGS/LDFLAGS may disrupt the configure script's operation,
424 in particular santization and fuzzer options that break assumptions
425 about memory and file descriptor dispositions.
426
427 This adds two flags to configure --with-cflags-after and
428 --with-ldflags-after that allow specifying additional compiler and
429 linker options that are added to the resultant Makefiles but not
430 used in the configure run itself.
431
432 E.g.
433
434 env CC=clang-3.9 ./configure \
435 --with-cflags-after=-fsantize=address \
436 --with-ldflags-after="-g -fsanitize=address"
437
438commit 22376d27a349f62c502fec3396dfe0fdcb2a40b7
439Author: djm@openbsd.org <djm@openbsd.org>
440Date: Sun Sep 3 23:33:13 2017 +0000
441
442 upstream commit
443
444 Expand ssh_config's StrictModes option with two new
445 settings:
446
447 StrictModes=accept-new will automatically accept hitherto-unseen keys
448 but will refuse connections for changed or invalid hostkeys.
449
450 StrictModes=off is the same as StrictModes=no
451
452 Motivation:
453
454 StrictModes=no combines two behaviours for host key processing:
455 automatically learning new hostkeys and continuing to connect to hosts
456 with invalid/changed hostkeys. The latter behaviour is quite dangerous
457 since it removes most of the protections the SSH protocol is supposed to
458 provide.
459
460 Quite a few users want to automatically learn hostkeys however, so
461 this makes that feature available with less danger.
462
463 At some point in the future, StrictModes=no will change to be a synonym
464 for accept-new, with its current behaviour remaining available via
465 StrictModes=off.
466
467 bz#2400, suggested by Michael Samuel; ok markus
468
469 Upstream-ID: 0f55502bf75fc93a74fb9853264a8276b9680b64
470
471commit ff3c42384033514e248ba5d7376aa033f4a2b99a
472Author: jmc@openbsd.org <jmc@openbsd.org>
473Date: Fri Sep 1 15:41:26 2017 +0000
474
475 upstream commit
476
477 remove blank line;
478
479 Upstream-ID: 2f46b51a0ddb3730020791719e94d3e418e9f423
480
481commit b828605d51f57851316d7ba402b4ae06cf37c55d
482Author: djm@openbsd.org <djm@openbsd.org>
483Date: Fri Sep 1 05:53:56 2017 +0000
484
485 upstream commit
486
487 identify the case where SSHFP records are missing but
488 other DNS RR types are present and display a more useful error message for
489 this case; patch by Thordur Bjornsson; bz#2501; ok dtucker@
490
491 Upstream-ID: 8f7a5a8344f684823d8317a9708b63e75be2c244
492
493commit 8042bad97e2789a50e8f742c3bcd665ebf0add32
494Author: djm@openbsd.org <djm@openbsd.org>
495Date: Fri Sep 1 05:50:48 2017 +0000
496
497 upstream commit
498
499 document available AuthenticationMethods; bz#2453 ok
500 dtucker@
501
502 Upstream-ID: 2c70576f237bb699aff59889dbf2acba4276d3d0
503
504commit 71e5a536ec815d542b199f2ae6d646c0db9f1b58
505Author: djm@openbsd.org <djm@openbsd.org>
506Date: Wed Aug 30 03:59:08 2017 +0000
507
508 upstream commit
509
510 pass packet state down to some of the channels function
511 (more to come...); ok markus@
512
513 Upstream-ID: d8ce7a94f4059d7ac1e01fb0eb01de0c4b36c81b
514
515commit 6227fe5b362239c872b91bbdee4bf63cf85aebc5
516Author: jmc@openbsd.org <jmc@openbsd.org>
517Date: Tue Aug 29 13:05:58 2017 +0000
518
519 upstream commit
520
521 sort options;
522
523 Upstream-ID: cf21d68cf54e81968bca629aaeddc87f0c684f3c
524
525commit 530591a5795a02d01c78877d58604723918aac87
526Author: dlg@openbsd.org <dlg@openbsd.org>
527Date: Tue Aug 29 09:42:29 2017 +0000
528
529 upstream commit
530
531 add a -q option to ssh-add to make it quiet on success.
532
533 if you want to silence ssh-add without this you generally redirect
534 the output to /dev/null, but that can hide error output which you
535 should see.
536
537 ok djm@
538
539 Upstream-ID: 2f31b9b13f99dcf587e9a8ba443458e6c0d8997c
540
541commit a54eb27dd64b5eca3ba94e15cec3535124bd5029
542Author: dtucker@openbsd.org <dtucker@openbsd.org>
543Date: Sun Aug 27 00:38:41 2017 +0000
544
545 upstream commit
546
547 Increase the buffer sizes for user prompts to ensure that
548 they won't be truncated by snprintf. Based on patch from cjwatson at
549 debian.org via bz#2768, ok djm@
550
551 Upstream-ID: 6ffacf1abec8f40b469de5b94bfb29997d96af3e
552
553commit dd9d9b3381a4597b840d480b043823112039327e
554Author: Darren Tucker <dtucker@zip.com.au>
555Date: Mon Aug 28 16:48:27 2017 +1000
556
557 Switch Capsicum header to sys/capsicum.h.
558
559 FreeBSD's <sys/capability.h> was renamed to <sys/capsicum.h> in 2014 to
560 avoid future conflicts with POSIX capabilities (the last release that
561 didn't have it was 9.3) so switch to that. Patch from des at des.no.
562
563commit f5e917ab105af5dd6429348d9bc463e52b263f92
564Author: Darren Tucker <dtucker@zip.com.au>
565Date: Sun Aug 27 08:55:40 2017 +1000
566
567 Add missing includes for bsd-err.c.
568
569 Patch from cjwatson at debian.org via bz#2767.
570
571commit 878e029797cfc9754771d6f6ea17f8c89e11d225
572Author: Damien Miller <djm@mindrot.org>
573Date: Fri Aug 25 13:25:01 2017 +1000
574
575 Split platform_sys_dir_uid into its own file
576
577 platform.o is too heavy for libssh.a use; it calls into the server on
578 many platforms. Move just the function needed by misc.c into its own
579 file.
580
581commit 07949bfe9133234eddd01715592aa0dde67745f0
582Author: Damien Miller <djm@mindrot.org>
583Date: Wed Aug 23 20:13:18 2017 +1000
584
585 misc.c needs functions from platform.c now
586
587commit b074c3c3f820000a21953441cea7699c4b17d72f
588Author: djm@openbsd.org <djm@openbsd.org>
589Date: Fri Aug 18 05:48:04 2017 +0000
590
591 upstream commit
592
593 add a "quiet" flag to exited_cleanly() that supresses
594 errors about exit status (failure due to signal is still reported)
595
596 Upstream-ID: db85c39c3aa08e6ff67fc1fb4ffa89f807a9d2f0
597
598commit de4ae07f12dabf8815ecede54235fce5d22e3f63
599Author: djm@openbsd.org <djm@openbsd.org>
600Date: Fri Aug 18 05:36:45 2017 +0000
601
602 upstream commit
603
604 Move several subprocess-related functions from various
605 locations to misc.c. Extend subprocess() to offer a little more control over
606 stdio disposition.
607
608 feedback & ok dtucker@
609
610 Upstream-ID: 3573dd7109d13ef9bd3bed93a3deb170fbfce049
611
612commit 643c2ad82910691b2240551ea8b14472f60b5078
613Author: djm@openbsd.org <djm@openbsd.org>
614Date: Sat Aug 12 06:46:01 2017 +0000
615
616 upstream commit
617
618 make "--" before the hostname terminate command-line
619 option processing completely; previous behaviour would not prevent further
620 options appearing after the hostname (ssh has a supported options after the
621 hostname for >20 years, so that's too late to change).
622
623 ok deraadt@
624
625 Upstream-ID: ef5ee50571b98ad94dcdf8282204e877ec88ad89
626
627commit 0f3455356bc284d7c6f4d3c1614d31161bd5dcc2
628Author: djm@openbsd.org <djm@openbsd.org>
629Date: Sat Aug 12 06:42:52 2017 +0000
630
631 upstream commit
632
633 Switch from aes256-cbc to aes256-ctr for encrypting
634 new-style private keys. The latter having the advantage of being supported
635 for no-OpenSSL builds; bz#2754 ok markus@
636
637 Upstream-ID: 54179a2afd28f93470471030567ac40431e56909
638
639commit c4972d0a9bd6f898462906b4827e09b7caea2d9b
640Author: djm@openbsd.org <djm@openbsd.org>
641Date: Fri Aug 11 04:47:12 2017 +0000
642
643 upstream commit
644
645 refuse to a private keys when its corresponding .pub key
646 does not match. bz#2737 ok dtucker@
647
648 Upstream-ID: 54ff5e2db00037f9db8d61690f26ef8f16e0d913
649
650commit 4b3ecbb663c919132dddb3758e17a23089413519
651Author: djm@openbsd.org <djm@openbsd.org>
652Date: Fri Aug 11 04:41:08 2017 +0000
653
654 upstream commit
655
656 don't print verbose error message when ssh disconnects
657 under sftp; bz#2750; ok dtucker@
658
659 Upstream-ID: 6d83708aed77b933c47cf155a87dc753ec01f370
660
661commit 42a8f8bc288ef8cac504c5c73f09ed610bc74a34
662Author: dtucker@openbsd.org <dtucker@openbsd.org>
663Date: Fri Aug 11 04:16:35 2017 +0000
664
665 upstream commit
666
667 Tweak previous keepalive commit: if last_time + keepalive
668 <= now instead of just "<" so client_alive_check will fire if the select
669 happens to return on exact second of the timeout. ok djm@
670
671 Upstream-ID: e02756bd6038d11bb8522bfd75a4761c3a684fcc
672
673commit b60ff20051ef96dfb207b6bfa45c0ad6c34a542a
674Author: dtucker@openbsd.org <dtucker@openbsd.org>
675Date: Fri Aug 11 03:58:36 2017 +0000
676
677 upstream commit
678
679 Keep track of the last time we actually heard from the
680 client and use this to also schedule a client_alive_check(). Prevents
681 activity on a forwarded port from indefinitely preventing the select timeout
682 so that client_alive_check() will eventually (although not optimally) be
683 called.
684
685 Analysis by willchan at google com via bz#2756, feedback & ok djm@
686
687 Upstream-ID: c08721e0bbda55c6d18e2760f3fe1b17fb71169e
688
689commit 94bc1e7ffba3cbdea8c7dcdab8376bf29283128f
690Author: Damien Miller <djm@mindrot.org>
691Date: Fri Jul 28 14:50:59 2017 +1000
692
693 Expose list of completed auth methods to PAM
694
695 bz#2408; ok dtucker@
696
697commit c78e6eec78c88acf8d51db90ae05a3e39458603d
698Author: Damien Miller <djm@mindrot.org>
699Date: Fri Jul 21 14:38:16 2017 +1000
700
701 fix problems in tunnel forwarding portability code
702
703 This fixes a few problems in the tun forwarding code, mostly to do
704 with host/network byte order confusion.
705
706 Based on a report and patch by stepe AT centaurus.uberspace.de;
707 bz#2735; ok dtucker@
708
709commit 2985d4062ebf4204bbd373456a810d558698f9f5
710Author: dtucker@openbsd.org <dtucker@openbsd.org>
711Date: Tue Jul 25 09:22:25 2017 +0000
712
713 upstream commit
714
715 Make WinSCP patterns for SSH_OLD_DHGEX more specific to
716 exclude WinSCP 5.10.x and up. bz#2748, from martin at winscp.net, ok djm@
717
718 Upstream-ID: 6fd7c32e99af3952db007aa180e73142ddbc741a
719
720commit 9f0e44e1a0439ff4646495d5735baa61138930a9
721Author: djm@openbsd.org <djm@openbsd.org>
722Date: Mon Jul 24 04:34:28 2017 +0000
723
724 upstream commit
725
726 g/c unused variable; make a little more portable
727
728 Upstream-ID: 3f5980481551cb823c6fb2858900f93fa9217dea
729
730commit 51676ec61491ec6d7cbd06082034e29b377b3bf6
731Author: djm@openbsd.org <djm@openbsd.org>
732Date: Sun Jul 23 23:37:02 2017 +0000
733
734 upstream commit
735
736 Allow IPQoS=none in ssh/sshd to not set an explicit
737 ToS/DSCP value and just use the operating system default; ok dtucker@
738
739 Upstream-ID: 77906ff8c7b660b02ba7cb1e47b17d66f54f1f7e
740
741commit 6c1fbd5a50d8d2415f06c920dd3b1279b741072d
742Author: Damien Miller <djm@mindrot.org>
743Date: Fri Jul 21 14:24:26 2017 +1000
744
745 mention libedit
746
747commit dc2bd308768386b02c7337120203ca477e67ba62
748Author: markus@openbsd.org <markus@openbsd.org>
749Date: Wed Jul 19 08:30:41 2017 +0000
750
751 upstream commit
752
753 fix support for unknown key types; ok djm@
754
755 Upstream-ID: 53fb29394ed04d616d65b3748dee5aa06b07ab48
756
757commit fd0e8fa5f89d21290b1fb5f9d110ca4f113d81d9
758Author: djm@openbsd.org <djm@openbsd.org>
759Date: Wed Jul 19 01:15:02 2017 +0000
760
761 upstream commit
762
763 switch from select() to poll() for the ssh-agent
764 mainloop; ok markus
765
766 Upstream-ID: 4a94888ee67b3fd948fd10693973beb12f802448
767
768commit b1e72df2b813ecc15bd0152167bf4af5f91c36d3
769Author: dtucker@openbsd.org <dtucker@openbsd.org>
770Date: Fri Jul 14 03:18:21 2017 +0000
771
772 upstream commit
773
774 Make ""Killed by signal 1" LogLevel verbose so it's not
775 shown at the default level. Prevents it from appearing during ssh -J and
776 equivalent ProxyCommand configs. bz#1906, bz#2744, feedback&ok markus@
777
778 Upstream-ID: debfaa7e859b272246c2f2633335d288d2e2ae28
779
780commit 1f3d202770a08ee6752ed2a234b7ca6f180eb498
781Author: jmc@openbsd.org <jmc@openbsd.org>
782Date: Thu Jul 13 19:16:33 2017 +0000
783
784 upstream commit
785
786 man pages with pseudo synopses which list filenames end
787 up creating very ugly output in man -k; after some discussion with ingo, we
788 feel the simplest fix is to remove such SYNOPSIS sections: the info is hardly
789 helpful at page top, is contained already in FILES, and there are
790 sufficiently few that just zapping them is simple;
791
792 ok schwarze, who also helpfully ran things through a build to check
793 output;
794
795 Upstream-ID: 3e211b99457e2f4c925c5927d608e6f97431336c
796
797commit 7f13a4827fb28957161de4249bd6d71954f1f2ed
798Author: espie@openbsd.org <espie@openbsd.org>
799Date: Mon Jul 10 14:09:59 2017 +0000
800
801 upstream commit
802
803 zap redundant Makefile variables. okay djm@
804
805 Upstream-ID: e39b3902fe1d6c4a7ba6a3c58e072219f3c1e604
806
807commit dc44dd3a9e2c9795394e6a7e1e71c929cbc70ce0
808Author: jmc@openbsd.org <jmc@openbsd.org>
809Date: Sat Jul 8 18:32:54 2017 +0000
810
811 upstream commit
812
813 slightly rework previous, to avoid an article issue;
814
815 Upstream-ID: 15a315f0460ddd3d4e2ade1f16d6c640a8c41b30
816
817commit 853edbe057a84ebd0024c8003e4da21bf2b469f7
818Author: djm@openbsd.org <djm@openbsd.org>
819Date: Fri Jul 7 03:53:12 2017 +0000
820
821 upstream commit
822
823 When generating all hostkeys (ssh-keygen -A), clobber
824 existing keys if they exist but are zero length. zero-length keys could
825 previously be made if ssh-keygen failed part way through generating them, so
826 avoid that case too. bz#2561 reported by Krzysztof Cieplucha; ok dtucker@
827
828 Upstream-ID: f662201c28ab8e1f086b5d43c59cddab5ade4044
829
830commit 43616876ba68a2ffaece6a6c792def4b039f2d6e
831Author: djm@openbsd.org <djm@openbsd.org>
832Date: Sat Jul 1 22:55:44 2017 +0000
833
834 upstream commit
835
836 actually remove these files
837
838 Upstream-ID: 1bd41cba06a7752de4df304305a8153ebfb6b0ac
839
840commit 83fa3a044891887369ce8b487ce88d713a04df48
841Author: djm@openbsd.org <djm@openbsd.org>
842Date: Sat Jul 1 13:50:45 2017 +0000
843
844 upstream commit
845
846 remove post-SSHv1 removal dead code from rsa.c and merge
847 the remaining bit that it still used into ssh-rsa.c; ok markus
848
849 Upstream-ID: ac8a048d24dcd89594b0052ea5e3404b473bfa2f
850
851commit 738c73dca2c99ee78c531b4cbeefc2008fe438f0
852Author: Damien Miller <djm@mindrot.org>
853Date: Fri Jul 14 14:26:36 2017 +1000
854
855 make explicit_bzero/memset safe for sz=0
856
857commit 8433d51e067e0829f5521c0c646b6fd3fe17e732
858Author: Tim Rice <tim@multitalents.net>
859Date: Tue Jul 11 18:47:56 2017 -0700
860
861 modified: configure.ac
862 UnixWare needs BROKEN_TCGETATTR_ICANON like Solaris
863 Analysis by Robbie Zhang
864
865commit ff3507aea9c7d30cd098e7801e156c68faff7cc7
866Author: Damien Miller <djm@mindrot.org>
867Date: Fri Jul 7 11:21:27 2017 +1000
868
869 typo
870
871commit d79bceb9311a9c137d268f5bc481705db4151810
872Author: dtucker@openbsd.org <dtucker@openbsd.org>
873Date: Fri Jun 30 04:17:23 2017 +0000
874
875 upstream commit
876
877 Only call close once in confree(). ssh_packet_close will
878 close the FD so only explicitly close non-SSH channels. bz#2734, from
879 bagajjal at microsoft.com, ok djm@
880
881 Upstream-ID: a81ce0c8b023527167739fccf1732b154718ab02
882
883commit 197dc9728f062e23ce374f44c95a2b5f9ffa4075
884Author: Darren Tucker <dtucker@zip.com.au>
885Date: Thu Jun 29 15:40:25 2017 +1000
886
887 Update link for my patches.
888
889commit a98339edbc1fc21342a390f345179a9c3031bef7
890Author: djm@openbsd.org <djm@openbsd.org>
891Date: Wed Jun 28 01:09:22 2017 +0000
892
893 upstream commit
894
895 Allow ssh-keygen to use a key held in ssh-agent as a CA when
896 signing certificates. bz#2377 ok markus
897
898 Upstream-ID: fb42e920b592edcbb5b50465739a867c09329c8f
899
900commit c9cdef35524bd59007e17d5bd2502dade69e2dfb
901Author: djm@openbsd.org <djm@openbsd.org>
902Date: Sat Jun 24 06:35:24 2017 +0000
903
904 upstream commit
905
906 regress test for ExposeAuthInfo
907
908 Upstream-Regress-ID: 190e5b6866376f4061c411ab157ca4d4e7ae86fd
909
910commit f17ee61cad25d210edab69d04ed447ad55fe80c1
911Author: djm@openbsd.org <djm@openbsd.org>
912Date: Sat Jun 24 07:08:57 2017 +0000
913
914 upstream commit
915
916 correct env var name
917
918 Upstream-ID: 721e761c2b1d6a4dcf700179f16fd53a1dadb313
919
920commit 40962198e3b132cecdb32e9350acd4294e6a1082
921Author: jmc@openbsd.org <jmc@openbsd.org>
922Date: Sat Jun 24 06:57:04 2017 +0000
923
924 upstream commit
925
926 spelling;
927
928 Upstream-ID: 606f933c8e2d0be902ea663946bc15e3eee40b25
929
930commit 33f86265d7e8a0e88d3a81745d746efbdd397370
931Author: djm@openbsd.org <djm@openbsd.org>
932Date: Sat Jun 24 06:38:11 2017 +0000
933
934 upstream commit
935
936 don't pass pointer to struct sshcipher between privsep
937 processes, just redo the lookup in each using the already-passed cipher name.
938 bz#2704 based on patch from Brooks Davis; ok markus dtucker
939
940 Upstream-ID: 2eab434c09bdf549dafd7da3e32a0d2d540adbe0
941
942commit 8f574959272ac7fe9239c4f5d10fd913f8920ab0
943Author: djm@openbsd.org <djm@openbsd.org>
944Date: Sat Jun 24 06:34:38 2017 +0000
945
946 upstream commit
947
948 refactor authentication logging
949
950 optionally record successful auth methods and public credentials
951 used in a file accessible to user sessions
952
953 feedback and ok markus@
954
955 Upstream-ID: 090b93036967015717b9a54fd0467875ae9d32fb
956
957commit e2004d4bb7eb01c663dd3a3e7eb224f1ccdc9bba
958Author: jmc@openbsd.org <jmc@openbsd.org>
959Date: Sat Jun 24 06:28:50 2017 +0000
960
961 upstream commit
962
963 word fix;
964
965 Upstream-ID: 8539bdaf2366603a34a9b2f034527ca13bb795c5
966
967commit 4540428cd0adf039bcf5a8a27f2d5cdf09191513
968Author: djm@openbsd.org <djm@openbsd.org>
969Date: Sat Jun 24 05:37:44 2017 +0000
970
971 upstream commit
972
973 switch sshconnect.c from (slightly abused) select() to
974 poll(); ok deraadt@ a while back
975
976 Upstream-ID: efc1937fc591bbe70ac9e9542bb984f354c8c175
977
978commit 6f8ca3b92540fa1a9b91670edc98d15448e3d765
979Author: djm@openbsd.org <djm@openbsd.org>
980Date: Sat Jun 24 05:35:05 2017 +0000
981
982 upstream commit
983
984 use HostKeyAlias if specified instead of hostname for
985 matching host certificate principal names; bz#2728; ok dtucker@
986
987 Upstream-ID: dc2e11c83ae9201bbe74872a0c895ae9725536dd
988
989commit 8904ffce057b80a7472955f1ec00d7d5c250076c
990Author: djm@openbsd.org <djm@openbsd.org>
991Date: Sat Jun 24 05:24:11 2017 +0000
992
993 upstream commit
994
995 no need to call log_init to reinitialise logged PID in
996 child sessions, since we haven't called openlog() in log_init() since 1999;
997 ok markus@
998
999 Upstream-ID: 0906e4002af5d83d3d544df75e1187c932a3cf2e
1000
1001commit e238645d789cd7eb47541b66aea2a887ea122c9b
1002Author: mestre@openbsd.org <mestre@openbsd.org>
1003Date: Fri Jun 23 07:24:48 2017 +0000
1004
1005 upstream commit
1006
1007 When using the escape sequence &~ the code path is
1008 client_loop() -> client_simple_escape_filter() -> process_escapes() -> fork()
1009 and the pledge for this path lacks the proc promise and therefore aborts the
1010 process. The solution is to just add proc the promise to this specific
1011 pledge.
1012
1013 Reported by Gregoire Jadi gjadi ! omecha.info
1014 Insight with tb@, OK jca@
1015
1016 Upstream-ID: 63c05e30c28209519f476023b65b0b1b0387a05b
1017
1018commit 5abbb31c4e7a6caa922cc1cbb14e87a77f9d19d3
1019Author: dtucker@openbsd.org <dtucker@openbsd.org>
1020Date: Fri Jun 23 03:30:42 2017 +0000
1021
1022 upstream commit
1023
1024 Import regenerated moduli.
1025
1026 Upstream-ID: b25bf747544265b39af74fe0716dc8d9f5b63b95
1027
1028commit 849c5468b6d9b4365784c5dd88e3f1fb568ba38f
1029Author: dtucker@openbsd.org <dtucker@openbsd.org>
1030Date: Fri Jun 23 03:25:53 2017 +0000
1031
1032 upstream commit
1033
1034 Run the screen twice so we end up with more candidate
1035 groups. ok djm@
1036
1037 Upstream-ID: b92c93266d8234d493857bb822260dacf4366157
1038
1039commit 4626e39c7053c6486c1c8b708ec757e464623f5f
1040Author: dtucker@openbsd.org <dtucker@openbsd.org>
1041Date: Wed Jun 14 00:31:38 2017 +0000
1042
1043 upstream commit
1044
1045 Add user@host prefix to client's "Permisison denied"
1046 messages, useful in particular when using "stacked" connections where it's
1047 not clear which host is denying. bz#2720, ok djm@ markus@
1048
1049 Upstream-ID: de88e1e9dcb050c98e85377482d1287a9fe0d2be
1050
1051commit c948030d54911b2d3cddb96a7a8e9269e15d11cd
1052Author: djm@openbsd.org <djm@openbsd.org>
1053Date: Tue Jun 13 12:13:59 2017 +0000
1054
1055 upstream commit
1056
1057 Do not require that unknown EXT_INFO extension values not
1058 contain \0 characters. This would cause fatal connection errors if an
1059 implementation sent e.g. string-encoded sub-values inside a value.
1060
1061 Reported by Denis Bider; ok markus@
1062
1063 Upstream-ID: 030e10fdc605563c040244c4b4f1d8ae75811a5c
1064
1065commit 6026f48dfca78b713e4a7f681ffa42a0afe0929e
1066Author: djm@openbsd.org <djm@openbsd.org>
1067Date: Tue Jun 13 11:22:15 2017 +0000
1068
1069 upstream commit
1070
1071 missing prototype.
1072
1073 Upstream-ID: f443d2be9910fd2165a0667956d03343c46f66c9
1074
1075commit bcd1485075aa72ba9418003f5cc27af2b049c51b
1076Author: Damien Miller <djm@mindrot.org>
1077Date: Sat Jun 10 23:41:25 2017 +1000
1078
1079 portability for sftp globbed ls sort by mtime
1080
1081 Include replacement timespeccmp() for systems that lack it.
1082 Support time_t struct stat->st_mtime in addition to
1083 timespec stat->st_mtim, as well as unsorted fallback.
1084
1085commit 072e172f1d302d2a2c6043ecbfb4004406717b96
1086Author: djm@openbsd.org <djm@openbsd.org>
1087Date: Sat Jun 10 06:36:46 2017 +0000
1088
1089 upstream commit
1090
1091 print '?' instead of incorrect link count (that the
1092 protocol doesn't provide) for remote listings. bz#2710 ok dtucker@
1093
1094 Upstream-ID: c611f98a66302cea452ef10f13fff8cf0385242e
1095
1096commit 72be5b2f8e7dc37235e8c4b8d0bc7b5ee1301505
1097Author: djm@openbsd.org <djm@openbsd.org>
1098Date: Sat Jun 10 06:33:34 2017 +0000
1099
1100 upstream commit
1101
1102 implement sorting for globbed ls; bz#2649 ok dtucker@
1103
1104 Upstream-ID: ed3110f351cc9703411bf847ba864041fb7216a8
1105
1106commit 5b2f34a74aa6a524cd57e856b23e1b7b25007721
1107Author: djm@openbsd.org <djm@openbsd.org>
1108Date: Fri Jun 9 06:47:13 2017 +0000
1109
1110 upstream commit
1111
1112 return failure rather than fatal() for more cases during
1113 mux negotiations. Causes the session to fall back to a non-mux connection if
1114 they occur. bz#2707 ok dtucker@
1115
1116 Upstream-ID: d2a7892f464d434e1f615334a1c9d0cdb83b29ab
1117
1118commit 7f5637c4a67a49ef256cb4eedf14e8590ac30976
1119Author: djm@openbsd.org <djm@openbsd.org>
1120Date: Fri Jun 9 06:43:01 2017 +0000
1121
1122 upstream commit
1123
1124 in description of public key authentication, mention that
1125 the server will send debug messages to the client for some error conditions
1126 after authentication has completed. bz#2709 ok dtucker
1127
1128 Upstream-ID: 750127dbd58c5a2672c2d28bc35fe221fcc8d1dd
1129
1130commit 2076e4adb986512ce8c415dd194fd4e52136c4b4
1131Author: djm@openbsd.org <djm@openbsd.org>
1132Date: Fri Jun 9 06:40:24 2017 +0000
1133
1134 upstream commit
1135
1136 better translate libcrypto errors by looking deeper in
1137 the accursed error stack for codes that indicate the wrong passphrase was
1138 supplied for a PEM key. bz#2699 ok dtucker@
1139
1140 Upstream-ID: 4da4286326d570f4f0489459bb71f6297e54b681
1141
1142commit ad0531614cbe8ec424af3c0fa90c34a8e1ebee4c
1143Author: dtucker@openbsd.org <dtucker@openbsd.org>
1144Date: Fri Jun 9 04:40:04 2017 +0000
1145
1146 upstream commit
1147
1148 Add comments referring to the relevant RFC sections for
1149 rekeying behaviour.
1150
1151 Upstream-ID: 6fc8e82485757a27633f9175ad00468f49a07d40
1152
1153commit ce9134260b9b1247e2385a1afed00c26112ba479
1154Author: Damien Miller <djm@mindrot.org>
1155Date: Fri Jun 9 14:43:47 2017 +1000
1156
1157 drop two more privileges in the Solaris sandbox
1158
1159 Drop PRIV_DAX_ACCESS and PRIV_SYS_IB_INFO.
1160 Patch from huieying.lee AT oracle.com via bz#2723
1161
1162commit e0f609c8a2ab940374689ab8c854199c3c285a76
1163Author: Darren Tucker <dtucker@zip.com.au>
1164Date: Fri Jun 9 13:36:29 2017 +1000
1165
1166 Wrap stdint.h include in #ifdef.
1167
1168commit 1de5e47a85850526a4fdaf77185134046c050f75
1169Author: djm@openbsd.org <djm@openbsd.org>
1170Date: Wed Jun 7 01:48:15 2017 +0000
1171
1172 upstream commit
1173
1174 unbreak after sshv1 purge
1175
1176 Upstream-Regress-ID: 8ea01a92d5f571b9fba88c1463a4254a7552d51b
1177
1178commit 550c053168123fcc0791f9952abad684704b5760
1179Author: dtucker@openbsd.org <dtucker@openbsd.org>
1180Date: Tue Jun 6 09:12:17 2017 +0000
1181
1182 upstream commit
1183
1184 Fix compression output stats broken in rev 1.201. Patch
1185 originally by Russell Coker via Debian bug #797964 and Christoph Biedl. ok
1186 djm@
1187
1188 Upstream-ID: 83a1903b95ec2e4ed100703debb4b4a313b01016
1189
1190commit 55d06c6e72a9abf1c06a7ac2749ba733134a1f39
1191Author: djm@openbsd.org <djm@openbsd.org>
1192Date: Fri Jun 2 06:06:10 2017 +0000
1193
1194 upstream commit
1195
1196 rationalise the long list of manual CDIAGFLAGS that we
1197 add; most of these were redundant to -Wall -Wextra
1198
1199 Upstream-ID: ea80f445e819719ccdcb237022cacfac990fdc5c
1200
1201commit 1527d9f61e6d50f6c2b4a3fa5b45829034b1b0b1
1202Author: djm@openbsd.org <djm@openbsd.org>
1203Date: Thu Jun 1 06:59:21 2017 +0000
1204
1205 upstream commit
1206
1207 no need to bzero allocated space now that we use use
1208 recallocarray; ok deraadt@
1209
1210 Upstream-ID: 53333c62ccf97de60b8cb570608c1ba5ca5803c8
1211
1212commit cc812baf39b93d5355565da98648d8c31f955990
1213Author: djm@openbsd.org <djm@openbsd.org>
1214Date: Thu Jun 1 06:58:25 2017 +0000
1215
1216 upstream commit
1217
1218 unconditionally zero init size of buffer; ok markus@
1219 deraadt@
1220
1221 Upstream-ID: 218963e846d8f26763ba25afe79294547b99da29
1222
1223commit 65eb8fae0d7ba45ef4483a3cf0ae7fd0dbc7c226
1224Author: Damien Miller <djm@mindrot.org>
1225Date: Thu Jun 1 16:25:09 2017 +1000
1226
1227 avoid compiler warning
1228
1229commit 2d75d74272dc2a0521fce13cfe6388800c9a2406
1230Author: djm@openbsd.org <djm@openbsd.org>
1231Date: Thu Jun 1 06:16:43 2017 +0000
1232
1233 upstream commit
1234
1235 some warnings spotted by clang; ok markus@
1236
1237 Upstream-ID: 24381d68ca249c5cee4388ceb0f383fa5b43991b
1238
1239commit 151c6e433a5f5af761c78de87d7b5d30a453cf5e
1240Author: Damien Miller <djm@mindrot.org>
1241Date: Thu Jun 1 15:25:13 2017 +1000
1242
1243 add recallocarray replacement and dependency
1244
1245 recallocarray() needs getpagesize() so add a tiny replacement for that.
1246
1247commit 01e6f78924da308447e71e9a32c8a6104ef4e888
1248Author: Damien Miller <djm@mindrot.org>
1249Date: Thu Jun 1 15:16:24 2017 +1000
1250
1251 add *.0 manpage droppings
1252
1253commit 4b2e2d3fd9dccff357e1e26ce9a5f2e103837a36
1254Author: djm@openbsd.org <djm@openbsd.org>
1255Date: Thu Jun 1 04:51:58 2017 +0000
1256
1257 upstream commit
1258
1259 fix casts re constness
1260
1261 Upstream-ID: e38f2bac162b37dbaf784d349c8327a6626fa266
1262
1263commit 75b8af8de805c0694b37fcf80ce82783b2acc86f
1264Author: markus@openbsd.org <markus@openbsd.org>
1265Date: Wed May 31 10:54:00 2017 +0000
1266
1267 upstream commit
1268
1269 make sure we don't pass a NULL string to vfprintf
1270 (triggered by the principals-command regress test); ok bluhm
1271
1272 Upstream-ID: eb49854f274ab37a0b57056a6af379a0b7111990
1273
1274commit 84008608c9ee944d9f72f5100f31ccff743b10f2
1275Author: markus@openbsd.org <markus@openbsd.org>
1276Date: Wed May 31 10:04:29 2017 +0000
1277
1278 upstream commit
1279
1280 use SO_ZEROIZE for privsep communication (if available)
1281
1282 Upstream-ID: abcbb6d2f8039fc4367a6a78096e5d5c39de4a62
1283
1284commit 9e509d4ec97cb3d71696f1a2f1fdad254cbbce11
1285Author: deraadt@openbsd.org <deraadt@openbsd.org>
1286Date: Wed May 31 09:15:42 2017 +0000
1287
1288 upstream commit
1289
1290 Switch to recallocarray() for a few operations. Both
1291 growth and shrinkage are handled safely, and there also is no need for
1292 preallocation dances. Future changes in this area will be less error prone.
1293 Review and one bug found by markus
1294
1295 Upstream-ID: 822d664d6a5a1d10eccb23acdd53578a679d5065
1296
1297commit dc5dc45662773c0f7745c29cf77ae2d52723e55e
1298Author: deraadt@openbsd.org <deraadt@openbsd.org>
1299Date: Wed May 31 08:58:52 2017 +0000
1300
1301 upstream commit
1302
1303 These shutdown() SHUT_RDWR are not needed before close()
1304 ok djm markus claudio
1305
1306 Upstream-ID: 36f13ae4ba10f5618cb9347933101eb4a98dbcb5
1307
1308commit 1e0cdf8efb745d0d1116e1aa22bdc99ee731695e
1309Author: markus@openbsd.org <markus@openbsd.org>
1310Date: Wed May 31 08:09:45 2017 +0000
1311
1312 upstream commit
1313
1314 clear session keys from memory; ok djm@
1315
1316 Upstream-ID: ecd178819868975affd5fd6637458b7c712b6a0f
1317
1318commit 92e9fe633130376a95dd533df6e5e6a578c1e6b8
1319Author: markus@openbsd.org <markus@openbsd.org>
1320Date: Wed May 31 07:00:13 2017 +0000
1321
1322 upstream commit
1323
1324 remove now obsolete ctx from ssh_dispatch_run; ok djm@
1325
1326 Upstream-ID: 9870aabf7f4d71660c31fda91b942b19a8e68d29
1327
1328commit 17ad5b346043c5bbc5befa864d0dbeb76be39390
1329Author: markus@openbsd.org <markus@openbsd.org>
1330Date: Wed May 31 05:34:14 2017 +0000
1331
1332 upstream commit
1333
1334 use the ssh_dispatch_run_fatal variant
1335
1336 Upstream-ID: 28c5b364e37c755d1b22652b8cd6735a05c625d8
1337
1338commit 39896b777320a6574dd06707aebac5fb98e666da
1339Author: djm@openbsd.org <djm@openbsd.org>
1340Date: Wed May 31 05:08:46 2017 +0000
1341
1342 upstream commit
1343
1344 another ctx => ssh conversion (in GSSAPI code)
1345
1346 Upstream-ID: 4d6574c3948075c60608d8e045af42fe5b5d8ae0
1347
1348commit 6116bd4ed354a71a733c8fd0f0467ce612f12911
1349Author: Damien Miller <djm@mindrot.org>
1350Date: Wed May 31 14:56:07 2017 +1000
1351
1352 fix conversion of kexc25519s.c to struct ssh too
1353
1354 git cvsimport missed this commit for some reason
1355
1356commit d40dbdc85b6fb2fd78485ba02225511b8cbf20d7
1357Author: djm@openbsd.org <djm@openbsd.org>
1358Date: Wed May 31 04:29:44 2017 +0000
1359
1360 upstream commit
1361
1362 spell out that custom options/extensions should follow the
1363 usual SSH naming rules, e.g. "extension@example.com"
1364
1365 Upstream-ID: ab326666d2fad40769ec96b5a6de4015ffd97b8d
1366
1367commit 2a108277f976e8d0955c8b29d1dfde04dcbb3d5b
1368Author: djm@openbsd.org <djm@openbsd.org>
1369Date: Wed May 31 04:17:12 2017 +0000
1370
1371 upstream commit
1372
1373 one more void *ctx => struct ssh *ssh conversion
1374
1375 Upstream-ID: d299d043471c10214cf52c03daa10f1c232759e2
1376
1377commit c04e979503e97f52b750d3b98caa6fe004ab2ab9
1378Author: djm@openbsd.org <djm@openbsd.org>
1379Date: Wed May 31 00:43:04 2017 +0000
1380
1381 upstream commit
1382
1383 fix possible OOB strlen() in SOCKS4A hostname parsing;
1384 ok markus@
1385
1386 Upstream-ID: c67297cbeb0e5a19d81752aa18ec44d31270cd11
1387
1388commit a3bb250c93bfe556838c46ed965066afce61cffa
1389Author: jmc@openbsd.org <jmc@openbsd.org>
1390Date: Tue May 30 19:38:17 2017 +0000
1391
1392 upstream commit
1393
1394 tweak previous;
1395
1396 Upstream-ID: 66987651046c42d142f7318c9695fb81a6d14031
1397
1398commit 1112b534a6a7a07190e497e6bf86b0d5c5fb02dc
1399Author: bluhm@openbsd.org <bluhm@openbsd.org>
1400Date: Tue May 30 18:58:37 2017 +0000
1401
1402 upstream commit
1403
1404 Add RemoteCommand option to specify a command in the
1405 ssh config file instead of giving it on the client's command line. This
1406 command will be executed on the remote host. The feature allows to automate
1407 tasks using ssh config. OK markus@
1408
1409 Upstream-ID: 5d982fc17adea373a9c68cae1021ce0a0904a5ee
1410
1411commit eb272ea4099fd6157846f15c129ac5727933aa69
1412Author: markus@openbsd.org <markus@openbsd.org>
1413Date: Tue May 30 14:29:59 2017 +0000
1414
1415 upstream commit
1416
1417 switch auth2 to ssh_dispatch API; ok djm@
1418
1419 Upstream-ID: a752ca19e2782900dd83060b5c6344008106215f
1420
1421commit 5a146bbd4fdf5c571f9fb438e5210d28cead76d9
1422Author: markus@openbsd.org <markus@openbsd.org>
1423Date: Tue May 30 14:27:22 2017 +0000
1424
1425 upstream commit
1426
1427 switch auth2-none.c to modern APIs; ok djm@
1428
1429 Upstream-ID: 07252b58e064d332214bcabbeae8e08c44b2001b
1430
1431commit 60306b2d2f029f91927c6aa7c8e08068519a0fa2
1432Author: markus@openbsd.org <markus@openbsd.org>
1433Date: Tue May 30 14:26:49 2017 +0000
1434
1435 upstream commit
1436
1437 switch auth2-passwd.c to modern APIs; ok djm@
1438
1439 Upstream-ID: cba0a8b72b4f97adfb7e3b3fd2f8ba3159981fc7
1440
1441commit eb76698b91338bd798c978d4db2d6af624d185e4
1442Author: markus@openbsd.org <markus@openbsd.org>
1443Date: Tue May 30 14:25:42 2017 +0000
1444
1445 upstream commit
1446
1447 switch auth2-hostbased.c to modern APIs; ok djm@
1448
1449 Upstream-ID: 146af25c36daeeb83d5dbbb8ca52b5d25de88f4e
1450
1451commit 2ae666a8fc20b3b871b2f1b90ad65cc027336ccd
1452Author: markus@openbsd.org <markus@openbsd.org>
1453Date: Tue May 30 14:23:52 2017 +0000
1454
1455 upstream commit
1456
1457 protocol handlers all get struct ssh passed; ok djm@
1458
1459 Upstream-ID: 0ca9ea2a5d01a6d2ded94c5024456a930c5bfb5d
1460
1461commit 94583beb24a6c5fd19cedb9104ab2d2d5cd052b6
1462Author: markus@openbsd.org <markus@openbsd.org>
1463Date: Tue May 30 14:19:15 2017 +0000
1464
1465 upstream commit
1466
1467 ssh: pass struct ssh to auth functions, too; ok djm@
1468
1469 Upstream-ID: d13c509cc782f8f19728fbea47ac7cf36f6e85dd
1470
1471commit 5f4082d886c6173b9e90b9768c9a38a3bfd92c2b
1472Author: markus@openbsd.org <markus@openbsd.org>
1473Date: Tue May 30 14:18:15 2017 +0000
1474
1475 upstream commit
1476
1477 sshd: pass struct ssh to auth functions; ok djm@
1478
1479 Upstream-ID: b00a80c3460884ebcdd14ef550154c761aebe488
1480
1481commit 7da5df11ac788bc1133d8d598d298e33500524cc
1482Author: markus@openbsd.org <markus@openbsd.org>
1483Date: Tue May 30 14:16:41 2017 +0000
1484
1485 upstream commit
1486
1487 remove unused wrapper functions from key.[ch]; ok djm@
1488
1489 Upstream-ID: ea0f4016666a6817fc11f439dd4be06bab69707e
1490
1491commit ff7371afd08ac0bbd957d90451d4dcd0da087ef5
1492Author: markus@openbsd.org <markus@openbsd.org>
1493Date: Tue May 30 14:15:17 2017 +0000
1494
1495 upstream commit
1496
1497 sshkey_new() might return NULL (pkcs#11 code only); ok
1498 djm@
1499
1500 Upstream-ID: de9f2ad4a42c0b430caaa7d08dea7bac943075dd
1501
1502commit beb965bbc5a984fa69fb1e2b45ebe766ae09d1ef
1503Author: markus@openbsd.org <markus@openbsd.org>
1504Date: Tue May 30 14:13:40 2017 +0000
1505
1506 upstream commit
1507
1508 switch sshconnect.c to modern APIs; ok djm@
1509
1510 Upstream-ID: 27be17f84b950d5e139b7a9b281aa487187945ad
1511
1512commit 00ed75c92d1f95fe50032835106c368fa22f0f02
1513Author: markus@openbsd.org <markus@openbsd.org>
1514Date: Tue May 30 14:10:53 2017 +0000
1515
1516 upstream commit
1517
1518 switch auth2-pubkey.c to modern APIs; with & ok djm@
1519
1520 Upstream-ID: 8f08d4316eb1b0c4ffe4a206c05cdd45ed1daf07
1521
1522commit 54d90ace1d3535b44d92a8611952dc109a74a031
1523Author: markus@openbsd.org <markus@openbsd.org>
1524Date: Tue May 30 08:52:19 2017 +0000
1525
1526 upstream commit
1527
1528 switch from Key typedef with struct sshkey; ok djm@
1529
1530 Upstream-ID: 3067d33e04efbe5131ce8f70668c47a58e5b7a1f
1531
1532commit c221219b1fbee47028dcaf66613f4f8d6b7640e9
1533Author: markus@openbsd.org <markus@openbsd.org>
1534Date: Tue May 30 08:49:58 2017 +0000
1535
1536 upstream commit
1537
1538 remove ssh1 references; ok djm@
1539
1540 Upstream-ID: fc23b7578e7b0a8daaec72946d7f5e58ffff5a3d
1541
1542commit afbfa68fa18081ef05a9cd294958509a5d3cda8b
1543Author: markus@openbsd.org <markus@openbsd.org>
1544Date: Tue May 30 08:49:32 2017 +0000
1545
1546 upstream commit
1547
1548 revise sshkey_load_public(): remove ssh1 related
1549 comments, remove extra open()/close() on keyfile, prevent leak of 'pub' if
1550 'keyp' is NULL, replace strlcpy+cat with asprintf; ok djm@
1551
1552 Upstream-ID: 6175e47cab5b4794dcd99c1175549a483ec673ca
1553
1554commit 813f55336a24fdfc45e7ed655fccc7d792e8f859
1555Author: markus@openbsd.org <markus@openbsd.org>
1556Date: Fri May 26 20:34:49 2017 +0000
1557
1558 upstream commit
1559
1560 sshbuf_consume: reset empty buffer; ok djm@
1561
1562 Upstream-ID: 0d4583ba57f69e369d38bbd7843d85cac37fa821
1563
1564commit 6cf711752cc2a7ffaad1fb4de18cae65715ed8bb
1565Author: markus@openbsd.org <markus@openbsd.org>
1566Date: Fri May 26 19:35:50 2017 +0000
1567
1568 upstream commit
1569
1570 remove SSH_CHANNEL_XXX_DRAINING (ssh1 only); ok djm@
1571
1572 Upstream-ID: e2e225b6ac67b84dd024f38819afff2554fafe42
1573
1574commit 364f0d5edea27767fb0f915ea7fc61aded88d3e8
1575Author: markus@openbsd.org <markus@openbsd.org>
1576Date: Fri May 26 19:34:12 2017 +0000
1577
1578 upstream commit
1579
1580 remove channel_input_close_confirmation (ssh1 only); ok
1581 djm@
1582
1583 Upstream-ID: 8e7c8c38f322d255bb0294a5c0ebef53fdf576f1
1584
1585commit 8ba0fd40082751dbbc23a830433488bbfb1abdca
1586Author: djm@openbsd.org <djm@openbsd.org>
1587Date: Fri May 26 01:40:07 2017 +0000
1588
1589 upstream commit
1590
1591 fix references to obsolete v00 cert format; spotted by
1592 Jakub Jelen
1593
1594 Upstream-ID: 7600ce193ab8fd19451acfe24fc2eb39d46b2c4f
1595
1596commit dcc714c65cfb81eb6903095b4590719e8690f3da
1597Author: Mike Frysinger <vapier@chromium.org>
1598Date: Wed May 24 23:21:19 2017 -0400
1599
1600 configure: actually set cache vars when cross-compiling
1601
1602 The cross-compiling fallback message says it's assuming the test
1603 passed, but it didn't actually set the cache var which causes
1604 later tests to fail.
1605
1606commit 947a3e829a5b8832a4768fd764283709a4ca7955
1607Author: djm@openbsd.org <djm@openbsd.org>
1608Date: Sat May 20 02:35:47 2017 +0000
1609
1610 upstream commit
1611
1612 there's no reason to artificially limit the key path
1613 here, just check that it fits PATH_MAX; spotted by Matthew Patton
1614
1615 Upstream-ID: 858addaf2009c9cf04d80164a41b2088edb30b58
1616
1617commit 773224802d7cb250bb8b461546fcce10567b4b2e
1618Author: djm@openbsd.org <djm@openbsd.org>
1619Date: Fri May 19 21:07:17 2017 +0000
1620
1621 upstream commit
1622
1623 Now that we no longer support SSHv1, replace the contents
1624 of this file with a pointer to
1625 https://tools.ietf.org/html/draft-miller-ssh-agent-00 It's better edited,
1626 doesn't need to document stuff we no longer implement and does document stuff
1627 that we do implement (RSA SHA256/512 signature flags)
1628
1629 Upstream-ID: da8cdc46bbcc266efabd565ddddd0d8e556f846e
1630
1631commit 54cd41a4663fad66406dd3c8fe0e4760ccd8a899
1632Author: djm@openbsd.org <djm@openbsd.org>
1633Date: Wed May 17 01:24:17 2017 +0000
1634
1635 upstream commit
1636
1637 allow LogLevel in sshd_config Match blocks; ok dtucker
1638 bz#2717
1639
1640 Upstream-ID: 662e303be63148f47db1aa78ab81c5c2e732baa8
1641
1642commit 277abcda3f1b08d2376686f0ef20320160d4c8ab
1643Author: djm@openbsd.org <djm@openbsd.org>
1644Date: Tue May 16 16:56:15 2017 +0000
1645
1646 upstream commit
1647
1648 remove duplicate check; spotted by Jakub Jelen
1649
1650 Upstream-ID: 30c2996c1767616a8fdc49d4cee088efac69c3b0
1651
1652commit adb47ce839c977fa197e770c1be8f852508d65aa
1653Author: djm@openbsd.org <djm@openbsd.org>
1654Date: Tue May 16 16:54:05 2017 +0000
1655
1656 upstream commit
1657
1658 mention that Ed25519 keys are valid as CA keys; spotted
1659 by Jakub Jelen
1660
1661 Upstream-ID: d3f6db58b30418cb1c3058211b893a1ffed3dfd4
1662
1663commit 6bdf70f01e700348bb4d8c064c31a0ab90896df6
1664Author: Damien Miller <djm@mindrot.org>
1665Date: Tue May 9 14:35:03 2017 +1000
1666
1667 clean up regress files and add a .gitignore
1668
1669commit 7bdb2eeb1d3c26acdc409bd94532eefa252e440b
1670Author: djm@openbsd.org <djm@openbsd.org>
1671Date: Mon May 8 22:57:38 2017 +0000
1672
1673 upstream commit
1674
1675 remove hmac-ripemd160; ok dtucker
1676
1677 Upstream-ID: 896e737ea0bad6e23327d1c127e02d5e9e9c654d
1678
1679commit 5f02bb1f99f70bb422be8a5c2b77ef853f1db554
1680Author: djm@openbsd.org <djm@openbsd.org>
1681Date: Mon May 8 06:11:06 2017 +0000
1682
1683 upstream commit
1684
1685 make requesting bad ECDSA bits yield the same error
1686 (SSH_ERR_KEY_LENGTH) as the same mistake for RSA/DSA
1687
1688 Upstream-ID: bf40d3fee567c271e33f05ef8e4e0fa0b6f0ece6
1689
1690commit d757a4b633e8874629a1442c7c2e7b1b55d28c19
1691Author: djm@openbsd.org <djm@openbsd.org>
1692Date: Mon May 8 06:08:42 2017 +0000
1693
1694 upstream commit
1695
1696 fix for new SSH_ERR_KEY_LENGTH error value
1697
1698 Upstream-Regress-ID: c38a6e6174d4c3feca3518df150d4fbae0dca8dc
1699
1700commit 2e58a69508ac49c02d1bb6057300fa6a76db1045
1701Author: djm@openbsd.org <djm@openbsd.org>
1702Date: Mon May 8 06:03:39 2017 +0000
1703
1704 upstream commit
1705
1706 helps if I commit the correct version of the file. fix
1707 missing return statement.
1708
1709 Upstream-ID: c86394a3beeb1ec6611e659bfa830254f325546c
1710
1711commit effaf526bfa57c0ac9056ca236becf52385ce8af
1712Author: djm@openbsd.org <djm@openbsd.org>
1713Date: Mon May 8 01:52:49 2017 +0000
1714
1715 upstream commit
1716
1717 remove arcfour, blowfish and CAST here too
1718
1719 Upstream-Regress-ID: c613b3bcbef75df1fe84ca4dc2d3ef253dc5e920
1720
1721commit 7461a5bc571696273252df28a1f1578968cae506
1722Author: djm@openbsd.org <djm@openbsd.org>
1723Date: Mon May 8 00:21:36 2017 +0000
1724
1725 upstream commit
1726
1727 I was too aggressive with the scalpel in the last commit;
1728 unbreak sshd, spotted quickly by naddy@
1729
1730 Upstream-ID: fb7e75d2b2c7e6ca57dee00ca645e322dd49adbf
1731
1732commit bd636f40911094a39c2920bf87d2ec340533c152
1733Author: djm@openbsd.org <djm@openbsd.org>
1734Date: Sun May 7 23:15:59 2017 +0000
1735
1736 upstream commit
1737
1738 Refuse RSA keys <1024 bits in length. Improve reporting
1739 for keys that do not meet this requirement. ok markus@
1740
1741 Upstream-ID: b385e2a7b13b1484792ee681daaf79e1e203df6c
1742
1743commit 70c1218fc45757a030285051eb4d209403f54785
1744Author: djm@openbsd.org <djm@openbsd.org>
1745Date: Sun May 7 23:13:42 2017 +0000
1746
1747 upstream commit
1748
1749 Don't offer CBC ciphers by default in the client. ok
1750 markus@
1751
1752 Upstream-ID: 94c9ce8d0d1a085052e11c7f3307950fdc0901ef
1753
1754commit acaf34fd823235d549c633c0146ee03ac5956e82
1755Author: djm@openbsd.org <djm@openbsd.org>
1756Date: Sun May 7 23:12:57 2017 +0000
1757
1758 upstream commit
1759
1760 As promised in last release announcement: remove
1761 support for Blowfish, RC4 and CAST ciphers. ok markus@ deraadt@
1762
1763 Upstream-ID: 21f8facdba3fd8da248df6417000867cec6ba222
1764
1765commit 3e371bd2124427403971db853fb2e36ce789b6fd
1766Author: naddy@openbsd.org <naddy@openbsd.org>
1767Date: Fri May 5 10:42:49 2017 +0000
1768
1769 upstream commit
1770
1771 more simplification and removal of SSHv1-related code;
1772 ok djm@
1773
1774 Upstream-ID: d2f041aa0b79c0ebd98c68a01e5a0bfab2cf3b55
1775
1776commit 2e9c324b3a7f15c092d118c2ac9490939f6228fd
1777Author: naddy@openbsd.org <naddy@openbsd.org>
1778Date: Fri May 5 10:41:58 2017 +0000
1779
1780 upstream commit
1781
1782 remove superfluous protocol 2 mentions; ok jmc@
1783
1784 Upstream-ID: 0aaf7567c9f2e50fac5906b6a500a39c33c4664d
1785
1786commit 744bde79c3361e2153cb395a2ecdcee6c713585d
1787Author: djm@openbsd.org <djm@openbsd.org>
1788Date: Thu May 4 06:10:57 2017 +0000
1789
1790 upstream commit
1791
1792 since a couple of people have asked, leave a comment
1793 explaining why we retain SSH v.1 support in the "delete all keys from agent"
1794 path.
1795
1796 Upstream-ID: 4b42dcfa339813c15fe9248a2c1b7ed41c21bbb4
1797
1798commit 0c378ff6d98d80bc465a4a6a787670fb9cc701ee
1799Author: djm@openbsd.org <djm@openbsd.org>
1800Date: Thu May 4 01:33:21 2017 +0000
1801
1802 upstream commit
1803
1804 another tentacle: cipher_set_key_string() was only ever
1805 used for SSHv1
1806
1807 Upstream-ID: 7fd31eb6c48946f7e7cc12af0699fe8eb637e94a
1808
1809commit 9a82e24b986e3e0dc70849dbb2c19aa6c707b37f
1810Author: naddy@openbsd.org <naddy@openbsd.org>
1811Date: Wed May 3 21:49:18 2017 +0000
1812
1813 upstream commit
1814
1815 restore mistakenly deleted description of the
1816 ConnectionAttempts option ok markus@
1817
1818 Upstream-ID: 943002b1b7c470caea3253ba7b7348c359de0348
1819
1820commit 768405fddf64ff83aa6ef701ebb3c1f82d98a2f3
1821Author: naddy@openbsd.org <naddy@openbsd.org>
1822Date: Wed May 3 21:08:09 2017 +0000
1823
1824 upstream commit
1825
1826 remove miscellaneous SSH1 leftovers; ok markus@
1827
1828 Upstream-ID: af23696022ae4d45a1abc2fb8b490d8d9dd63b7c
1829
1830commit 1a1b24f8229bf7a21f89df21987433283265527a
1831Author: jmc@openbsd.org <jmc@openbsd.org>
1832Date: Wed May 3 10:01:44 2017 +0000
1833
1834 upstream commit
1835
1836 more protocol 1 bits removed; ok djm
1837
1838 Upstream-ID: b5b977eaf756915acb56aef3604a650e27f7c2b9
1839
1840commit 2b6f799e9b230cf13a7eefc05ecead7d8569d6b5
1841Author: jmc@openbsd.org <jmc@openbsd.org>
1842Date: Wed May 3 06:32:02 2017 +0000
1843
1844 upstream commit
1845
1846 more protocol 1 stuff to go; ok djm
1847
1848 Upstream-ID: 307a30441d2edda480fd1661d998d36665671e47
1849
1850commit f10c0d32cde2084d2a0b19bc47d80cb93e85a093
1851Author: jmc@openbsd.org <jmc@openbsd.org>
1852Date: Tue May 2 17:04:09 2017 +0000
1853
1854 upstream commit
1855
1856 rsa1 is no longer valid;
1857
1858 Upstream-ID: 9953d09ed9841c44b7dcf7019fa874783a709d89
1859
1860commit 42b690b4fd0faef78c4d68225948b6e5c46c5163
1861Author: jmc@openbsd.org <jmc@openbsd.org>
1862Date: Tue May 2 14:06:37 2017 +0000
1863
1864 upstream commit
1865
1866 add PubKeyAcceptedKeyTypes to the -o list: scp(1) has
1867 it, so i guess this should too;
1868
1869 Upstream-ID: 7fab32e869ca5831d09ab0c40d210b461d527a2c
1870
1871commit d852603214defd93e054de2877b20cc79c19d0c6
1872Author: jmc@openbsd.org <jmc@openbsd.org>
1873Date: Tue May 2 13:44:51 2017 +0000
1874
1875 upstream commit
1876
1877 remove now obsolete protocol1 options from the -o
1878 lists;
1879
1880 Upstream-ID: 828e478a440bc5f9947672c392420510a362b3dd
1881
1882commit 8b60ce8d8111e604c711c4cdd9579ffe0edced74
1883Author: jmc@openbsd.org <jmc@openbsd.org>
1884Date: Tue May 2 09:05:58 2017 +0000
1885
1886 upstream commit
1887
1888 more -O shuffle; ok djm
1889
1890 Upstream-ID: c239991a3a025cdbb030b73e990188dd9bfbeceb
1891
1892commit 3575f0b12afe6b561681582fd3c34067d1196231
1893Author: djm@openbsd.org <djm@openbsd.org>
1894Date: Tue May 2 08:54:19 2017 +0000
1895
1896 upstream commit
1897
1898 remove -1 / -2 options; pointed out by jmc@
1899
1900 Upstream-ID: 65d2a816000741a95df1c7cfdb5fa8469fcc7daa
1901
1902commit 4f1ca823bad12e4f9614895eefe0d0073b84a28f
1903Author: jmc@openbsd.org <jmc@openbsd.org>
1904Date: Tue May 2 08:06:33 2017 +0000
1905
1906 upstream commit
1907
1908 remove options -12 from usage();
1909
1910 Upstream-ID: db7ceef25132e63b50ed05289bf447fece1d1270
1911
1912commit 6b84897f7fd39956b849eac7810319d8a9958568
1913Author: jmc@openbsd.org <jmc@openbsd.org>
1914Date: Tue May 2 07:13:31 2017 +0000
1915
1916 upstream commit
1917
1918 tidy up -O somewhat; ok djm
1919
1920 Upstream-ID: 804405f716bf7ef15c1f36ab48581ca16aeb4d52
1921
1922commit d1c6b7fdbdfe4a7a37ecd48a97f0796b061c2868
1923Author: djm@openbsd.org <djm@openbsd.org>
1924Date: Mon May 1 22:09:48 2017 +0000
1925
1926 upstream commit
1927
1928 when freeing a bitmap, zero all it bytes; spotted by Ilya
1929 Kaliman
1930
1931 Upstream-ID: 834ac024f2c82389d6ea6b1c7d6701b3836e28e4
1932
1933commit 0f163983016c2988a92e039d18a7569f9ea8e071
1934Author: djm@openbsd.org <djm@openbsd.org>
1935Date: Mon May 1 14:08:26 2017 +0000
1936
1937 upstream commit
1938
1939 this one I did forget to "cvs rm"
1940
1941 Upstream-ID: 5781670c0578fe89663c9085ed3ba477cf7e7913
1942
1943commit 21ed00a8e26fe8a772bcca782175fafc2b0890ed
1944Author: djm@openbsd.org <djm@openbsd.org>
1945Date: Mon May 1 09:27:45 2017 +0000
1946
1947 upstream commit
1948
1949 don't know why cvs didn't exterminate these the first
1950 time around, I use rm -f and everuthing...
1951
1952 pointed out by sobrado@
1953
1954 Upstream-ID: a6c44a0c2885330d322ee01fcfd7f6f209b1e15d
1955
1956commit d29ba6f45086703fdcb894532848ada3427dfde6
1957Author: Darren Tucker <dtucker@zip.com.au>
1958Date: Mon May 1 13:53:07 2017 +1000
1959
1960 Define INT32_MAX and INT64_MAX if needed.
1961
1962commit 329037e389f02ec95c8e16bf93ffede94d3d44ce
1963Author: Darren Tucker <dtucker@zip.com.au>
1964Date: Mon May 1 13:19:41 2017 +1000
1965
1966 Wrap stdint.h in HAVE_STDINT_H
1967
1968commit f382362e8dfb6b277f16779ab1936399d7f2af78
1969Author: djm@openbsd.org <djm@openbsd.org>
1970Date: Mon May 1 02:27:11 2017 +0000
1971
1972 upstream commit
1973
1974 remove unused variable
1975
1976 Upstream-ID: 66011f00819d0e71b14700449a98414033284516
1977
1978commit dd369320d2435b630a5974ab270d686dcd92d024
1979Author: djm@openbsd.org <djm@openbsd.org>
1980Date: Sun Apr 30 23:34:55 2017 +0000
1981
1982 upstream commit
1983
1984 eliminate explicit specification of protocol in tests and
1985 loops over protocol. We only support SSHv2 now.
1986
1987 Upstream-Regress-ID: 0082838a9b8a382b7ee9cbf0c1b9db727784fadd
1988
1989commit 557f921aad004be15805e09fd9572969eb3d9321
1990Author: djm@openbsd.org <djm@openbsd.org>
1991Date: Sun Apr 30 23:33:48 2017 +0000
1992
1993 upstream commit
1994
1995 remove SSHv1 support from unit tests
1996
1997 Upstream-Regress-ID: 395ca2aa48f1f7d23eefff6cb849ea733ca8bbfe
1998
1999commit e77e1562716fb3da413e4c2397811017b762f5e3
2000Author: djm@openbsd.org <djm@openbsd.org>
2001Date: Mon May 1 00:03:18 2017 +0000
2002
2003 upstream commit
2004
2005 fixup setting ciphercontext->plaintext (lost in SSHv1 purge),
2006 though it isn't really used for much anymore.
2007
2008 Upstream-ID: 859b8bce84ff4865b32097db5430349d04b9b747
2009
2010commit f7849e6c83a4e0f602dea6c834a24091c622d68e
2011Author: Damien Miller <djm@mindrot.org>
2012Date: Mon May 1 09:55:56 2017 +1000
2013
2014 remove configure --with-ssh1
2015
2016commit f4a6a88ddb6dba6d2f7bfb9e2c9879fcc9633043
2017Author: djm@openbsd.org <djm@openbsd.org>
2018Date: Sun Apr 30 23:29:10 2017 +0000
2019
2020 upstream commit
2021
2022 flense SSHv1 support from ssh-agent, considerably
2023 simplifying it
2024
2025 ok markus
2026
2027 Upstream-ID: 71d772cdcefcb29f76e01252e8361e6fc2dfc365
2028
2029commit 930e8d2827853bc2e196c20c3e000263cc87fb75
2030Author: djm@openbsd.org <djm@openbsd.org>
2031Date: Sun Apr 30 23:28:41 2017 +0000
2032
2033 upstream commit
2034
2035 obliterate ssh1.h and some dead code that used it
2036
2037 ok markus@
2038
2039 Upstream-ID: 1ca9159a9fb95618f9d51e069ac8e1131a087343
2040
2041commit a3710d5d529a34b8f56aa62db798c70e85d576a0
2042Author: djm@openbsd.org <djm@openbsd.org>
2043Date: Sun Apr 30 23:28:12 2017 +0000
2044
2045 upstream commit
2046
2047 exterminate the -1 flag from scp
2048
2049 ok markus@
2050
2051 Upstream-ID: 26d247f7065da15056b209cef5f594ff591b89db
2052
2053commit aebd0abfaa8a41e75d50f9f7934267b0a2d9acb4
2054Author: djm@openbsd.org <djm@openbsd.org>
2055Date: Sun Apr 30 23:26:54 2017 +0000
2056
2057 upstream commit
2058
2059 purge the last traces of SSHv1 from the TTY modes
2060 handling code
2061
2062 ok markus
2063
2064 Upstream-ID: 963a19f1e06577377c38a3b7ce468f121b966195
2065
2066commit dfa641f758d4b8b2608ab1b00abaf88df0a8e36a
2067Author: djm@openbsd.org <djm@openbsd.org>
2068Date: Sun Apr 30 23:26:16 2017 +0000
2069
2070 upstream commit
2071
2072 remove the (in)famous SSHv1 CRC compensation attack
2073 detector.
2074
2075 Despite your cameo in The Matrix movies, you will not be missed.
2076
2077 ok markus
2078
2079 Upstream-ID: 44261fce51a56d93cdb2af7b6e184be629f667e0
2080
2081commit e5d3bd36ef67d82092861f39b5bf422cb12b31a6
2082Author: djm@openbsd.org <djm@openbsd.org>
2083Date: Sun Apr 30 23:25:03 2017 +0000
2084
2085 upstream commit
2086
2087 undo some local debugging stuff that I committed by
2088 accident
2089
2090 Upstream-ID: fe5b31f69a60d47171836911f144acff77810217
2091
2092commit 3d6d09f2e90f4ad650ebda6520bf2da446f37f14
2093Author: djm@openbsd.org <djm@openbsd.org>
2094Date: Sun Apr 30 23:23:54 2017 +0000
2095
2096 upstream commit
2097
2098 remove SSHv1 support from packet and buffer APIs
2099
2100 ok markus@
2101
2102 Upstream-ID: bfc290053d40b806ecac46317d300677d80e1dc9
2103
2104commit 05164358577c82de18ed7373196bc7dbd8a3f79c
2105Author: djm@openbsd.org <djm@openbsd.org>
2106Date: Sun Apr 30 23:21:54 2017 +0000
2107
2108 upstream commit
2109
2110 remove SSHv1-related buffers from client code
2111
2112 Upstream-ID: dca5d01108f891861ceaf7ba1c0f2eb274e0c7dd
2113
2114commit 873d3e7d9a4707d0934fb4c4299354418f91b541
2115Author: djm@openbsd.org <djm@openbsd.org>
2116Date: Sun Apr 30 23:18:44 2017 +0000
2117
2118 upstream commit
2119
2120 remove KEY_RSA1
2121
2122 ok markus@
2123
2124 Upstream-ID: 7408517b077c892a86b581e19f82a163069bf133
2125
2126commit 788ac799a6efa40517f2ac0d895a610394298ffc
2127Author: djm@openbsd.org <djm@openbsd.org>
2128Date: Sun Apr 30 23:18:22 2017 +0000
2129
2130 upstream commit
2131
2132 remove SSHv1 configuration options and man pages bits
2133
2134 ok markus@
2135
2136 Upstream-ID: 84638c23546c056727b7a7d653c72574e0f19424
2137
2138commit e6882463a8ae0594aacb6d6575a6318a41973d84
2139Author: djm@openbsd.org <djm@openbsd.org>
2140Date: Sun Apr 30 23:17:37 2017 +0000
2141
2142 upstream commit
2143
2144 remove SSH1 make flag and associated files ok markus@
2145
2146 Upstream-ID: ba9feacc5787337c413db7cf26ea3d53f854cfef
2147
2148commit cdccebdf85204bf7542b7fcc1aa2ea3f36661833
2149Author: djm@openbsd.org <djm@openbsd.org>
2150Date: Sun Apr 30 23:15:04 2017 +0000
2151
2152 upstream commit
2153
2154 remove SSHv1 ciphers; ok markus@
2155
2156 Upstream-ID: e5ebc5e540d7f23a8c1266db1839794d4d177890
2157
2158commit 97f4d3083b036ce3e68d6346a6140a22123d5864
2159Author: djm@openbsd.org <djm@openbsd.org>
2160Date: Sun Apr 30 23:13:25 2017 +0000
2161
2162 upstream commit
2163
2164 remove compat20/compat13/compat15 variables
2165
2166 ok markus@
2167
2168 Upstream-ID: 43802c035ceb3fef6c50c400e4ecabf12354691c
2169
2170commit 99f95ba82673d33215dce17bfa1512b57f54ec09
2171Author: djm@openbsd.org <djm@openbsd.org>
2172Date: Sun Apr 30 23:11:45 2017 +0000
2173
2174 upstream commit
2175
2176 remove options.protocol and client Protocol
2177 configuration knob
2178
2179 ok markus@
2180
2181 Upstream-ID: 5a967f5d06e2d004b0235457b6de3a9a314e9366
2182
2183commit 56912dea6ef63dae4eb1194e5d88973a7c6c5740
2184Author: djm@openbsd.org <djm@openbsd.org>
2185Date: Sun Apr 30 23:10:43 2017 +0000
2186
2187 upstream commit
2188
2189 unifdef WITH_SSH1 ok markus@
2190
2191 Upstream-ID: 9716e62a883ef8826c57f4d33b4a81a9cc7755c7
2192
2193commit d4084cd230f7319056559b00db8b99296dad49d5
2194Author: jmc@openbsd.org <jmc@openbsd.org>
2195Date: Sat Apr 29 06:06:01 2017 +0000
2196
2197 upstream commit
2198
2199 tweak previous;
2200
2201 Upstream-ID: a3abc6857455299aa42a046d232b7984568bceb9
2202
2203commit 249516e428e8461b46340a5df5d5ed1fbad2ccce
2204Author: djm@openbsd.org <djm@openbsd.org>
2205Date: Sat Apr 29 04:12:25 2017 +0000
2206
2207 upstream commit
2208
2209 allow ssh-keygen to include arbitrary string or flag
2210 certificate extensions and critical options. ok markus@ dtucker@
2211
2212 Upstream-ID: 2cf28dd6c5489eb9fc136e0b667ac3ea10241646
2213
2214commit 47a287bb6ac936c26b4f3ae63279c02902ded3b9
2215Author: jmc@openbsd.org <jmc@openbsd.org>
2216Date: Fri Apr 28 06:15:03 2017 +0000
2217
2218 upstream commit
2219
2220 sort;
2221
2222 Upstream-ID: 7e6b56e52b039cf44d0418e9de9aca20a2d2d15a
2223
2224commit 36465a76a79ad5040800711b41cf5f32249d5120
2225Author: Darren Tucker <dtucker@zip.com.au>
2226Date: Fri Apr 28 14:44:28 2017 +1000
2227
2228 Typo.
2229
2230 Upstream-Regress-ID: 1e6b51ddf767cbad0a4e63eb08026c127e654308
2231
2232commit 9d18cb7bdeb00b20205fd13d412aae8c0e0457ed
2233Author: Darren Tucker <dtucker@zip.com.au>
2234Date: Fri Apr 28 14:41:17 2017 +1000
2235
2236 Add 2 regress commits I applied by hand.
2237
2238 Upstream-Regress-ID: 30c20180c87cbc99fa1020489fe7fd8245b6420c
2239 Upstream-Regress-ID: 1e6b51ddf767cbad0a4e63eb08026c127e654308
2240
2241commit 9504ea6b27f9f0ece64e88582ebb9235e664a100
2242Author: Darren Tucker <dtucker@zip.com.au>
2243Date: Fri Apr 28 14:33:43 2017 +1000
2244
2245 Merge integrity.sh rev 1.22.
2246
2247 Merge missing bits from Colin Watson's patch in bz#2658 which make integrity
2248 tests more robust against timeouts. ok djm@
2249
2250commit 06ec837a34542627e2183a412d6a9d2236f22140
2251Author: Darren Tucker <dtucker@zip.com.au>
2252Date: Fri Apr 28 14:30:03 2017 +1000
2253
2254 Id sync for integrity.sh rev 1.21 which pulls in some shell portability fixes
2255
2256commit e0194b471efe7d3daedc9cc66686cb1ab69d3be8
2257Author: jsg@openbsd.org <jsg@openbsd.org>
2258Date: Mon Apr 17 11:02:31 2017 +0000
2259
2260 upstream commit
2261
2262 Change COMPILER_VERSION tests which limited additional
2263 warnings to gcc4 to instead skip them on gcc3 as clang can handle
2264 -Wpointer-sign and -Wold-style-definition.
2265
2266 Upstream-Regress-ID: e48d7dc13e48d9334b8195ef884dfbc51316012f
2267
2268commit 6830be90e71f46bcd182a9202b151eaf2b299434
2269Author: djm@openbsd.org <djm@openbsd.org>
2270Date: Fri Apr 28 03:24:53 2017 +0000
2271
2272 upstream commit
2273
2274 include key fingerprint in "Offering public key" debug
2275 message
2276
2277 Upstream-ID: 964749f820c2ed4cf6a866268b1a05e907315c52
2278
2279commit 066437187e16dcafcbc19f9402ef0e6575899b1d
2280Author: millert@openbsd.org <millert@openbsd.org>
2281Date: Fri Apr 28 03:21:12 2017 +0000
2282
2283 upstream commit
2284
2285 Avoid relying on implementation-specific behavior when
2286 detecting whether the timestamp or file size overflowed. If time_t and off_t
2287 are not either 32-bit or 64-bit scp will exit with an error. OK djm@
2288
2289 Upstream-ID: f31caae73ddab6df496b7bbbf7da431e267ad135
2290
2291commit 68d3a2a059183ebd83b15e54984ffaced04d2742
2292Author: dtucker@openbsd.org <dtucker@openbsd.org>
2293Date: Fri Apr 28 03:20:27 2017 +0000
2294
2295 upstream commit
2296
2297 Add SyslogFacility option to ssh(1) matching the
2298 equivalent option in sshd(8). bz#2705, patch from erahn at arista.com, ok
2299 djm@
2300
2301 Upstream-ID: d5115c2c0193ceb056ed857813b2a7222abda9ed
2302
2303commit e13aad66e73a14b062d13aee4e98f1e21a3f6a14
2304Author: jsg@openbsd.org <jsg@openbsd.org>
2305Date: Thu Apr 27 13:40:05 2017 +0000
2306
2307 upstream commit
2308
2309 remove a static array unused since rev 1.306 spotted by
2310 clang ok djm@
2311
2312 Upstream-ID: 249b3eed2446f6074ba2219ccc46919dd235a7b8
2313
2314commit 91bd2181866659f00714903e78e1c3edd4c45f3d
2315Author: millert@openbsd.org <millert@openbsd.org>
2316Date: Thu Apr 27 11:53:12 2017 +0000
2317
2318 upstream commit
2319
2320 Avoid potential signed int overflow when parsing the file
2321 size. Use strtoul() instead of parsing manually. OK djm@
2322
2323 Upstream-ID: 1f82640861c7d905bbb05e7d935d46b0419ced02
2324
2325commit 17a54a03f5a1d35e33cc24e22cd7a9d0f6865dc4
2326Author: Darren Tucker <dtucker@zip.com.au>
2327Date: Tue Apr 25 08:32:27 2017 +1000
2328
2329 Fix typo in "socketcall".
2330
2331 Pointed out by jjelen at redhat.com.
2332
2333commit 8b0eee148f7cf8b248c30d1bae57300f2cc5aafd
2334Author: Darren Tucker <dtucker@zip.com.au>
2335Date: Mon Apr 24 19:40:31 2017 +1000
2336
2337 Deny socketcall in seccomp filter on ppc64le.
2338
2339 OpenSSL is using socket() calls (in FIPS mode) when handling ECDSA keys
2340 in privsep child. The socket() syscall is already denied in the seccomp
2341 filter, but in ppc64le kernel, it is implemented using socketcall()
2342 syscall, which is not denied yet (only SYS_SHUTDOWN is allowed) and
2343 therefore fails hard.
2344
2345 Patch from jjelen at redhat.com.
2346
2347commit f8500b2be599053daa05248a86a743232ec6a536
2348Author: schwarze@openbsd.org <schwarze@openbsd.org>
2349Date: Mon Apr 17 14:31:23 2017 +0000
2350
2351 upstream commit
2352
2353 Recognize nl_langinfo(CODESET) return values "646" and ""
2354 as aliases for "US-ASCII", useful for different versions of NetBSD and
2355 Solaris. Found by dtucker@ and by Tom G. Christensen <tgc at jupiterrise dot
2356 com>. OK dtucker@ deraadt@
2357
2358 Upstream-ID: 38c2133817cbcae75c88c63599ac54228f0fa384
2359
2360commit 7480dfedf8c5c93baaabef444b3def9331e86ad5
2361Author: jsg@openbsd.org <jsg@openbsd.org>
2362Date: Mon Apr 17 11:02:31 2017 +0000
2363
2364 upstream commit
2365
2366 Change COMPILER_VERSION tests which limited additional
2367 warnings to gcc4 to instead skip them on gcc3 as clang can handle
2368 -Wpointer-sign and -Wold-style-definition.
2369
2370 Upstream-ID: 5cbe348aa76dc1adf55be6c0e388fafaa945439a
2371
2372commit 4d827f0d75a53d3952288ab882efbddea7ffadfe
2373Author: djm@openbsd.org <djm@openbsd.org>
2374Date: Tue Apr 4 00:24:56 2017 +0000
2375
2376 upstream commit
2377
2378 disallow creation (of empty files) in read-only mode;
2379 reported by Michal Zalewski, feedback & ok deraadt@
2380
2381 Upstream-ID: 5d9c8f2fa8511d4ecf95322994ffe73e9283899b
2382
2383commit ef47843af0a904a21c920e619c5aec97b65dd9ac
2384Author: deraadt@openbsd.org <deraadt@openbsd.org>
2385Date: Sun Mar 26 00:18:52 2017 +0000
2386
2387 upstream commit
2388
2389 incorrect renditions of this quote bother me
2390
2391 Upstream-ID: 1662be3ebb7a71d543da088119c31d4d463a9e49
2392
2393commit d9048861bea842c4eba9c2dbbf97064cc2a5ef02
2394Author: Darren Tucker <dtucker@zip.com.au>
2395Date: Fri Mar 31 11:04:43 2017 +1100
2396
2397 Check for and use gcc's -pipe.
2398
2399 Speeds up configure and build by a couple of percent. ok djm@
2400
2401commit 282cad2240c4fbc104c2f2df86d688192cbbe4bb
2402Author: Darren Tucker <dtucker@zip.com.au>
2403Date: Wed Mar 29 16:34:44 2017 +1100
2404
2405 Import fmt_scaled.c rev 1.16 from OpenBSD.
2406
2407 Fix overly-conservative overflow checks on mulitplications and add checks
2408 on additions. This allows scan_scaled to work up to +/-LLONG_MAX (LLONG_MIN
2409 will still be flagged as a range error). ok millert@
2410
2411commit c73a229e4edf98920f395e19fd310684fc6bb951
2412Author: Darren Tucker <dtucker@zip.com.au>
2413Date: Wed Mar 29 16:34:02 2017 +1100
2414
2415 Import fmt_scaled.c rev 1.15 from OpenBSD.
2416
2417 Collapse underflow and overflow checks into a single block.
2418 ok djm@ millert@
2419
2420commit d427b73bf5a564f663d16546dbcbd84ba8b9d4af
2421Author: Darren Tucker <dtucker@zip.com.au>
2422Date: Wed Mar 29 16:32:57 2017 +1100
2423
2424 Import fmt_scaled.c rev 1.14 from OpenBSD.
2425
2426 Catch integer underflow in scan_scaled reported by Nicolas Iooss.
2427 ok deraadt@ djm@
2428
2429commit d13281f2964abc5f2e535e1613c77fc61b0c53e7
2430Author: Darren Tucker <dtucker@zip.com.au>
2431Date: Wed Mar 29 12:39:39 2017 +1100
2432
2433 Don't check privsep user or path when unprivileged
2434
2435 If running with privsep (mandatory now) as a non-privileged user, we
2436 don't chroot or change to an unprivileged user however we still checked
2437 the existence of the user and directory. Don't do those checks if we're
2438 not going to use them. Based in part on a patch from Lionel Fourquaux
2439 via Corinna Vinschen, ok djm@
2440
2441commit f2742a481fe151e493765a3fbdef200df2ea7037
2442Author: Darren Tucker <dtucker@zip.com.au>
2443Date: Wed Mar 29 10:50:31 2017 +1100
2444
2445 Remove SHA256 EVP wrapper implementation.
2446
2447 All supported versions of OpenSSL should now have SHA256 so remove our
2448 EVP wrapper implementaion. ok djm@
2449
2450commit 5346f271fc76549caf4a8e65b5fba319be422fe9
2451Author: Darren Tucker <dtucker@zip.com.au>
2452Date: Wed Mar 29 10:23:58 2017 +1100
2453
2454 Remove check for OpenSSL < 0.9.8g.
2455
2456 We no longer support OpenSSL < 1.0.1 so remove check for unreliable ECC
2457 in OpenSSL < 0.9.8g.
2458
2459commit 8fed0a5fe7b4e78a6810b133d8e91be9742ee0a1
2460Author: Darren Tucker <dtucker@zip.com.au>
2461Date: Wed Mar 29 10:16:15 2017 +1100
2462
2463 Remove compat code for OpenSSL < 0.9.7.
2464
2465 Resyncs that code with OpenBSD upstream.
2466
2467commit 608ec1f62ff22fdccc3952e51463d79c43cbd0d3
2468Author: Darren Tucker <dtucker@zip.com.au>
2469Date: Wed Mar 29 09:50:54 2017 +1100
2470
2471 Remove SSHv1 code path.
2472
2473 Server-side support for Protocol 1 has been removed so remove !compat20
2474 PAM code path.
2475
2476commit 7af27bf538cbc493d609753f9a6d43168d438f1b
2477Author: Darren Tucker <dtucker@zip.com.au>
2478Date: Fri Mar 24 09:44:56 2017 +1100
2479
2480 Enable ldns when using ldns-config.
2481
2482 Actually enable ldns when attempting to use ldns-config. bz#2697, patch
2483 from fredrik at fornwall.net.
2484
2485commit 58b8cfa2a062b72139d7229ae8de567f55776f24
2486Author: Damien Miller <djm@mindrot.org>
2487Date: Wed Mar 22 12:43:02 2017 +1100
2488
2489 Missing header on Linux/s390
2490
2491 Patch from Jakub Jelen
2492
2493commit 096fb65084593f9f3c1fc91b6d9052759a272a00
2494Author: djm@openbsd.org <djm@openbsd.org>
2495Date: Mon Mar 20 22:08:06 2017 +0000
2496
2497 upstream commit
2498
2499 remove /usr/bin/time calls around tests, makes diffing test
2500 runs harder. Based on patch from Mike Frysinger
2501
2502 Upstream-Regress-ID: 81c1083b14dcf473b23d2817882f40b346ebc95c
2503
2504commit 6b853c6f8ba5eecc50f3b57af8e63f8184eb0fa6
2505Author: Damien Miller <djm@mindrot.org>
2506Date: Tue Mar 21 08:47:55 2017 +1100
2507
2508 Fix syntax error on Linux/X32
2509
2510 Patch from Mike Frysinger
2511
1commit d38f05dbdd291212bc95ea80648b72b7177e9f4e 2512commit d38f05dbdd291212bc95ea80648b72b7177e9f4e
2Author: Darren Tucker <dtucker@zip.com.au> 2513Author: Darren Tucker <dtucker@zip.com.au>
3Date: Mon Mar 20 13:38:27 2017 +1100 2514Date: Mon Mar 20 13:38:27 2017 +1100
@@ -6838,2557 +9349,3 @@ Date: Tue Sep 22 08:33:23 2015 +0000
6838 fix two typos. 9349 fix two typos.
6839 9350
6840 Upstream-ID: 424402c0d8863a11b51749bacd7f8d932083b709 9351 Upstream-ID: 424402c0d8863a11b51749bacd7f8d932083b709
6841
6842commit 8408218c1ca88cb17d15278174a24a94a6f65fe1
6843Author: djm@openbsd.org <djm@openbsd.org>
6844Date: Mon Sep 21 04:31:00 2015 +0000
6845
6846 upstream commit
6847
6848 fix possible hang on closed output; bz#2469 reported by Tomas
6849 Kuthan ok markus@
6850
6851 Upstream-ID: f7afd41810f8540f524284f1be6b970859f94fe3
6852
6853commit 0097248f90a00865082e8c146b905a6555cc146f
6854Author: djm@openbsd.org <djm@openbsd.org>
6855Date: Fri Sep 11 04:55:01 2015 +0000
6856
6857 upstream commit
6858
6859 skip if running as root; many systems (inc OpenBSD) allow
6860 root to ptrace arbitrary processes
6861
6862 Upstream-Regress-ID: be2b925df89360dff36f972951fa0fa793769038
6863
6864commit 9c06c814aff925e11a5cc592c06929c258a014f6
6865Author: djm@openbsd.org <djm@openbsd.org>
6866Date: Fri Sep 11 03:44:21 2015 +0000
6867
6868 upstream commit
6869
6870 try all supported key types here; bz#2455 reported by
6871 Jakub Jelen
6872
6873 Upstream-Regress-ID: 188cb7d9031cdbac3a0fa58b428b8fa2b2482bba
6874
6875commit 3c019a936b43f3e2773f3edbde7c114d73caaa4c
6876Author: tim@openbsd.org <tim@openbsd.org>
6877Date: Sun Sep 13 14:39:16 2015 +0000
6878
6879 upstream commit
6880
6881 - Fix error message: passphrase needs to be at least 5
6882 characters, not 4. - Remove unused function argument. - Remove two
6883 unnecessary variables.
6884
6885 OK djm@
6886
6887 Upstream-ID: 13010c05bfa8b523da1c0dc19e81dd180662bc30
6888
6889commit 2681cdb6e0de7c1af549dac37a9531af202b4434
6890Author: tim@openbsd.org <tim@openbsd.org>
6891Date: Sun Sep 13 13:48:19 2015 +0000
6892
6893 upstream commit
6894
6895 When adding keys to the agent, don't ignore the comment
6896 of keys for which the user is prompted for a passphrase.
6897
6898 Tweak and OK djm@
6899
6900 Upstream-ID: dc737c620a5a8d282cc4f66e3b9b624e9abefbec
6901
6902commit 14692f7b8251cdda847e648a82735eef8a4d2a33
6903Author: guenther@openbsd.org <guenther@openbsd.org>
6904Date: Fri Sep 11 08:50:04 2015 +0000
6905
6906 upstream commit
6907
6908 Use explicit_bzero() when zeroing before free()
6909
6910 from Michael McConville (mmcconv1 (at) sccs.swarthmore.edu)
6911 ok millert@ djm@
6912
6913 Upstream-ID: 2e3337db046c3fe70c7369ee31515ac73ec00f50
6914
6915commit 846f6fa4cfa8483a9195971dbdd162220f199d85
6916Author: jmc@openbsd.org <jmc@openbsd.org>
6917Date: Fri Sep 11 06:55:46 2015 +0000
6918
6919 upstream commit
6920
6921 sync -Q in usage() to SYNOPSIS; since it's drastically
6922 shorter, i've reformatted the block to sync with the man (80 cols) and saved
6923 a line;
6924
6925 Upstream-ID: 86e2c65c3989a0777a6258a77e589b9f6f354abd
6926
6927commit 95923e0520a8647417ee6dcdff44694703dfeef0
6928Author: jmc@openbsd.org <jmc@openbsd.org>
6929Date: Fri Sep 11 06:51:39 2015 +0000
6930
6931 upstream commit
6932
6933 tweak previous;
6934
6935 Upstream-ID: f29b3cfcfd9aa31fa140c393e7bd48c1c74139d6
6936
6937commit 86ac462f833b05d8ed9de9c50ccb295d7faa79ff
6938Author: dtucker@openbsd.org <dtucker@openbsd.org>
6939Date: Fri Sep 11 05:27:02 2015 +0000
6940
6941 upstream commit
6942
6943 Update usage to match man page.
6944
6945 Upstream-ID: 9e85aefaecfb6aaf34c7cfd0700cd21783a35675
6946
6947commit 674b3b68c1d36b2562324927cd03857b565e05e8
6948Author: djm@openbsd.org <djm@openbsd.org>
6949Date: Fri Sep 11 03:47:28 2015 +0000
6950
6951 upstream commit
6952
6953 expand %i in ControlPath to UID; bz#2449
6954
6955 patch from Christian Hesse w/ feedback from dtucker@
6956
6957 Upstream-ID: 2ba8d303e555a84e2f2165ab4b324b41e80ab925
6958
6959commit c0f55db7ee00c8202b05cb4b9ad4ce72cc45df41
6960Author: djm@openbsd.org <djm@openbsd.org>
6961Date: Fri Sep 11 03:42:32 2015 +0000
6962
6963 upstream commit
6964
6965 mention -Q key-plain and -Q key-cert; bz#2455 pointed out
6966 by Jakub Jelen
6967
6968 Upstream-ID: c8f1f8169332e4fa73ac96b0043e3b84e01d4896
6969
6970commit cfffbdb10fdf0f02d3f4232232eef7ec3876c383
6971Author: Darren Tucker <dtucker@zip.com.au>
6972Date: Mon Sep 14 16:24:21 2015 +1000
6973
6974 Use ssh-keygen -A when generating host keys.
6975
6976 Use ssh-keygen -A instead of per-keytype invocations when generating host
6977 keys. Add tests when doing host-key-force since we can't use ssh-keygen -A
6978 since it can't specify alternate locations. bz#2459, ok djm@
6979
6980commit 366bada1e9e124654aac55b72b6ccf878755b0dc
6981Author: Darren Tucker <dtucker@zip.com.au>
6982Date: Fri Sep 11 13:29:22 2015 +1000
6983
6984 Correct default value for --with-ssh1.
6985
6986 bz#2457, from konto-mindrot.org at walimnieto.com.
6987
6988commit 2bca8a43e7dd9b04d7070824ffebb823c72587b2
6989Author: djm@openbsd.org <djm@openbsd.org>
6990Date: Fri Sep 11 03:13:36 2015 +0000
6991
6992 upstream commit
6993
6994 more clarity on what AuthorizedKeysFile=none does; based
6995 on diff by Thiebaud Weksteen
6996
6997 Upstream-ID: 78ab87f069080f0cc3bc353bb04eddd9e8ad3704
6998
6999commit 61942ea4a01e6db4fdf37ad61de81312ffe310e9
7000Author: djm@openbsd.org <djm@openbsd.org>
7001Date: Wed Sep 9 00:52:44 2015 +0000
7002
7003 upstream commit
7004
7005 openssh_RSA_verify return type is int, so don't make it
7006 size_t within the function itself with only negative numbers or zero assigned
7007 to it. bz#2460
7008
7009 Upstream-ID: b6e794b0c7fc4f9f329509263c8668d35f83ea55
7010
7011commit 4f7cc2f8cc861a21e6dbd7f6c25652afb38b9b96
7012Author: dtucker@openbsd.org <dtucker@openbsd.org>
7013Date: Fri Sep 4 08:21:47 2015 +0000
7014
7015 upstream commit
7016
7017 Plug minor memory leaks when options are used more than
7018 once. bz#2182, patch from Tiago Cunha, ok deraadt djm
7019
7020 Upstream-ID: 5b84d0401e27fe1614c10997010cc55933adb48e
7021
7022commit 7ad8b287c8453a3e61dbc0d34d467632b8b06fc8
7023Author: Darren Tucker <dtucker@zip.com.au>
7024Date: Fri Sep 11 13:11:02 2015 +1000
7025
7026 Force resolution of _res for correct detection.
7027
7028 bz#2259, from sconeu at yahoo.com.
7029
7030commit 26ad18247213ff72b4438abe7fc660c958810fa2
7031Author: Damien Miller <djm@mindrot.org>
7032Date: Thu Sep 10 10:57:41 2015 +1000
7033
7034 allow getrandom syscall; from Felix von Leitner
7035
7036commit 5245bc1e6b129a10a928f73f11c3aa32656c44b4
7037Author: jmc@openbsd.org <jmc@openbsd.org>
7038Date: Fri Sep 4 06:40:45 2015 +0000
7039
7040 upstream commit
7041
7042 full stop belongs outside the brackets, not inside;
7043
7044 Upstream-ID: 99d098287767799ac33d2442a05b5053fa5a551a
7045
7046commit a85768a9321d74b41219eeb3c9be9f1702cbf6a5
7047Author: djm@openbsd.org <djm@openbsd.org>
7048Date: Fri Sep 4 04:56:09 2015 +0000
7049
7050 upstream commit
7051
7052 add a debug2() right before DNS resolution; it's a place
7053 where ssh could previously silently hang for a while. bz#2433
7054
7055 Upstream-ID: 52a1a3e0748db66518e7598352c427145692a6a0
7056
7057commit 46152af8d27aa34d5d26ed1c371dc8aa142d4730
7058Author: djm@openbsd.org <djm@openbsd.org>
7059Date: Fri Sep 4 04:55:24 2015 +0000
7060
7061 upstream commit
7062
7063 correct function name in error messages
7064
7065 Upstream-ID: 92fb2798617ad9561370897f4ab60adef2ff4c0e
7066
7067commit a954cdb799a4d83c2d40fbf3e7b9f187fbfd72fc
7068Author: djm@openbsd.org <djm@openbsd.org>
7069Date: Fri Sep 4 04:47:50 2015 +0000
7070
7071 upstream commit
7072
7073 better document ExitOnForwardFailure; bz#2444, ok
7074 dtucker@
7075
7076 Upstream-ID: a126209b5a6d9cb3117ac7ab5bc63d284538bfc2
7077
7078commit f54d8ac2474b6fc3afa081cf759b48a6c89d3319
7079Author: djm@openbsd.org <djm@openbsd.org>
7080Date: Fri Sep 4 04:44:08 2015 +0000
7081
7082 upstream commit
7083
7084 don't record hostbased authentication hostkeys as user
7085 keys in test for multiple authentication with the same key
7086
7087 Upstream-ID: 26b368fa2cff481f47f37e01b8da1ae5b57b1adc
7088
7089commit ac3451dd65f27ecf85dc045c46d49e2bbcb8dddd
7090Author: djm@openbsd.org <djm@openbsd.org>
7091Date: Fri Sep 4 03:57:38 2015 +0000
7092
7093 upstream commit
7094
7095 remove extra newline in nethack-mode hostkey; from
7096 Christian Hesse bz#2686
7097
7098 Upstream-ID: 4f56368b1cc47baeea0531912186f66007fd5b92
7099
7100commit 9e3ed9ebb1a7e47c155c28399ddf09b306ea05df
7101Author: djm@openbsd.org <djm@openbsd.org>
7102Date: Fri Sep 4 04:23:10 2015 +0000
7103
7104 upstream commit
7105
7106 trim junk from end of file; bz#2455 from Jakub Jelen
7107
7108 Upstream-Regress-ID: a4e64e8931e40d23874b047074444eff919cdfe6
7109
7110commit f3a3ea180afff080bab82087ee0b60db9fd84f6c
7111Author: jsg@openbsd.org <jsg@openbsd.org>
7112Date: Wed Sep 2 07:51:12 2015 +0000
7113
7114 upstream commit
7115
7116 Fix occurrences of "r = func() != 0" which result in the
7117 wrong error codes being returned due to != having higher precedence than =.
7118
7119 ok deraadt@ markus@
7120
7121 Upstream-ID: 5fc35c9fc0319cc6fca243632662d2f06b5fd840
7122
7123commit f498a98cf83feeb7ea01c15cd1c98b3111361f3a
7124Author: Damien Miller <djm@mindrot.org>
7125Date: Thu Sep 3 09:11:22 2015 +1000
7126
7127 don't check for yp_match; ok tim@
7128
7129commit 9690b78b7848b0b376980a61d51b1613e187ddb5
7130Author: djm@openbsd.org <djm@openbsd.org>
7131Date: Fri Aug 21 23:57:48 2015 +0000
7132
7133 upstream commit
7134
7135 Improve printing of KEX offers and decisions
7136
7137 The debug output now labels the client and server offers and the
7138 negotiated options. ok markus@
7139
7140 Upstream-ID: 8db921b3f92a4565271b1c1fbce6e7f508e1a2cb
7141
7142commit 60a92470e21340e1a3fc10f9c7140d8e1519dc55
7143Author: djm@openbsd.org <djm@openbsd.org>
7144Date: Fri Aug 21 23:53:08 2015 +0000
7145
7146 upstream commit
7147
7148 Fix printing (ssh -G ...) of HostKeyAlgorithms=+...
7149 Reported by Bryan Drewery
7150
7151 Upstream-ID: 19ad20c41bd5971e006289b6f9af829dd46c1293
7152
7153commit 6310f60fffca2d1e464168e7d1f7e3b6b0268897
7154Author: djm@openbsd.org <djm@openbsd.org>
7155Date: Fri Aug 21 23:52:30 2015 +0000
7156
7157 upstream commit
7158
7159 Fix expansion of HostkeyAlgorithms=+...
7160
7161 Reported by Bryan Drewery
7162
7163 Upstream-ID: 70ca1deea39d758ba36d36428ae832e28566f78d
7164
7165commit e774e5ea56237fd626a8161f9005023dff3e76c9
7166Author: deraadt@openbsd.org <deraadt@openbsd.org>
7167Date: Fri Aug 21 23:29:31 2015 +0000
7168
7169 upstream commit
7170
7171 Improve size == 0, count == 0 checking in mm_zalloc,
7172 which is "array" like. Discussed with tedu, millert, otto.... and ok djm
7173
7174 Upstream-ID: 899b021be43b913fad3eca1aef44efe710c53e29
7175
7176commit 189de02d9ad6f3645417c0ddf359b923aae5f926
7177Author: Damien Miller <djm@mindrot.org>
7178Date: Fri Aug 21 15:45:02 2015 +1000
7179
7180 expose POLLHUP and POLLNVAL for netcat.c
7181
7182commit e91346dc2bbf460246df2ab591b7613908c1b0ad
7183Author: Damien Miller <djm@mindrot.org>
7184Date: Fri Aug 21 14:49:03 2015 +1000
7185
7186 we don't use Github for issues/pull-requests
7187
7188commit a4f5b507c708cc3dc2c8dd2d02e4416d7514dc23
7189Author: Damien Miller <djm@mindrot.org>
7190Date: Fri Aug 21 14:43:55 2015 +1000
7191
7192 fix URL for connect.c
7193
7194commit d026a8d3da0f8186598442997c7d0a28e7275414
7195Author: Damien Miller <djm@mindrot.org>
7196Date: Fri Aug 21 13:47:10 2015 +1000
7197
7198 update version numbers for 7.1
7199
7200commit 78f8f589f0ca1c9f41e5a9bae3cda5ce8a6b42ed
7201Author: djm@openbsd.org <djm@openbsd.org>
7202Date: Fri Aug 21 03:45:26 2015 +0000
7203
7204 upstream commit
7205
7206 openssh-7.1
7207
7208 Upstream-ID: ff7b1ef4b06caddfb45e08ba998128c88be3d73f
7209
7210commit 32a181980c62fce94f7f9ffaf6a79d90f0c309cf
7211Author: djm@openbsd.org <djm@openbsd.org>
7212Date: Fri Aug 21 03:42:19 2015 +0000
7213
7214 upstream commit
7215
7216 fix inverted logic that broke PermitRootLogin; reported
7217 by Mantas Mikulenas; ok markus@
7218
7219 Upstream-ID: 260dd6a904c1bb7e43267e394b1c9cf70bdd5ea5
7220
7221commit ce445b0ed927e45bd5bdce8f836eb353998dd65c
7222Author: deraadt@openbsd.org <deraadt@openbsd.org>
7223Date: Thu Aug 20 22:32:42 2015 +0000
7224
7225 upstream commit
7226
7227 Do not cast result of malloc/calloc/realloc* if stdlib.h
7228 is in scope ok krw millert
7229
7230 Upstream-ID: 5e50ded78cadf3841556649a16cc4b1cb6c58667
7231
7232commit 05291e5288704d1a98bacda269eb5a0153599146
7233Author: naddy@openbsd.org <naddy@openbsd.org>
7234Date: Thu Aug 20 19:20:06 2015 +0000
7235
7236 upstream commit
7237
7238 In the certificates section, be consistent about using
7239 "host_key" and "user_key" for the respective key types. ok sthen@ deraadt@
7240
7241 Upstream-ID: 9e037ea3b15577b238604c5533e082a3947f13cb
7242
7243commit 8543d4ef6f2e9f98c3e6b77c894ceec30c5e4ae4
7244Author: djm@openbsd.org <djm@openbsd.org>
7245Date: Wed Aug 19 23:21:42 2015 +0000
7246
7247 upstream commit
7248
7249 Better compat matching for WinSCP, add compat matching
7250 for FuTTY (fork of PuTTY); ok markus@ deraadt@
7251
7252 Upstream-ID: 24001d1ac115fa3260fbdc329a4b9aeb283c5389
7253
7254commit ec6eda16ebab771aa3dfc90629b41953b999cb1e
7255Author: djm@openbsd.org <djm@openbsd.org>
7256Date: Wed Aug 19 23:19:01 2015 +0000
7257
7258 upstream commit
7259
7260 fix double-free() in error path of DSA key generation
7261 reported by Mateusz Kocielski; ok markus@
7262
7263 Upstream-ID: 4735d8f888b10599a935fa1b374787089116713c
7264
7265commit 45b0eb752c94954a6de046bfaaf129e518ad4b5b
7266Author: djm@openbsd.org <djm@openbsd.org>
7267Date: Wed Aug 19 23:18:26 2015 +0000
7268
7269 upstream commit
7270
7271 fix free() of uninitialised pointer reported by Mateusz
7272 Kocielski; ok markus@
7273
7274 Upstream-ID: 519552b050618501a06b7b023de5cb104e2c5663
7275
7276commit c837643b93509a3ef538cb6624b678c5fe32ff79
7277Author: djm@openbsd.org <djm@openbsd.org>
7278Date: Wed Aug 19 23:17:51 2015 +0000
7279
7280 upstream commit
7281
7282 fixed unlink([uninitialised memory]) reported by Mateusz
7283 Kocielski; ok markus@
7284
7285 Upstream-ID: 14a0c4e7d891f5a8dabc4b89d4f6b7c0d5a20109
7286
7287commit 1f8d3d629cd553031021068eb9c646a5f1e50994
7288Author: jmc@openbsd.org <jmc@openbsd.org>
7289Date: Fri Aug 14 15:32:41 2015 +0000
7290
7291 upstream commit
7292
7293 match myproposal.h order; from brian conway (i snuck in a
7294 tweak while here)
7295
7296 ok dtucker
7297
7298 Upstream-ID: 35174a19b5237ea36aa3798f042bf5933b772c67
7299
7300commit 1dc8d93ce69d6565747eb44446ed117187621b26
7301Author: deraadt@openbsd.org <deraadt@openbsd.org>
7302Date: Thu Aug 6 14:53:21 2015 +0000
7303
7304 upstream commit
7305
7306 add prohibit-password as a synonymn for without-password,
7307 since the without-password is causing too many questions. Harden it to ban
7308 all but pubkey, hostbased, and GSSAPI auth (when the latter is enabled) from
7309 djm, ok markus
7310
7311 Upstream-ID: d53317d7b28942153e6236d3fd6e12ceb482db7a
7312
7313commit 90a95a4745a531b62b81ce3b025e892bdc434de5
7314Author: Damien Miller <djm@mindrot.org>
7315Date: Tue Aug 11 13:53:41 2015 +1000
7316
7317 update version in README
7318
7319commit 318c37743534b58124f1bab37a8a0087a3a9bd2f
7320Author: Damien Miller <djm@mindrot.org>
7321Date: Tue Aug 11 13:53:09 2015 +1000
7322
7323 update versions in *.spec
7324
7325commit 5e75f5198769056089fb06c4d738ab0e5abc66f7
7326Author: Damien Miller <djm@mindrot.org>
7327Date: Tue Aug 11 13:34:12 2015 +1000
7328
7329 set sshpam_ctxt to NULL after free
7330
7331 Avoids use-after-free in monitor when privsep child is compromised.
7332 Reported by Moritz Jodeit; ok dtucker@
7333
7334commit d4697fe9a28dab7255c60433e4dd23cf7fce8a8b
7335Author: Damien Miller <djm@mindrot.org>
7336Date: Tue Aug 11 13:33:24 2015 +1000
7337
7338 Don't resend username to PAM; it already has it.
7339
7340 Pointed out by Moritz Jodeit; ok dtucker@
7341
7342commit 88763a6c893bf3dfe951ba9271bf09715e8d91ca
7343Author: Darren Tucker <dtucker@zip.com.au>
7344Date: Mon Jul 27 12:14:25 2015 +1000
7345
7346 Import updated moduli file from OpenBSD.
7347
7348commit 55b263fb7cfeacb81aaf1c2036e0394c881637da
7349Author: Damien Miller <djm@mindrot.org>
7350Date: Mon Aug 10 11:13:44 2015 +1000
7351
7352 let principals-command.sh work for noexec /var/run
7353
7354commit 2651e34cd11b1aac3a0fe23b86d8c2ff35c07897
7355Author: Damien Miller <djm@mindrot.org>
7356Date: Thu Aug 6 11:43:42 2015 +1000
7357
7358 work around echo -n / sed behaviour in tests
7359
7360commit d85dad81778c1aa8106acd46930b25fdf0d15b2a
7361Author: djm@openbsd.org <djm@openbsd.org>
7362Date: Wed Aug 5 05:27:33 2015 +0000
7363
7364 upstream commit
7365
7366 adjust for RSA minimum modulus switch; ok deraadt@
7367
7368 Upstream-Regress-ID: 5a72c83431b96224d583c573ca281cd3a3ebfdae
7369
7370commit 57e8e229bad5fe6056b5f1199665f5f7008192c6
7371Author: djm@openbsd.org <djm@openbsd.org>
7372Date: Tue Aug 4 05:23:06 2015 +0000
7373
7374 upstream commit
7375
7376 backout SSH_RSA_MINIMUM_MODULUS_SIZE increase for this
7377 release; problems spotted by sthen@ ok deraadt@ markus@
7378
7379 Upstream-ID: d0bd60dde9e8c3cd7030007680371894c1499822
7380
7381commit f097d0ea1e0889ca0fa2e53a00214e43ab7fa22a
7382Author: djm@openbsd.org <djm@openbsd.org>
7383Date: Sun Aug 2 09:56:42 2015 +0000
7384
7385 upstream commit
7386
7387 openssh 7.0; ok deraadt@
7388
7389 Upstream-ID: c63afdef537f57f28ae84145c5a8e29e9250221f
7390
7391commit 3d5728a0f6874ce4efb16913a12963595070f3a9
7392Author: chris@openbsd.org <chris@openbsd.org>
7393Date: Fri Jul 31 15:38:09 2015 +0000
7394
7395 upstream commit
7396
7397 Allow PermitRootLogin to be overridden by config
7398
7399 ok markus@ deeradt@
7400
7401 Upstream-ID: 5cf3e26ed702888de84e2dc9d0054ccf4d9125b4
7402
7403commit 6f941396b6835ad18018845f515b0c4fe20be21a
7404Author: djm@openbsd.org <djm@openbsd.org>
7405Date: Thu Jul 30 23:09:15 2015 +0000
7406
7407 upstream commit
7408
7409 fix pty permissions; patch from Nikolay Edigaryev; ok
7410 deraadt
7411
7412 Upstream-ID: 40ff076d2878b916fbfd8e4f45dbe5bec019e550
7413
7414commit f4373ed1e8fbc7c8ce3fc4ea97d0ba2e0c1d7ef0
7415Author: deraadt@openbsd.org <deraadt@openbsd.org>
7416Date: Thu Jul 30 19:23:02 2015 +0000
7417
7418 upstream commit
7419
7420 change default: PermitRootLogin without-password matching
7421 install script changes coming as well ok djm markus
7422
7423 Upstream-ID: 0e2a6c4441daf5498b47a61767382bead5eb8ea6
7424
7425commit 0c30ba91f87fcda7e975e6ff8a057f624e87ea1c
7426Author: Damien Miller <djm@mindrot.org>
7427Date: Thu Jul 30 12:31:39 2015 +1000
7428
7429 downgrade OOM adjustment logging: verbose -> debug
7430
7431commit f9eca249d4961f28ae4b09186d7dc91de74b5895
7432Author: djm@openbsd.org <djm@openbsd.org>
7433Date: Thu Jul 30 00:01:34 2015 +0000
7434
7435 upstream commit
7436
7437 Allow ssh_config and sshd_config kex parameters options be
7438 prefixed by a '+' to indicate that the specified items be appended to the
7439 default rather than replacing it.
7440
7441 approach suggested by dtucker@, feedback dlg@, ok markus@
7442
7443 Upstream-ID: 0f901137298fc17095d5756ff1561a7028e8882a
7444
7445commit 5cefe769105a2a2e3ca7479d28d9a325d5ef0163
7446Author: djm@openbsd.org <djm@openbsd.org>
7447Date: Wed Jul 29 08:34:54 2015 +0000
7448
7449 upstream commit
7450
7451 fix bug in previous; was printing incorrect string for
7452 failed host key algorithms negotiation
7453
7454 Upstream-ID: 22c0dc6bc61930513065d92e11f0753adc4c6e6e
7455
7456commit f319912b0d0e1675b8bb051ed8213792c788bcb2
7457Author: djm@openbsd.org <djm@openbsd.org>
7458Date: Wed Jul 29 04:43:06 2015 +0000
7459
7460 upstream commit
7461
7462 include the peer's offer when logging a failure to
7463 negotiate a mutual set of algorithms (kex, pubkey, ciphers, etc.) ok markus@
7464
7465 Upstream-ID: bbb8caabf5c01790bb845f5ce135565248d7c796
7466
7467commit b6ea0e573042eb85d84defb19227c89eb74cf05a
7468Author: djm@openbsd.org <djm@openbsd.org>
7469Date: Tue Jul 28 23:20:42 2015 +0000
7470
7471 upstream commit
7472
7473 add Cisco to the list of clients that choke on the
7474 hostkeys update extension. Pointed out by Howard Kash
7475
7476 Upstream-ID: c9eadde28ecec056c73d09ee10ba4570dfba7e84
7477
7478commit 3f628c7b537291c1019ce86af90756fb4e66d0fd
7479Author: guenther@openbsd.org <guenther@openbsd.org>
7480Date: Mon Jul 27 16:29:23 2015 +0000
7481
7482 upstream commit
7483
7484 Permit kbind(2) use in the sandbox now, to ease testing
7485 of ld.so work using it
7486
7487 reminded by miod@, ok deraadt@
7488
7489 Upstream-ID: 523922e4d1ba7a091e3824e77a8a3c818ee97413
7490
7491commit ebe27ebe520098bbc0fe58945a87ce8490121edb
7492Author: millert@openbsd.org <millert@openbsd.org>
7493Date: Mon Jul 20 18:44:12 2015 +0000
7494
7495 upstream commit
7496
7497 Move .Pp before .Bl, not after to quiet mandoc -Tlint.
7498 Noticed by jmc@
7499
7500 Upstream-ID: 59fadbf8407cec4e6931e50c53cfa0214a848e23
7501
7502commit d5d91d0da819611167782c66ab629159169d94d4
7503Author: millert@openbsd.org <millert@openbsd.org>
7504Date: Mon Jul 20 18:42:35 2015 +0000
7505
7506 upstream commit
7507
7508 Sync usage with SYNOPSIS
7509
7510 Upstream-ID: 7a321a170181a54f6450deabaccb6ef60cf3f0b7
7511
7512commit 79ec2142fbc68dd2ed9688608da355fc0b1ed743
7513Author: millert@openbsd.org <millert@openbsd.org>
7514Date: Mon Jul 20 15:39:52 2015 +0000
7515
7516 upstream commit
7517
7518 Better desciption of Unix domain socket forwarding.
7519 bz#2423; ok jmc@
7520
7521 Upstream-ID: 85e28874726897e3f26ae50dfa2e8d2de683805d
7522
7523commit d56fd1828074a4031b18b8faa0bf949669eb18a0
7524Author: Damien Miller <djm@mindrot.org>
7525Date: Mon Jul 20 11:19:51 2015 +1000
7526
7527 make realpath.c compile -Wsign-compare clean
7528
7529commit c63c9a691dca26bb7648827f5a13668832948929
7530Author: djm@openbsd.org <djm@openbsd.org>
7531Date: Mon Jul 20 00:30:01 2015 +0000
7532
7533 upstream commit
7534
7535 mention that the default of UseDNS=no implies that
7536 hostnames cannot be used for host matching in sshd_config and
7537 authorized_keys; bz#2045, ok dtucker@
7538
7539 Upstream-ID: 0812705d5f2dfa59aab01f2764ee800b1741c4e1
7540
7541commit 63ebcd0005e9894fcd6871b7b80aeea1fec0ff76
7542Author: djm@openbsd.org <djm@openbsd.org>
7543Date: Sat Jul 18 08:02:17 2015 +0000
7544
7545 upstream commit
7546
7547 don't ignore PKCS#11 hosted keys that return empty
7548 CKA_ID; patch by Jakub Jelen via bz#2429; ok markus
7549
7550 Upstream-ID: 2f7c94744eb0342f8ee8bf97b2351d4e00116485
7551
7552commit b15fd989c8c62074397160147a8d5bc34b3f3c63
7553Author: djm@openbsd.org <djm@openbsd.org>
7554Date: Sat Jul 18 08:00:21 2015 +0000
7555
7556 upstream commit
7557
7558 skip uninitialised PKCS#11 slots; patch from Jakub Jelen
7559 in bz#2427 ok markus@
7560
7561 Upstream-ID: 744c1e7796e237ad32992d0d02148e8a18f27d29
7562
7563commit 5b64f85bb811246c59ebab70aed331f26ba37b18
7564Author: djm@openbsd.org <djm@openbsd.org>
7565Date: Sat Jul 18 07:57:14 2015 +0000
7566
7567 upstream commit
7568
7569 only query each keyboard-interactive device once per
7570 authentication request regardless of how many times it is listed; ok markus@
7571
7572 Upstream-ID: d73fafba6e86030436ff673656ec1f33d9ffeda1
7573
7574commit cd7324d0667794eb5c236d8a4e0f236251babc2d
7575Author: djm@openbsd.org <djm@openbsd.org>
7576Date: Fri Jul 17 03:34:27 2015 +0000
7577
7578 upstream commit
7579
7580 remove -u flag to diff (only used for error output) to make
7581 things easier for -portable
7582
7583 Upstream-Regress-ID: a5d6777d2909540d87afec3039d9bb2414ade548
7584
7585commit deb8d99ecba70b67f4af7880b11ca8768df9ec3a
7586Author: djm@openbsd.org <djm@openbsd.org>
7587Date: Fri Jul 17 03:09:19 2015 +0000
7588
7589 upstream commit
7590
7591 direct-streamlocal@openssh.com Unix domain foward
7592 messages do not contain a "reserved for future use" field and in fact,
7593 serverloop.c checks that there isn't one. Remove erroneous mention from
7594 PROTOCOL description. bz#2421 from Daniel Black
7595
7596 Upstream-ID: 3d51a19e64f72f764682f1b08f35a8aa810a43ac
7597
7598commit 356b61f365405b5257f5b2ab446e5d7bd33a7b52
7599Author: djm@openbsd.org <djm@openbsd.org>
7600Date: Fri Jul 17 03:04:27 2015 +0000
7601
7602 upstream commit
7603
7604 describe magic for setting up Unix domain socket fowards
7605 via the mux channel; bz#2422 patch from Daniel Black
7606
7607 Upstream-ID: 943080fe3864715c423bdeb7c920bb30c4eee861
7608
7609commit d3e2aee41487d55b8d7d40f538b84ff1db7989bc
7610Author: Darren Tucker <dtucker@zip.com.au>
7611Date: Fri Jul 17 12:52:34 2015 +1000
7612
7613 Check if realpath works on nonexistent files.
7614
7615 On some platforms the native realpath doesn't work with non-existent
7616 files (this is actually specified in some versions of POSIX), however
7617 the sftp spec says its realpath with "canonicalize any given path name".
7618 On those platforms, use realpath from the compat library.
7619
7620 In addition, when compiling with -DFORTIFY_SOURCE, glibc redefines
7621 the realpath symbol to the checked version, so redefine ours to
7622 something else so we pick up the compat version we want.
7623
7624 bz#2428, ok djm@
7625
7626commit 25b14610dab655646a109db5ef8cb4c4bf2a48a0
7627Author: djm@openbsd.org <djm@openbsd.org>
7628Date: Fri Jul 17 02:47:45 2015 +0000
7629
7630 upstream commit
7631
7632 fix incorrect test for SSH1 keys when compiled without SSH1
7633 support
7634
7635 Upstream-ID: 6004d720345b8e481c405e8ad05ce2271726e451
7636
7637commit df56a8035d429b2184ee94aaa7e580c1ff67f73a
7638Author: djm@openbsd.org <djm@openbsd.org>
7639Date: Wed Jul 15 08:00:11 2015 +0000
7640
7641 upstream commit
7642
7643 fix NULL-deref when SSH1 reenabled
7644
7645 Upstream-ID: f22fd805288c92b3e9646782d15b48894b2d5295
7646
7647commit 41e38c4d49dd60908484e6703316651333f16b93
7648Author: djm@openbsd.org <djm@openbsd.org>
7649Date: Wed Jul 15 07:19:50 2015 +0000
7650
7651 upstream commit
7652
7653 regen RSA1 test keys; the last batch was missing their
7654 private parts
7655
7656 Upstream-Regress-ID: 7ccf437305dd63ff0b48dd50c5fd0f4d4230c10a
7657
7658commit 5bf0933184cb622ca3f96d224bf3299fd2285acc
7659Author: markus@openbsd.org <markus@openbsd.org>
7660Date: Fri Jul 10 06:23:25 2015 +0000
7661
7662 upstream commit
7663
7664 Adapt tests, now that DSA if off by default; use
7665 PubkeyAcceptedKeyTypes and PubkeyAcceptedKeyTypes to test DSA.
7666
7667 Upstream-Regress-ID: 0ff2a3ff5ac1ce5f92321d27aa07b98656efcc5c
7668
7669commit 7a6e3fd7b41dbd3756b6bf9acd67954c0b1564cc
7670Author: markus@openbsd.org <markus@openbsd.org>
7671Date: Tue Jul 7 14:54:16 2015 +0000
7672
7673 upstream commit
7674
7675 regen test data after mktestdata.sh changes
7676
7677 Upstream-Regress-ID: 3495ecb082b9a7c048a2d7c5c845d3bf181d25a4
7678
7679commit 7c8c174c69f681d4910fa41c37646763692b28e2
7680Author: markus@openbsd.org <markus@openbsd.org>
7681Date: Tue Jul 7 14:53:30 2015 +0000
7682
7683 upstream commit
7684
7685 adapt tests to new minimum RSA size and default FP format
7686
7687 Upstream-Regress-ID: a4b30afd174ce82b96df14eb49fb0b81398ffd0e
7688
7689commit 6a977a4b68747ade189e43d302f33403fd4a47ac
7690Author: djm@openbsd.org <djm@openbsd.org>
7691Date: Fri Jul 3 04:39:23 2015 +0000
7692
7693 upstream commit
7694
7695 legacy v00 certificates are gone; adapt and don't try to
7696 test them; "sure" markus@ dtucker@
7697
7698 Upstream-Regress-ID: c57321e69b3cd4a3b3396dfcc43f0803d047da12
7699
7700commit 0c4123ad5e93fb90fee9c6635b13a6cdabaac385
7701Author: djm@openbsd.org <djm@openbsd.org>
7702Date: Wed Jul 1 23:11:18 2015 +0000
7703
7704 upstream commit
7705
7706 don't expect SSH v.1 in unittests
7707
7708 Upstream-Regress-ID: f8812b16668ba78e6a698646b2a652b90b653397
7709
7710commit 3c099845798a817cdde513c39074ec2063781f18
7711Author: djm@openbsd.org <djm@openbsd.org>
7712Date: Mon Jun 15 06:38:50 2015 +0000
7713
7714 upstream commit
7715
7716 turn SSH1 back on to match src/usr.bin/ssh being tested
7717
7718 Upstream-Regress-ID: 6c4f763a2f0cc6893bf33983919e9030ae638333
7719
7720commit b1dc2b33689668c75e95f873a42d5aea1f4af1db
7721Author: dtucker@openbsd.org <dtucker@openbsd.org>
7722Date: Mon Jul 13 04:57:14 2015 +0000
7723
7724 upstream commit
7725
7726 Add "PuTTY_Local:" to the clients to which we do not
7727 offer DH-GEX. This was the string that was used for development versions
7728 prior to September 2014 and they don't do RFC4419 DH-GEX, but unfortunately
7729 there are some extant products based on those versions. bx2424 from Jay
7730 Rouman, ok markus@ djm@
7731
7732 Upstream-ID: be34d41e18b966832fe09ca243d275b81882e1d5
7733
7734commit 3a1638dda19bbc73d0ae02b4c251ce08e564b4b9
7735Author: markus@openbsd.org <markus@openbsd.org>
7736Date: Fri Jul 10 06:21:53 2015 +0000
7737
7738 upstream commit
7739
7740 Turn off DSA by default; add HostKeyAlgorithms to the
7741 server and PubkeyAcceptedKeyTypes to the client side, so it still can be
7742 tested or turned back on; feedback and ok djm@
7743
7744 Upstream-ID: 8450a9e6d83f80c9bfed864ff061dfc9323cec21
7745
7746commit 16db0a7ee9a87945cc594d13863cfcb86038db59
7747Author: markus@openbsd.org <markus@openbsd.org>
7748Date: Thu Jul 9 09:49:46 2015 +0000
7749
7750 upstream commit
7751
7752 re-enable ed25519-certs if compiled w/o openssl; ok djm
7753
7754 Upstream-ID: e10c90808b001fd2c7a93778418e9b318f5c4c49
7755
7756commit c355bf306ac33de6545ce9dac22b84a194601e2f
7757Author: markus@openbsd.org <markus@openbsd.org>
7758Date: Wed Jul 8 20:24:02 2015 +0000
7759
7760 upstream commit
7761
7762 no need to include the old buffer/key API
7763
7764 Upstream-ID: fb13c9f7c0bba2545f3eb0a0e69cb0030819f52b
7765
7766commit a3cc48cdf9853f1e832d78cb29bedfab7adce1ee
7767Author: markus@openbsd.org <markus@openbsd.org>
7768Date: Wed Jul 8 19:09:25 2015 +0000
7769
7770 upstream commit
7771
7772 typedefs for Cipher&CipherContext are unused
7773
7774 Upstream-ID: 50e6a18ee92221d23ad173a96d5b6c42207cf9a7
7775
7776commit a635bd06b5c427a57c3ae760d3a2730bb2c863c0
7777Author: markus@openbsd.org <markus@openbsd.org>
7778Date: Wed Jul 8 19:04:21 2015 +0000
7779
7780 upstream commit
7781
7782 xmalloc.h is unused
7783
7784 Upstream-ID: afb532355b7fa7135a60d944ca1e644d1d63cb58
7785
7786commit 2521cf0e36c7f3f6b19f206da0af134f535e4a31
7787Author: markus@openbsd.org <markus@openbsd.org>
7788Date: Wed Jul 8 19:01:15 2015 +0000
7789
7790 upstream commit
7791
7792 compress.c is gone
7793
7794 Upstream-ID: 174fa7faa9b9643cba06164b5e498591356fbced
7795
7796commit c65a7aa6c43aa7a308ee1ab8a96f216169ae9615
7797Author: djm@openbsd.org <djm@openbsd.org>
7798Date: Fri Jul 3 04:05:54 2015 +0000
7799
7800 upstream commit
7801
7802 another SSH_RSA_MINIMUM_MODULUS_SIZE that needed
7803 cranking
7804
7805 Upstream-ID: 9d8826cafe96aab4ae8e2f6fd22800874b7ffef1
7806
7807commit b1f383da5cd3cb921fc7776f17a14f44b8a31757
7808Author: djm@openbsd.org <djm@openbsd.org>
7809Date: Fri Jul 3 03:56:25 2015 +0000
7810
7811 upstream commit
7812
7813 add an XXX reminder for getting correct key paths from
7814 sshd_config
7815
7816 Upstream-ID: feae52b209d7782ad742df04a4260e9fe41741db
7817
7818commit 933935ce8d093996c34d7efa4d59113163080680
7819Author: djm@openbsd.org <djm@openbsd.org>
7820Date: Fri Jul 3 03:49:45 2015 +0000
7821
7822 upstream commit
7823
7824 refuse to generate or accept RSA keys smaller than 1024
7825 bits; feedback and ok dtucker@
7826
7827 Upstream-ID: 7ea3d31271366ba264f06e34a3539bf1ac30f0ba
7828
7829commit bdfd29f60b74f3e678297269dc6247a5699583c1
7830Author: djm@openbsd.org <djm@openbsd.org>
7831Date: Fri Jul 3 03:47:00 2015 +0000
7832
7833 upstream commit
7834
7835 turn off 1024 bit diffie-hellman-group1-sha1 key
7836 exchange method (already off in server, this turns it off in the client by
7837 default too) ok dtucker@
7838
7839 Upstream-ID: f59b88f449210ab7acf7d9d88f20f1daee97a4fa
7840
7841commit c28fc62d789d860c75e23a9fa9fb250eb2beca57
7842Author: djm@openbsd.org <djm@openbsd.org>
7843Date: Fri Jul 3 03:43:18 2015 +0000
7844
7845 upstream commit
7846
7847 delete support for legacy v00 certificates; "sure"
7848 markus@ dtucker@
7849
7850 Upstream-ID: b5b9bb5f9202d09e88f912989d74928601b6636f
7851
7852commit 564d63e1b4a9637a209d42a9d49646781fc9caef
7853Author: djm@openbsd.org <djm@openbsd.org>
7854Date: Wed Jul 1 23:10:47 2015 +0000
7855
7856 upstream commit
7857
7858 Compile-time disable SSH v.1 again
7859
7860 Upstream-ID: 1d4b513a3a06232f02650b73bad25100d1b800af
7861
7862commit 868109b650504dd9bcccdb1f51d0906f967c20ff
7863Author: djm@openbsd.org <djm@openbsd.org>
7864Date: Wed Jul 1 02:39:06 2015 +0000
7865
7866 upstream commit
7867
7868 twiddle PermitRootLogin back
7869
7870 Upstream-ID: 2bd23976305d0512e9f84d054e1fc23cd70b89f2
7871
7872commit 7de4b03a6e4071d454b72927ffaf52949fa34545
7873Author: djm@openbsd.org <djm@openbsd.org>
7874Date: Wed Jul 1 02:32:17 2015 +0000
7875
7876 upstream commit
7877
7878 twiddle; (this commit marks the openssh-6.9 release)
7879
7880 Upstream-ID: 78500582819f61dd8adee36ec5cc9b9ac9351234
7881
7882commit 1bf477d3cdf1a864646d59820878783d42357a1d
7883Author: djm@openbsd.org <djm@openbsd.org>
7884Date: Wed Jul 1 02:26:31 2015 +0000
7885
7886 upstream commit
7887
7888 better refuse ForwardX11Trusted=no connections attempted
7889 after ForwardX11Timeout expires; reported by Jann Horn
7890
7891 Upstream-ID: bf0fddadc1b46a0334e26c080038313b4b6dea21
7892
7893commit 47aa7a0f8551b471fcae0447c1d78464f6dba869
7894Author: djm@openbsd.org <djm@openbsd.org>
7895Date: Wed Jul 1 01:56:13 2015 +0000
7896
7897 upstream commit
7898
7899 put back default PermitRootLogin=no
7900
7901 Upstream-ID: 7bdedd5cead99c57ed5571f3b6b7840922d5f728
7902
7903commit 984b064fe2a23733733262f88d2e1b2a1a501662
7904Author: djm@openbsd.org <djm@openbsd.org>
7905Date: Wed Jul 1 01:55:13 2015 +0000
7906
7907 upstream commit
7908
7909 openssh-6.9
7910
7911 Upstream-ID: 6cfe8e1904812531080e6ab6e752d7001b5b2d45
7912
7913commit d921082ed670f516652eeba50705e1e9f6325346
7914Author: djm@openbsd.org <djm@openbsd.org>
7915Date: Wed Jul 1 01:55:00 2015 +0000
7916
7917 upstream commit
7918
7919 reset default PermitRootLogin to 'yes' (momentarily, for
7920 release)
7921
7922 Upstream-ID: cad8513527066e65dd7a1c16363d6903e8cefa24
7923
7924commit 66295e0e1ba860e527f191b6325d2d77dec4dbce
7925Author: Damien Miller <djm@mindrot.org>
7926Date: Wed Jul 1 11:49:12 2015 +1000
7927
7928 crank version numbers for release
7929
7930commit 37035c07d4f26bb1fbe000d2acf78efdb008681d
7931Author: Damien Miller <djm@mindrot.org>
7932Date: Wed Jul 1 10:49:37 2015 +1000
7933
7934 s/--with-ssh1/--without-ssh1/
7935
7936commit 629df770dbadc2accfbe1c81b3f31f876d0acd84
7937Author: djm@openbsd.org <djm@openbsd.org>
7938Date: Tue Jun 30 05:25:07 2015 +0000
7939
7940 upstream commit
7941
7942 fatal() when a remote window update causes the window
7943 value to overflow. Reported by Georg Wicherski, ok markus@
7944
7945 Upstream-ID: ead397a9aceb3bf74ebfa5fcaf259d72e569f351
7946
7947commit f715afebe735d61df3fd30ad72d9ac1c8bd3b5f2
7948Author: djm@openbsd.org <djm@openbsd.org>
7949Date: Tue Jun 30 05:23:25 2015 +0000
7950
7951 upstream commit
7952
7953 Fix math error in remote window calculations that causes
7954 eventual stalls for datagram channels. Reported by Georg Wicherski, ok
7955 markus@
7956
7957 Upstream-ID: be54059d11bf64e0d85061f7257f53067842e2ab
7958
7959commit 52fb6b9b034fcfd24bf88cc7be313e9c31de9889
7960Author: Damien Miller <djm@mindrot.org>
7961Date: Tue Jun 30 16:05:40 2015 +1000
7962
7963 skip IPv6-related portions on hosts without IPv6
7964
7965 with Tim Rice
7966
7967commit 512caddf590857af6aa12218461b5c0441028cf5
7968Author: djm@openbsd.org <djm@openbsd.org>
7969Date: Mon Jun 29 22:35:12 2015 +0000
7970
7971 upstream commit
7972
7973 add getpid to sandbox, reachable by grace_alarm_handler
7974
7975 reported by Jakub Jelen; bz#2419
7976
7977 Upstream-ID: d0da1117c16d4c223954995d35b0f47c8f684cd8
7978
7979commit 78c2a4f883ea9aba866358e2acd9793a7f42ca93
7980Author: djm@openbsd.org <djm@openbsd.org>
7981Date: Fri Jun 26 05:13:20 2015 +0000
7982
7983 upstream commit
7984
7985 Fix \-escaping bug that caused forward path parsing to skip
7986 two characters and skip past the end of the string.
7987
7988 Based on patch by Salvador Fandino; ok dtucker@
7989
7990 Upstream-ID: 7b879dc446335677cbe4cb549495636a0535f3bd
7991
7992commit bc20205c91c9920361d12b15d253d4997dba494a
7993Author: Damien Miller <djm@mindrot.org>
7994Date: Thu Jun 25 09:51:39 2015 +1000
7995
7996 add missing pselect6
7997
7998 patch from Jakub Jelen
7999
8000commit 9d27fb73b4a4e5e99cb880af790d5b1ce44f720a
8001Author: djm@openbsd.org <djm@openbsd.org>
8002Date: Wed Jun 24 23:47:23 2015 +0000
8003
8004 upstream commit
8005
8006 correct test to sshkey_sign(); spotted by Albert S.
8007
8008 Upstream-ID: 5f7347f40f0ca6abdaca2edb3bd62f4776518933
8009
8010commit 7ed01a96a1911d8b4a9ef4f3d064e1923bfad7e3
8011Author: dtucker@openbsd.org <dtucker@openbsd.org>
8012Date: Wed Jun 24 01:49:19 2015 +0000
8013
8014 upstream commit
8015
8016 Revert previous commit. We still want to call setgroups
8017 in the case where there are zero groups to remove any that we might otherwise
8018 inherit (as pointed out by grawity at gmail.com) and since the 2nd argument
8019 to setgroups is always a static global it's always valid to dereference in
8020 this case. ok deraadt@ djm@
8021
8022 Upstream-ID: 895b5ac560a10befc6b82afa778641315725fd01
8023
8024commit 882f8bf94f79528caa65b0ba71c185d705bb7195
8025Author: dtucker@openbsd.org <dtucker@openbsd.org>
8026Date: Wed Jun 24 01:49:19 2015 +0000
8027
8028 upstream commit
8029
8030 Revert previous commit. We still want to call setgroups in
8031 the case where there are zero groups to remove any that we might otherwise
8032 inherit (as pointed out by grawity at gmail.com) and since the 2nd argument
8033 to setgroups is always a static global it's always valid to dereference in
8034 this case. ok deraadt@ djm@
8035
8036 Upstream-ID: 895b5ac560a10befc6b82afa778641315725fd01
8037
8038commit 9488538a726951e82b3a4374f3c558d72c80a89b
8039Author: djm@openbsd.org <djm@openbsd.org>
8040Date: Mon Jun 22 23:42:16 2015 +0000
8041
8042 upstream commit
8043
8044 Don't count successful partial authentication as failures
8045 in monitor; this may have caused the monitor to refuse multiple
8046 authentications that would otherwise have successfully completed; ok markus@
8047
8048 Upstream-ID: eb74b8e506714d0f649bd5c300f762a527af04a3
8049
8050commit 63b78d003bd8ca111a736e6cea6333da50f5f09b
8051Author: dtucker@openbsd.org <dtucker@openbsd.org>
8052Date: Mon Jun 22 12:29:57 2015 +0000
8053
8054 upstream commit
8055
8056 Don't call setgroups if we have zero groups; there's no
8057 guarantee that it won't try to deref the pointer. Based on a patch from mail
8058 at quitesimple.org, ok djm deraadt
8059
8060 Upstream-ID: 2fff85e11d7a9a387ef7fddf41fbfaf566708ab1
8061
8062commit 5c15e22c691c79a47747bcf5490126656f97cecd
8063Author: Damien Miller <djm@mindrot.org>
8064Date: Thu Jun 18 15:07:56 2015 +1000
8065
8066 fix syntax error
8067
8068commit 596dbca82f3f567fb3d2d69af4b4e1d3ba1e6403
8069Author: jsing@openbsd.org <jsing@openbsd.org>
8070Date: Mon Jun 15 18:44:22 2015 +0000
8071
8072 upstream commit
8073
8074 If AuthorizedPrincipalsCommand is specified, however
8075 AuthorizedPrincipalsFile is not (or is set to "none"), authentication will
8076 potentially fail due to key_cert_check_authority() failing to locate a
8077 principal that matches the username, even though an authorized principal has
8078 already been matched in the output of the subprocess. Fix this by using the
8079 same logic to determine if pw->pw_name should be passed, as is used to
8080 determine if a authorized principal must be matched earlier on.
8081
8082 ok djm@
8083
8084 Upstream-ID: 43b42302ec846b0ea68aceb40677245391b9409d
8085
8086commit aff3e94c0d75d0d0fa84ea392b50ab04f8c57905
8087Author: jsing@openbsd.org <jsing@openbsd.org>
8088Date: Mon Jun 15 18:42:19 2015 +0000
8089
8090 upstream commit
8091
8092 Make the arguments to match_principals_command() similar
8093 to match_principals_file(), by changing the last argument a struct
8094 sshkey_cert * and dereferencing key->cert in the caller.
8095
8096 No functional change.
8097
8098 ok djm@
8099
8100 Upstream-ID: 533f99b844b21b47342b32b62e198dfffcf8651c
8101
8102commit 97e2e1596c202a4693468378b16b2353fd2d6c5e
8103Author: Damien Miller <djm@mindrot.org>
8104Date: Wed Jun 17 14:36:54 2015 +1000
8105
8106 trivial optimisation for seccomp-bpf
8107
8108 When doing arg inspection and the syscall doesn't match, skip
8109 past the instruction that reloads the syscall into the accumulator,
8110 since the accumulator hasn't been modified at this point.
8111
8112commit 99f33d7304893bd9fa04d227cb6e870171cded19
8113Author: Damien Miller <djm@mindrot.org>
8114Date: Wed Jun 17 10:50:51 2015 +1000
8115
8116 aarch64 support for seccomp-bpf sandbox
8117
8118 Also resort and tidy syscall list. Based on patches by Jakub Jelen
8119 bz#2361; ok dtucker@
8120
8121commit 4ef702e1244633c1025ec7cfe044b9ab267097bf
8122Author: djm@openbsd.org <djm@openbsd.org>
8123Date: Mon Jun 15 01:32:50 2015 +0000
8124
8125 upstream commit
8126
8127 return failure on RSA signature error; reported by Albert S
8128
8129 Upstream-ID: e61bb93dbe0349625807b0810bc213a6822121fa
8130
8131commit a170f22baf18af0b1acf2788b8b715605f41a1f9
8132Author: Tim Rice <tim@multitalents.net>
8133Date: Tue Jun 9 22:41:13 2015 -0700
8134
8135 Fix t12 rules for out of tree builds.
8136
8137commit ec04dc4a5515c913121bc04ed261857e68fa5c18
8138Author: millert@openbsd.org <millert@openbsd.org>
8139Date: Fri Jun 5 15:13:13 2015 +0000
8140
8141 upstream commit
8142
8143 For "ssh -L 12345:/tmp/sock" don't fail with "No forward host
8144 name." (we have a path, not a host name). Based on a diff from Jared
8145 Yanovich. OK djm@
8146
8147 Upstream-ID: 2846b0a8c7de037e33657f95afbd282837fc213f
8148
8149commit 732d61f417a6aea0aa5308b59cb0f563bcd6edd6
8150Author: djm@openbsd.org <djm@openbsd.org>
8151Date: Fri Jun 5 03:44:14 2015 +0000
8152
8153 upstream commit
8154
8155 typo: accidental repetition; bz#2386
8156
8157 Upstream-ID: 45e620d99f6bc301e5949d34a54027374991c88b
8158
8159commit adfb24c69d1b6f5e758db200866c711e25a2ba73
8160Author: Darren Tucker <dtucker@zip.com.au>
8161Date: Fri Jun 5 14:51:40 2015 +1000
8162
8163 Add Linux powerpc64le and powerpcle entries.
8164
8165 Stopgap to resolve bz#2409 because we are so close to release and will
8166 update config.guess and friends shortly after the release. ok djm@
8167
8168commit a1195a0fdc9eddddb04d3e9e44c4775431cb77da
8169Merge: 6397eed d2480bc
8170Author: Tim Rice <tim@multitalents.net>
8171Date: Wed Jun 3 21:43:13 2015 -0700
8172
8173 Merge branch 'master' of git.mindrot.org:/var/git/openssh
8174
8175commit 6397eedf953b2b973d2d7cbb504ab501a07f8ddc
8176Author: Tim Rice <tim@multitalents.net>
8177Date: Wed Jun 3 21:41:11 2015 -0700
8178
8179 Remove unneeded backslashes. Patch from Ángel González
8180
8181commit d2480bcac1caf31b03068de877a47d6e1027bf6d
8182Author: Darren Tucker <dtucker@zip.com.au>
8183Date: Thu Jun 4 14:10:55 2015 +1000
8184
8185 Remove redundant include of stdarg.h. bz#2410
8186
8187commit 5e67859a623826ccdf2df284cbb37e2d8e2787eb
8188Author: djm@openbsd.org <djm@openbsd.org>
8189Date: Tue Jun 2 09:10:40 2015 +0000
8190
8191 upstream commit
8192
8193 mention CheckHostIP adding addresses to known_hosts;
8194 bz#1993; ok dtucker@
8195
8196 Upstream-ID: fd44b68440fd0dc29abf9f2d3f703d74a2396cb7
8197
8198commit d7a58bbac6583e33fd5eca8e2c2cc70c57617818
8199Author: Darren Tucker <dtucker@zip.com.au>
8200Date: Tue Jun 2 20:15:26 2015 +1000
8201
8202 Replace strcpy with strlcpy.
8203
8204 ok djm, sanity check by Corinna Vinschen.
8205
8206commit 51a1c2115265c6e80ede8a5c9dccada9aeed7143
8207Author: Damien Miller <djm@mindrot.org>
8208Date: Fri May 29 18:27:21 2015 +1000
8209
8210 skip, rather than fatal when run without SUDO set
8211
8212commit 599f01142a376645b15cbc9349d7e8975e1cf245
8213Author: Damien Miller <djm@mindrot.org>
8214Date: Fri May 29 18:03:15 2015 +1000
8215
8216 fix merge botch that left ",," in KEX algs
8217
8218commit 0c2a81dfc21822f2423edd30751e5ec53467b347
8219Author: Damien Miller <djm@mindrot.org>
8220Date: Fri May 29 17:08:28 2015 +1000
8221
8222 re-enable SSH protocol 1 at compile time
8223
8224commit db438f9285d64282d3ac9e8c0944f59f037c0151
8225Author: djm@openbsd.org <djm@openbsd.org>
8226Date: Fri May 29 03:05:13 2015 +0000
8227
8228 upstream commit
8229
8230 make this work without SUDO set; ok dtucker@
8231
8232 Upstream-Regress-ID: bca88217b70bce2fe52b23b8e06bdeb82d98c715
8233
8234commit 1d9a2e2849c9864fe75daabf433436341c968e14
8235Author: djm@openbsd.org <djm@openbsd.org>
8236Date: Thu May 28 07:37:31 2015 +0000
8237
8238 upstream commit
8239
8240 wrap all moduli-related code in #ifdef WITH_OPENSSL.
8241 based on patch from Reuben Hawkins; bz#2388 feedback and ok dtucker@
8242
8243 Upstream-ID: d80cfc8be3e6ec65b3fac9e87c4466533b31b7cf
8244
8245commit 496aeb25bc2d6c434171292e4714771b594bd00e
8246Author: dtucker@openbsd.org <dtucker@openbsd.org>
8247Date: Thu May 28 05:41:29 2015 +0000
8248
8249 upstream commit
8250
8251 Increase the allowed length of the known host file name
8252 in the log message to be consistent with other cases. Part of bz#1993, ok
8253 deraadt.
8254
8255 Upstream-ID: a9e97567be49f25daf286721450968251ff78397
8256
8257commit dd2cfeb586c646ff8d70eb93567b2e559ace5b14
8258Author: dtucker@openbsd.org <dtucker@openbsd.org>
8259Date: Thu May 28 05:09:45 2015 +0000
8260
8261 upstream commit
8262
8263 Fix typo (keywork->keyword)
8264
8265 Upstream-ID: 8aacd0f4089c0a244cf43417f4f9045dfaeab534
8266
8267commit 9cc6842493fbf23025ccc1edab064869640d3bec
8268Author: djm@openbsd.org <djm@openbsd.org>
8269Date: Thu May 28 04:50:53 2015 +0000
8270
8271 upstream commit
8272
8273 add error message on ftruncate failure; bz#2176
8274
8275 Upstream-ID: cbcc606e0b748520c74a210d8f3cc9718d3148cf
8276
8277commit d1958793a0072c22be26d136dbda5ae263e717a0
8278Author: djm@openbsd.org <djm@openbsd.org>
8279Date: Thu May 28 04:40:13 2015 +0000
8280
8281 upstream commit
8282
8283 make ssh-keygen default to ed25519 keys when compiled
8284 without OpenSSL; bz#2388, ok dtucker@
8285
8286 Upstream-ID: 85a471fa6d3fa57a7b8e882d22cfbfc1d84cdc71
8287
8288commit 3ecde664c9fc5fb3667aedf9e6671462600f6496
8289Author: dtucker@openbsd.org <dtucker@openbsd.org>
8290Date: Wed May 27 23:51:10 2015 +0000
8291
8292 upstream commit
8293
8294 Reorder client proposal to prefer
8295 diffie-hellman-group-exchange-sha1 over diffie-hellman-group14-sha1. ok djm@
8296
8297 Upstream-ID: 552c08d47347c3ee1a9a57d88441ab50abe17058
8298
8299commit 40f64292b907afd0a674fdbf3e4c2356d17a7d68
8300Author: dtucker@openbsd.org <dtucker@openbsd.org>
8301Date: Wed May 27 23:39:18 2015 +0000
8302
8303 upstream commit
8304
8305 Add a stronger (4k bit) fallback group that sshd can use
8306 when the moduli file is missing or broken, sourced from RFC3526. bz#2302, ok
8307 markus@ (earlier version), djm@
8308
8309 Upstream-ID: b635215746a25a829d117673d5e5a76d4baee7f4
8310
8311commit 5ab7d5fa03ad55bc438fab45dfb3aeb30a3c237a
8312Author: Darren Tucker <dtucker@zip.com.au>
8313Date: Thu May 28 10:03:40 2015 +1000
8314
8315 New moduli file from OpenBSD, removing 1k groups.
8316
8317 Remove 1k bit groups. ok deraadt@, markus@
8318
8319commit a71ba58adf34e599f30cdda6e9b93ae6e3937eea
8320Author: djm@openbsd.org <djm@openbsd.org>
8321Date: Wed May 27 05:15:02 2015 +0000
8322
8323 upstream commit
8324
8325 support PKCS#11 devices with external PIN entry devices
8326 bz#2240, based on patch from Dirk-Willem van Gulik; feedback and ok dtucker@
8327
8328 Upstream-ID: 504568992b55a8fc984375242b1bd505ced61b0d
8329
8330commit b282fec1aa05246ed3482270eb70fc3ec5f39a00
8331Author: dtucker@openbsd.org <dtucker@openbsd.org>
8332Date: Tue May 26 23:23:40 2015 +0000
8333
8334 upstream commit
8335
8336 Cap DH-GEX group size at 4kbits for Cisco implementations.
8337 Some of them will choke when asked for preferred sizes >4k instead of
8338 returning the 4k group that they do have. bz#2209, ok djm@
8339
8340 Upstream-ID: 54b863a19713446b7431f9d06ad0532b4fcfef8d
8341
8342commit 3e91b4e8b0dc2b4b7e7d42cf6e8994a32e4cb55e
8343Author: djm@openbsd.org <djm@openbsd.org>
8344Date: Sun May 24 23:39:16 2015 +0000
8345
8346 upstream commit
8347
8348 add missing 'c' option to getopt(), case statement was
8349 already there; from Felix Bolte
8350
8351 Upstream-ID: 9b19b4e2e0b54d6fefa0dfac707c51cf4bae3081
8352
8353commit 64a89ec07660abba4d0da7c0095b7371c98bab62
8354Author: jsg@openbsd.org <jsg@openbsd.org>
8355Date: Sat May 23 14:28:37 2015 +0000
8356
8357 upstream commit
8358
8359 fix a memory leak in an error path ok markus@ dtucker@
8360
8361 Upstream-ID: bc1da0f205494944918533d8780fde65dff6c598
8362
8363commit f948737449257d2cb83ffcfe7275eb79b677fd4a
8364Author: djm@openbsd.org <djm@openbsd.org>
8365Date: Fri May 22 05:28:45 2015 +0000
8366
8367 upstream commit
8368
8369 mention ssh-keygen -E for comparing legacy MD5
8370 fingerprints; bz#2332
8371
8372 Upstream-ID: 079a3669549041dbf10dbc072d9563f0dc3b2859
8373
8374commit 0882332616e4f0272c31cc47bf2018f9cb258a4e
8375Author: djm@openbsd.org <djm@openbsd.org>
8376Date: Fri May 22 04:45:52 2015 +0000
8377
8378 upstream commit
8379
8380 Reorder EscapeChar option parsing to avoid a single-byte
8381 out- of-bounds read. bz#2396 from Jaak Ristioja; ok dtucker@
8382
8383 Upstream-ID: 1dc6b5b63d1c8d9a88619da0b27ade461d79b060
8384
8385commit d7c31da4d42c115843edee2074d7d501f8804420
8386Author: djm@openbsd.org <djm@openbsd.org>
8387Date: Fri May 22 03:50:02 2015 +0000
8388
8389 upstream commit
8390
8391 add knob to relax GSSAPI host credential check for
8392 multihomed hosts bz#928, patch by Simon Wilkinson; ok dtucker
8393 (kerberos/GSSAPI is not compiled by default on OpenBSD)
8394
8395 Upstream-ID: 15ddf1c6f7fd9d98eea9962f480079ae3637285d
8396
8397commit aa72196a00be6e0b666215edcffbc10af234cb0e
8398Author: Darren Tucker <dtucker@zip.com.au>
8399Date: Fri May 22 17:49:46 2015 +1000
8400
8401 Include signal.h for sig_atomic_t, used by kex.h.
8402
8403 bz#2402, from tomas.kuthan at oracle com.
8404
8405commit 8b02481143d75e91c49d1bfae0876ac1fbf9511a
8406Author: Darren Tucker <dtucker@zip.com.au>
8407Date: Fri May 22 12:47:24 2015 +1000
8408
8409 Import updated moduli file from OpenBSD.
8410
8411commit 4739e8d5e1c0be49624082bd9f6b077e9e758db9
8412Author: djm@openbsd.org <djm@openbsd.org>
8413Date: Thu May 21 12:01:19 2015 +0000
8414
8415 upstream commit
8416
8417 Support "ssh-keygen -lF hostname" to find search known_hosts
8418 and print key hashes. Already advertised by ssh-keygen(1), but not delivered
8419 by code; ok dtucker@
8420
8421 Upstream-ID: 459e0e2bf39825e41b0811c336db2d56a1c23387
8422
8423commit e97201feca10b5196da35819ae516d0b87cf3a50
8424Author: Damien Miller <djm@mindrot.org>
8425Date: Thu May 21 17:55:15 2015 +1000
8426
8427 conditionalise util.h inclusion
8428
8429commit 13640798c7dd011ece0a7d02841fe48e94cfa0e0
8430Author: djm@openbsd.org <djm@openbsd.org>
8431Date: Thu May 21 06:44:25 2015 +0000
8432
8433 upstream commit
8434
8435 regress test for AuthorizedPrincipalsCommand
8436
8437 Upstream-Regress-ID: c658fbf1ab6b6011dc83b73402322e396f1e1219
8438
8439commit 84452c5d03c21f9bfb28c234e0dc1dc67dd817b1
8440Author: djm@openbsd.org <djm@openbsd.org>
8441Date: Thu May 21 06:40:02 2015 +0000
8442
8443 upstream commit
8444
8445 regress test for AuthorizedKeysCommand arguments
8446
8447 Upstream-Regress-ID: bbd65c13c6b3be9a442ec115800bff9625898f12
8448
8449commit bcc50d816187fa9a03907ac1f3a52f04a52e10d1
8450Author: djm@openbsd.org <djm@openbsd.org>
8451Date: Thu May 21 06:43:30 2015 +0000
8452
8453 upstream commit
8454
8455 add AuthorizedPrincipalsCommand that allows getting
8456 authorized_principals from a subprocess rather than a file, which is quite
8457 useful in deployments with large userbases
8458
8459 feedback and ok markus@
8460
8461 Upstream-ID: aa1bdac7b16fc6d2fa3524ef08f04c7258d247f6
8462
8463commit 24232a3e5ab467678a86aa67968bbb915caffed4
8464Author: djm@openbsd.org <djm@openbsd.org>
8465Date: Thu May 21 06:38:35 2015 +0000
8466
8467 upstream commit
8468
8469 support arguments to AuthorizedKeysCommand
8470
8471 bz#2081 loosely based on patch by Sami Hartikainen
8472 feedback and ok markus@
8473
8474 Upstream-ID: b080387a14aa67dddd8ece67c00f268d626541f7
8475
8476commit d80fbe41a57c72420c87a628444da16d09d66ca7
8477Author: djm@openbsd.org <djm@openbsd.org>
8478Date: Thu May 21 04:55:51 2015 +0000
8479
8480 upstream commit
8481
8482 refactor: split base64 encoding of pubkey into its own
8483 sshkey_to_base64() function and out of sshkey_write(); ok markus@
8484
8485 Upstream-ID: 54fc38f5832e9b91028900819bda46c3959a0c1a
8486
8487commit 7cc44ef74133a473734bbcbd3484f24d6a7328c5
8488Author: deraadt@openbsd.org <deraadt@openbsd.org>
8489Date: Mon May 18 15:06:05 2015 +0000
8490
8491 upstream commit
8492
8493 getentropy() and sendsyslog() have been around long
8494 enough. openssh-portable may want the #ifdef's but not base. discussed with
8495 djm few weeks back
8496
8497 Upstream-ID: 0506a4334de108e3fb6c66f8d6e0f9c112866926
8498
8499commit 9173d0fbe44de7ebcad8a15618e13a8b8d78902e
8500Author: dtucker@openbsd.org <dtucker@openbsd.org>
8501Date: Fri May 15 05:44:21 2015 +0000
8502
8503 upstream commit
8504
8505 Use a salted hash of the lock passphrase instead of plain
8506 text and do constant-time comparisons of it. Should prevent leaking any
8507 information about it via timing, pointed out by Ryan Castellucci. Add a 0.1s
8508 incrementing delay for each failed unlock attempt up to 10s. ok markus@
8509 (earlier version), djm@
8510
8511 Upstream-ID: c599fcc325aa1cc65496b25220b622d22208c85f
8512
8513commit d028d5d3a697c71b21e4066d8672cacab3caa0a8
8514Author: Damien Miller <djm@mindrot.org>
8515Date: Tue May 5 19:10:58 2015 +1000
8516
8517 upstream commit
8518
8519 - tedu@cvs.openbsd.org 2015/01/12 03:20:04
8520 [bcrypt_pbkdf.c]
8521 rename blocks to words. bcrypt "blocks" are unrelated to blowfish blocks,
8522 nor are they the same size.
8523
8524commit f6391d4e59b058984163ab28f4e317e7a72478f1
8525Author: Damien Miller <djm@mindrot.org>
8526Date: Tue May 5 19:10:23 2015 +1000
8527
8528 upstream commit
8529
8530 - deraadt@cvs.openbsd.org 2015/01/08 00:30:07
8531 [bcrypt_pbkdf.c]
8532 declare a local version of MIN(), call it MINIMUM()
8533
8534commit 8ac6b13cc9113eb47cd9e86c97d7b26b4b71b77f
8535Author: Damien Miller <djm@mindrot.org>
8536Date: Tue May 5 19:09:46 2015 +1000
8537
8538 upstream commit
8539
8540 - djm@cvs.openbsd.org 2014/12/30 01:41:43
8541 [bcrypt_pbkdf.c]
8542 typo in comment: ouput => output
8543
8544commit 1f792489d5cf86a4f4e3003e6e9177654033f0f2
8545Author: djm@openbsd.org <djm@openbsd.org>
8546Date: Mon May 4 06:10:48 2015 +0000
8547
8548 upstream commit
8549
8550 Remove pattern length argument from match_pattern_list(), we
8551 only ever use it for strlen(pattern).
8552
8553 Prompted by hanno AT hboeck.de pointing an out-of-bound read
8554 error caused by an incorrect pattern length found using AFL
8555 and his own tools.
8556
8557 ok markus@
8558
8559commit 639d6bc57b1942393ed12fb48f00bc05d4e093e4
8560Author: djm@openbsd.org <djm@openbsd.org>
8561Date: Fri May 1 07:10:01 2015 +0000
8562
8563 upstream commit
8564
8565 refactor ssh_dispatch_run_fatal() to use sshpkt_fatal()
8566 to better report error conditions. Teach sshpkt_fatal() about ECONNRESET.
8567
8568 Improves error messages on TCP connection resets. bz#2257
8569
8570 ok dtucker@
8571
8572commit 9559d7de34c572d4d3fd990ca211f8ec99f62c4d
8573Author: djm@openbsd.org <djm@openbsd.org>
8574Date: Fri May 1 07:08:08 2015 +0000
8575
8576 upstream commit
8577
8578 a couple of parse targets were missing activep checks,
8579 causing them to be misapplied in match context; bz#2272 diagnosis and
8580 original patch from Sami Hartikainen ok dtucker@
8581
8582commit 7e8528cad04b2775c3b7db08abf8fb42e47e6b2a
8583Author: djm@openbsd.org <djm@openbsd.org>
8584Date: Fri May 1 04:17:51 2015 +0000
8585
8586 upstream commit
8587
8588 make handling of AuthorizedPrincipalsFile=none more
8589 consistent with other =none options; bz#2288 from Jakub Jelen; ok dtucker@
8590
8591commit ca430d4d9cc0f62eca3b1fb1e2928395b7ce80f7
8592Author: djm@openbsd.org <djm@openbsd.org>
8593Date: Fri May 1 04:03:20 2015 +0000
8594
8595 upstream commit
8596
8597 remove failed remote forwards established by muliplexing
8598 from the list of active forwards; bz#2363, patch mostly by Yoann Ricordel; ok
8599 dtucker@
8600
8601commit 8312cfb8ad88657517b3e23ac8c56c8e38eb9792
8602Author: djm@openbsd.org <djm@openbsd.org>
8603Date: Fri May 1 04:01:58 2015 +0000
8604
8605 upstream commit
8606
8607 reduce stderr spam when using ssh -S /path/mux -O forward
8608 -R 0:... ok dtucker@
8609
8610commit 179be0f5e62f1f492462571944e45a3da660d82b
8611Author: djm@openbsd.org <djm@openbsd.org>
8612Date: Fri May 1 03:23:51 2015 +0000
8613
8614 upstream commit
8615
8616 prevent authorized_keys options picked up on public key
8617 tests without a corresponding private key authentication being applied to
8618 other authentication methods. Reported by halex@, ok markus@
8619
8620commit a42d67be65b719a430b7fcaba2a4e4118382723a
8621Author: djm@openbsd.org <djm@openbsd.org>
8622Date: Fri May 1 03:20:54 2015 +0000
8623
8624 upstream commit
8625
8626 Don't make parsing of authorized_keys' environment=
8627 option conditional on PermitUserEnv - always parse it, but only use the
8628 result if the option is enabled. This prevents the syntax of authorized_keys
8629 changing depending on which sshd_config options were enabled.
8630
8631 bz#2329; based on patch from coladict AT gmail.com, ok dtucker@
8632
8633commit e661a86353e11592c7ed6a847e19a83609f49e77
8634Author: djm@openbsd.org <djm@openbsd.org>
8635Date: Mon May 4 06:10:48 2015 +0000
8636
8637 upstream commit
8638
8639 Remove pattern length argument from match_pattern_list(), we
8640 only ever use it for strlen(pattern).
8641
8642 Prompted by hanno AT hboeck.de pointing an out-of-bound read
8643 error caused by an incorrect pattern length found using AFL
8644 and his own tools.
8645
8646 ok markus@
8647
8648commit 0ef1de742be2ee4b10381193fe90730925b7f027
8649Author: dtucker@openbsd.org <dtucker@openbsd.org>
8650Date: Thu Apr 23 05:01:19 2015 +0000
8651
8652 upstream commit
8653
8654 Add a simple regression test for sshd's configuration
8655 parser. Right now, all it does is run the output of sshd -T back through
8656 itself and ensure the output is valid and invariant.
8657
8658commit 368f83c793275faa2c52f60eaa9bdac155c4254b
8659Author: djm@openbsd.org <djm@openbsd.org>
8660Date: Wed Apr 22 01:38:36 2015 +0000
8661
8662 upstream commit
8663
8664 use correct key for nested certificate test
8665
8666commit 8d4d1bfddbbd7d21f545dc6997081d1ea1fbc99a
8667Author: djm@openbsd.org <djm@openbsd.org>
8668Date: Fri May 1 07:11:47 2015 +0000
8669
8670 upstream commit
8671
8672 mention that the user's shell from /etc/passwd is used
8673 for commands too; bz#1459 ok dtucker@
8674
8675commit 5ab283d0016bbc9d4d71e8e5284d011bc5a930cf
8676Author: djm@openbsd.org <djm@openbsd.org>
8677Date: Fri May 8 07:29:00 2015 +0000
8678
8679 upstream commit
8680
8681 whitespace
8682
8683 Upstream-Regress-ID: 6b708a3e709d5b7fd37890f874bafdff1f597519
8684
8685commit 8377d5008ad260048192e1e56ad7d15a56d103dd
8686Author: djm@openbsd.org <djm@openbsd.org>
8687Date: Fri May 8 07:26:13 2015 +0000
8688
8689 upstream commit
8690
8691 whitespace at EOL
8692
8693 Upstream-Regress-ID: 9c48911643d5b05173b36a012041bed4080b8554
8694
8695commit c28a3436fa8737709ea88e4437f8f23a6ab50359
8696Author: djm@openbsd.org <djm@openbsd.org>
8697Date: Fri May 8 06:45:13 2015 +0000
8698
8699 upstream commit
8700
8701 moar whitespace at eol
8702
8703 Upstream-ID: 64eaf872a3ba52ed41e494287e80d40aaba4b515
8704
8705commit 2b64c490468fd4ca35ac8d5cc31c0520dc1508bb
8706Author: djm@openbsd.org <djm@openbsd.org>
8707Date: Fri May 8 06:41:56 2015 +0000
8708
8709 upstream commit
8710
8711 whitespace at EOL
8712
8713 Upstream-ID: 57bcf67d666c6fc1ad798aee448fdc3f70f7ec2c
8714
8715commit 4e636cf201ce6e7e3b9088568218f9d4e2c51712
8716Author: djm@openbsd.org <djm@openbsd.org>
8717Date: Fri May 8 03:56:51 2015 +0000
8718
8719 upstream commit
8720
8721 whitespace at EOL
8722
8723commit 38b8272f823dc1dd4e29dbcee83943ed48bb12fa
8724Author: dtucker@openbsd.org <dtucker@openbsd.org>
8725Date: Mon May 4 01:47:53 2015 +0000
8726
8727 upstream commit
8728
8729 Use diff w/out -u for better portability
8730
8731commit 297060f42d5189a4065ea1b6f0afdf6371fb0507
8732Author: dtucker@openbsd.org <dtucker@openbsd.org>
8733Date: Fri May 8 03:25:07 2015 +0000
8734
8735 upstream commit
8736
8737 Use xcalloc for permitted_adm_opens instead of xmalloc to
8738 ensure it's zeroed. Fixes post-auth crash with permitopen=none. bz#2355, ok
8739 djm@
8740
8741commit 63ebf019be863b2d90492a85e248cf55a6e87403
8742Author: djm@openbsd.org <djm@openbsd.org>
8743Date: Fri May 8 03:17:49 2015 +0000
8744
8745 upstream commit
8746
8747 don't choke on new-format private keys encrypted with an
8748 AEAD cipher; bz#2366, patch from Ron Frederick; ok markus@
8749
8750commit f8484dac678ab3098ae522a5f03bb2530f822987
8751Author: dtucker@openbsd.org <dtucker@openbsd.org>
8752Date: Wed May 6 05:45:17 2015 +0000
8753
8754 upstream commit
8755
8756 Clarify pseudo-terminal request behaviour and use
8757 "pseudo-terminal" consistently. bz#1716, ok jmc@ "I like it" deraadt@.
8758
8759commit ea139507bef8bad26e86ed99a42c7233ad115c38
8760Author: dtucker@openbsd.org <dtucker@openbsd.org>
8761Date: Wed May 6 04:07:18 2015 +0000
8762
8763 upstream commit
8764
8765 Blacklist DH-GEX for specific PuTTY versions known to
8766 send non-RFC4419 DH-GEX messages rather than all versions of PuTTY.
8767 According to Simon Tatham, 0.65 and newer versions will send RFC4419 DH-GEX
8768 messages. ok djm@
8769
8770commit b58234f00ee3872eb84f6e9e572a9a34e902e36e
8771Author: dtucker@openbsd.org <dtucker@openbsd.org>
8772Date: Tue May 5 10:17:49 2015 +0000
8773
8774 upstream commit
8775
8776 WinSCP doesn't implement RFC4419 DH-GEX so flag it so we
8777 don't offer that KEX method. ok markus@
8778
8779commit d5b1507a207253b39e810e91e68f9598691b7a29
8780Author: jsg@openbsd.org <jsg@openbsd.org>
8781Date: Tue May 5 02:48:17 2015 +0000
8782
8783 upstream commit
8784
8785 use the sizeof the struct not the sizeof a pointer to the
8786 struct in ssh_digest_start()
8787
8788 This file is only used if ssh is built with OPENSSL=no
8789
8790 ok markus@
8791
8792commit a647b9b8e616c231594b2710c925d31b1b8afea3
8793Author: Darren Tucker <dtucker@zip.com.au>
8794Date: Fri May 8 11:07:27 2015 +1000
8795
8796 Put brackets around mblen() compat constant.
8797
8798 This might help with the reported problem cross compiling for Android
8799 ("error: expected identifier or '(' before numeric constant") but
8800 shouldn't hurt in any case.
8801
8802commit d1680d36e17244d9af3843aeb5025cb8e40d6c07
8803Author: Darren Tucker <dtucker@zip.com.au>
8804Date: Thu Apr 30 09:18:11 2015 +1000
8805
8806 xrealloc -> xreallocarray in portable code too.
8807
8808commit 531a57a3893f9fcd4aaaba8c312b612bbbcc021e
8809Author: dtucker@openbsd.org <dtucker@openbsd.org>
8810Date: Wed Apr 29 03:48:56 2015 +0000
8811
8812 upstream commit
8813
8814 Allow ListenAddress, Port and AddressFamily in any
8815 order. bz#68, ok djm@, jmc@ (for the man page bit).
8816
8817commit c1d5bcf1aaf1209af02f79e48ba1cbc76a87b56f
8818Author: jmc@openbsd.org <jmc@openbsd.org>
8819Date: Tue Apr 28 13:47:38 2015 +0000
8820
8821 upstream commit
8822
8823 enviroment -> environment: apologies to darren for not
8824 spotting that first time round...
8825
8826commit 43beea053db191cac47c2cd8d3dc1930158aff1a
8827Author: dtucker@openbsd.org <dtucker@openbsd.org>
8828Date: Tue Apr 28 10:25:15 2015 +0000
8829
8830 upstream commit
8831
8832 Fix typo in previous
8833
8834commit 85b96ef41374f3ddc9139581f87da09b2cd9199e
8835Author: dtucker@openbsd.org <dtucker@openbsd.org>
8836Date: Tue Apr 28 10:17:58 2015 +0000
8837
8838 upstream commit
8839
8840 Document that the TERM environment variable is not
8841 subject to SendEnv and AcceptEnv. bz#2386, based loosely on a patch from
8842 jjelen at redhat, help and ok jmc@
8843
8844commit 88a7c598a94ff53f76df228eeaae238d2d467565
8845Author: djm@openbsd.org <djm@openbsd.org>
8846Date: Mon Apr 27 21:42:48 2015 +0000
8847
8848 upstream commit
8849
8850 Make sshd default to PermitRootLogin=no; ok deraadt@
8851 rpe@
8852
8853commit 734226b4480a6c736096c729fcf6f391400599c7
8854Author: djm@openbsd.org <djm@openbsd.org>
8855Date: Mon Apr 27 01:52:30 2015 +0000
8856
8857 upstream commit
8858
8859 fix compilation with OPENSSL=no; ok dtucker@
8860
8861commit a4b9d2ce1eb7703eaf0809b0c8a82ded8aa4f1c6
8862Author: dtucker@openbsd.org <dtucker@openbsd.org>
8863Date: Mon Apr 27 00:37:53 2015 +0000
8864
8865 upstream commit
8866
8867 Include stdio.h for FILE (used in sshkey.h) so it
8868 compiles with OPENSSL=no.
8869
8870commit dbcc652f4ca11fe04e5930c7ef18a219318c6cda
8871Author: djm@openbsd.org <djm@openbsd.org>
8872Date: Mon Apr 27 00:21:21 2015 +0000
8873
8874 upstream commit
8875
8876 allow "sshd -f none" to skip reading the config file,
8877 much like "ssh -F none" does. ok dtucker
8878
8879commit b7ca276fca316c952f0b90f5adb1448c8481eedc
8880Author: jmc@openbsd.org <jmc@openbsd.org>
8881Date: Fri Apr 24 06:26:49 2015 +0000
8882
8883 upstream commit
8884
8885 combine -Dd onto one line and update usage();
8886
8887commit 2ea974630d7017e4c7666d14d9dc939707613e96
8888Author: djm@openbsd.org <djm@openbsd.org>
8889Date: Fri Apr 24 05:26:44 2015 +0000
8890
8891 upstream commit
8892
8893 add ssh-agent -D to leave ssh-agent in foreground
8894 without enabling debug mode; bz#2381 ok dtucker@
8895
8896commit 8ac2ffd7aa06042f6b924c87139f2fea5c5682f7
8897Author: deraadt@openbsd.org <deraadt@openbsd.org>
8898Date: Fri Apr 24 01:36:24 2015 +0000
8899
8900 upstream commit
8901
8902 2*len -> use xreallocarray() ok djm
8903
8904commit 657a5fbc0d0aff309079ff8fb386f17e964963c2
8905Author: deraadt@openbsd.org <deraadt@openbsd.org>
8906Date: Fri Apr 24 01:36:00 2015 +0000
8907
8908 upstream commit
8909
8910 rename xrealloc() to xreallocarray() since it follows
8911 that form. ok djm
8912
8913commit 1108ae242fdd2c304307b68ddf46aebe43ebffaa
8914Author: dtucker@openbsd.org <dtucker@openbsd.org>
8915Date: Thu Apr 23 04:59:10 2015 +0000
8916
8917 upstream commit
8918
8919 Two small fixes for sshd -T: ListenAddress'es are added
8920 to a list head so reverse the order when printing them to ensure the
8921 behaviour remains the same, and print StreamLocalBindMask as octal with
8922 leading zero. ok deraadt@
8923
8924commit bd902b8473e1168f19378d5d0ae68d0c203525df
8925Author: dtucker@openbsd.org <dtucker@openbsd.org>
8926Date: Thu Apr 23 04:53:53 2015 +0000
8927
8928 upstream commit
8929
8930 Check for and reject missing arguments for
8931 VersionAddendum and ForceCommand. bz#2281, patch from plautrba at redhat com,
8932 ok djm@
8933
8934commit ca42c1758575e592239de1d5755140e054b91a0d
8935Author: djm@openbsd.org <djm@openbsd.org>
8936Date: Wed Apr 22 01:24:01 2015 +0000
8937
8938 upstream commit
8939
8940 unknown certificate extensions are non-fatal, so don't
8941 fatal when they are encountered; bz#2387 reported by Bob Van Zant; ok
8942 dtucker@
8943
8944commit 39bfbf7caad231cc4bda6909fb1af0705bca04d8
8945Author: jsg@openbsd.org <jsg@openbsd.org>
8946Date: Tue Apr 21 07:01:00 2015 +0000
8947
8948 upstream commit
8949
8950 Add back a backslash removed in rev 1.42 so
8951 KEX_SERVER_ENCRYPT will include aes again.
8952
8953 ok deraadt@
8954
8955commit 6b0d576bb87eca3efd2b309fcfe4edfefc289f9c
8956Author: djm@openbsd.org <djm@openbsd.org>
8957Date: Fri Apr 17 13:32:09 2015 +0000
8958
8959 upstream commit
8960
8961 s/recommended/required/ that private keys be og-r this
8962 wording change was made a while ago but got accidentally reverted
8963
8964commit 44a8e7ce6f3ab4c2eb1ae49115c210b98e53c4df
8965Author: djm@openbsd.org <djm@openbsd.org>
8966Date: Fri Apr 17 13:25:52 2015 +0000
8967
8968 upstream commit
8969
8970 don't try to cleanup NULL KEX proposals in
8971 kex_prop_free(); found by Jukka Taimisto and Markus Hietava
8972
8973commit 3038a191872d2882052306098c1810d14835e704
8974Author: djm@openbsd.org <djm@openbsd.org>
8975Date: Fri Apr 17 13:19:22 2015 +0000
8976
8977 upstream commit
8978
8979 use error/logit/fatal instead of fprintf(stderr, ...)
8980 and exit(0), fix a few errors that were being printed to stdout instead of
8981 stderr and a few non-errors that were going to stderr instead of stdout
8982 bz#2325; ok dtucker
8983
8984commit a58be33cb6cd24441fa7e634db0e5babdd56f07f
8985Author: djm@openbsd.org <djm@openbsd.org>
8986Date: Fri Apr 17 13:16:48 2015 +0000
8987
8988 upstream commit
8989
8990 debug log missing DISPLAY environment when X11
8991 forwarding requested; bz#1682 ok dtucker@
8992
8993commit 17d4d9d9fbc8fb80e322f94d95eecc604588a474
8994Author: djm@openbsd.org <djm@openbsd.org>
8995Date: Fri Apr 17 04:32:31 2015 +0000
8996
8997 upstream commit
8998
8999 don't call record_login() in monitor when UseLogin is
9000 enabled; bz#278 reported by drk AT sgi.com; ok dtucker
9001
9002commit 40132ff87b6cbc3dc05fb5df2e9d8e3afa06aafd
9003Author: dtucker@openbsd.org <dtucker@openbsd.org>
9004Date: Fri Apr 17 04:12:35 2015 +0000
9005
9006 upstream commit
9007
9008 Add some missing options to sshd -T and fix the output
9009 of VersionAddendum HostCertificate. bz#2346, patch from jjelen at redhat
9010 com, ok djm.
9011
9012commit 6cc7cfa936afde2d829e56ee6528c7ea47a42441
9013Author: dtucker@openbsd.org <dtucker@openbsd.org>
9014Date: Thu Apr 16 23:25:50 2015 +0000
9015
9016 upstream commit
9017
9018 Document "none" for PidFile XAuthLocation
9019 TrustedUserCAKeys and RevokedKeys. bz#2382, feedback from jmc@, ok djm@
9020
9021commit 15fdfc9b1c6808b26bc54d4d61a38b54541763ed
9022Author: dtucker@openbsd.org <dtucker@openbsd.org>
9023Date: Wed Apr 15 23:23:25 2015 +0000
9024
9025 upstream commit
9026
9027 Plug leak of address passed to logging. bz#2373, patch
9028 from jjelen at redhat, ok markus@
9029
9030commit bb2289e2a47d465eaaaeff3dee2a6b7777b4c291
9031Author: dtucker@openbsd.org <dtucker@openbsd.org>
9032Date: Tue Apr 14 04:17:03 2015 +0000
9033
9034 upstream commit
9035
9036 Output remote username in debug output since with Host
9037 and Match it's not always obvious what it will be. bz#2368, ok djm@
9038
9039commit 70860b6d07461906730632f9758ff1b7c98c695a
9040Author: Darren Tucker <dtucker@zip.com.au>
9041Date: Fri Apr 17 10:56:13 2015 +1000
9042
9043 Format UsePAM setting when using sshd -T.
9044
9045 Part of bz#2346, patch from jjelen at redhat com.
9046
9047commit ee15d9c9f0720f5a8b0b34e4b10ecf21f9824814
9048Author: Darren Tucker <dtucker@zip.com.au>
9049Date: Fri Apr 17 10:40:23 2015 +1000
9050
9051 Wrap endian.h include inside ifdef (bz#2370).
9052
9053commit 408f4c2ad4a4c41baa7b9b2b7423d875abbfa70b
9054Author: Darren Tucker <dtucker@zip.com.au>
9055Date: Fri Apr 17 09:39:58 2015 +1000
9056
9057 Look for '${host}-ar' before 'ar'.
9058
9059 This changes configure.ac to look for '${host}-ar' as set by
9060 AC_CANONICAL_HOST before looking for the unprefixed 'ar'.
9061 Useful when cross-compiling when all your binutils are prefixed.
9062
9063 Patch from moben at exherbo org via astrand at lysator liu se and
9064 bz#2352.
9065
9066commit 673a1c16ad078d41558247ce739fe812c960acc8
9067Author: Damien Miller <djm@google.com>
9068Date: Thu Apr 16 11:40:20 2015 +1000
9069
9070 remove dependency on arpa/telnet.h
9071
9072commit 202d443eeda1829d336595a3cfc07827e49f45ed
9073Author: Darren Tucker <dtucker@zip.com.au>
9074Date: Wed Apr 15 15:59:49 2015 +1000
9075
9076 Remove duplicate include of pwd.h. bz#2337, patch from Mordy Ovits.
9077
9078commit 597986493412c499f2bc2209420cb195f97b3668
9079Author: Damien Miller <djm@google.com>
9080Date: Thu Apr 9 10:14:48 2015 +1000
9081
9082 platform's with openpty don't need pty_release
9083
9084commit 318be28cda1fd9108f2e6f2f86b0b7589ba2aed0
9085Author: djm@openbsd.org <djm@openbsd.org>
9086Date: Mon Apr 13 02:04:08 2015 +0000
9087
9088 upstream commit
9089
9090 deprecate ancient, pre-RFC4419 and undocumented
9091 SSH2_MSG_KEX_DH_GEX_REQUEST_OLD message; ok markus@ deraadt@ "seems
9092 reasonable" dtucker@
9093
9094commit d8f391caef62378463a0e6b36f940170dadfe605
9095Author: dtucker@openbsd.org <dtucker@openbsd.org>
9096Date: Fri Apr 10 05:16:50 2015 +0000
9097
9098 upstream commit
9099
9100 Don't send hostkey advertisments
9101 (hostkeys-00@openssh.com) to current versions of Tera Term as they can't
9102 handle them. Newer versions should be OK. Patch from Bryan Drewery and
9103 IWAMOTO Kouichi, ok djm@
9104
9105commit 2c2cfe1a1c97eb9a08cc9817fd0678209680c636
9106Author: djm@openbsd.org <djm@openbsd.org>
9107Date: Fri Apr 10 00:08:55 2015 +0000
9108
9109 upstream commit
9110
9111 include port number if a non-default one has been
9112 specified; based on patch from Michael Handler
9113
9114commit 4492a4f222da4cf1e8eab12689196322e27b08c4
9115Author: djm@openbsd.org <djm@openbsd.org>
9116Date: Tue Apr 7 23:00:42 2015 +0000
9117
9118 upstream commit
9119
9120 treat Protocol=1,2|2,1 as Protocol=2 when compiled
9121 without SSH1 support; ok dtucker@ millert@
9122
9123commit c265e2e6e932efc6d86f6cc885dea33637a67564
9124Author: miod@openbsd.org <miod@openbsd.org>
9125Date: Sun Apr 5 15:43:43 2015 +0000
9126
9127 upstream commit
9128
9129 Do not use int for sig_atomic_t; spotted by
9130 christos@netbsd; ok markus@
9131
9132commit e7bf3a5eda6a1b02bef6096fed78527ee11e54cc
9133Author: Darren Tucker <dtucker@zip.com.au>
9134Date: Tue Apr 7 10:48:04 2015 +1000
9135
9136 Use do{}while(0) for no-op functions.
9137
9138 From FreeBSD.
9139
9140commit bb99844abae2b6447272f79e7fa84134802eb4df
9141Author: Darren Tucker <dtucker@zip.com.au>
9142Date: Tue Apr 7 10:47:15 2015 +1000
9143
9144 Wrap blf.h include in ifdef. From FreeBSD.
9145
9146commit d9b9b43656091cf0ad55c122f08fadb07dad0abd
9147Author: Darren Tucker <dtucker@zip.com.au>
9148Date: Tue Apr 7 09:10:00 2015 +1000
9149
9150 Fix misspellings of regress CONFOPTS env variables.
9151
9152 Patch from Bryan Drewery.
9153
9154commit 3f4ea3c9ab1d32d43c9222c4351f58ca11144156
9155Author: djm@openbsd.org <djm@openbsd.org>
9156Date: Fri Apr 3 22:17:27 2015 +0000
9157
9158 upstream commit
9159
9160 correct return value in pubkey parsing, spotted by Ben Hawkes
9161 ok markus@
9162
9163commit 7da2be0cb9601ed25460c83aa4d44052b967ba0f
9164Author: djm@openbsd.org <djm@openbsd.org>
9165Date: Tue Mar 31 22:59:01 2015 +0000
9166
9167 upstream commit
9168
9169 adapt to recent hostfile.c change: when parsing
9170 known_hosts without fully parsing the keys therein, hostkeys_foreach() will
9171 now correctly identify KEY_RSA1 keys; ok markus@ miod@
9172
9173commit 9e1777a0d1c706714b055811c12ab8cc21033e4a
9174Author: markus@openbsd.org <markus@openbsd.org>
9175Date: Tue Mar 24 20:19:15 2015 +0000
9176
9177 upstream commit
9178
9179 use ${SSH} for -Q instead of installed ssh
9180
9181commit ce1b358ea414a2cc88e4430cd5a2ea7fecd9de57
9182Author: djm@openbsd.org <djm@openbsd.org>
9183Date: Mon Mar 16 22:46:14 2015 +0000
9184
9185 upstream commit
9186
9187 make CLEANFILES clean up more of the tests' droppings
9188
9189commit 398f9ef192d820b67beba01ec234d66faca65775
9190Author: djm@openbsd.org <djm@openbsd.org>
9191Date: Tue Mar 31 22:57:06 2015 +0000
9192
9193 upstream commit
9194
9195 downgrade error() for known_hosts parse errors to debug()
9196 to quiet warnings from ssh1 keys present when compiled !ssh1.
9197
9198 also identify ssh1 keys when scanning, even when compiled !ssh1
9199
9200 ok markus@ miod@
9201
9202commit 9a47ab80030a31f2d122b8fd95bd48c408b9fcd9
9203Author: djm@openbsd.org <djm@openbsd.org>
9204Date: Tue Mar 31 22:55:50 2015 +0000
9205
9206 upstream commit
9207
9208 fd leak for !ssh1 case; found by unittests; ok markus@
9209
9210commit c9a0805a6280681901c270755a7cd630d7c5280e
9211Author: djm@openbsd.org <djm@openbsd.org>
9212Date: Tue Mar 31 22:55:24 2015 +0000
9213
9214 upstream commit
9215
9216 don't fatal when a !ssh1 sshd is reexeced from a w/ssh1
9217 listener; reported by miod@; ok miod@ markus@
9218
9219commit 704d8c88988cae38fb755a6243b119731d223222
9220Author: tobias@openbsd.org <tobias@openbsd.org>
9221Date: Tue Mar 31 11:06:49 2015 +0000
9222
9223 upstream commit
9224
9225 Comments are only supported for RSA1 keys. If a user
9226 tried to add one and entered his passphrase, explicitly clear it before exit.
9227 This is done in all other error paths, too.
9228
9229 ok djm
9230
9231commit 78de1673c05ea2c33e0d4a4b64ecb5186b6ea2e9
9232Author: jmc@openbsd.org <jmc@openbsd.org>
9233Date: Mon Mar 30 18:28:37 2015 +0000
9234
9235 upstream commit
9236
9237 ssh-askpass(1) is the default, overridden by SSH_ASKPASS;
9238 diff originally from jiri b;
9239
9240commit 26e0bcf766fadb4a44fb6199386fb1dcab65ad00
9241Author: djm@openbsd.org <djm@openbsd.org>
9242Date: Mon Mar 30 00:00:29 2015 +0000
9243
9244 upstream commit
9245
9246 fix uninitialised memory read when parsing a config file
9247 consisting of a single nul byte. Found by hanno AT hboeck.de using AFL; ok
9248 dtucker
9249
9250commit fecede00a76fbb33a349f5121c0b2f9fbc04a777
9251Author: markus@openbsd.org <markus@openbsd.org>
9252Date: Thu Mar 26 19:32:19 2015 +0000
9253
9254 upstream commit
9255
9256 sigp and lenp are not optional in ssh_agent_sign(); ok
9257 djm@
9258
9259commit 1b0ef3813244c78669e6d4d54c624f600945327d
9260Author: naddy@openbsd.org <naddy@openbsd.org>
9261Date: Thu Mar 26 12:32:38 2015 +0000
9262
9263 upstream commit
9264
9265 don't try to load .ssh/identity by default if SSH1 is
9266 disabled; ok markus@
9267
9268commit f9b78852379b74a2d14e6fc94fe52af30b7e9c31
9269Author: djm@openbsd.org <djm@openbsd.org>
9270Date: Thu Mar 26 07:00:04 2015 +0000
9271
9272 upstream commit
9273
9274 ban all-zero curve25519 keys as recommended by latest
9275 CFRG curves draft; ok markus
9276
9277commit b8afbe2c1aaf573565e4da775261dfafc8b1ba9c
9278Author: djm@openbsd.org <djm@openbsd.org>
9279Date: Thu Mar 26 06:59:28 2015 +0000
9280
9281 upstream commit
9282
9283 relax bits needed check to allow
9284 diffie-hellman-group1-sha1 key exchange to complete for chacha20-poly1305 was
9285 selected as symmetric cipher; ok markus
9286
9287commit 47842f71e31da130555353c1d57a1e5a8937f1c0
9288Author: markus@openbsd.org <markus@openbsd.org>
9289Date: Wed Mar 25 19:29:58 2015 +0000
9290
9291 upstream commit
9292
9293 ignore v1 errors on ssh-add -D; only try v2 keys on
9294 -l/-L (unless WITH_SSH1) ok djm@
9295
9296commit 5f57e77f91bf2230c09eca96eb5ecec39e5f2da6
9297Author: markus@openbsd.org <markus@openbsd.org>
9298Date: Wed Mar 25 19:21:48 2015 +0000
9299
9300 upstream commit
9301
9302 unbreak ssh_agent_sign (lenp vs *lenp)
9303
9304commit 4daeb67181054f2a377677fac919ee8f9ed3490e
9305Author: markus@openbsd.org <markus@openbsd.org>
9306Date: Tue Mar 24 20:10:08 2015 +0000
9307
9308 upstream commit
9309
9310 don't leak 'setp' on error; noted by Nicholas Lemonias;
9311 ok djm@
9312
9313commit 7d4f96f9de2a18af0d9fa75ea89a4990de0344f5
9314Author: markus@openbsd.org <markus@openbsd.org>
9315Date: Tue Mar 24 20:09:11 2015 +0000
9316
9317 upstream commit
9318
9319 consistent check for NULL as noted by Nicholas
9320 Lemonias; ok djm@
9321
9322commit df100be51354e447d9345cf1ec22e6013c0eed50
9323Author: markus@openbsd.org <markus@openbsd.org>
9324Date: Tue Mar 24 20:03:44 2015 +0000
9325
9326 upstream commit
9327
9328 correct fmt-string for size_t as noted by Nicholas
9329 Lemonias; ok djm@
9330
9331commit a22b9ef21285e81775732436f7c84a27bd3f71e0
9332Author: djm@openbsd.org <djm@openbsd.org>
9333Date: Tue Mar 24 09:17:21 2015 +0000
9334
9335 upstream commit
9336
9337 promote chacha20-poly1305@openssh.com to be the default
9338 cipher; ok markus
9339
9340commit 2aa9da1a3b360cf7b13e96fe1521534b91501fb5
9341Author: djm@openbsd.org <djm@openbsd.org>
9342Date: Tue Mar 24 01:29:19 2015 +0000
9343
9344 upstream commit
9345
9346 Compile-time disable SSH protocol 1. You can turn it
9347 back on using the Makefile.inc knob if you need it to talk to ancient
9348 devices.
9349
9350commit 53097b2022154edf96b4e8526af5666f979503f7
9351Author: djm@openbsd.org <djm@openbsd.org>
9352Date: Tue Mar 24 01:11:12 2015 +0000
9353
9354 upstream commit
9355
9356 fix double-negative error message "ssh1 is not
9357 unsupported"
9358
9359commit 5c27e3b6ec2db711dfcd40e6359c0bcdd0b62ea9
9360Author: djm@openbsd.org <djm@openbsd.org>
9361Date: Mon Mar 23 06:06:38 2015 +0000
9362
9363 upstream commit
9364
9365 for ssh-keygen -A, don't try (and fail) to generate ssh
9366 v.1 keys when compiled without SSH1 support RSA/DSA/ECDSA keys when compiled
9367 without OpenSSL based on patch by Mike Frysinger; bz#2369
9368
9369commit 725fd22a8c41db7de73a638539a5157b7e4424ae
9370Author: djm@openbsd.org <djm@openbsd.org>
9371Date: Wed Mar 18 01:44:21 2015 +0000
9372
9373 upstream commit
9374
9375 KRL support doesn't need OpenSSL anymore, remove #ifdefs
9376 from around call
9377
9378commit b07011c18e0b2e172c5fd09d21fb159a0bf5fcc7
9379Author: djm@openbsd.org <djm@openbsd.org>
9380Date: Mon Mar 16 11:09:52 2015 +0000
9381
9382 upstream commit
9383
9384 #if 0 some more arrays used only for decrypting (we don't
9385 use since we only need encrypt for AES-CTR)
9386
9387commit 1cb3016635898d287e9d58b50c430995652d5358
9388Author: jsg@openbsd.org <jsg@openbsd.org>
9389Date: Wed Mar 11 00:48:39 2015 +0000
9390
9391 upstream commit
9392
9393 add back the changes from rev 1.206, djm reverted this by
9394 mistake in rev 1.207
diff --git a/INSTALL b/INSTALL
index 92106bf02..e4865bbb4 100644
--- a/INSTALL
+++ b/INSTALL
@@ -99,7 +99,7 @@ http://www.gnu.org/software/autoconf/
99 99
100Basic Security Module (BSM): 100Basic Security Module (BSM):
101 101
102Native BSM support is know to exist in Solaris from at least 2.5.1, 102Native BSM support is known to exist in Solaris from at least 2.5.1,
103FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM 103FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM
104implementation (http://www.openbsm.org). 104implementation (http://www.openbsm.org).
105 105
diff --git a/LICENCE b/LICENCE
index f52387139..15248212a 100644
--- a/LICENCE
+++ b/LICENCE
@@ -75,27 +75,6 @@ OpenSSH contains no GPL code.
75 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 75 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
76 POSSIBILITY OF SUCH DAMAGES. 76 POSSIBILITY OF SUCH DAMAGES.
77 77
782)
79 The 32-bit CRC compensation attack detector in deattack.c was
80 contributed by CORE SDI S.A. under a BSD-style license.
81
82 * Cryptographic attack detector for ssh - source code
83 *
84 * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.
85 *
86 * All rights reserved. Redistribution and use in source and binary
87 * forms, with or without modification, are permitted provided that
88 * this copyright notice is retained.
89 *
90 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
91 * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE
92 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
93 * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS
94 * SOFTWARE.
95 *
96 * Ariel Futoransky <futo@core-sdi.com>
97 * <http://www.core-sdi.com>
98
993) 783)
100 ssh-keyscan was contributed by David Mazieres under a BSD-style 79 ssh-keyscan was contributed by David Mazieres under a BSD-style
101 license. 80 license.
@@ -337,4 +316,4 @@ OpenSSH contains no GPL code.
337 316
338 317
339------ 318------
340$OpenBSD: LICENCE,v 1.19 2004/08/30 09:18:08 markus Exp $ 319$OpenBSD: LICENCE,v 1.20 2017/04/30 23:26:16 djm Exp $
diff --git a/Makefile.in b/Makefile.in
index 5870e9e6e..c52ce191f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -78,10 +78,10 @@ LIBOPENSSH_OBJS=\
78LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ 78LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
79 authfd.o authfile.o bufaux.o bufbn.o bufec.o buffer.o \ 79 authfd.o authfile.o bufaux.o bufbn.o bufec.o buffer.o \
80 canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ 80 canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \
81 cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ 81 cipher-ctr.o cleanup.o \
82 compat.o crc32.o deattack.o fatal.o hostfile.o \ 82 compat.o crc32.o fatal.o hostfile.o \
83 log.o match.o md-sha256.o moduli.o nchan.o packet.o opacket.o \ 83 log.o match.o moduli.o nchan.o packet.o opacket.o \
84 readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ 84 readpass.o ttymodes.o xmalloc.o addrmatch.o \
85 atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \ 85 atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \
86 monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ 86 monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
87 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ 87 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
@@ -92,10 +92,10 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
92 kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ 92 kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
93 kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ 93 kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
94 kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ 94 kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \
95 platform-pledge.o platform-tracing.o 95 platform-pledge.o platform-tracing.o platform-misc.o
96 96
97SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ 97SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
98 sshconnect.o sshconnect1.o sshconnect2.o mux.o 98 sshconnect.o sshconnect2.o mux.o
99 99
100SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ 100SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
101 audit.o audit-bsm.o audit-linux.o platform.o \ 101 audit.o audit-bsm.o audit-linux.o platform.o \
@@ -228,26 +228,27 @@ umac128.o: umac.c
228clean: regressclean 228clean: regressclean
229 rm -f *.o *.a $(TARGETS) logintest config.cache config.log 229 rm -f *.o *.a $(TARGETS) logintest config.cache config.log
230 rm -f *.out core survey 230 rm -f *.out core survey
231 rm -f regress/check-perm$(EXEEXT)
231 rm -f regress/unittests/test_helper/*.a 232 rm -f regress/unittests/test_helper/*.a
232 rm -f regress/unittests/test_helper/*.o 233 rm -f regress/unittests/test_helper/*.o
233 rm -f regress/unittests/sshbuf/*.o 234 rm -f regress/unittests/sshbuf/*.o
234 rm -f regress/unittests/sshbuf/test_sshbuf 235 rm -f regress/unittests/sshbuf/test_sshbuf$(EXEEXT)
235 rm -f regress/unittests/sshkey/*.o 236 rm -f regress/unittests/sshkey/*.o
236 rm -f regress/unittests/sshkey/test_sshkey 237 rm -f regress/unittests/sshkey/test_sshkey$(EXEEXT)
237 rm -f regress/unittests/bitmap/*.o 238 rm -f regress/unittests/bitmap/*.o
238 rm -f regress/unittests/bitmap/test_bitmap 239 rm -f regress/unittests/bitmap/test_bitmap$(EXEEXT)
239 rm -f regress/unittests/conversion/*.o 240 rm -f regress/unittests/conversion/*.o
240 rm -f regress/unittests/conversion/test_conversion 241 rm -f regress/unittests/conversion/test_conversion$(EXEEXT)
241 rm -f regress/unittests/hostkeys/*.o 242 rm -f regress/unittests/hostkeys/*.o
242 rm -f regress/unittests/hostkeys/test_hostkeys 243 rm -f regress/unittests/hostkeys/test_hostkeys$(EXEEXT)
243 rm -f regress/unittests/kex/*.o 244 rm -f regress/unittests/kex/*.o
244 rm -f regress/unittests/kex/test_kex 245 rm -f regress/unittests/kex/test_kex$(EXEEXT)
245 rm -f regress/unittests/match/*.o 246 rm -f regress/unittests/match/*.o
246 rm -f regress/unittests/match/test_match 247 rm -f regress/unittests/match/test_match$(EXEEXT)
247 rm -f regress/unittests/utf8/*.o 248 rm -f regress/unittests/utf8/*.o
248 rm -f regress/unittests/utf8/test_utf8 249 rm -f regress/unittests/utf8/test_utf8$(EXEEXT)
249 rm -f regress/misc/kexfuzz/*.o 250 rm -f regress/misc/kexfuzz/*.o
250 rm -f regress/misc/kexfuzz/kexfuzz 251 rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT)
251 (cd openbsd-compat && $(MAKE) clean) 252 (cd openbsd-compat && $(MAKE) clean)
252 253
253distclean: regressclean 254distclean: regressclean
diff --git a/PROTOCOL b/PROTOCOL
index 192da55b2..4e9e87575 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -33,8 +33,8 @@ The method is documented in:
33 33
34https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt 34https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt
35 35
361.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com", 361.3. transport: New public key algorithms "ssh-rsa-cert-v01@openssh.com",
37 "ssh-dsa-cert-v00@openssh.com", 37 "ssh-dsa-cert-v01@openssh.com",
38 "ecdsa-sha2-nistp256-cert-v01@openssh.com", 38 "ecdsa-sha2-nistp256-cert-v01@openssh.com",
39 "ecdsa-sha2-nistp384-cert-v01@openssh.com" and 39 "ecdsa-sha2-nistp384-cert-v01@openssh.com" and
40 "ecdsa-sha2-nistp521-cert-v01@openssh.com" 40 "ecdsa-sha2-nistp521-cert-v01@openssh.com"
@@ -454,4 +454,4 @@ respond with a SSH_FXP_STATUS message.
454This extension is advertised in the SSH_FXP_VERSION hello with version 454This extension is advertised in the SSH_FXP_VERSION hello with version
455"1". 455"1".
456 456
457$OpenBSD: PROTOCOL,v 1.30 2016/04/08 06:35:54 djm Exp $ 457$OpenBSD: PROTOCOL,v 1.31 2017/05/26 01:40:07 djm Exp $
diff --git a/PROTOCOL.agent b/PROTOCOL.agent
index 60d36f912..da3381942 100644
--- a/PROTOCOL.agent
+++ b/PROTOCOL.agent
@@ -1,582 +1,5 @@
1This describes the protocol used by OpenSSH's ssh-agent. 1This file used to contain a description of the SSH agent protocol
2implemented by OpenSSH. It has since been superseded by an Internet-
3draft that is available from:
2 4
3OpenSSH's agent supports managing keys for the standard SSH protocol 5https://tools.ietf.org/html/draft-miller-ssh-agent-02
42 as well as the legacy SSH protocol 1. Support for these key types
5is almost completely disjoint - in all but a few cases, operations on
6protocol 2 keys cannot see or affect protocol 1 keys and vice-versa.
7
8Protocol 1 and protocol 2 keys are separated because of the differing
9cryptographic usage: protocol 1 private RSA keys are used to decrypt
10challenges that were encrypted with the corresponding public key,
11whereas protocol 2 RSA private keys are used to sign challenges with
12a private key for verification with the corresponding public key. It
13is considered unsound practice to use the same key for signing and
14encryption.
15
16With a couple of exceptions, the protocol message names used in this
17document indicate which type of key the message relates to. SSH_*
18messages refer to protocol 1 keys only. SSH2_* messages refer to
19protocol 2 keys. Furthermore, the names also indicate whether the
20message is a request to the agent (*_AGENTC_*) or a reply from the
21agent (*_AGENT_*). Section 3 below contains the mapping of the
22protocol message names to their integer values.
23
241. Data types
25
26Because of support for legacy SSH protocol 1 keys, OpenSSH's agent
27protocol makes use of some data types not defined in RFC 4251.
28
291.1 uint16
30
31The "uint16" data type is a simple MSB-first 16 bit unsigned integer
32encoded in two bytes.
33
341.2 mpint1
35
36The "mpint1" type represents an arbitrary precision integer (bignum).
37Its format is as follows:
38
39 uint16 bits
40 byte[(bits + 7) / 8] bignum
41
42"bignum" contains an unsigned arbitrary precision integer encoded as
43eight bits per byte in big-endian (MSB first) format.
44
45Note the difference between the "mpint1" encoding and the "mpint"
46encoding defined in RFC 4251. Also note that the length of the encoded
47integer is specified in bits, not bytes and that the byte length of
48the integer must be calculated by rounding up the number of bits to the
49nearest eight.
50
512. Protocol Messages
52
53All protocol messages are prefixed with their length in bytes, encoded
54as a 32 bit unsigned integer. Specifically:
55
56 uint32 message_length
57 byte[message_length] message
58
59The following message descriptions refer only to the content the
60"message" field.
61
622.1 Generic server responses
63
64The following generic messages may be sent by the server in response to
65requests from the client. On success the agent may reply either with:
66
67 byte SSH_AGENT_SUCCESS
68
69or a request-specific success message.
70
71On failure, the agent may reply with:
72
73 byte SSH_AGENT_FAILURE
74
75SSH_AGENT_FAILURE messages are also sent in reply to unknown request
76types.
77
782.2 Adding keys to the agent
79
80Keys are added to the agent using the SSH_AGENTC_ADD_RSA_IDENTITY and
81SSH2_AGENTC_ADD_IDENTITY requests for protocol 1 and protocol 2 keys
82respectively.
83
84Two variants of these requests are SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
85and SSH2_AGENTC_ADD_ID_CONSTRAINED - these add keys with optional
86"constraints" on their usage.
87
88OpenSSH may be built with support for keys hosted on a smartcard
89or other hardware security module. These keys may be added
90to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and
91SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests.
92
932.2.1 Key constraints
94
95The OpenSSH agent supports some basic optional constraints on key usage.
96At present there are two constraints defined.
97
98The first constraint limits the validity duration of a key. It is
99encoded as:
100
101 byte SSH_AGENT_CONSTRAIN_LIFETIME
102 uint32 seconds
103
104Where "seconds" contains the number of seconds that the key shall remain
105valid measured from the moment that the agent receives it. After the
106validity period has expired, OpenSSH's agent will erase these keys from
107memory.
108
109The second constraint requires the agent to seek explicit user
110confirmation before performing private key operations with the loaded
111key. This constraint is encoded as:
112
113 byte SSH_AGENT_CONSTRAIN_CONFIRM
114
115Zero or more constraints may be specified when adding a key with one
116of the *_CONSTRAINED requests. Multiple constraints are appended
117consecutively to the end of the request:
118
119 byte constraint1_type
120 .... constraint1_data
121 byte constraint2_type
122 .... constraint2_data
123 ....
124 byte constraintN_type
125 .... constraintN_data
126
127Such a sequence of zero or more constraints will be referred to below
128as "constraint[]". Agents may determine whether there are constraints
129by checking whether additional data exists in the "add key" request
130after the key data itself. OpenSSH will refuse to add a key if it
131contains unknown constraints.
132
1332.2.2 Add protocol 1 key
134
135A client may add a protocol 1 key to an agent with the following
136request:
137
138 byte SSH_AGENTC_ADD_RSA_IDENTITY or
139 SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
140 uint32 ignored
141 mpint1 rsa_n
142 mpint1 rsa_e
143 mpint1 rsa_d
144 mpint1 rsa_iqmp
145 mpint1 rsa_q
146 mpint1 rsa_p
147 string key_comment
148 constraint[] key_constraints
149
150Note that there is some redundancy in the key parameters; a key could be
151fully specified using just rsa_q, rsa_p and rsa_e at the cost of extra
152computation.
153
154"key_constraints" may only be present if the request type is
155SSH_AGENTC_ADD_RSA_ID_CONSTRAINED.
156
157The agent will reply with a SSH_AGENT_SUCCESS if the key has been
158successfully added or a SSH_AGENT_FAILURE if an error occurred.
159
1602.2.3 Add protocol 2 key
161
162The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA
163keys may be added using the following request
164
165 byte SSH2_AGENTC_ADD_IDENTITY or
166 SSH2_AGENTC_ADD_ID_CONSTRAINED
167 string "ssh-dss"
168 mpint dsa_p
169 mpint dsa_q
170 mpint dsa_g
171 mpint dsa_public_key
172 mpint dsa_private_key
173 string key_comment
174 constraint[] key_constraints
175
176DSA certificates may be added with:
177 byte SSH2_AGENTC_ADD_IDENTITY or
178 SSH2_AGENTC_ADD_ID_CONSTRAINED
179 string "ssh-dss-cert-v00@openssh.com"
180 string certificate
181 mpint dsa_private_key
182 string key_comment
183 constraint[] key_constraints
184
185ECDSA keys may be added using the following request
186
187 byte SSH2_AGENTC_ADD_IDENTITY or
188 SSH2_AGENTC_ADD_ID_CONSTRAINED
189 string "ecdsa-sha2-nistp256" |
190 "ecdsa-sha2-nistp384" |
191 "ecdsa-sha2-nistp521"
192 string ecdsa_curve_name
193 string ecdsa_public_key
194 mpint ecdsa_private
195 string key_comment
196 constraint[] key_constraints
197
198ECDSA certificates may be added with:
199 byte SSH2_AGENTC_ADD_IDENTITY or
200 SSH2_AGENTC_ADD_ID_CONSTRAINED
201 string "ecdsa-sha2-nistp256-cert-v01@openssh.com" |
202 "ecdsa-sha2-nistp384-cert-v01@openssh.com" |
203 "ecdsa-sha2-nistp521-cert-v01@openssh.com"
204 string certificate
205 mpint ecdsa_private_key
206 string key_comment
207 constraint[] key_constraints
208
209ED25519 keys may be added using the following request
210 byte SSH2_AGENTC_ADD_IDENTITY or
211 SSH2_AGENTC_ADD_ID_CONSTRAINED
212 string "ssh-ed25519"
213 string ed25519_public_key
214 string ed25519_private_key || ed25519_public_key
215 string key_comment
216 constraint[] key_constraints
217
218ED25519 certificates may be added with:
219 byte SSH2_AGENTC_ADD_IDENTITY or
220 SSH2_AGENTC_ADD_ID_CONSTRAINED
221 string "ssh-ed25519-cert-v01@openssh.com"
222 string certificate
223 string ed25519_public_key
224 string ed25519_private_key || ed25519_public_key
225 string key_comment
226 constraint[] key_constraints
227
228For both ssh-ed25519 and ssh-ed25519-cert-v01@openssh.com keys, the private
229key has the public key appended (for historical reasons).
230
231RSA keys may be added with this request:
232
233 byte SSH2_AGENTC_ADD_IDENTITY or
234 SSH2_AGENTC_ADD_ID_CONSTRAINED
235 string "ssh-rsa"
236 mpint rsa_n
237 mpint rsa_e
238 mpint rsa_d
239 mpint rsa_iqmp
240 mpint rsa_p
241 mpint rsa_q
242 string key_comment
243 constraint[] key_constraints
244
245RSA certificates may be added with this request:
246
247 byte SSH2_AGENTC_ADD_IDENTITY or
248 SSH2_AGENTC_ADD_ID_CONSTRAINED
249 string "ssh-rsa-cert-v00@openssh.com"
250 string certificate
251 mpint rsa_d
252 mpint rsa_iqmp
253 mpint rsa_p
254 mpint rsa_q
255 string key_comment
256 constraint[] key_constraints
257
258Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse
259order to the protocol 1 add keys message. As with the corresponding
260protocol 1 "add key" request, the private key is overspecified to avoid
261redundant processing.
262
263For DSA, ECDSA and RSA key add requests, "key_constraints" may only be
264present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED.
265
266The agent will reply with a SSH_AGENT_SUCCESS if the key has been
267successfully added or a SSH_AGENT_FAILURE if an error occurred.
268
2692.2.4 Loading keys from a smartcard
270
271The OpenSSH agent may have optional smartcard support built in to it. If
272so, it supports an operation to load keys from a smartcard. Technically,
273only the public components of the keys are loaded into the agent so
274this operation really arranges for future private key operations to be
275delegated to the smartcard.
276
277 byte SSH_AGENTC_ADD_SMARTCARD_KEY or
278 SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
279 string reader_id
280 string pin
281 constraint[] key_constraints
282
283"reader_id" is an identifier to a smartcard reader and "pin"
284is a PIN or passphrase used to unlock the private key(s) on the
285device. "key_constraints" may only be present if the request type is
286SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED.
287
288This operation may load all SSH keys that are unlocked using the
289"pin" on the specified reader. The type of key loaded (protocol 1
290or protocol 2) will be specified by the smartcard itself, it is not
291client-specified.
292
293The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
294been successfully loaded or a SSH_AGENT_FAILURE if an error occurred.
295The agent will also return SSH_AGENT_FAILURE if it does not support
296smartcards.
297
2982.3 Removing multiple keys
299
300A client may request that an agent delete all protocol 1 keys using the
301following request:
302
303 byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES
304
305This message requests the deletion of all protocol 2 keys:
306
307 byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES
308
309On success, the agent will delete all keys of the requested type and
310reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent
311will reply with SSH_AGENT_FAILURE.
312
313Note that, to delete all keys (both protocol 1 and 2), a client
314must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a
315SSH2_AGENTC_REMOVE_ALL_IDENTITIES request.
316
3172.4 Removing specific keys
318
3192.4.1 Removing a protocol 1 key
320
321Removal of a protocol 1 key may be requested with the following message:
322
323 byte SSH_AGENTC_REMOVE_RSA_IDENTITY
324 uint32 key_bits
325 mpint1 rsa_e
326 mpint1 rsa_n
327
328Note that key_bits is strictly redundant, as it may be inferred by the
329length of rsa_n.
330
331The agent will delete any private key matching the specified public key
332and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
333return SSH_AGENT_FAILURE.
334
3352.4.2 Removing a protocol 2 key
336
337Protocol 2 keys may be removed with the following request:
338
339 byte SSH2_AGENTC_REMOVE_IDENTITY
340 string key_blob
341
342Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
343Algorithms" for any of the supported protocol 2 key types.
344
345The agent will delete any private key matching the specified public key
346and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
347return SSH_AGENT_FAILURE.
348
3492.4.3 Removing keys loaded from a smartcard
350
351A client may request that a server remove one or more smartcard-hosted
352keys using this message:
353
354 byte SSH_AGENTC_REMOVE_SMARTCARD_KEY
355 string reader_id
356 string pin
357
358"reader_id" the an identifier to a smartcard reader and "pin" is a PIN
359or passphrase used to unlock the private key(s) on the device.
360
361When this message is received, and if the agent supports
362smartcard-hosted keys, it will delete all keys that are hosted on the
363specified smartcard that may be accessed with the given "pin".
364
365The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
366been successfully removed or a SSH_AGENT_FAILURE if an error occurred.
367The agent will also return SSH_AGENT_FAILURE if it does not support
368smartcards.
369
3702.5 Requesting a list of known keys
371
372An agent may be requested to list which keys it holds. Different
373requests exist for protocol 1 and protocol 2 keys.
374
3752.5.1 Requesting a list of protocol 1 keys
376
377To request a list of protocol 1 keys that are held in the agent, a
378client may send the following message:
379
380 byte SSH_AGENTC_REQUEST_RSA_IDENTITIES
381
382The agent will reply with the following message:
383
384 byte SSH_AGENT_RSA_IDENTITIES_ANSWER
385 uint32 num_keys
386
387Followed by zero or more consecutive keys, encoded as:
388
389 uint32 bits
390 mpint1 rsa_e
391 mpint1 rsa_n
392 string key_comment
393
3942.5.2 Requesting a list of protocol 2 keys
395
396A client may send the following message to request a list of
397protocol 2 keys that are stored in the agent:
398
399 byte SSH2_AGENTC_REQUEST_IDENTITIES
400
401The agent will reply with the following message header:
402
403 byte SSH2_AGENT_IDENTITIES_ANSWER
404 uint32 num_keys
405
406Followed by zero or more consecutive keys, encoded as:
407
408 string key_blob
409 string key_comment
410
411Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
412Algorithms" for any of the supported protocol 2 key types.
413
4142.6 Private key operations
415
416The purpose of the agent is to perform private key operations, such as
417signing and encryption without requiring a passphrase to unlock the
418key and without allowing the private key itself to be exposed. There
419are separate requests for the protocol 1 and protocol 2 private key
420operations.
421
4222.6.1 Protocol 1 private key challenge
423
424The private key operation used in version 1 of the SSH protocol is
425decrypting a challenge that has been encrypted with a public key.
426It may be requested using this message:
427
428 byte SSH_AGENTC_RSA_CHALLENGE
429 uint32 ignored
430 mpint1 rsa_e
431 mpint1 rsa_n
432 mpint1 encrypted_challenge
433 byte[16] session_id
434 uint32 response_type /* must be 1 */
435
436"rsa_e" and "rsa_n" are used to identify which private key to use.
437"encrypted_challenge" is a challenge blob that has (presumably)
438been encrypted with the public key and must be in the range
4391 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1
440session ID (computed from the server host key, the server semi-ephemeral
441key and the session cookie).
442
443"ignored" and "response_type" exist for compatibility with legacy
444implementations. "response_type" must be equal to 1; other response
445types are not supported.
446
447On receiving this request, the server decrypts the "encrypted_challenge"
448using the private key matching the supplied (rsa_e, rsa_n) values. For
449the response derivation, the decrypted challenge is represented as an
450unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values
451smaller than 2^248 will have leading 0 bytes).
452
453The response value is then calculated as:
454
455 response = MD5(decrypted_challenge || session_id)
456
457and returned in the following message
458
459 byte SSH_AGENT_RSA_RESPONSE
460 byte[16] response
461
462If the agent cannot find the key specified by the supplied (rsa_e,
463rsa_n) then it will return SSH_AGENT_FAILURE.
464
4652.6.2 Protocol 2 private key signature request
466
467A client may use the following message to request signing of data using
468a protocol 2 key:
469
470 byte SSH2_AGENTC_SIGN_REQUEST
471 string key_blob
472 string data
473 uint32 flags
474
475Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
476Algorithms" for any of the supported protocol 2 key types. "flags" is
477a bit-mask, but at present only one possible value is defined (see below
478for its meaning):
479
480 SSH_AGENT_OLD_SIGNATURE 1
481
482Upon receiving this request, the agent will look up the private key that
483corresponds to the public key contained in key_blob. It will use this
484private key to sign the "data" and produce a signature blob using the
485key type-specific method described in RFC 4253 section 6.6 "Public Key
486Algorithms".
487
488An exception to this is for "ssh-dss" keys where the "flags" word
489contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy
490signature encoding is used in lieu of the standard one. In this case,
491the DSA signature blob is encoded as:
492
493 byte[40] signature
494
495The signature will be returned in the response message:
496
497 byte SSH2_AGENT_SIGN_RESPONSE
498 string signature_blob
499
500If the agent cannot find the key specified by the supplied key_blob then
501it will return SSH_AGENT_FAILURE.
502
5032.7 Locking or unlocking an agent
504
505The agent supports temporary locking with a passphrase to suspend
506processing of sensitive operations until it has been unlocked with the
507same passphrase. To lock an agent, a client send the following request:
508
509 byte SSH_AGENTC_LOCK
510 string passphrase
511
512Upon receipt of this message and if the agent is not already locked,
513it will suspend processing requests and return a SSH_AGENT_SUCCESS
514reply. If the agent is already locked, it will return SSH_AGENT_FAILURE.
515
516While locked, the agent will refuse all requests except
517SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and
518SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are
519treated specially by a locked agent: it will always return an empty list
520of keys.
521
522To unlock an agent, a client may request:
523
524 byte SSH_AGENTC_UNLOCK
525 string passphrase
526
527If the passphrase matches and the agent is locked, then it will resume
528processing all requests and return SSH_AGENT_SUCCESS. If the agent
529is not locked or the passphrase does not match then it will return
530SSH_AGENT_FAILURE.
531
532Locking and unlocking affects both protocol 1 and protocol 2 keys.
533
5343. Protocol message numbers
535
5363.1 Requests from client to agent for protocol 1 key operations
537
538 SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
539 SSH_AGENTC_RSA_CHALLENGE 3
540 SSH_AGENTC_ADD_RSA_IDENTITY 7
541 SSH_AGENTC_REMOVE_RSA_IDENTITY 8
542 SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
543 SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
544
5453.2 Requests from client to agent for protocol 2 key operations
546
547 SSH2_AGENTC_REQUEST_IDENTITIES 11
548 SSH2_AGENTC_SIGN_REQUEST 13
549 SSH2_AGENTC_ADD_IDENTITY 17
550 SSH2_AGENTC_REMOVE_IDENTITY 18
551 SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
552 SSH2_AGENTC_ADD_ID_CONSTRAINED 25
553
5543.3 Key-type independent requests from client to agent
555
556 SSH_AGENTC_ADD_SMARTCARD_KEY 20
557 SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
558 SSH_AGENTC_LOCK 22
559 SSH_AGENTC_UNLOCK 23
560 SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
561
5623.4 Generic replies from agent to client
563
564 SSH_AGENT_FAILURE 5
565 SSH_AGENT_SUCCESS 6
566
5673.5 Replies from agent to client for protocol 1 key operations
568
569 SSH_AGENT_RSA_IDENTITIES_ANSWER 2
570 SSH_AGENT_RSA_RESPONSE 4
571
5723.6 Replies from agent to client for protocol 2 key operations
573
574 SSH2_AGENT_IDENTITIES_ANSWER 12
575 SSH2_AGENT_SIGN_RESPONSE 14
576
5773.7 Key constraint identifiers
578
579 SSH_AGENT_CONSTRAIN_LIFETIME 1
580 SSH_AGENT_CONSTRAIN_CONFIRM 2
581
582$OpenBSD: PROTOCOL.agent,v 1.11 2016/05/19 07:45:32 djm Exp $
diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys
index aa6f5ae4c..42aa8c2a1 100644
--- a/PROTOCOL.certkeys
+++ b/PROTOCOL.certkeys
@@ -192,12 +192,13 @@ compatibility.
192The reserved field is currently unused and is ignored in this version of 192The reserved field is currently unused and is ignored in this version of
193the protocol. 193the protocol.
194 194
195signature key contains the CA key used to sign the certificate. 195The signature key field contains the CA key used to sign the
196The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types 196certificate. The valid key types for CA keys are ssh-rsa,
197ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" 197ssh-dss, ssh-ed25519 and the ECDSA types ecdsa-sha2-nistp256,
198certificates, where the signature key type is a certificate type itself 198ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where
199are NOT supported. Note that it is possible for a RSA certificate key to 199the signature key type is a certificate type itself are NOT supported.
200be signed by a DSS or ECDSA CA key and vice-versa. 200Note that it is possible for a RSA certificate key to be signed by a
201Ed25519 or ECDSA CA key and vice-versa.
201 202
202signature is computed over all preceding fields from the initial string 203signature is computed over all preceding fields from the initial string
203up to, and including the signature key. Signatures are computed and 204up to, and including the signature key. Signatures are computed and
@@ -223,6 +224,9 @@ option-specific information (see below). All options are
223"critical", if an implementation does not recognise a option 224"critical", if an implementation does not recognise a option
224then the validating party should refuse to accept the certificate. 225then the validating party should refuse to accept the certificate.
225 226
227Custom options should append the originating author or organisation's
228domain name to the option name, e.g. "my-option@example.com".
229
226No critical options are defined for host certificates at present. The 230No critical options are defined for host certificates at present. The
227supported user certificate options and the contents and structure of 231supported user certificate options and the contents and structure of
228their data fields are: 232their data fields are:
@@ -254,6 +258,9 @@ as is the requirement that each name appear only once.
254If an implementation does not recognise an extension, then it should 258If an implementation does not recognise an extension, then it should
255ignore it. 259ignore it.
256 260
261Custom options should append the originating author or organisation's
262domain name to the option name, e.g. "my-option@example.com".
263
257No extensions are defined for host certificates at present. The 264No extensions are defined for host certificates at present. The
258supported user certificate extensions and the contents and structure of 265supported user certificate extensions and the contents and structure of
259their data fields are: 266their data fields are:
@@ -284,4 +291,4 @@ permit-user-rc empty Flag indicating that execution of
284 of this script will not be permitted if 291 of this script will not be permitted if
285 this option is not present. 292 this option is not present.
286 293
287$OpenBSD: PROTOCOL.certkeys,v 1.10 2016/05/03 10:27:59 djm Exp $ 294$OpenBSD: PROTOCOL.certkeys,v 1.12 2017/05/31 04:29:44 djm Exp $
diff --git a/README b/README
index bda852548..103d43e9b 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
1See https://www.openssh.com/releasenotes.html#7.5p1 for the release notes. 1See https://www.openssh.com/releasenotes.html#7.6p1 for the release notes.
2 2
3Please read https://www.openssh.com/report.html for bug reporting 3Please read https://www.openssh.com/report.html for bug reporting
4instructions and note that we do not use Github for bug reporting or 4instructions and note that we do not use Github for bug reporting or
@@ -30,7 +30,8 @@ The PAM support is now more functional than the popular packages of
30commercial ssh-1.2.x. It checks "account" and "session" modules for 30commercial ssh-1.2.x. It checks "account" and "session" modules for
31all logins, not just when using password authentication. 31all logins, not just when using password authentication.
32 32
33OpenSSH depends on Zlib[3], OpenSSL[4] and optionally PAM[5]. 33OpenSSH depends on Zlib[3], OpenSSL[4], and optionally PAM[5] and
34libedit[6]
34 35
35There is now several mailing lists for this port of OpenSSH. Please 36There is now several mailing lists for this port of OpenSSH. Please
36refer to https://www.openssh.com/list.html for details on how to join. 37refer to https://www.openssh.com/list.html for details on how to join.
@@ -38,7 +39,7 @@ refer to https://www.openssh.com/list.html for details on how to join.
38Please send bug reports and patches to the mailing list 39Please send bug reports and patches to the mailing list
39openssh-unix-dev@mindrot.org. The list is open to posting by unsubscribed 40openssh-unix-dev@mindrot.org. The list is open to posting by unsubscribed
40users. Code contribution are welcomed, but please follow the OpenBSD 41users. Code contribution are welcomed, but please follow the OpenBSD
41style guidelines[6]. 42style guidelines[7].
42 43
43Please refer to the INSTALL document for information on how to install 44Please refer to the INSTALL document for information on how to install
44OpenSSH on your system. 45OpenSSH on your system.
@@ -61,4 +62,5 @@ References -
61[5] http://www.openpam.org 62[5] http://www.openpam.org
62 http://www.kernel.org/pub/linux/libs/pam/ 63 http://www.kernel.org/pub/linux/libs/pam/
63 (PAM also is standard on Solaris and HP-UX 11) 64 (PAM also is standard on Solaris and HP-UX 11)
64[6] http://man.openbsd.org/style.9 65[6] http://thrysoee.dk/editline/ (portable version)
66[7] http://man.openbsd.org/style.9
diff --git a/auth-options.c b/auth-options.c
index 57b49f7fd..bed00eef0 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.c,v 1.72 2016/11/30 02:57:40 djm Exp $ */ 1/* $OpenBSD: auth-options.c,v 1.74 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -61,9 +61,13 @@ char *authorized_principals = NULL;
61 61
62extern ServerOptions options; 62extern ServerOptions options;
63 63
64/* XXX refactor to be stateless */
65
64void 66void
65auth_clear_options(void) 67auth_clear_options(void)
66{ 68{
69 struct ssh *ssh = active_state; /* XXX */
70
67 no_agent_forwarding_flag = 0; 71 no_agent_forwarding_flag = 0;
68 no_port_forwarding_flag = 0; 72 no_port_forwarding_flag = 0;
69 no_pty_flag = 0; 73 no_pty_flag = 0;
@@ -81,7 +85,7 @@ auth_clear_options(void)
81 free(authorized_principals); 85 free(authorized_principals);
82 authorized_principals = NULL; 86 authorized_principals = NULL;
83 forced_tun_device = -1; 87 forced_tun_device = -1;
84 channel_clear_permitted_opens(); 88 channel_clear_permitted_opens(ssh);
85} 89}
86 90
87/* 91/*
@@ -117,9 +121,11 @@ match_flag(const char *opt, int allow_negate, char **optsp, const char *msg)
117/* 121/*
118 * return 1 if access is granted, 0 if not. 122 * return 1 if access is granted, 0 if not.
119 * side effect: sets key option flags 123 * side effect: sets key option flags
124 * XXX remove side effects; fill structure instead.
120 */ 125 */
121int 126int
122auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) 127auth_parse_options(struct passwd *pw, char *opts, const char *file,
128 u_long linenum)
123{ 129{
124 struct ssh *ssh = active_state; /* XXX */ 130 struct ssh *ssh = active_state; /* XXX */
125 const char *cp; 131 const char *cp;
@@ -379,7 +385,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
379 goto bad_option; 385 goto bad_option;
380 } 386 }
381 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) 387 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0)
382 channel_add_permitted_opens(host, port); 388 channel_add_permitted_opens(ssh, host, port);
383 free(patterns); 389 free(patterns);
384 goto next_option; 390 goto next_option;
385 } 391 }
diff --git a/auth-options.h b/auth-options.h
index 52cbb42aa..547f01635 100644
--- a/auth-options.h
+++ b/auth-options.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.h,v 1.22 2016/11/30 02:57:40 djm Exp $ */ 1/* $OpenBSD: auth-options.h,v 1.23 2017/05/31 10:54:00 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -33,7 +33,7 @@ extern int forced_tun_device;
33extern int key_is_cert_authority; 33extern int key_is_cert_authority;
34extern char *authorized_principals; 34extern char *authorized_principals;
35 35
36int auth_parse_options(struct passwd *, char *, char *, u_long); 36int auth_parse_options(struct passwd *, char *, const char *, u_long);
37void auth_clear_options(void); 37void auth_clear_options(void);
38int auth_cert_options(struct sshkey *, struct passwd *, const char **); 38int auth_cert_options(struct sshkey *, struct passwd *, const char **);
39 39
diff --git a/auth-pam.c b/auth-pam.c
index bc8e5e02d..de29c04c9 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -106,7 +106,6 @@ extern char *__progname;
106 106
107extern ServerOptions options; 107extern ServerOptions options;
108extern Buffer loginmsg; 108extern Buffer loginmsg;
109extern int compat20;
110extern u_int utmp_len; 109extern u_int utmp_len;
111 110
112/* so we don't silently change behaviour */ 111/* so we don't silently change behaviour */
@@ -468,18 +467,16 @@ sshpam_thread(void *ctxtp)
468 if (sshpam_err != PAM_SUCCESS) 467 if (sshpam_err != PAM_SUCCESS)
469 goto auth_fail; 468 goto auth_fail;
470 469
471 if (compat20) { 470 if (!do_pam_account()) {
472 if (!do_pam_account()) { 471 sshpam_err = PAM_ACCT_EXPIRED;
473 sshpam_err = PAM_ACCT_EXPIRED; 472 goto auth_fail;
473 }
474 if (sshpam_authctxt->force_pwchange) {
475 sshpam_err = pam_chauthtok(sshpam_handle,
476 PAM_CHANGE_EXPIRED_AUTHTOK);
477 if (sshpam_err != PAM_SUCCESS)
474 goto auth_fail; 478 goto auth_fail;
475 } 479 sshpam_password_change_required(0);
476 if (sshpam_authctxt->force_pwchange) {
477 sshpam_err = pam_chauthtok(sshpam_handle,
478 PAM_CHANGE_EXPIRED_AUTHTOK);
479 if (sshpam_err != PAM_SUCCESS)
480 goto auth_fail;
481 sshpam_password_change_required(0);
482 }
483 } 480 }
484 481
485 buffer_put_cstring(&buffer, "OK"); 482 buffer_put_cstring(&buffer, "OK");
@@ -929,6 +926,27 @@ finish_pam(void)
929 sshpam_cleanup(); 926 sshpam_cleanup();
930} 927}
931 928
929static void
930expose_authinfo(const char *caller)
931{
932 char *auth_info;
933
934 /*
935 * Expose authentication information to PAM.
936 * The enviornment variable is versioned. Please increment the
937 * version suffix if the format of session_info changes.
938 */
939 if (sshpam_authctxt->session_info == NULL)
940 auth_info = xstrdup("");
941 else if ((auth_info = sshbuf_dup_string(
942 sshpam_authctxt->session_info)) == NULL)
943 fatal("%s: sshbuf_dup_string failed", __func__);
944
945 debug2("%s: auth information in SSH_AUTH_INFO_0", caller);
946 do_pam_putenv("SSH_AUTH_INFO_0", auth_info);
947 free(auth_info);
948}
949
932u_int 950u_int
933do_pam_account(void) 951do_pam_account(void)
934{ 952{
@@ -936,6 +954,8 @@ do_pam_account(void)
936 if (sshpam_account_status != -1) 954 if (sshpam_account_status != -1)
937 return (sshpam_account_status); 955 return (sshpam_account_status);
938 956
957 expose_authinfo(__func__);
958
939 sshpam_err = pam_acct_mgmt(sshpam_handle, 0); 959 sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
940 debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, 960 debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
941 pam_strerror(sshpam_handle, sshpam_err)); 961 pam_strerror(sshpam_handle, sshpam_err));
@@ -1060,6 +1080,9 @@ void
1060do_pam_session(void) 1080do_pam_session(void)
1061{ 1081{
1062 debug3("PAM: opening session"); 1082 debug3("PAM: opening session");
1083
1084 expose_authinfo(__func__);
1085
1063 sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, 1086 sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
1064 (const void *)&store_conv); 1087 (const void *)&store_conv);
1065 if (sshpam_err != PAM_SUCCESS) 1088 if (sshpam_err != PAM_SUCCESS)
diff --git a/auth.c b/auth.c
index 6ee6116df..a44906174 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.c,v 1.119 2016/12/15 21:29:05 dtucker Exp $ */ 1/* $OpenBSD: auth.c,v 1.124 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -43,9 +43,6 @@
43#ifdef USE_SHADOW 43#ifdef USE_SHADOW
44#include <shadow.h> 44#include <shadow.h>
45#endif 45#endif
46#ifdef HAVE_LIBGEN_H
47#include <libgen.h>
48#endif
49#include <stdarg.h> 46#include <stdarg.h>
50#include <stdio.h> 47#include <stdio.h>
51#include <string.h> 48#include <string.h>
@@ -267,21 +264,41 @@ allowed_user(struct passwd * pw)
267 return 1; 264 return 1;
268} 265}
269 266
270void 267/*
271auth_info(Authctxt *authctxt, const char *fmt, ...) 268 * Formats any key left in authctxt->auth_method_key for inclusion in
269 * auth_log()'s message. Also includes authxtct->auth_method_info if present.
270 */
271static char *
272format_method_key(Authctxt *authctxt)
272{ 273{
273 va_list ap; 274 const struct sshkey *key = authctxt->auth_method_key;
274 int i; 275 const char *methinfo = authctxt->auth_method_info;
275 276 char *fp, *ret = NULL;
276 free(authctxt->info);
277 authctxt->info = NULL;
278 277
279 va_start(ap, fmt); 278 if (key == NULL)
280 i = vasprintf(&authctxt->info, fmt, ap); 279 return NULL;
281 va_end(ap);
282 280
283 if (i < 0 || authctxt->info == NULL) 281 if (key_is_cert(key)) {
284 fatal("vasprintf failed"); 282 fp = sshkey_fingerprint(key->cert->signature_key,
283 options.fingerprint_hash, SSH_FP_DEFAULT);
284 xasprintf(&ret, "%s ID %s (serial %llu) CA %s %s%s%s",
285 sshkey_type(key), key->cert->key_id,
286 (unsigned long long)key->cert->serial,
287 sshkey_type(key->cert->signature_key),
288 fp == NULL ? "(null)" : fp,
289 methinfo == NULL ? "" : ", ",
290 methinfo == NULL ? "" : methinfo);
291 free(fp);
292 } else {
293 fp = sshkey_fingerprint(key, options.fingerprint_hash,
294 SSH_FP_DEFAULT);
295 xasprintf(&ret, "%s %s%s%s", sshkey_type(key),
296 fp == NULL ? "(null)" : fp,
297 methinfo == NULL ? "" : ", ",
298 methinfo == NULL ? "" : methinfo);
299 free(fp);
300 }
301 return ret;
285} 302}
286 303
287void 304void
@@ -290,7 +307,8 @@ auth_log(Authctxt *authctxt, int authenticated, int partial,
290{ 307{
291 struct ssh *ssh = active_state; /* XXX */ 308 struct ssh *ssh = active_state; /* XXX */
292 void (*authlog) (const char *fmt,...) = verbose; 309 void (*authlog) (const char *fmt,...) = verbose;
293 char *authmsg; 310 const char *authmsg;
311 char *extra = NULL;
294 312
295 if (use_privsep && !mm_is_monitor() && !authctxt->postponed) 313 if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
296 return; 314 return;
@@ -309,6 +327,11 @@ auth_log(Authctxt *authctxt, int authenticated, int partial,
309 else 327 else
310 authmsg = authenticated ? "Accepted" : "Failed"; 328 authmsg = authenticated ? "Accepted" : "Failed";
311 329
330 if ((extra = format_method_key(authctxt)) == NULL) {
331 if (authctxt->auth_method_info != NULL)
332 extra = xstrdup(authctxt->auth_method_info);
333 }
334
312 authlog("%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s", 335 authlog("%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s",
313 authmsg, 336 authmsg,
314 method, 337 method,
@@ -317,10 +340,10 @@ auth_log(Authctxt *authctxt, int authenticated, int partial,
317 authctxt->user, 340 authctxt->user,
318 ssh_remote_ipaddr(ssh), 341 ssh_remote_ipaddr(ssh),
319 ssh_remote_port(ssh), 342 ssh_remote_port(ssh),
320 authctxt->info != NULL ? ": " : "", 343 extra != NULL ? ": " : "",
321 authctxt->info != NULL ? authctxt->info : ""); 344 extra != NULL ? extra : "");
322 free(authctxt->info); 345
323 authctxt->info = NULL; 346 free(extra);
324 347
325#ifdef CUSTOM_FAILED_LOGIN 348#ifdef CUSTOM_FAILED_LOGIN
326 if (authenticated == 0 && !authctxt->postponed && 349 if (authenticated == 0 && !authctxt->postponed &&
@@ -428,7 +451,7 @@ authorized_principals_file(struct passwd *pw)
428 451
429/* return ok if key exists in sysfile or userfile */ 452/* return ok if key exists in sysfile or userfile */
430HostStatus 453HostStatus
431check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, 454check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
432 const char *sysfile, const char *userfile) 455 const char *sysfile, const char *userfile)
433{ 456{
434 char *user_hostfile; 457 char *user_hostfile;
@@ -472,98 +495,6 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
472 return host_status; 495 return host_status;
473} 496}
474 497
475/*
476 * Check a given path for security. This is defined as all components
477 * of the path to the file must be owned by either the owner of
478 * of the file or root and no directories must be group or world writable.
479 *
480 * XXX Should any specific check be done for sym links ?
481 *
482 * Takes a file name, its stat information (preferably from fstat() to
483 * avoid races), the uid of the expected owner, their home directory and an
484 * error buffer plus max size as arguments.
485 *
486 * Returns 0 on success and -1 on failure
487 */
488int
489auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
490 uid_t uid, char *err, size_t errlen)
491{
492 char buf[PATH_MAX], homedir[PATH_MAX];
493 char *cp;
494 int comparehome = 0;
495 struct stat st;
496
497 if (realpath(name, buf) == NULL) {
498 snprintf(err, errlen, "realpath %s failed: %s", name,
499 strerror(errno));
500 return -1;
501 }
502 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
503 comparehome = 1;
504
505 if (!S_ISREG(stp->st_mode)) {
506 snprintf(err, errlen, "%s is not a regular file", buf);
507 return -1;
508 }
509 if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
510 (stp->st_mode & 022) != 0) {
511 snprintf(err, errlen, "bad ownership or modes for file %s",
512 buf);
513 return -1;
514 }
515
516 /* for each component of the canonical path, walking upwards */
517 for (;;) {
518 if ((cp = dirname(buf)) == NULL) {
519 snprintf(err, errlen, "dirname() failed");
520 return -1;
521 }
522 strlcpy(buf, cp, sizeof(buf));
523
524 if (stat(buf, &st) < 0 ||
525 (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
526 (st.st_mode & 022) != 0) {
527 snprintf(err, errlen,
528 "bad ownership or modes for directory %s", buf);
529 return -1;
530 }
531
532 /* If are past the homedir then we can stop */
533 if (comparehome && strcmp(homedir, buf) == 0)
534 break;
535
536 /*
537 * dirname should always complete with a "/" path,
538 * but we can be paranoid and check for "." too
539 */
540 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
541 break;
542 }
543 return 0;
544}
545
546/*
547 * Version of secure_path() that accepts an open file descriptor to
548 * avoid races.
549 *
550 * Returns 0 on success and -1 on failure
551 */
552static int
553secure_filename(FILE *f, const char *file, struct passwd *pw,
554 char *err, size_t errlen)
555{
556 struct stat st;
557
558 /* check the open file to avoid races */
559 if (fstat(fileno(f), &st) < 0) {
560 snprintf(err, errlen, "cannot stat file %s: %s",
561 file, strerror(errno));
562 return -1;
563 }
564 return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
565}
566
567static FILE * 498static FILE *
568auth_openfile(const char *file, struct passwd *pw, int strict_modes, 499auth_openfile(const char *file, struct passwd *pw, int strict_modes,
569 int log_missing, char *file_type) 500 int log_missing, char *file_type)
@@ -596,7 +527,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
596 return NULL; 527 return NULL;
597 } 528 }
598 if (strict_modes && 529 if (strict_modes &&
599 secure_filename(f, file, pw, line, sizeof(line)) != 0) { 530 safe_path_fd(fileno(f), file, pw, line, sizeof(line)) != 0) {
600 fclose(f); 531 fclose(f);
601 logit("Authentication refused: %s", line); 532 logit("Authentication refused: %s", line);
602 auth_debug_add("Ignored %s: %s", file_type, line); 533 auth_debug_add("Ignored %s: %s", file_type, line);
@@ -635,6 +566,8 @@ getpwnamallow(const char *user)
635 566
636 ci->user = user; 567 ci->user = user;
637 parse_server_match_config(&options, ci); 568 parse_server_match_config(&options, ci);
569 log_change_level(options.log_level);
570 process_permitopen(ssh, &options);
638 571
639#if defined(_AIX) && defined(HAVE_SETAUTHDB) 572#if defined(_AIX) && defined(HAVE_SETAUTHDB)
640 aix_setauthdb(user); 573 aix_setauthdb(user);
@@ -694,7 +627,7 @@ getpwnamallow(const char *user)
694 627
695/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ 628/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */
696int 629int
697auth_key_is_revoked(Key *key) 630auth_key_is_revoked(struct sshkey *key)
698{ 631{
699 char *fp = NULL; 632 char *fp = NULL;
700 int r; 633 int r;
diff --git a/auth.h b/auth.h
index 338a62da7..29835ae92 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.h,v 1.89 2016/08/13 17:47:41 markus Exp $ */ 1/* $OpenBSD: auth.h,v 1.93 2017/08/18 05:36:45 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -44,6 +44,7 @@
44 44
45struct ssh; 45struct ssh;
46struct sshkey; 46struct sshkey;
47struct sshbuf;
47 48
48typedef struct Authctxt Authctxt; 49typedef struct Authctxt Authctxt;
49typedef struct Authmethod Authmethod; 50typedef struct Authmethod Authmethod;
@@ -62,13 +63,17 @@ struct Authctxt {
62 char *service; 63 char *service;
63 struct passwd *pw; /* set if 'valid' */ 64 struct passwd *pw; /* set if 'valid' */
64 char *style; 65 char *style;
66
67 /* Method lists for multiple authentication */
68 char **auth_methods; /* modified from server config */
69 u_int num_auth_methods;
70
71 /* Authentication method-specific data */
72 void *methoddata;
65 void *kbdintctxt; 73 void *kbdintctxt;
66 char *info; /* Extra info for next auth_log */
67#ifdef BSD_AUTH 74#ifdef BSD_AUTH
68 auth_session_t *as; 75 auth_session_t *as;
69#endif 76#endif
70 char **auth_methods; /* modified from server config */
71 u_int num_auth_methods;
72#ifdef KRB5 77#ifdef KRB5
73 krb5_context krb5_ctx; 78 krb5_context krb5_ctx;
74 krb5_ccache krb5_fwd_ccache; 79 krb5_ccache krb5_fwd_ccache;
@@ -76,12 +81,20 @@ struct Authctxt {
76 char *krb5_ticket_file; 81 char *krb5_ticket_file;
77 char *krb5_ccname; 82 char *krb5_ccname;
78#endif 83#endif
79 Buffer *loginmsg; 84 struct sshbuf *loginmsg;
80 void *methoddata; 85
86 /* Authentication keys already used; these will be refused henceforth */
87 struct sshkey **prev_keys;
88 u_int nprev_keys;
81 89
82 struct sshkey **prev_userkeys; 90 /* Last used key and ancilliary information from active auth method */
83 u_int nprev_userkeys; 91 struct sshkey *auth_method_key;
92 char *auth_method_info;
93
94 /* Information exposed to session */
95 struct sshbuf *session_info; /* Auth info for environment */
84}; 96};
97
85/* 98/*
86 * Every authentication method has to handle authentication requests for 99 * Every authentication method has to handle authentication requests for
87 * non-existing users, or for users that are not allowed to login. In this 100 * non-existing users, or for users that are not allowed to login. In this
@@ -91,7 +104,7 @@ struct Authctxt {
91 104
92struct Authmethod { 105struct Authmethod {
93 char *name; 106 char *name;
94 int (*userauth)(Authctxt *authctxt); 107 int (*userauth)(struct ssh *);
95 int *enabled; 108 int *enabled;
96}; 109};
97 110
@@ -117,16 +130,21 @@ auth_rhosts2(struct passwd *, const char *, const char *, const char *);
117 130
118int auth_password(Authctxt *, const char *); 131int auth_password(Authctxt *, const char *);
119 132
120int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); 133int hostbased_key_allowed(struct passwd *, const char *, char *,
121int user_key_allowed(struct passwd *, Key *, int); 134 struct sshkey *);
122void pubkey_auth_info(Authctxt *, const Key *, const char *, ...) 135int user_key_allowed(struct passwd *, struct sshkey *, int);
123 __attribute__((__format__ (printf, 3, 4))); 136int auth2_key_already_used(Authctxt *, const struct sshkey *);
124void auth2_record_userkey(Authctxt *, struct sshkey *);
125int auth2_userkey_already_used(Authctxt *, struct sshkey *);
126 137
127struct stat; 138/*
128int auth_secure_path(const char *, struct stat *, const char *, uid_t, 139 * Handling auth method-specific information for logging and prevention
129 char *, size_t); 140 * of key reuse during multiple authentication.
141 */
142void auth2_authctxt_reset_info(Authctxt *);
143void auth2_record_key(Authctxt *, int, const struct sshkey *);
144void auth2_record_info(Authctxt *authctxt, const char *, ...)
145 __attribute__((__format__ (printf, 2, 3)))
146 __attribute__((__nonnull__ (2)));
147void auth2_update_session_info(Authctxt *, const char *, const char *);
130 148
131#ifdef KRB5 149#ifdef KRB5
132int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); 150int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
@@ -149,12 +167,9 @@ void disable_forwarding(void);
149 167
150void do_authentication2(Authctxt *); 168void do_authentication2(Authctxt *);
151 169
152void auth_info(Authctxt *authctxt, const char *, ...)
153 __attribute__((__format__ (printf, 2, 3)))
154 __attribute__((__nonnull__ (2)));
155void auth_log(Authctxt *, int, int, const char *, const char *); 170void auth_log(Authctxt *, int, int, const char *, const char *);
156void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn)); 171void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn));
157void userauth_finish(Authctxt *, int, const char *, const char *); 172void userauth_finish(struct ssh *, int, const char *, const char *);
158int auth_root_allowed(const char *); 173int auth_root_allowed(const char *);
159 174
160void userauth_send_banner(const char *); 175void userauth_send_banner(const char *);
@@ -167,8 +182,8 @@ int auth2_method_allowed(Authctxt *, const char *, const char *);
167 182
168void privsep_challenge_enable(void); 183void privsep_challenge_enable(void);
169 184
170int auth2_challenge(Authctxt *, char *); 185int auth2_challenge(struct ssh *, char *);
171void auth2_challenge_stop(Authctxt *); 186void auth2_challenge_stop(struct ssh *);
172int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); 187int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
173int bsdauth_respond(void *, u_int, char **); 188int bsdauth_respond(void *, u_int, char **);
174int skey_query(void *, char **, char **, u_int *, char ***, u_int **); 189int skey_query(void *, char **, char **, u_int *, char ***, u_int **);
@@ -182,22 +197,22 @@ char *authorized_principals_file(struct passwd *);
182 197
183FILE *auth_openkeyfile(const char *, struct passwd *, int); 198FILE *auth_openkeyfile(const char *, struct passwd *, int);
184FILE *auth_openprincipals(const char *, struct passwd *, int); 199FILE *auth_openprincipals(const char *, struct passwd *, int);
185int auth_key_is_revoked(Key *); 200int auth_key_is_revoked(struct sshkey *);
186 201
187const char *auth_get_canonical_hostname(struct ssh *, int); 202const char *auth_get_canonical_hostname(struct ssh *, int);
188 203
189HostStatus 204HostStatus
190check_key_in_hostfiles(struct passwd *, Key *, const char *, 205check_key_in_hostfiles(struct passwd *, struct sshkey *, const char *,
191 const char *, const char *); 206 const char *, const char *);
192 207
193/* hostkey handling */ 208/* hostkey handling */
194Key *get_hostkey_by_index(int); 209struct sshkey *get_hostkey_by_index(int);
195Key *get_hostkey_public_by_index(int, struct ssh *); 210struct sshkey *get_hostkey_public_by_index(int, struct ssh *);
196Key *get_hostkey_public_by_type(int, int, struct ssh *); 211struct sshkey *get_hostkey_public_by_type(int, int, struct ssh *);
197Key *get_hostkey_private_by_type(int, int, struct ssh *); 212struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *);
198int get_hostkey_index(Key *, int, struct ssh *); 213int get_hostkey_index(struct sshkey *, int, struct ssh *);
199int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, 214int sshd_hostkey_sign(struct sshkey *, struct sshkey *, u_char **,
200 const u_char *, size_t, const char *, u_int); 215 size_t *, const u_char *, size_t, const char *, u_int);
201 216
202/* debug messages during authentication */ 217/* debug messages during authentication */
203void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); 218void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
diff --git a/auth2-chall.c b/auth2-chall.c
index ead480318..11c8d31b3 100644
--- a/auth2-chall.c
+++ b/auth2-chall.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-chall.c,v 1.44 2016/05/02 08:49:03 djm Exp $ */ 1/* $OpenBSD: auth2-chall.c,v 1.48 2017/05/30 14:29:59 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2001 Per Allansson. All rights reserved. 4 * Copyright (c) 2001 Per Allansson. All rights reserved.
@@ -47,9 +47,9 @@
47/* import */ 47/* import */
48extern ServerOptions options; 48extern ServerOptions options;
49 49
50static int auth2_challenge_start(Authctxt *); 50static int auth2_challenge_start(struct ssh *);
51static int send_userauth_info_request(Authctxt *); 51static int send_userauth_info_request(Authctxt *);
52static int input_userauth_info_response(int, u_int32_t, void *); 52static int input_userauth_info_response(int, u_int32_t, struct ssh *);
53 53
54#ifdef BSD_AUTH 54#ifdef BSD_AUTH
55extern KbdintDevice bsdauth_device; 55extern KbdintDevice bsdauth_device;
@@ -195,8 +195,9 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt)
195 * wait for the response. 195 * wait for the response.
196 */ 196 */
197int 197int
198auth2_challenge(Authctxt *authctxt, char *devs) 198auth2_challenge(struct ssh *ssh, char *devs)
199{ 199{
200 Authctxt *authctxt = ssh->authctxt;
200 debug("auth2_challenge: user=%s devs=%s", 201 debug("auth2_challenge: user=%s devs=%s",
201 authctxt->user ? authctxt->user : "<nouser>", 202 authctxt->user ? authctxt->user : "<nouser>",
202 devs ? devs : "<no devs>"); 203 devs ? devs : "<no devs>");
@@ -205,15 +206,16 @@ auth2_challenge(Authctxt *authctxt, char *devs)
205 return 0; 206 return 0;
206 if (authctxt->kbdintctxt == NULL) 207 if (authctxt->kbdintctxt == NULL)
207 authctxt->kbdintctxt = kbdint_alloc(devs); 208 authctxt->kbdintctxt = kbdint_alloc(devs);
208 return auth2_challenge_start(authctxt); 209 return auth2_challenge_start(ssh);
209} 210}
210 211
211/* unregister kbd-int callbacks and context */ 212/* unregister kbd-int callbacks and context */
212void 213void
213auth2_challenge_stop(Authctxt *authctxt) 214auth2_challenge_stop(struct ssh *ssh)
214{ 215{
216 Authctxt *authctxt = ssh->authctxt;
215 /* unregister callback */ 217 /* unregister callback */
216 dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); 218 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
217 if (authctxt->kbdintctxt != NULL) { 219 if (authctxt->kbdintctxt != NULL) {
218 kbdint_free(authctxt->kbdintctxt); 220 kbdint_free(authctxt->kbdintctxt);
219 authctxt->kbdintctxt = NULL; 221 authctxt->kbdintctxt = NULL;
@@ -222,29 +224,30 @@ auth2_challenge_stop(Authctxt *authctxt)
222 224
223/* side effect: sets authctxt->postponed if a reply was sent*/ 225/* side effect: sets authctxt->postponed if a reply was sent*/
224static int 226static int
225auth2_challenge_start(Authctxt *authctxt) 227auth2_challenge_start(struct ssh *ssh)
226{ 228{
229 Authctxt *authctxt = ssh->authctxt;
227 KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt; 230 KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt;
228 231
229 debug2("auth2_challenge_start: devices %s", 232 debug2("auth2_challenge_start: devices %s",
230 kbdintctxt->devices ? kbdintctxt->devices : "<empty>"); 233 kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
231 234
232 if (kbdint_next_device(authctxt, kbdintctxt) == 0) { 235 if (kbdint_next_device(authctxt, kbdintctxt) == 0) {
233 auth2_challenge_stop(authctxt); 236 auth2_challenge_stop(ssh);
234 return 0; 237 return 0;
235 } 238 }
236 debug("auth2_challenge_start: trying authentication method '%s'", 239 debug("auth2_challenge_start: trying authentication method '%s'",
237 kbdintctxt->device->name); 240 kbdintctxt->device->name);
238 241
239 if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) { 242 if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
240 auth2_challenge_stop(authctxt); 243 auth2_challenge_stop(ssh);
241 return 0; 244 return 0;
242 } 245 }
243 if (send_userauth_info_request(authctxt) == 0) { 246 if (send_userauth_info_request(authctxt) == 0) {
244 auth2_challenge_stop(authctxt); 247 auth2_challenge_stop(ssh);
245 return 0; 248 return 0;
246 } 249 }
247 dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, 250 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE,
248 &input_userauth_info_response); 251 &input_userauth_info_response);
249 252
250 authctxt->postponed = 1; 253 authctxt->postponed = 1;
@@ -285,9 +288,9 @@ send_userauth_info_request(Authctxt *authctxt)
285} 288}
286 289
287static int 290static int
288input_userauth_info_response(int type, u_int32_t seq, void *ctxt) 291input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
289{ 292{
290 Authctxt *authctxt = ctxt; 293 Authctxt *authctxt = ssh->authctxt;
291 KbdintAuthctxt *kbdintctxt; 294 KbdintAuthctxt *kbdintctxt;
292 int authenticated = 0, res; 295 int authenticated = 0, res;
293 u_int i, nresp; 296 u_int i, nresp;
@@ -340,14 +343,14 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
340 devicename = kbdintctxt->device->name; 343 devicename = kbdintctxt->device->name;
341 if (!authctxt->postponed) { 344 if (!authctxt->postponed) {
342 if (authenticated) { 345 if (authenticated) {
343 auth2_challenge_stop(authctxt); 346 auth2_challenge_stop(ssh);
344 } else { 347 } else {
345 /* start next device */ 348 /* start next device */
346 /* may set authctxt->postponed */ 349 /* may set authctxt->postponed */
347 auth2_challenge_start(authctxt); 350 auth2_challenge_start(ssh);
348 } 351 }
349 } 352 }
350 userauth_finish(authctxt, authenticated, "keyboard-interactive", 353 userauth_finish(ssh, authenticated, "keyboard-interactive",
351 devicename); 354 devicename);
352 return 0; 355 return 0;
353} 356}
diff --git a/auth2-gss.c b/auth2-gss.c
index 1ca835773..589283b72 100644
--- a/auth2-gss.c
+++ b/auth2-gss.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-gss.c,v 1.22 2015/01/19 20:07:45 markus Exp $ */ 1/* $OpenBSD: auth2-gss.c,v 1.26 2017/06/24 06:34:38 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -48,18 +48,19 @@
48 48
49extern ServerOptions options; 49extern ServerOptions options;
50 50
51static int input_gssapi_token(int type, u_int32_t plen, void *ctxt); 51static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh);
52static int input_gssapi_mic(int type, u_int32_t plen, void *ctxt); 52static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh);
53static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); 53static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh);
54static int input_gssapi_errtok(int, u_int32_t, void *); 54static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
55 55
56/* 56/*
57 * We only support those mechanisms that we know about (ie ones that we know 57 * We only support those mechanisms that we know about (ie ones that we know
58 * how to check local user kuserok and the like) 58 * how to check local user kuserok and the like)
59 */ 59 */
60static int 60static int
61userauth_gssapi(Authctxt *authctxt) 61userauth_gssapi(struct ssh *ssh)
62{ 62{
63 Authctxt *authctxt = ssh->authctxt;
63 gss_OID_desc goid = {0, NULL}; 64 gss_OID_desc goid = {0, NULL};
64 Gssctxt *ctxt = NULL; 65 Gssctxt *ctxt = NULL;
65 int mechs; 66 int mechs;
@@ -119,17 +120,17 @@ userauth_gssapi(Authctxt *authctxt)
119 packet_send(); 120 packet_send();
120 free(doid); 121 free(doid);
121 122
122 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); 123 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
123 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); 124 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
124 authctxt->postponed = 1; 125 authctxt->postponed = 1;
125 126
126 return (0); 127 return (0);
127} 128}
128 129
129static int 130static int
130input_gssapi_token(int type, u_int32_t plen, void *ctxt) 131input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
131{ 132{
132 Authctxt *authctxt = ctxt; 133 Authctxt *authctxt = ssh->authctxt;
133 Gssctxt *gssctxt; 134 Gssctxt *gssctxt;
134 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 135 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
135 gss_buffer_desc recv_tok; 136 gss_buffer_desc recv_tok;
@@ -157,8 +158,8 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
157 packet_send(); 158 packet_send();
158 } 159 }
159 authctxt->postponed = 0; 160 authctxt->postponed = 0;
160 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 161 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
161 userauth_finish(authctxt, 0, "gssapi-with-mic", NULL); 162 userauth_finish(ssh, 0, "gssapi-with-mic", NULL);
162 } else { 163 } else {
163 if (send_tok.length != 0) { 164 if (send_tok.length != 0) {
164 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); 165 packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
@@ -166,12 +167,12 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
166 packet_send(); 167 packet_send();
167 } 168 }
168 if (maj_status == GSS_S_COMPLETE) { 169 if (maj_status == GSS_S_COMPLETE) {
169 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 170 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
170 if (flags & GSS_C_INTEG_FLAG) 171 if (flags & GSS_C_INTEG_FLAG)
171 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, 172 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC,
172 &input_gssapi_mic); 173 &input_gssapi_mic);
173 else 174 else
174 dispatch_set( 175 ssh_dispatch_set(ssh,
175 SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, 176 SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
176 &input_gssapi_exchange_complete); 177 &input_gssapi_exchange_complete);
177 } 178 }
@@ -182,9 +183,9 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
182} 183}
183 184
184static int 185static int
185input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) 186input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
186{ 187{
187 Authctxt *authctxt = ctxt; 188 Authctxt *authctxt = ssh->authctxt;
188 Gssctxt *gssctxt; 189 Gssctxt *gssctxt;
189 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 190 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
190 gss_buffer_desc recv_tok; 191 gss_buffer_desc recv_tok;
@@ -207,8 +208,8 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
207 free(recv_tok.value); 208 free(recv_tok.value);
208 209
209 /* We can't return anything to the client, even if we wanted to */ 210 /* We can't return anything to the client, even if we wanted to */
210 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 211 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
211 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); 212 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
212 213
213 /* The client will have already moved on to the next auth */ 214 /* The client will have already moved on to the next auth */
214 215
@@ -223,10 +224,11 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
223 */ 224 */
224 225
225static int 226static int
226input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) 227input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh)
227{ 228{
228 Authctxt *authctxt = ctxt; 229 Authctxt *authctxt = ssh->authctxt;
229 int authenticated; 230 int authenticated;
231 const char *displayname;
230 232
231 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) 233 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
232 fatal("No authentication or GSSAPI context"); 234 fatal("No authentication or GSSAPI context");
@@ -240,24 +242,29 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
240 242
241 authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); 243 authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
242 244
245 if ((!use_privsep || mm_is_monitor()) &&
246 (displayname = ssh_gssapi_displayname()) != NULL)
247 auth2_record_info(authctxt, "%s", displayname);
248
243 authctxt->postponed = 0; 249 authctxt->postponed = 0;
244 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 250 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
245 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); 251 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
246 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); 252 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
247 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 253 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
248 userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); 254 userauth_finish(ssh, authenticated, "gssapi-with-mic", NULL);
249 return 0; 255 return 0;
250} 256}
251 257
252static int 258static int
253input_gssapi_mic(int type, u_int32_t plen, void *ctxt) 259input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
254{ 260{
255 Authctxt *authctxt = ctxt; 261 Authctxt *authctxt = ssh->authctxt;
256 Gssctxt *gssctxt; 262 Gssctxt *gssctxt;
257 int authenticated = 0; 263 int authenticated = 0;
258 Buffer b; 264 Buffer b;
259 gss_buffer_desc mic, gssbuf; 265 gss_buffer_desc mic, gssbuf;
260 u_int len; 266 u_int len;
267 const char *displayname;
261 268
262 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) 269 if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
263 fatal("No authentication or GSSAPI context"); 270 fatal("No authentication or GSSAPI context");
@@ -281,12 +288,16 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
281 buffer_free(&b); 288 buffer_free(&b);
282 free(mic.value); 289 free(mic.value);
283 290
291 if ((!use_privsep || mm_is_monitor()) &&
292 (displayname = ssh_gssapi_displayname()) != NULL)
293 auth2_record_info(authctxt, "%s", displayname);
294
284 authctxt->postponed = 0; 295 authctxt->postponed = 0;
285 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 296 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
286 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); 297 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
287 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); 298 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
288 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 299 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
289 userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); 300 userauth_finish(ssh, authenticated, "gssapi-with-mic", NULL);
290 return 0; 301 return 0;
291} 302}
292 303
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 1b3c3b202..92758b38c 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-hostbased.c,v 1.26 2016/03/07 19:02:43 djm Exp $ */ 1/* $OpenBSD: auth2-hostbased.c,v 1.31 2017/06/24 06:34:38 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -39,7 +39,7 @@
39#include "misc.h" 39#include "misc.h"
40#include "servconf.h" 40#include "servconf.h"
41#include "compat.h" 41#include "compat.h"
42#include "key.h" 42#include "sshkey.h"
43#include "hostfile.h" 43#include "hostfile.h"
44#include "auth.h" 44#include "auth.h"
45#include "canohost.h" 45#include "canohost.h"
@@ -48,6 +48,7 @@
48#endif 48#endif
49#include "monitor_wrap.h" 49#include "monitor_wrap.h"
50#include "pathnames.h" 50#include "pathnames.h"
51#include "ssherr.h"
51#include "match.h" 52#include "match.h"
52 53
53/* import */ 54/* import */
@@ -56,54 +57,56 @@ extern u_char *session_id2;
56extern u_int session_id2_len; 57extern u_int session_id2_len;
57 58
58static int 59static int
59userauth_hostbased(Authctxt *authctxt) 60userauth_hostbased(struct ssh *ssh)
60{ 61{
61 Buffer b; 62 Authctxt *authctxt = ssh->authctxt;
62 Key *key = NULL; 63 struct sshbuf *b;
64 struct sshkey *key = NULL;
63 char *pkalg, *cuser, *chost, *service; 65 char *pkalg, *cuser, *chost, *service;
64 u_char *pkblob, *sig; 66 u_char *pkblob, *sig;
65 u_int alen, blen, slen; 67 size_t alen, blen, slen;
66 int pktype; 68 int r, pktype, authenticated = 0;
67 int authenticated = 0;
68 69
69 if (!authctxt->valid) { 70 if (!authctxt->valid) {
70 debug2("userauth_hostbased: disabled because of invalid user"); 71 debug2("%s: disabled because of invalid user", __func__);
71 return 0; 72 return 0;
72 } 73 }
73 pkalg = packet_get_string(&alen); 74 /* XXX use sshkey_froms() */
74 pkblob = packet_get_string(&blen); 75 if ((r = sshpkt_get_cstring(ssh, &pkalg, &alen)) != 0 ||
75 chost = packet_get_string(NULL); 76 (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
76 cuser = packet_get_string(NULL); 77 (r = sshpkt_get_cstring(ssh, &chost, NULL)) != 0 ||
77 sig = packet_get_string(&slen); 78 (r = sshpkt_get_cstring(ssh, &cuser, NULL)) != 0 ||
79 (r = sshpkt_get_string(ssh, &sig, &slen)) != 0)
80 fatal("%s: packet parsing: %s", __func__, ssh_err(r));
78 81
79 debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d", 82 debug("%s: cuser %s chost %s pkalg %s slen %zu", __func__,
80 cuser, chost, pkalg, slen); 83 cuser, chost, pkalg, slen);
81#ifdef DEBUG_PK 84#ifdef DEBUG_PK
82 debug("signature:"); 85 debug("signature:");
83 buffer_init(&b); 86 sshbuf_dump_data(sig, siglen, stderr);
84 buffer_append(&b, sig, slen);
85 buffer_dump(&b);
86 buffer_free(&b);
87#endif 87#endif
88 pktype = key_type_from_name(pkalg); 88 pktype = sshkey_type_from_name(pkalg);
89 if (pktype == KEY_UNSPEC) { 89 if (pktype == KEY_UNSPEC) {
90 /* this is perfectly legal */ 90 /* this is perfectly legal */
91 logit("userauth_hostbased: unsupported " 91 logit("%s: unsupported public key algorithm: %s",
92 "public key algorithm: %s", pkalg); 92 __func__, pkalg);
93 goto done;
94 }
95 if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
96 error("%s: key_from_blob: %s", __func__, ssh_err(r));
93 goto done; 97 goto done;
94 } 98 }
95 key = key_from_blob(pkblob, blen);
96 if (key == NULL) { 99 if (key == NULL) {
97 error("userauth_hostbased: cannot decode key: %s", pkalg); 100 error("%s: cannot decode key: %s", __func__, pkalg);
98 goto done; 101 goto done;
99 } 102 }
100 if (key->type != pktype) { 103 if (key->type != pktype) {
101 error("userauth_hostbased: type mismatch for decoded key " 104 error("%s: type mismatch for decoded key "
102 "(received %d, expected %d)", key->type, pktype); 105 "(received %d, expected %d)", __func__, key->type, pktype);
103 goto done; 106 goto done;
104 } 107 }
105 if (key_type_plain(key->type) == KEY_RSA && 108 if (sshkey_type_plain(key->type) == KEY_RSA &&
106 (datafellows & SSH_BUG_RSASIGMD5) != 0) { 109 (ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
107 error("Refusing RSA key because peer uses unsafe " 110 error("Refusing RSA key because peer uses unsafe "
108 "signature format"); 111 "signature format");
109 goto done; 112 goto done;
@@ -115,38 +118,40 @@ userauth_hostbased(Authctxt *authctxt)
115 goto done; 118 goto done;
116 } 119 }
117 120
118 service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : 121 service = ssh->compat & SSH_BUG_HBSERVICE ? "ssh-userauth" :
119 authctxt->service; 122 authctxt->service;
120 buffer_init(&b); 123 if ((b = sshbuf_new()) == NULL)
121 buffer_put_string(&b, session_id2, session_id2_len); 124 fatal("%s: sshbuf_new failed", __func__);
122 /* reconstruct packet */ 125 /* reconstruct packet */
123 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 126 if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 ||
124 buffer_put_cstring(&b, authctxt->user); 127 (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
125 buffer_put_cstring(&b, service); 128 (r = sshbuf_put_cstring(b, authctxt->user)) != 0 ||
126 buffer_put_cstring(&b, "hostbased"); 129 (r = sshbuf_put_cstring(b, service)) != 0 ||
127 buffer_put_string(&b, pkalg, alen); 130 (r = sshbuf_put_cstring(b, "hostbased")) != 0 ||
128 buffer_put_string(&b, pkblob, blen); 131 (r = sshbuf_put_string(b, pkalg, alen)) != 0 ||
129 buffer_put_cstring(&b, chost); 132 (r = sshbuf_put_string(b, pkblob, blen)) != 0 ||
130 buffer_put_cstring(&b, cuser); 133 (r = sshbuf_put_cstring(b, chost)) != 0 ||
134 (r = sshbuf_put_cstring(b, cuser)) != 0)
135 fatal("%s: buffer error: %s", __func__, ssh_err(r));
131#ifdef DEBUG_PK 136#ifdef DEBUG_PK
132 buffer_dump(&b); 137 sshbuf_dump(b, stderr);
133#endif 138#endif
134 139
135 pubkey_auth_info(authctxt, key, 140 auth2_record_info(authctxt,
136 "client user \"%.100s\", client host \"%.100s\"", cuser, chost); 141 "client user \"%.100s\", client host \"%.100s\"", cuser, chost);
137 142
138 /* test for allowed key and correct signature */ 143 /* test for allowed key and correct signature */
139 authenticated = 0; 144 authenticated = 0;
140 if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && 145 if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
141 PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), 146 PRIVSEP(sshkey_verify(key, sig, slen,
142 buffer_len(&b))) == 1) 147 sshbuf_ptr(b), sshbuf_len(b), ssh->compat)) == 0)
143 authenticated = 1; 148 authenticated = 1;
144 149
145 buffer_free(&b); 150 auth2_record_key(authctxt, authenticated, key);
151 sshbuf_free(b);
146done: 152done:
147 debug2("userauth_hostbased: authenticated %d", authenticated); 153 debug2("%s: authenticated %d", __func__, authenticated);
148 if (key != NULL) 154 sshkey_free(key);
149 key_free(key);
150 free(pkalg); 155 free(pkalg);
151 free(pkblob); 156 free(pkblob);
152 free(cuser); 157 free(cuser);
@@ -158,7 +163,7 @@ done:
158/* return 1 if given hostkey is allowed */ 163/* return 1 if given hostkey is allowed */
159int 164int
160hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, 165hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
161 Key *key) 166 struct sshkey *key)
162{ 167{
163 struct ssh *ssh = active_state; /* XXX */ 168 struct ssh *ssh = active_state; /* XXX */
164 const char *resolvedname, *ipaddr, *lookup, *reason; 169 const char *resolvedname, *ipaddr, *lookup, *reason;
@@ -203,8 +208,8 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
203 } 208 }
204 debug2("%s: access allowed by auth_rhosts2", __func__); 209 debug2("%s: access allowed by auth_rhosts2", __func__);
205 210
206 if (key_is_cert(key) && 211 if (sshkey_is_cert(key) &&
207 key_cert_check_authority(key, 1, 0, lookup, &reason)) { 212 sshkey_cert_check_authority(key, 1, 0, lookup, &reason)) {
208 error("%s", reason); 213 error("%s", reason);
209 auth_debug_add("%s", reason); 214 auth_debug_add("%s", reason);
210 return 0; 215 return 0;
@@ -223,20 +228,20 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
223 } 228 }
224 229
225 if (host_status == HOST_OK) { 230 if (host_status == HOST_OK) {
226 if (key_is_cert(key)) { 231 if (sshkey_is_cert(key)) {
227 if ((fp = sshkey_fingerprint(key->cert->signature_key, 232 if ((fp = sshkey_fingerprint(key->cert->signature_key,
228 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) 233 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
229 fatal("%s: sshkey_fingerprint fail", __func__); 234 fatal("%s: sshkey_fingerprint fail", __func__);
230 verbose("Accepted certificate ID \"%s\" signed by " 235 verbose("Accepted certificate ID \"%s\" signed by "
231 "%s CA %s from %s@%s", key->cert->key_id, 236 "%s CA %s from %s@%s", key->cert->key_id,
232 key_type(key->cert->signature_key), fp, 237 sshkey_type(key->cert->signature_key), fp,
233 cuser, lookup); 238 cuser, lookup);
234 } else { 239 } else {
235 if ((fp = sshkey_fingerprint(key, 240 if ((fp = sshkey_fingerprint(key,
236 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) 241 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
237 fatal("%s: sshkey_fingerprint fail", __func__); 242 fatal("%s: sshkey_fingerprint fail", __func__);
238 verbose("Accepted %s public key %s from %s@%s", 243 verbose("Accepted %s public key %s from %s@%s",
239 key_type(key), fp, cuser, lookup); 244 sshkey_type(key), fp, cuser, lookup);
240 } 245 }
241 free(fp); 246 free(fp);
242 } 247 }
diff --git a/auth2-kbdint.c b/auth2-kbdint.c
index bf75c6059..86aad8ddc 100644
--- a/auth2-kbdint.c
+++ b/auth2-kbdint.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-kbdint.c,v 1.7 2014/07/15 15:54:14 millert Exp $ */ 1/* $OpenBSD: auth2-kbdint.c,v 1.8 2017/05/30 14:29:59 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -43,7 +43,7 @@
43extern ServerOptions options; 43extern ServerOptions options;
44 44
45static int 45static int
46userauth_kbdint(Authctxt *authctxt) 46userauth_kbdint(struct ssh *ssh)
47{ 47{
48 int authenticated = 0; 48 int authenticated = 0;
49 char *lang, *devs; 49 char *lang, *devs;
@@ -55,7 +55,7 @@ userauth_kbdint(Authctxt *authctxt)
55 debug("keyboard-interactive devs %s", devs); 55 debug("keyboard-interactive devs %s", devs);
56 56
57 if (options.challenge_response_authentication) 57 if (options.challenge_response_authentication)
58 authenticated = auth2_challenge(authctxt, devs); 58 authenticated = auth2_challenge(ssh, devs);
59 59
60 free(devs); 60 free(devs);
61 free(lang); 61 free(lang);
diff --git a/auth2-none.c b/auth2-none.c
index e71e2219c..35d25fa63 100644
--- a/auth2-none.c
+++ b/auth2-none.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-none.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */ 1/* $OpenBSD: auth2-none.c,v 1.20 2017/05/30 14:29:59 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -37,7 +37,7 @@
37 37
38#include "atomicio.h" 38#include "atomicio.h"
39#include "xmalloc.h" 39#include "xmalloc.h"
40#include "key.h" 40#include "sshkey.h"
41#include "hostfile.h" 41#include "hostfile.h"
42#include "auth.h" 42#include "auth.h"
43#include "packet.h" 43#include "packet.h"
@@ -47,6 +47,7 @@
47#include "servconf.h" 47#include "servconf.h"
48#include "compat.h" 48#include "compat.h"
49#include "ssh2.h" 49#include "ssh2.h"
50#include "ssherr.h"
50#ifdef GSSAPI 51#ifdef GSSAPI
51#include "ssh-gss.h" 52#include "ssh-gss.h"
52#endif 53#endif
@@ -59,12 +60,15 @@ extern ServerOptions options;
59static int none_enabled = 1; 60static int none_enabled = 1;
60 61
61static int 62static int
62userauth_none(Authctxt *authctxt) 63userauth_none(struct ssh *ssh)
63{ 64{
65 int r;
66
64 none_enabled = 0; 67 none_enabled = 0;
65 packet_check_eom(); 68 if ((r = sshpkt_get_end(ssh)) != 0)
69 fatal("%s: %s", __func__, ssh_err(r));
66 if (options.permit_empty_passwd && options.password_authentication) 70 if (options.permit_empty_passwd && options.password_authentication)
67 return (PRIVSEP(auth_password(authctxt, ""))); 71 return (PRIVSEP(auth_password(ssh->authctxt, "")));
68 return (0); 72 return (0);
69} 73}
70 74
diff --git a/auth2-passwd.c b/auth2-passwd.c
index b638e8715..5f7ba3244 100644
--- a/auth2-passwd.c
+++ b/auth2-passwd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-passwd.c,v 1.12 2014/07/15 15:54:14 millert Exp $ */ 1/* $OpenBSD: auth2-passwd.c,v 1.14 2017/05/30 14:29:59 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -30,10 +30,10 @@
30#include <string.h> 30#include <string.h>
31#include <stdarg.h> 31#include <stdarg.h>
32 32
33#include "xmalloc.h"
34#include "packet.h" 33#include "packet.h"
34#include "ssherr.h"
35#include "log.h" 35#include "log.h"
36#include "key.h" 36#include "sshkey.h"
37#include "hostfile.h" 37#include "hostfile.h"
38#include "auth.h" 38#include "auth.h"
39#include "buffer.h" 39#include "buffer.h"
@@ -48,26 +48,22 @@
48extern ServerOptions options; 48extern ServerOptions options;
49 49
50static int 50static int
51userauth_passwd(Authctxt *authctxt) 51userauth_passwd(struct ssh *ssh)
52{ 52{
53 char *password, *newpass; 53 char *password;
54 int authenticated = 0; 54 int authenticated = 0, r;
55 int change; 55 u_char change;
56 u_int len, newlen; 56 size_t len;
57 57
58 change = packet_get_char(); 58 if ((r = sshpkt_get_u8(ssh, &change)) != 0 ||
59 password = packet_get_string(&len); 59 (r = sshpkt_get_cstring(ssh, &password, &len)) != 0 ||
60 if (change) { 60 (change && (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0) ||
61 /* discard new password from packet */ 61 (r = sshpkt_get_end(ssh)) != 0)
62 newpass = packet_get_string(&newlen); 62 fatal("%s: %s", __func__, ssh_err(r));
63 explicit_bzero(newpass, newlen);
64 free(newpass);
65 }
66 packet_check_eom();
67 63
68 if (change) 64 if (change)
69 logit("password change not supported"); 65 logit("password change not supported");
70 else if (PRIVSEP(auth_password(authctxt, password)) == 1) 66 else if (PRIVSEP(auth_password(ssh->authctxt, password)) == 1)
71 authenticated = 1; 67 authenticated = 1;
72 explicit_bzero(password, len); 68 explicit_bzero(password, len);
73 free(password); 69 free(password);
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 3e5706f4d..169839b01 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.62 2017/01/30 01:03:00 djm Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.71 2017/09/07 23:48:09 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -27,7 +27,6 @@
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29#include <sys/stat.h> 29#include <sys/stat.h>
30#include <sys/wait.h>
31 30
32#include <errno.h> 31#include <errno.h>
33#include <fcntl.h> 32#include <fcntl.h>
@@ -52,7 +51,7 @@
52#include "misc.h" 51#include "misc.h"
53#include "servconf.h" 52#include "servconf.h"
54#include "compat.h" 53#include "compat.h"
55#include "key.h" 54#include "sshkey.h"
56#include "hostfile.h" 55#include "hostfile.h"
57#include "auth.h" 56#include "auth.h"
58#include "pathnames.h" 57#include "pathnames.h"
@@ -75,42 +74,52 @@ extern u_char *session_id2;
75extern u_int session_id2_len; 74extern u_int session_id2_len;
76 75
77static int 76static int
78userauth_pubkey(Authctxt *authctxt) 77userauth_pubkey(struct ssh *ssh)
79{ 78{
80 Buffer b; 79 Authctxt *authctxt = ssh->authctxt;
81 Key *key = NULL; 80 struct sshbuf *b;
82 char *pkalg, *userstyle, *fp = NULL; 81 struct sshkey *key = NULL;
83 u_char *pkblob, *sig; 82 char *pkalg, *userstyle = NULL, *fp = NULL;
84 u_int alen, blen, slen; 83 u_char *pkblob, *sig, have_sig;
85 int have_sig, pktype; 84 size_t blen, slen;
85 int r, pktype;
86 int authenticated = 0; 86 int authenticated = 0;
87 87
88 if (!authctxt->valid) { 88 if (!authctxt->valid) {
89 debug2("%s: disabled because of invalid user", __func__); 89 debug2("%s: disabled because of invalid user", __func__);
90 return 0; 90 return 0;
91 } 91 }
92 have_sig = packet_get_char(); 92 if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0)
93 if (datafellows & SSH_BUG_PKAUTH) { 93 fatal("%s: sshpkt_get_u8 failed: %s", __func__, ssh_err(r));
94 if (ssh->compat & SSH_BUG_PKAUTH) {
94 debug2("%s: SSH_BUG_PKAUTH", __func__); 95 debug2("%s: SSH_BUG_PKAUTH", __func__);
96 if ((b = sshbuf_new()) == NULL)
97 fatal("%s: sshbuf_new failed", __func__);
95 /* no explicit pkalg given */ 98 /* no explicit pkalg given */
96 pkblob = packet_get_string(&blen);
97 buffer_init(&b);
98 buffer_append(&b, pkblob, blen);
99 /* so we have to extract the pkalg from the pkblob */ 99 /* so we have to extract the pkalg from the pkblob */
100 pkalg = buffer_get_string(&b, &alen); 100 /* XXX use sshbuf_from() */
101 buffer_free(&b); 101 if ((r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
102 (r = sshbuf_put(b, pkblob, blen)) != 0 ||
103 (r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0)
104 fatal("%s: failed: %s", __func__, ssh_err(r));
105 sshbuf_free(b);
102 } else { 106 } else {
103 pkalg = packet_get_string(&alen); 107 if ((r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
104 pkblob = packet_get_string(&blen); 108 (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0)
109 fatal("%s: sshpkt_get_cstring failed: %s",
110 __func__, ssh_err(r));
105 } 111 }
106 pktype = key_type_from_name(pkalg); 112 pktype = sshkey_type_from_name(pkalg);
107 if (pktype == KEY_UNSPEC) { 113 if (pktype == KEY_UNSPEC) {
108 /* this is perfectly legal */ 114 /* this is perfectly legal */
109 logit("%s: unsupported public key algorithm: %s", 115 logit("%s: unsupported public key algorithm: %s",
110 __func__, pkalg); 116 __func__, pkalg);
111 goto done; 117 goto done;
112 } 118 }
113 key = key_from_blob(pkblob, blen); 119 if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
120 error("%s: could not parse key: %s", __func__, ssh_err(r));
121 goto done;
122 }
114 if (key == NULL) { 123 if (key == NULL) {
115 error("%s: cannot decode key: %s", __func__, pkalg); 124 error("%s: cannot decode key: %s", __func__, pkalg);
116 goto done; 125 goto done;
@@ -120,15 +129,15 @@ userauth_pubkey(Authctxt *authctxt)
120 "(received %d, expected %d)", __func__, key->type, pktype); 129 "(received %d, expected %d)", __func__, key->type, pktype);
121 goto done; 130 goto done;
122 } 131 }
123 if (key_type_plain(key->type) == KEY_RSA && 132 if (sshkey_type_plain(key->type) == KEY_RSA &&
124 (datafellows & SSH_BUG_RSASIGMD5) != 0) { 133 (ssh->compat & SSH_BUG_RSASIGMD5) != 0) {
125 logit("Refusing RSA key because client uses unsafe " 134 logit("Refusing RSA key because client uses unsafe "
126 "signature scheme"); 135 "signature scheme");
127 goto done; 136 goto done;
128 } 137 }
129 fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); 138 fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
130 if (auth2_userkey_already_used(authctxt, key)) { 139 if (auth2_key_already_used(authctxt, key)) {
131 logit("refusing previously-used %s key", key_type(key)); 140 logit("refusing previously-used %s key", sshkey_type(key));
132 goto done; 141 goto done;
133 } 142 }
134 if (match_pattern_list(sshkey_ssh_name(key), 143 if (match_pattern_list(sshkey_ssh_name(key),
@@ -141,54 +150,65 @@ userauth_pubkey(Authctxt *authctxt)
141 if (have_sig) { 150 if (have_sig) {
142 debug3("%s: have signature for %s %s", 151 debug3("%s: have signature for %s %s",
143 __func__, sshkey_type(key), fp); 152 __func__, sshkey_type(key), fp);
144 sig = packet_get_string(&slen); 153 if ((r = sshpkt_get_string(ssh, &sig, &slen)) != 0 ||
145 packet_check_eom(); 154 (r = sshpkt_get_end(ssh)) != 0)
146 buffer_init(&b); 155 fatal("%s: %s", __func__, ssh_err(r));
147 if (datafellows & SSH_OLD_SESSIONID) { 156 if ((b = sshbuf_new()) == NULL)
148 buffer_append(&b, session_id2, session_id2_len); 157 fatal("%s: sshbuf_new failed", __func__);
158 if (ssh->compat & SSH_OLD_SESSIONID) {
159 if ((r = sshbuf_put(b, session_id2,
160 session_id2_len)) != 0)
161 fatal("%s: sshbuf_put session id: %s",
162 __func__, ssh_err(r));
149 } else { 163 } else {
150 buffer_put_string(&b, session_id2, session_id2_len); 164 if ((r = sshbuf_put_string(b, session_id2,
165 session_id2_len)) != 0)
166 fatal("%s: sshbuf_put_string session id: %s",
167 __func__, ssh_err(r));
151 } 168 }
152 /* reconstruct packet */ 169 /* reconstruct packet */
153 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
154 xasprintf(&userstyle, "%s%s%s", authctxt->user, 170 xasprintf(&userstyle, "%s%s%s", authctxt->user,
155 authctxt->style ? ":" : "", 171 authctxt->style ? ":" : "",
156 authctxt->style ? authctxt->style : ""); 172 authctxt->style ? authctxt->style : "");
157 buffer_put_cstring(&b, userstyle); 173 if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
158 free(userstyle); 174 (r = sshbuf_put_cstring(b, userstyle)) != 0 ||
159 buffer_put_cstring(&b, 175 (r = sshbuf_put_cstring(b, ssh->compat & SSH_BUG_PKSERVICE ?
160 datafellows & SSH_BUG_PKSERVICE ? 176 "ssh-userauth" : authctxt->service)) != 0)
161 "ssh-userauth" : 177 fatal("%s: build packet failed: %s",
162 authctxt->service); 178 __func__, ssh_err(r));
163 if (datafellows & SSH_BUG_PKAUTH) { 179 if (ssh->compat & SSH_BUG_PKAUTH) {
164 buffer_put_char(&b, have_sig); 180 if ((r = sshbuf_put_u8(b, have_sig)) != 0)
181 fatal("%s: build packet failed: %s",
182 __func__, ssh_err(r));
165 } else { 183 } else {
166 buffer_put_cstring(&b, "publickey"); 184 if ((r = sshbuf_put_cstring(b, "publickey")) != 0 ||
167 buffer_put_char(&b, have_sig); 185 (r = sshbuf_put_u8(b, have_sig)) != 0 ||
168 buffer_put_cstring(&b, pkalg); 186 (r = sshbuf_put_cstring(b, pkalg) != 0))
187 fatal("%s: build packet failed: %s",
188 __func__, ssh_err(r));
169 } 189 }
170 buffer_put_string(&b, pkblob, blen); 190 if ((r = sshbuf_put_string(b, pkblob, blen)) != 0)
191 fatal("%s: build packet failed: %s",
192 __func__, ssh_err(r));
171#ifdef DEBUG_PK 193#ifdef DEBUG_PK
172 buffer_dump(&b); 194 sshbuf_dump(b, stderr);
173#endif 195#endif
174 pubkey_auth_info(authctxt, key, NULL);
175 196
176 /* test for correct signature */ 197 /* test for correct signature */
177 authenticated = 0; 198 authenticated = 0;
178 if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && 199 if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
179 PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), 200 PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b),
180 buffer_len(&b))) == 1) { 201 sshbuf_len(b), ssh->compat)) == 0) {
181 authenticated = 1; 202 authenticated = 1;
182 /* Record the successful key to prevent reuse */
183 auth2_record_userkey(authctxt, key);
184 key = NULL; /* Don't free below */
185 } 203 }
186 buffer_free(&b); 204 sshbuf_free(b);
187 free(sig); 205 free(sig);
206 auth2_record_key(authctxt, authenticated, key);
188 } else { 207 } else {
189 debug("%s: test whether pkalg/pkblob are acceptable for %s %s", 208 debug("%s: test whether pkalg/pkblob are acceptable for %s %s",
190 __func__, sshkey_type(key), fp); 209 __func__, sshkey_type(key), fp);
191 packet_check_eom(); 210 if ((r = sshpkt_get_end(ssh)) != 0)
211 fatal("%s: %s", __func__, ssh_err(r));
192 212
193 /* XXX fake reply and always send PK_OK ? */ 213 /* XXX fake reply and always send PK_OK ? */
194 /* 214 /*
@@ -199,11 +219,13 @@ userauth_pubkey(Authctxt *authctxt)
199 * issue? -markus 219 * issue? -markus
200 */ 220 */
201 if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) { 221 if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) {
202 packet_start(SSH2_MSG_USERAUTH_PK_OK); 222 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK))
203 packet_put_string(pkalg, alen); 223 != 0 ||
204 packet_put_string(pkblob, blen); 224 (r = sshpkt_put_cstring(ssh, pkalg)) != 0 ||
205 packet_send(); 225 (r = sshpkt_put_string(ssh, pkblob, blen)) != 0 ||
206 packet_write_wait(); 226 (r = sshpkt_send(ssh)) != 0)
227 fatal("%s: %s", __func__, ssh_err(r));
228 ssh_packet_write_wait(ssh);
207 authctxt->postponed = 1; 229 authctxt->postponed = 1;
208 } 230 }
209 } 231 }
@@ -211,333 +233,14 @@ userauth_pubkey(Authctxt *authctxt)
211 auth_clear_options(); 233 auth_clear_options();
212done: 234done:
213 debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg); 235 debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg);
214 if (key != NULL) 236 sshkey_free(key);
215 key_free(key); 237 free(userstyle);
216 free(pkalg); 238 free(pkalg);
217 free(pkblob); 239 free(pkblob);
218 free(fp); 240 free(fp);
219 return authenticated; 241 return authenticated;
220} 242}
221 243
222void
223pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
224{
225 char *fp, *extra;
226 va_list ap;
227 int i;
228
229 extra = NULL;
230 if (fmt != NULL) {
231 va_start(ap, fmt);
232 i = vasprintf(&extra, fmt, ap);
233 va_end(ap);
234 if (i < 0 || extra == NULL)
235 fatal("%s: vasprintf failed", __func__);
236 }
237
238 if (key_is_cert(key)) {
239 fp = sshkey_fingerprint(key->cert->signature_key,
240 options.fingerprint_hash, SSH_FP_DEFAULT);
241 auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s",
242 key_type(key), key->cert->key_id,
243 (unsigned long long)key->cert->serial,
244 key_type(key->cert->signature_key),
245 fp == NULL ? "(null)" : fp,
246 extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
247 free(fp);
248 } else {
249 fp = sshkey_fingerprint(key, options.fingerprint_hash,
250 SSH_FP_DEFAULT);
251 auth_info(authctxt, "%s %s%s%s", key_type(key),
252 fp == NULL ? "(null)" : fp,
253 extra == NULL ? "" : ", ", extra == NULL ? "" : extra);
254 free(fp);
255 }
256 free(extra);
257}
258
259/*
260 * Splits 's' into an argument vector. Handles quoted string and basic
261 * escape characters (\\, \", \'). Caller must free the argument vector
262 * and its members.
263 */
264static int
265split_argv(const char *s, int *argcp, char ***argvp)
266{
267 int r = SSH_ERR_INTERNAL_ERROR;
268 int argc = 0, quote, i, j;
269 char *arg, **argv = xcalloc(1, sizeof(*argv));
270
271 *argvp = NULL;
272 *argcp = 0;
273
274 for (i = 0; s[i] != '\0'; i++) {
275 /* Skip leading whitespace */
276 if (s[i] == ' ' || s[i] == '\t')
277 continue;
278
279 /* Start of a token */
280 quote = 0;
281 if (s[i] == '\\' &&
282 (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\'))
283 i++;
284 else if (s[i] == '\'' || s[i] == '"')
285 quote = s[i++];
286
287 argv = xreallocarray(argv, (argc + 2), sizeof(*argv));
288 arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1);
289 argv[argc] = NULL;
290
291 /* Copy the token in, removing escapes */
292 for (j = 0; s[i] != '\0'; i++) {
293 if (s[i] == '\\') {
294 if (s[i + 1] == '\'' ||
295 s[i + 1] == '\"' ||
296 s[i + 1] == '\\') {
297 i++; /* Skip '\' */
298 arg[j++] = s[i];
299 } else {
300 /* Unrecognised escape */
301 arg[j++] = s[i];
302 }
303 } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t'))
304 break; /* done */
305 else if (quote != 0 && s[i] == quote)
306 break; /* done */
307 else
308 arg[j++] = s[i];
309 }
310 if (s[i] == '\0') {
311 if (quote != 0) {
312 /* Ran out of string looking for close quote */
313 r = SSH_ERR_INVALID_FORMAT;
314 goto out;
315 }
316 break;
317 }
318 }
319 /* Success */
320 *argcp = argc;
321 *argvp = argv;
322 argc = 0;
323 argv = NULL;
324 r = 0;
325 out:
326 if (argc != 0 && argv != NULL) {
327 for (i = 0; i < argc; i++)
328 free(argv[i]);
329 free(argv);
330 }
331 return r;
332}
333
334/*
335 * Reassemble an argument vector into a string, quoting and escaping as
336 * necessary. Caller must free returned string.
337 */
338static char *
339assemble_argv(int argc, char **argv)
340{
341 int i, j, ws, r;
342 char c, *ret;
343 struct sshbuf *buf, *arg;
344
345 if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL)
346 fatal("%s: sshbuf_new failed", __func__);
347
348 for (i = 0; i < argc; i++) {
349 ws = 0;
350 sshbuf_reset(arg);
351 for (j = 0; argv[i][j] != '\0'; j++) {
352 r = 0;
353 c = argv[i][j];
354 switch (c) {
355 case ' ':
356 case '\t':
357 ws = 1;
358 r = sshbuf_put_u8(arg, c);
359 break;
360 case '\\':
361 case '\'':
362 case '"':
363 if ((r = sshbuf_put_u8(arg, '\\')) != 0)
364 break;
365 /* FALLTHROUGH */
366 default:
367 r = sshbuf_put_u8(arg, c);
368 break;
369 }
370 if (r != 0)
371 fatal("%s: sshbuf_put_u8: %s",
372 __func__, ssh_err(r));
373 }
374 if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) ||
375 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) ||
376 (r = sshbuf_putb(buf, arg)) != 0 ||
377 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0))
378 fatal("%s: buffer error: %s", __func__, ssh_err(r));
379 }
380 if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL)
381 fatal("%s: malloc failed", __func__);
382 memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf));
383 ret[sshbuf_len(buf)] = '\0';
384 sshbuf_free(buf);
385 sshbuf_free(arg);
386 return ret;
387}
388
389/*
390 * Runs command in a subprocess. Returns pid on success and a FILE* to the
391 * subprocess' stdout or 0 on failure.
392 * NB. "command" is only used for logging.
393 */
394static pid_t
395subprocess(const char *tag, struct passwd *pw, const char *command,
396 int ac, char **av, FILE **child)
397{
398 FILE *f;
399 struct stat st;
400 int devnull, p[2], i;
401 pid_t pid;
402 char *cp, errmsg[512];
403 u_int envsize;
404 char **child_env;
405
406 *child = NULL;
407
408 debug3("%s: %s command \"%s\" running as %s", __func__,
409 tag, command, pw->pw_name);
410
411 /* Verify the path exists and is safe-ish to execute */
412 if (*av[0] != '/') {
413 error("%s path is not absolute", tag);
414 return 0;
415 }
416 temporarily_use_uid(pw);
417 if (stat(av[0], &st) < 0) {
418 error("Could not stat %s \"%s\": %s", tag,
419 av[0], strerror(errno));
420 restore_uid();
421 return 0;
422 }
423 if (auth_secure_path(av[0], &st, NULL, 0,
424 errmsg, sizeof(errmsg)) != 0) {
425 error("Unsafe %s \"%s\": %s", tag, av[0], errmsg);
426 restore_uid();
427 return 0;
428 }
429
430 /*
431 * Run the command; stderr is left in place, stdout is the
432 * authorized_keys output.
433 */
434 if (pipe(p) != 0) {
435 error("%s: pipe: %s", tag, strerror(errno));
436 restore_uid();
437 return 0;
438 }
439
440 /*
441 * Don't want to call this in the child, where it can fatal() and
442 * run cleanup_exit() code.
443 */
444 restore_uid();
445
446 switch ((pid = fork())) {
447 case -1: /* error */
448 error("%s: fork: %s", tag, strerror(errno));
449 close(p[0]);
450 close(p[1]);
451 return 0;
452 case 0: /* child */
453 /* Prepare a minimal environment for the child. */
454 envsize = 5;
455 child_env = xcalloc(sizeof(*child_env), envsize);
456 child_set_env(&child_env, &envsize, "PATH", _PATH_STDPATH);
457 child_set_env(&child_env, &envsize, "USER", pw->pw_name);
458 child_set_env(&child_env, &envsize, "LOGNAME", pw->pw_name);
459 child_set_env(&child_env, &envsize, "HOME", pw->pw_dir);
460 if ((cp = getenv("LANG")) != NULL)
461 child_set_env(&child_env, &envsize, "LANG", cp);
462
463 for (i = 0; i < NSIG; i++)
464 signal(i, SIG_DFL);
465
466 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
467 error("%s: open %s: %s", tag, _PATH_DEVNULL,
468 strerror(errno));
469 _exit(1);
470 }
471 /* Keep stderr around a while longer to catch errors */
472 if (dup2(devnull, STDIN_FILENO) == -1 ||
473 dup2(p[1], STDOUT_FILENO) == -1) {
474 error("%s: dup2: %s", tag, strerror(errno));
475 _exit(1);
476 }
477 closefrom(STDERR_FILENO + 1);
478
479 /* Don't use permanently_set_uid() here to avoid fatal() */
480 if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
481 error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid,
482 strerror(errno));
483 _exit(1);
484 }
485 if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
486 error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid,
487 strerror(errno));
488 _exit(1);
489 }
490 /* stdin is pointed to /dev/null at this point */
491 if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
492 error("%s: dup2: %s", tag, strerror(errno));
493 _exit(1);
494 }
495
496 execve(av[0], av, child_env);
497 error("%s exec \"%s\": %s", tag, command, strerror(errno));
498 _exit(127);
499 default: /* parent */
500 break;
501 }
502
503 close(p[1]);
504 if ((f = fdopen(p[0], "r")) == NULL) {
505 error("%s: fdopen: %s", tag, strerror(errno));
506 close(p[0]);
507 /* Don't leave zombie child */
508 kill(pid, SIGTERM);
509 while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
510 ;
511 return 0;
512 }
513 /* Success */
514 debug3("%s: %s pid %ld", __func__, tag, (long)pid);
515 *child = f;
516 return pid;
517}
518
519/* Returns 0 if pid exited cleanly, non-zero otherwise */
520static int
521exited_cleanly(pid_t pid, const char *tag, const char *cmd)
522{
523 int status;
524
525 while (waitpid(pid, &status, 0) == -1) {
526 if (errno != EINTR) {
527 error("%s: waitpid: %s", tag, strerror(errno));
528 return -1;
529 }
530 }
531 if (WIFSIGNALED(status)) {
532 error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status));
533 return -1;
534 } else if (WEXITSTATUS(status) != 0) {
535 error("%s %s failed, status %d", tag, cmd, WEXITSTATUS(status));
536 return -1;
537 }
538 return 0;
539}
540
541static int 244static int
542match_principals_option(const char *principal_list, struct sshkey_cert *cert) 245match_principals_option(const char *principal_list, struct sshkey_cert *cert)
543{ 246{
@@ -559,7 +262,7 @@ match_principals_option(const char *principal_list, struct sshkey_cert *cert)
559} 262}
560 263
561static int 264static int
562process_principals(FILE *f, char *file, struct passwd *pw, 265process_principals(FILE *f, const char *file, struct passwd *pw,
563 const struct sshkey_cert *cert) 266 const struct sshkey_cert *cert)
564{ 267{
565 char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; 268 char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
@@ -597,8 +300,7 @@ process_principals(FILE *f, char *file, struct passwd *pw,
597 for (i = 0; i < cert->nprincipals; i++) { 300 for (i = 0; i < cert->nprincipals; i++) {
598 if (strcmp(cp, cert->principals[i]) == 0) { 301 if (strcmp(cp, cert->principals[i]) == 0) {
599 debug3("%s:%lu: matched principal \"%.100s\"", 302 debug3("%s:%lu: matched principal \"%.100s\"",
600 file == NULL ? "(command)" : file, 303 file, linenum, cert->principals[i]);
601 linenum, cert->principals[i]);
602 if (auth_parse_options(pw, line_opts, 304 if (auth_parse_options(pw, line_opts,
603 file, linenum) != 1) 305 file, linenum) != 1)
604 continue; 306 continue;
@@ -671,7 +373,7 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key)
671 } 373 }
672 374
673 /* Turn the command into an argument vector */ 375 /* Turn the command into an argument vector */
674 if (split_argv(options.authorized_principals_command, &ac, &av) != 0) { 376 if (argv_split(options.authorized_principals_command, &ac, &av) != 0) {
675 error("AuthorizedPrincipalsCommand \"%s\" contains " 377 error("AuthorizedPrincipalsCommand \"%s\" contains "
676 "invalid quotes", command); 378 "invalid quotes", command);
677 goto out; 379 goto out;
@@ -720,21 +422,22 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key)
720 av[i] = tmp; 422 av[i] = tmp;
721 } 423 }
722 /* Prepare a printable command for logs, etc. */ 424 /* Prepare a printable command for logs, etc. */
723 command = assemble_argv(ac, av); 425 command = argv_assemble(ac, av);
724 426
725 if ((pid = subprocess("AuthorizedPrincipalsCommand", pw, command, 427 if ((pid = subprocess("AuthorizedPrincipalsCommand", pw, command,
726 ac, av, &f)) == 0) 428 ac, av, &f,
429 SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
727 goto out; 430 goto out;
728 431
729 uid_swapped = 1; 432 uid_swapped = 1;
730 temporarily_use_uid(pw); 433 temporarily_use_uid(pw);
731 434
732 ok = process_principals(f, NULL, pw, cert); 435 ok = process_principals(f, "(command)", pw, cert);
733 436
734 fclose(f); 437 fclose(f);
735 f = NULL; 438 f = NULL;
736 439
737 if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0) 440 if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command, 0) != 0)
738 goto out; 441 goto out;
739 442
740 /* Read completed successfully */ 443 /* Read completed successfully */
@@ -761,26 +464,25 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key)
761 * returns 1 if the key is allowed or 0 otherwise. 464 * returns 1 if the key is allowed or 0 otherwise.
762 */ 465 */
763static int 466static int
764check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) 467check_authkeys_file(FILE *f, char *file, struct sshkey *key, struct passwd *pw)
765{ 468{
766 char line[SSH_MAX_PUBKEY_BYTES]; 469 char line[SSH_MAX_PUBKEY_BYTES];
767 int found_key = 0; 470 int found_key = 0;
768 u_long linenum = 0; 471 u_long linenum = 0;
769 Key *found; 472 struct sshkey *found = NULL;
770
771 found_key = 0;
772 473
773 found = NULL;
774 while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { 474 while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
775 char *cp, *key_options = NULL, *fp = NULL; 475 char *cp, *key_options = NULL, *fp = NULL;
776 const char *reason = NULL; 476 const char *reason = NULL;
777 477
778 /* Always consume entrire file */ 478 /* Always consume entire file */
779 if (found_key) 479 if (found_key)
780 continue; 480 continue;
781 if (found != NULL) 481 if (found != NULL)
782 key_free(found); 482 sshkey_free(found);
783 found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); 483 found = sshkey_new(sshkey_is_cert(key) ? KEY_UNSPEC : key->type);
484 if (found == NULL)
485 goto done;
784 auth_clear_options(); 486 auth_clear_options();
785 487
786 /* Skip leading whitespace, empty and comment lines. */ 488 /* Skip leading whitespace, empty and comment lines. */
@@ -789,7 +491,7 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
789 if (!*cp || *cp == '\n' || *cp == '#') 491 if (!*cp || *cp == '\n' || *cp == '#')
790 continue; 492 continue;
791 493
792 if (key_read(found, &cp) != 1) { 494 if (sshkey_read(found, &cp) != 0) {
793 /* no key? check if there are options for this key */ 495 /* no key? check if there are options for this key */
794 int quoted = 0; 496 int quoted = 0;
795 debug2("user_key_allowed: check options: '%s'", cp); 497 debug2("user_key_allowed: check options: '%s'", cp);
@@ -803,14 +505,14 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
803 /* Skip remaining whitespace. */ 505 /* Skip remaining whitespace. */
804 for (; *cp == ' ' || *cp == '\t'; cp++) 506 for (; *cp == ' ' || *cp == '\t'; cp++)
805 ; 507 ;
806 if (key_read(found, &cp) != 1) { 508 if (sshkey_read(found, &cp) != 0) {
807 debug2("user_key_allowed: advance: '%s'", cp); 509 debug2("user_key_allowed: advance: '%s'", cp);
808 /* still no key? advance to next line*/ 510 /* still no key? advance to next line*/
809 continue; 511 continue;
810 } 512 }
811 } 513 }
812 if (key_is_cert(key)) { 514 if (sshkey_is_cert(key)) {
813 if (!key_equal(found, key->cert->signature_key)) 515 if (!sshkey_equal(found, key->cert->signature_key))
814 continue; 516 continue;
815 if (auth_parse_options(pw, key_options, file, 517 if (auth_parse_options(pw, key_options, file,
816 linenum) != 1) 518 linenum) != 1)
@@ -821,7 +523,7 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
821 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) 523 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
822 continue; 524 continue;
823 debug("matching CA found: file %s, line %lu, %s %s", 525 debug("matching CA found: file %s, line %lu, %s %s",
824 file, linenum, key_type(found), fp); 526 file, linenum, sshkey_type(found), fp);
825 /* 527 /*
826 * If the user has specified a list of principals as 528 * If the user has specified a list of principals as
827 * a key option, then prefer that list to matching 529 * a key option, then prefer that list to matching
@@ -838,7 +540,7 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
838 auth_debug_add("%s", reason); 540 auth_debug_add("%s", reason);
839 continue; 541 continue;
840 } 542 }
841 if (key_cert_check_authority(key, 0, 0, 543 if (sshkey_cert_check_authority(key, 0, 0,
842 authorized_principals == NULL ? pw->pw_name : NULL, 544 authorized_principals == NULL ? pw->pw_name : NULL,
843 &reason) != 0) 545 &reason) != 0)
844 goto fail_reason; 546 goto fail_reason;
@@ -847,11 +549,11 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
847 verbose("Accepted certificate ID \"%s\" (serial %llu) " 549 verbose("Accepted certificate ID \"%s\" (serial %llu) "
848 "signed by %s CA %s via %s", key->cert->key_id, 550 "signed by %s CA %s via %s", key->cert->key_id,
849 (unsigned long long)key->cert->serial, 551 (unsigned long long)key->cert->serial,
850 key_type(found), fp, file); 552 sshkey_type(found), fp, file);
851 free(fp); 553 free(fp);
852 found_key = 1; 554 found_key = 1;
853 break; 555 break;
854 } else if (key_equal(found, key)) { 556 } else if (sshkey_equal(found, key)) {
855 if (auth_parse_options(pw, key_options, file, 557 if (auth_parse_options(pw, key_options, file,
856 linenum) != 1) 558 linenum) != 1)
857 continue; 559 continue;
@@ -861,14 +563,15 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
861 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) 563 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
862 continue; 564 continue;
863 debug("matching key found: file %s, line %lu %s %s", 565 debug("matching key found: file %s, line %lu %s %s",
864 file, linenum, key_type(found), fp); 566 file, linenum, sshkey_type(found), fp);
865 free(fp); 567 free(fp);
866 found_key = 1; 568 found_key = 1;
867 continue; 569 continue;
868 } 570 }
869 } 571 }
572 done:
870 if (found != NULL) 573 if (found != NULL)
871 key_free(found); 574 sshkey_free(found);
872 if (!found_key) 575 if (!found_key)
873 debug2("key not found"); 576 debug2("key not found");
874 return found_key; 577 return found_key;
@@ -876,24 +579,24 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
876 579
877/* Authenticate a certificate key against TrustedUserCAKeys */ 580/* Authenticate a certificate key against TrustedUserCAKeys */
878static int 581static int
879user_cert_trusted_ca(struct passwd *pw, Key *key) 582user_cert_trusted_ca(struct passwd *pw, struct sshkey *key)
880{ 583{
881 char *ca_fp, *principals_file = NULL; 584 char *ca_fp, *principals_file = NULL;
882 const char *reason; 585 const char *reason;
883 int ret = 0, found_principal = 0, use_authorized_principals; 586 int r, ret = 0, found_principal = 0, use_authorized_principals;
884 587
885 if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) 588 if (!sshkey_is_cert(key) || options.trusted_user_ca_keys == NULL)
886 return 0; 589 return 0;
887 590
888 if ((ca_fp = sshkey_fingerprint(key->cert->signature_key, 591 if ((ca_fp = sshkey_fingerprint(key->cert->signature_key,
889 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) 592 options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
890 return 0; 593 return 0;
891 594
892 if (sshkey_in_file(key->cert->signature_key, 595 if ((r = sshkey_in_file(key->cert->signature_key,
893 options.trusted_user_ca_keys, 1, 0) != 0) { 596 options.trusted_user_ca_keys, 1, 0)) != 0) {
894 debug2("%s: CA %s %s is not listed in %s", __func__, 597 debug2("%s: CA %s %s is not listed in %s: %s", __func__,
895 key_type(key->cert->signature_key), ca_fp, 598 sshkey_type(key->cert->signature_key), ca_fp,
896 options.trusted_user_ca_keys); 599 options.trusted_user_ca_keys, ssh_err(r));
897 goto out; 600 goto out;
898 } 601 }
899 /* 602 /*
@@ -918,7 +621,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
918 auth_debug_add("%s", reason); 621 auth_debug_add("%s", reason);
919 goto out; 622 goto out;
920 } 623 }
921 if (key_cert_check_authority(key, 0, 1, 624 if (sshkey_cert_check_authority(key, 0, 1,
922 use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) 625 use_authorized_principals ? NULL : pw->pw_name, &reason) != 0)
923 goto fail_reason; 626 goto fail_reason;
924 if (auth_cert_options(key, pw, &reason) != 0) 627 if (auth_cert_options(key, pw, &reason) != 0)
@@ -927,7 +630,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
927 verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " 630 verbose("Accepted certificate ID \"%s\" (serial %llu) signed by "
928 "%s CA %s via %s", key->cert->key_id, 631 "%s CA %s via %s", key->cert->key_id,
929 (unsigned long long)key->cert->serial, 632 (unsigned long long)key->cert->serial,
930 key_type(key->cert->signature_key), ca_fp, 633 sshkey_type(key->cert->signature_key), ca_fp,
931 options.trusted_user_ca_keys); 634 options.trusted_user_ca_keys);
932 ret = 1; 635 ret = 1;
933 636
@@ -942,7 +645,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
942 * returns 1 if the key is allowed or 0 otherwise. 645 * returns 1 if the key is allowed or 0 otherwise.
943 */ 646 */
944static int 647static int
945user_key_allowed2(struct passwd *pw, Key *key, char *file) 648user_key_allowed2(struct passwd *pw, struct sshkey *key, char *file)
946{ 649{
947 FILE *f; 650 FILE *f;
948 int found_key = 0; 651 int found_key = 0;
@@ -965,7 +668,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
965 * returns 1 if the key is allowed or 0 otherwise. 668 * returns 1 if the key is allowed or 0 otherwise.
966 */ 669 */
967static int 670static int
968user_key_command_allowed2(struct passwd *user_pw, Key *key) 671user_key_command_allowed2(struct passwd *user_pw, struct sshkey *key)
969{ 672{
970 FILE *f = NULL; 673 FILE *f = NULL;
971 int r, ok, found_key = 0; 674 int r, ok, found_key = 0;
@@ -1011,7 +714,7 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
1011 } 714 }
1012 715
1013 /* Turn the command into an argument vector */ 716 /* Turn the command into an argument vector */
1014 if (split_argv(options.authorized_keys_command, &ac, &av) != 0) { 717 if (argv_split(options.authorized_keys_command, &ac, &av) != 0) {
1015 error("AuthorizedKeysCommand \"%s\" contains invalid quotes", 718 error("AuthorizedKeysCommand \"%s\" contains invalid quotes",
1016 command); 719 command);
1017 goto out; 720 goto out;
@@ -1035,7 +738,7 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
1035 av[i] = tmp; 738 av[i] = tmp;
1036 } 739 }
1037 /* Prepare a printable command for logs, etc. */ 740 /* Prepare a printable command for logs, etc. */
1038 command = assemble_argv(ac, av); 741 command = argv_assemble(ac, av);
1039 742
1040 /* 743 /*
1041 * If AuthorizedKeysCommand was run without arguments 744 * If AuthorizedKeysCommand was run without arguments
@@ -1052,7 +755,8 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
1052 } 755 }
1053 756
1054 if ((pid = subprocess("AuthorizedKeysCommand", pw, command, 757 if ((pid = subprocess("AuthorizedKeysCommand", pw, command,
1055 ac, av, &f)) == 0) 758 ac, av, &f,
759 SSH_SUBPROCESS_STDOUT_CAPTURE|SSH_SUBPROCESS_STDERR_DISCARD)) == 0)
1056 goto out; 760 goto out;
1057 761
1058 uid_swapped = 1; 762 uid_swapped = 1;
@@ -1063,7 +767,7 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
1063 fclose(f); 767 fclose(f);
1064 f = NULL; 768 f = NULL;
1065 769
1066 if (exited_cleanly(pid, "AuthorizedKeysCommand", command) != 0) 770 if (exited_cleanly(pid, "AuthorizedKeysCommand", command, 0) != 0)
1067 goto out; 771 goto out;
1068 772
1069 /* Read completed successfully */ 773 /* Read completed successfully */
@@ -1088,14 +792,15 @@ user_key_command_allowed2(struct passwd *user_pw, Key *key)
1088 * Check whether key authenticates and authorises the user. 792 * Check whether key authenticates and authorises the user.
1089 */ 793 */
1090int 794int
1091user_key_allowed(struct passwd *pw, Key *key, int auth_attempt) 795user_key_allowed(struct passwd *pw, struct sshkey *key, int auth_attempt)
1092{ 796{
1093 u_int success, i; 797 u_int success, i;
1094 char *file; 798 char *file;
1095 799
1096 if (auth_key_is_revoked(key)) 800 if (auth_key_is_revoked(key))
1097 return 0; 801 return 0;
1098 if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key)) 802 if (sshkey_is_cert(key) &&
803 auth_key_is_revoked(key->cert->signature_key))
1099 return 0; 804 return 0;
1100 805
1101 success = user_cert_trusted_ca(pw, key); 806 success = user_cert_trusted_ca(pw, key);
@@ -1120,35 +825,6 @@ user_key_allowed(struct passwd *pw, Key *key, int auth_attempt)
1120 return success; 825 return success;
1121} 826}
1122 827
1123/* Records a public key in the list of previously-successful keys */
1124void
1125auth2_record_userkey(Authctxt *authctxt, struct sshkey *key)
1126{
1127 struct sshkey **tmp;
1128
1129 if (authctxt->nprev_userkeys >= INT_MAX ||
1130 (tmp = reallocarray(authctxt->prev_userkeys,
1131 authctxt->nprev_userkeys + 1, sizeof(*tmp))) == NULL)
1132 fatal("%s: reallocarray failed", __func__);
1133 authctxt->prev_userkeys = tmp;
1134 authctxt->prev_userkeys[authctxt->nprev_userkeys] = key;
1135 authctxt->nprev_userkeys++;
1136}
1137
1138/* Checks whether a key has already been used successfully for authentication */
1139int
1140auth2_userkey_already_used(Authctxt *authctxt, struct sshkey *key)
1141{
1142 u_int i;
1143
1144 for (i = 0; i < authctxt->nprev_userkeys; i++) {
1145 if (sshkey_equal_public(key, authctxt->prev_userkeys[i])) {
1146 return 1;
1147 }
1148 }
1149 return 0;
1150}
1151
1152Authmethod method_pubkey = { 828Authmethod method_pubkey = {
1153 "publickey", 829 "publickey",
1154 userauth_pubkey, 830 userauth_pubkey,
diff --git a/auth2.c b/auth2.c
index 97dd2ef0a..862e09960 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2.c,v 1.137 2017/02/03 23:05:57 djm Exp $ */ 1/* $OpenBSD: auth2.c,v 1.143 2017/06/24 06:34:38 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -30,6 +30,7 @@
30#include <sys/uio.h> 30#include <sys/uio.h>
31 31
32#include <fcntl.h> 32#include <fcntl.h>
33#include <limits.h>
33#include <pwd.h> 34#include <pwd.h>
34#include <stdarg.h> 35#include <stdarg.h>
35#include <string.h> 36#include <string.h>
@@ -55,6 +56,7 @@
55#include "ssh-gss.h" 56#include "ssh-gss.h"
56#endif 57#endif
57#include "monitor_wrap.h" 58#include "monitor_wrap.h"
59#include "ssherr.h"
58 60
59/* import */ 61/* import */
60extern ServerOptions options; 62extern ServerOptions options;
@@ -87,8 +89,8 @@ Authmethod *authmethods[] = {
87 89
88/* protocol */ 90/* protocol */
89 91
90static int input_service_request(int, u_int32_t, void *); 92static int input_service_request(int, u_int32_t, struct ssh *);
91static int input_userauth_request(int, u_int32_t, void *); 93static int input_userauth_request(int, u_int32_t, struct ssh *);
92 94
93/* helper */ 95/* helper */
94static Authmethod *authmethod_lookup(Authctxt *, const char *); 96static Authmethod *authmethod_lookup(Authctxt *, const char *);
@@ -168,16 +170,19 @@ done:
168void 170void
169do_authentication2(Authctxt *authctxt) 171do_authentication2(Authctxt *authctxt)
170{ 172{
171 dispatch_init(&dispatch_protocol_error); 173 struct ssh *ssh = active_state; /* XXX */
172 dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); 174 ssh->authctxt = authctxt; /* XXX move to caller */
173 dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); 175 ssh_dispatch_init(ssh, &dispatch_protocol_error);
176 ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request);
177 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success);
178 ssh->authctxt = NULL;
174} 179}
175 180
176/*ARGSUSED*/ 181/*ARGSUSED*/
177static int 182static int
178input_service_request(int type, u_int32_t seq, void *ctxt) 183input_service_request(int type, u_int32_t seq, struct ssh *ssh)
179{ 184{
180 Authctxt *authctxt = ctxt; 185 Authctxt *authctxt = ssh->authctxt;
181 u_int len; 186 u_int len;
182 int acceptit = 0; 187 int acceptit = 0;
183 char *service = packet_get_cstring(&len); 188 char *service = packet_get_cstring(&len);
@@ -190,7 +195,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
190 if (!authctxt->success) { 195 if (!authctxt->success) {
191 acceptit = 1; 196 acceptit = 1;
192 /* now we can handle user-auth requests */ 197 /* now we can handle user-auth requests */
193 dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); 198 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
194 } 199 }
195 } 200 }
196 /* XXX all other service requests are denied */ 201 /* XXX all other service requests are denied */
@@ -210,10 +215,9 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
210 215
211/*ARGSUSED*/ 216/*ARGSUSED*/
212static int 217static int
213input_userauth_request(int type, u_int32_t seq, void *ctxt) 218input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
214{ 219{
215 struct ssh *ssh = active_state; /* XXX */ 220 Authctxt *authctxt = ssh->authctxt;
216 Authctxt *authctxt = ctxt;
217 Authmethod *m = NULL; 221 Authmethod *m = NULL;
218 char *user, *service, *method, *style = NULL; 222 char *user, *service, *method, *style = NULL;
219 int authenticated = 0; 223 int authenticated = 0;
@@ -267,14 +271,15 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
267 authctxt->user, authctxt->service, user, service); 271 authctxt->user, authctxt->service, user, service);
268 } 272 }
269 /* reset state */ 273 /* reset state */
270 auth2_challenge_stop(authctxt); 274 auth2_challenge_stop(ssh);
271 275
272#ifdef GSSAPI 276#ifdef GSSAPI
273 /* XXX move to auth2_gssapi_stop() */ 277 /* XXX move to auth2_gssapi_stop() */
274 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 278 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
275 dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 279 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
276#endif 280#endif
277 281
282 auth2_authctxt_reset_info(authctxt);
278 authctxt->postponed = 0; 283 authctxt->postponed = 0;
279 authctxt->server_caused_failure = 0; 284 authctxt->server_caused_failure = 0;
280 285
@@ -282,9 +287,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
282 m = authmethod_lookup(authctxt, method); 287 m = authmethod_lookup(authctxt, method);
283 if (m != NULL && authctxt->failures < options.max_authtries) { 288 if (m != NULL && authctxt->failures < options.max_authtries) {
284 debug2("input_userauth_request: try method %s", method); 289 debug2("input_userauth_request: try method %s", method);
285 authenticated = m->userauth(authctxt); 290 authenticated = m->userauth(ssh);
286 } 291 }
287 userauth_finish(authctxt, authenticated, method, NULL); 292 userauth_finish(ssh, authenticated, method, NULL);
288 293
289 free(service); 294 free(service);
290 free(user); 295 free(user);
@@ -293,10 +298,10 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
293} 298}
294 299
295void 300void
296userauth_finish(Authctxt *authctxt, int authenticated, const char *method, 301userauth_finish(struct ssh *ssh, int authenticated, const char *method,
297 const char *submethod) 302 const char *submethod)
298{ 303{
299 struct ssh *ssh = active_state; /* XXX */ 304 Authctxt *authctxt = ssh->authctxt;
300 char *methods; 305 char *methods;
301 int partial = 0; 306 int partial = 0;
302 307
@@ -325,6 +330,10 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
325 /* Log before sending the reply */ 330 /* Log before sending the reply */
326 auth_log(authctxt, authenticated, partial, method, submethod); 331 auth_log(authctxt, authenticated, partial, method, submethod);
327 332
333 /* Update information exposed to session */
334 if (authenticated || partial)
335 auth2_update_session_info(authctxt, method, submethod);
336
328 if (authctxt->postponed) 337 if (authctxt->postponed)
329 return; 338 return;
330 339
@@ -352,7 +361,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
352 361
353 if (authenticated == 1) { 362 if (authenticated == 1) {
354 /* turn off userauth */ 363 /* turn off userauth */
355 dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); 364 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
356 packet_start(SSH2_MSG_USERAUTH_SUCCESS); 365 packet_start(SSH2_MSG_USERAUTH_SUCCESS);
357 packet_send(); 366 packet_send();
358 packet_write_wait(); 367 packet_write_wait();
@@ -622,4 +631,128 @@ auth2_update_methods_lists(Authctxt *authctxt, const char *method,
622 return 0; 631 return 0;
623} 632}
624 633
634/* Reset method-specific information */
635void auth2_authctxt_reset_info(Authctxt *authctxt)
636{
637 sshkey_free(authctxt->auth_method_key);
638 free(authctxt->auth_method_info);
639 authctxt->auth_method_key = NULL;
640 authctxt->auth_method_info = NULL;
641}
642
643/* Record auth method-specific information for logs */
644void
645auth2_record_info(Authctxt *authctxt, const char *fmt, ...)
646{
647 va_list ap;
648 int i;
649
650 free(authctxt->auth_method_info);
651 authctxt->auth_method_info = NULL;
652
653 va_start(ap, fmt);
654 i = vasprintf(&authctxt->auth_method_info, fmt, ap);
655 va_end(ap);
656
657 if (i < 0 || authctxt->auth_method_info == NULL)
658 fatal("%s: vasprintf failed", __func__);
659}
660
661/*
662 * Records a public key used in authentication. This is used for logging
663 * and to ensure that the same key is not subsequently accepted again for
664 * multiple authentication.
665 */
666void
667auth2_record_key(Authctxt *authctxt, int authenticated,
668 const struct sshkey *key)
669{
670 struct sshkey **tmp, *dup;
671 int r;
672
673 if ((r = sshkey_demote(key, &dup)) != 0)
674 fatal("%s: copy key: %s", __func__, ssh_err(r));
675 sshkey_free(authctxt->auth_method_key);
676 authctxt->auth_method_key = dup;
677
678 if (!authenticated)
679 return;
680
681 /* If authenticated, make sure we don't accept this key again */
682 if ((r = sshkey_demote(key, &dup)) != 0)
683 fatal("%s: copy key: %s", __func__, ssh_err(r));
684 if (authctxt->nprev_keys >= INT_MAX ||
685 (tmp = recallocarray(authctxt->prev_keys, authctxt->nprev_keys,
686 authctxt->nprev_keys + 1, sizeof(*authctxt->prev_keys))) == NULL)
687 fatal("%s: reallocarray failed", __func__);
688 authctxt->prev_keys = tmp;
689 authctxt->prev_keys[authctxt->nprev_keys] = dup;
690 authctxt->nprev_keys++;
691
692}
693
694/* Checks whether a key has already been previously used for authentication */
695int
696auth2_key_already_used(Authctxt *authctxt, const struct sshkey *key)
697{
698 u_int i;
699 char *fp;
700
701 for (i = 0; i < authctxt->nprev_keys; i++) {
702 if (sshkey_equal_public(key, authctxt->prev_keys[i])) {
703 fp = sshkey_fingerprint(authctxt->prev_keys[i],
704 options.fingerprint_hash, SSH_FP_DEFAULT);
705 debug3("%s: key already used: %s %s", __func__,
706 sshkey_type(authctxt->prev_keys[i]),
707 fp == NULL ? "UNKNOWN" : fp);
708 free(fp);
709 return 1;
710 }
711 }
712 return 0;
713}
714
715/*
716 * Updates authctxt->session_info with details of authentication. Should be
717 * whenever an authentication method succeeds.
718 */
719void
720auth2_update_session_info(Authctxt *authctxt, const char *method,
721 const char *submethod)
722{
723 int r;
724
725 if (authctxt->session_info == NULL) {
726 if ((authctxt->session_info = sshbuf_new()) == NULL)
727 fatal("%s: sshbuf_new", __func__);
728 }
729
730 /* Append method[/submethod] */
731 if ((r = sshbuf_putf(authctxt->session_info, "%s%s%s",
732 method, submethod == NULL ? "" : "/",
733 submethod == NULL ? "" : submethod)) != 0)
734 fatal("%s: append method: %s", __func__, ssh_err(r));
735
736 /* Append key if present */
737 if (authctxt->auth_method_key != NULL) {
738 if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
739 (r = sshkey_format_text(authctxt->auth_method_key,
740 authctxt->session_info)) != 0)
741 fatal("%s: append key: %s", __func__, ssh_err(r));
742 }
743
744 if (authctxt->auth_method_info != NULL) {
745 /* Ensure no ambiguity here */
746 if (strchr(authctxt->auth_method_info, '\n') != NULL)
747 fatal("%s: auth_method_info contains \\n", __func__);
748 if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
749 (r = sshbuf_putf(authctxt->session_info, "%s",
750 authctxt->auth_method_info)) != 0) {
751 fatal("%s: append method info: %s",
752 __func__, ssh_err(r));
753 }
754 }
755 if ((r = sshbuf_put_u8(authctxt->session_info, '\n')) != 0)
756 fatal("%s: append: %s", __func__, ssh_err(r));
757}
625 758
diff --git a/authfd.c b/authfd.c
index a634bcb81..a460fa350 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfd.c,v 1.100 2015/12/04 16:41:28 markus Exp $ */ 1/* $OpenBSD: authfd.c,v 1.105 2017/07/01 13:50:45 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -51,7 +51,6 @@
51 51
52#include "xmalloc.h" 52#include "xmalloc.h"
53#include "ssh.h" 53#include "ssh.h"
54#include "rsa.h"
55#include "sshbuf.h" 54#include "sshbuf.h"
56#include "sshkey.h" 55#include "sshkey.h"
57#include "authfd.h" 56#include "authfd.h"
@@ -199,43 +198,6 @@ ssh_lock_agent(int sock, int lock, const char *password)
199 return r; 198 return r;
200} 199}
201 200
202#ifdef WITH_SSH1
203static int
204deserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
205{
206 struct sshkey *key;
207 int r, keybits;
208 u_int32_t bits;
209 char *comment = NULL;
210
211 if ((key = sshkey_new(KEY_RSA1)) == NULL)
212 return SSH_ERR_ALLOC_FAIL;
213 if ((r = sshbuf_get_u32(ids, &bits)) != 0 ||
214 (r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 ||
215 (r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 ||
216 (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0)
217 goto out;
218 keybits = BN_num_bits(key->rsa->n);
219 /* XXX previously we just warned here. I think we should be strict */
220 if (keybits < 0 || bits != (u_int)keybits) {
221 r = SSH_ERR_KEY_BITS_MISMATCH;
222 goto out;
223 }
224 if (keyp != NULL) {
225 *keyp = key;
226 key = NULL;
227 }
228 if (commentp != NULL) {
229 *commentp = comment;
230 comment = NULL;
231 }
232 r = 0;
233 out:
234 sshkey_free(key);
235 free(comment);
236 return r;
237}
238#endif
239 201
240static int 202static int
241deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp) 203deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
@@ -264,35 +226,21 @@ deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
264 * Fetch list of identities held by the agent. 226 * Fetch list of identities held by the agent.
265 */ 227 */
266int 228int
267ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp) 229ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp)
268{ 230{
269 u_char type, code1 = 0, code2 = 0; 231 u_char type;
270 u_int32_t num, i; 232 u_int32_t num, i;
271 struct sshbuf *msg; 233 struct sshbuf *msg;
272 struct ssh_identitylist *idl = NULL; 234 struct ssh_identitylist *idl = NULL;
273 int r; 235 int r;
274 236
275 /* Determine request and expected response types */
276 switch (version) {
277 case 1:
278 code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
279 code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
280 break;
281 case 2:
282 code1 = SSH2_AGENTC_REQUEST_IDENTITIES;
283 code2 = SSH2_AGENT_IDENTITIES_ANSWER;
284 break;
285 default:
286 return SSH_ERR_INVALID_ARGUMENT;
287 }
288
289 /* 237 /*
290 * Send a message to the agent requesting for a list of the 238 * Send a message to the agent requesting for a list of the
291 * identities it can represent. 239 * identities it can represent.
292 */ 240 */
293 if ((msg = sshbuf_new()) == NULL) 241 if ((msg = sshbuf_new()) == NULL)
294 return SSH_ERR_ALLOC_FAIL; 242 return SSH_ERR_ALLOC_FAIL;
295 if ((r = sshbuf_put_u8(msg, code1)) != 0) 243 if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_REQUEST_IDENTITIES)) != 0)
296 goto out; 244 goto out;
297 245
298 if ((r = ssh_request_reply(sock, msg, msg)) != 0) 246 if ((r = ssh_request_reply(sock, msg, msg)) != 0)
@@ -304,7 +252,7 @@ ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)
304 if (agent_failed(type)) { 252 if (agent_failed(type)) {
305 r = SSH_ERR_AGENT_FAILURE; 253 r = SSH_ERR_AGENT_FAILURE;
306 goto out; 254 goto out;
307 } else if (type != code2) { 255 } else if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
308 r = SSH_ERR_INVALID_FORMAT; 256 r = SSH_ERR_INVALID_FORMAT;
309 goto out; 257 goto out;
310 } 258 }
@@ -329,25 +277,14 @@ ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)
329 goto out; 277 goto out;
330 } 278 }
331 for (i = 0; i < num;) { 279 for (i = 0; i < num;) {
332 switch (version) { 280 if ((r = deserialise_identity2(msg, &(idl->keys[i]),
333 case 1: 281 &(idl->comments[i]))) != 0) {
334#ifdef WITH_SSH1 282 if (r == SSH_ERR_KEY_TYPE_UNKNOWN) {
335 if ((r = deserialise_identity1(msg, 283 /* Gracefully skip unknown key types */
336 &(idl->keys[i]), &(idl->comments[i]))) != 0) 284 num--;
285 continue;
286 } else
337 goto out; 287 goto out;
338#endif
339 break;
340 case 2:
341 if ((r = deserialise_identity2(msg,
342 &(idl->keys[i]), &(idl->comments[i]))) != 0) {
343 if (r == SSH_ERR_KEY_TYPE_UNKNOWN) {
344 /* Gracefully skip unknown key types */
345 num--;
346 continue;
347 } else
348 goto out;
349 }
350 break;
351 } 288 }
352 i++; 289 i++;
353 } 290 }
@@ -385,50 +322,10 @@ ssh_free_identitylist(struct ssh_identitylist *idl)
385 * otherwise. 322 * otherwise.
386 */ 323 */
387 324
388#ifdef WITH_SSH1
389int
390ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
391 u_char session_id[16], u_char response[16])
392{
393 struct sshbuf *msg;
394 int r;
395 u_char type;
396
397 if (key->type != KEY_RSA1)
398 return SSH_ERR_INVALID_ARGUMENT;
399 if ((msg = sshbuf_new()) == NULL)
400 return SSH_ERR_ALLOC_FAIL;
401 if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 ||
402 (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
403 (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
404 (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 ||
405 (r = sshbuf_put_bignum1(msg, challenge)) != 0 ||
406 (r = sshbuf_put(msg, session_id, 16)) != 0 ||
407 (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */
408 goto out;
409 if ((r = ssh_request_reply(sock, msg, msg)) != 0)
410 goto out;
411 if ((r = sshbuf_get_u8(msg, &type)) != 0)
412 goto out;
413 if (agent_failed(type)) {
414 r = SSH_ERR_AGENT_FAILURE;
415 goto out;
416 } else if (type != SSH_AGENT_RSA_RESPONSE) {
417 r = SSH_ERR_INVALID_FORMAT;
418 goto out;
419 }
420 if ((r = sshbuf_get(msg, response, 16)) != 0)
421 goto out;
422 r = 0;
423 out:
424 sshbuf_free(msg);
425 return r;
426}
427#endif
428 325
429/* encode signature algoritm in flag bits, so we can keep the msg format */ 326/* encode signature algoritm in flag bits, so we can keep the msg format */
430static u_int 327static u_int
431agent_encode_alg(struct sshkey *key, const char *alg) 328agent_encode_alg(const struct sshkey *key, const char *alg)
432{ 329{
433 if (alg != NULL && key->type == KEY_RSA) { 330 if (alg != NULL && key->type == KEY_RSA) {
434 if (strcmp(alg, "rsa-sha2-256") == 0) 331 if (strcmp(alg, "rsa-sha2-256") == 0)
@@ -441,7 +338,7 @@ agent_encode_alg(struct sshkey *key, const char *alg)
441 338
442/* ask agent to sign data, returns err.h code on error, 0 on success */ 339/* ask agent to sign data, returns err.h code on error, 0 on success */
443int 340int
444ssh_agent_sign(int sock, struct sshkey *key, 341ssh_agent_sign(int sock, const struct sshkey *key,
445 u_char **sigp, size_t *lenp, 342 u_char **sigp, size_t *lenp,
446 const u_char *data, size_t datalen, const char *alg, u_int compat) 343 const u_char *data, size_t datalen, const char *alg, u_int compat)
447{ 344{
@@ -494,25 +391,6 @@ ssh_agent_sign(int sock, struct sshkey *key,
494 391
495/* Encode key for a message to the agent. */ 392/* Encode key for a message to the agent. */
496 393
497#ifdef WITH_SSH1
498static int
499ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment)
500{
501 int r;
502
503 /* To keep within the protocol: p < q for ssh. in SSL p > q */
504 if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 ||
505 (r = sshbuf_put_bignum1(b, key->n)) != 0 ||
506 (r = sshbuf_put_bignum1(b, key->e)) != 0 ||
507 (r = sshbuf_put_bignum1(b, key->d)) != 0 ||
508 (r = sshbuf_put_bignum1(b, key->iqmp)) != 0 ||
509 (r = sshbuf_put_bignum1(b, key->q)) != 0 ||
510 (r = sshbuf_put_bignum1(b, key->p)) != 0 ||
511 (r = sshbuf_put_cstring(b, comment)) != 0)
512 return r;
513 return 0;
514}
515#endif
516 394
517static int 395static int
518ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key, 396ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key,
@@ -561,16 +439,6 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, const char *comment,
561 return SSH_ERR_ALLOC_FAIL; 439 return SSH_ERR_ALLOC_FAIL;
562 440
563 switch (key->type) { 441 switch (key->type) {
564#ifdef WITH_SSH1
565 case KEY_RSA1:
566 type = constrained ?
567 SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
568 SSH_AGENTC_ADD_RSA_IDENTITY;
569 if ((r = sshbuf_put_u8(msg, type)) != 0 ||
570 (r = ssh_encode_identity_rsa1(msg, key->rsa, comment)) != 0)
571 goto out;
572 break;
573#endif
574#ifdef WITH_OPENSSL 442#ifdef WITH_OPENSSL
575 case KEY_RSA: 443 case KEY_RSA:
576 case KEY_RSA_CERT: 444 case KEY_RSA_CERT:
@@ -620,16 +488,6 @@ ssh_remove_identity(int sock, struct sshkey *key)
620 if ((msg = sshbuf_new()) == NULL) 488 if ((msg = sshbuf_new()) == NULL)
621 return SSH_ERR_ALLOC_FAIL; 489 return SSH_ERR_ALLOC_FAIL;
622 490
623#ifdef WITH_SSH1
624 if (key->type == KEY_RSA1) {
625 if ((r = sshbuf_put_u8(msg,
626 SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||
627 (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
628 (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
629 (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0)
630 goto out;
631 } else
632#endif
633 if (key->type != KEY_UNSPEC) { 491 if (key->type != KEY_UNSPEC) {
634 if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) 492 if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
635 goto out; 493 goto out;
@@ -696,6 +554,10 @@ ssh_update_card(int sock, int add, const char *reader_id, const char *pin,
696/* 554/*
697 * Removes all identities from the agent. 555 * Removes all identities from the agent.
698 * This call is intended only for use by ssh-add(1) and like applications. 556 * This call is intended only for use by ssh-add(1) and like applications.
557 *
558 * This supports the SSH protocol 1 message to because, when clearing all
559 * keys from an agent, we generally want to clear both protocol v1 and v2
560 * keys.
699 */ 561 */
700int 562int
701ssh_remove_all_identities(int sock, int version) 563ssh_remove_all_identities(int sock, int version)
diff --git a/authfd.h b/authfd.h
index 4b417e3f4..43abf85da 100644
--- a/authfd.h
+++ b/authfd.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfd.h,v 1.39 2015/12/04 16:41:28 markus Exp $ */ 1/* $OpenBSD: authfd.h,v 1.41 2017/06/28 01:09:22 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -27,8 +27,7 @@ int ssh_get_authentication_socket(int *fdp);
27void ssh_close_authentication_socket(int sock); 27void ssh_close_authentication_socket(int sock);
28 28
29int ssh_lock_agent(int sock, int lock, const char *password); 29int ssh_lock_agent(int sock, int lock, const char *password);
30int ssh_fetch_identitylist(int sock, int version, 30int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp);
31 struct ssh_identitylist **idlp);
32void ssh_free_identitylist(struct ssh_identitylist *idl); 31void ssh_free_identitylist(struct ssh_identitylist *idl);
33int ssh_add_identity_constrained(int sock, struct sshkey *key, 32int ssh_add_identity_constrained(int sock, struct sshkey *key,
34 const char *comment, u_int life, u_int confirm); 33 const char *comment, u_int life, u_int confirm);
@@ -39,7 +38,7 @@ int ssh_remove_all_identities(int sock, int version);
39 38
40int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, 39int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
41 u_char session_id[16], u_char response[16]); 40 u_char session_id[16], u_char response[16]);
42int ssh_agent_sign(int sock, struct sshkey *key, 41int ssh_agent_sign(int sock, const struct sshkey *key,
43 u_char **sigp, size_t *lenp, 42 u_char **sigp, size_t *lenp,
44 const u_char *data, size_t datalen, const char *alg, u_int compat); 43 const u_char *data, size_t datalen, const char *alg, u_int compat);
45 44
diff --git a/authfile.c b/authfile.c
index 7411b68f6..d09b700d2 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.122 2016/11/25 23:24:45 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.127 2017/07/01 13:50:45 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
4 * 4 *
@@ -42,7 +42,6 @@
42#include "ssh.h" 42#include "ssh.h"
43#include "log.h" 43#include "log.h"
44#include "authfile.h" 44#include "authfile.h"
45#include "rsa.h"
46#include "misc.h" 45#include "misc.h"
47#include "atomicio.h" 46#include "atomicio.h"
48#include "sshkey.h" 47#include "sshkey.h"
@@ -100,25 +99,13 @@ sshkey_load_file(int fd, struct sshbuf *blob)
100 u_char buf[1024]; 99 u_char buf[1024];
101 size_t len; 100 size_t len;
102 struct stat st; 101 struct stat st;
103 int r, dontmax = 0; 102 int r;
104 103
105 if (fstat(fd, &st) < 0) 104 if (fstat(fd, &st) < 0)
106 return SSH_ERR_SYSTEM_ERROR; 105 return SSH_ERR_SYSTEM_ERROR;
107 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && 106 if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 &&
108 st.st_size > MAX_KEY_FILE_SIZE) 107 st.st_size > MAX_KEY_FILE_SIZE)
109 return SSH_ERR_INVALID_FORMAT; 108 return SSH_ERR_INVALID_FORMAT;
110 /*
111 * Pre-allocate the buffer used for the key contents and clamp its
112 * maximum size. This ensures that key contents are never leaked via
113 * implicit realloc() in the sshbuf code.
114 */
115 if ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) {
116 st.st_size = 64*1024; /* 64k should be enough for anyone :) */
117 dontmax = 1;
118 }
119 if ((r = sshbuf_allocate(blob, st.st_size)) != 0 ||
120 (dontmax && (r = sshbuf_set_max_size(blob, st.st_size)) != 0))
121 return r;
122 for (;;) { 109 for (;;) {
123 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { 110 if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) {
124 if (errno == EPIPE) 111 if (errno == EPIPE)
@@ -147,35 +134,6 @@ sshkey_load_file(int fd, struct sshbuf *blob)
147 return r; 134 return r;
148} 135}
149 136
150#ifdef WITH_SSH1
151/*
152 * Loads the public part of the ssh v1 key file. Returns NULL if an error was
153 * encountered (the file does not exist or is not readable), and the key
154 * otherwise.
155 */
156static int
157sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp)
158{
159 struct sshbuf *b = NULL;
160 int r;
161
162 if (keyp != NULL)
163 *keyp = NULL;
164 if (commentp != NULL)
165 *commentp = NULL;
166
167 if ((b = sshbuf_new()) == NULL)
168 return SSH_ERR_ALLOC_FAIL;
169 if ((r = sshkey_load_file(fd, b)) != 0)
170 goto out;
171 if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
172 goto out;
173 r = 0;
174 out:
175 sshbuf_free(b);
176 return r;
177}
178#endif /* WITH_SSH1 */
179 137
180/* XXX remove error() calls from here? */ 138/* XXX remove error() calls from here? */
181int 139int
@@ -345,75 +303,48 @@ sshkey_try_load_public(struct sshkey *k, const char *filename, char **commentp)
345 return SSH_ERR_INVALID_FORMAT; 303 return SSH_ERR_INVALID_FORMAT;
346} 304}
347 305
348/* load public key from ssh v1 private or any pubkey file */ 306/* load public key from any pubkey file */
349int 307int
350sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) 308sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
351{ 309{
352 struct sshkey *pub = NULL; 310 struct sshkey *pub = NULL;
353 char file[PATH_MAX]; 311 char *file = NULL;
354 int r, fd; 312 int r;
355 313
356 if (keyp != NULL) 314 if (keyp != NULL)
357 *keyp = NULL; 315 *keyp = NULL;
358 if (commentp != NULL) 316 if (commentp != NULL)
359 *commentp = NULL; 317 *commentp = NULL;
360 318
361 /* XXX should load file once and attempt to parse each format */
362
363 if ((fd = open(filename, O_RDONLY)) < 0)
364 goto skip;
365#ifdef WITH_SSH1
366 /* try rsa1 private key */
367 r = sshkey_load_public_rsa1(fd, keyp, commentp);
368 close(fd);
369 switch (r) {
370 case SSH_ERR_INTERNAL_ERROR:
371 case SSH_ERR_ALLOC_FAIL:
372 case SSH_ERR_INVALID_ARGUMENT:
373 case SSH_ERR_SYSTEM_ERROR:
374 case 0:
375 return r;
376 }
377#else /* WITH_SSH1 */
378 close(fd);
379#endif /* WITH_SSH1 */
380
381 /* try ssh2 public key */
382 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) 319 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
383 return SSH_ERR_ALLOC_FAIL; 320 return SSH_ERR_ALLOC_FAIL;
384 if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) { 321 if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
385 if (keyp != NULL) 322 if (keyp != NULL) {
386 *keyp = pub;
387 return 0;
388 }
389 sshkey_free(pub);
390
391#ifdef WITH_SSH1
392 /* try rsa1 public key */
393 if ((pub = sshkey_new(KEY_RSA1)) == NULL)
394 return SSH_ERR_ALLOC_FAIL;
395 if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
396 if (keyp != NULL)
397 *keyp = pub; 323 *keyp = pub;
398 return 0; 324 pub = NULL;
325 }
326 r = 0;
327 goto out;
399 } 328 }
400 sshkey_free(pub); 329 sshkey_free(pub);
401#endif /* WITH_SSH1 */
402 330
403 skip:
404 /* try .pub suffix */ 331 /* try .pub suffix */
405 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) 332 if (asprintf(&file, "%s.pub", filename) == -1)
406 return SSH_ERR_ALLOC_FAIL; 333 return SSH_ERR_ALLOC_FAIL;
407 r = SSH_ERR_ALLOC_FAIL; /* in case strlcpy or strlcat fail */ 334 if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) {
408 if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && 335 r = SSH_ERR_ALLOC_FAIL;
409 (strlcat(file, ".pub", sizeof file) < sizeof(file)) && 336 goto out;
410 (r = sshkey_try_load_public(pub, file, commentp)) == 0) { 337 }
411 if (keyp != NULL) 338 if ((r = sshkey_try_load_public(pub, file, commentp)) == 0) {
339 if (keyp != NULL) {
412 *keyp = pub; 340 *keyp = pub;
413 return 0; 341 pub = NULL;
342 }
343 r = 0;
414 } 344 }
345 out:
346 free(file);
415 sshkey_free(pub); 347 sshkey_free(pub);
416
417 return r; 348 return r;
418} 349}
419 350
diff --git a/bitmap.c b/bitmap.c
index f95032250..5089b0407 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -53,8 +53,9 @@ void
53bitmap_free(struct bitmap *b) 53bitmap_free(struct bitmap *b)
54{ 54{
55 if (b != NULL && b->d != NULL) { 55 if (b != NULL && b->d != NULL) {
56 explicit_bzero(b->d, b->len); 56 bitmap_zero(b);
57 free(b->d); 57 free(b->d);
58 b->d = NULL;
58 } 59 }
59 free(b); 60 free(b);
60} 61}
@@ -86,10 +87,10 @@ reserve(struct bitmap *b, u_int n)
86 return -1; /* invalid */ 87 return -1; /* invalid */
87 nlen = (n / BITMAP_BITS) + 1; 88 nlen = (n / BITMAP_BITS) + 1;
88 if (b->len < nlen) { 89 if (b->len < nlen) {
89 if ((tmp = reallocarray(b->d, nlen, BITMAP_BYTES)) == NULL) 90 if ((tmp = recallocarray(b->d, b->len,
91 nlen, BITMAP_BYTES)) == NULL)
90 return -1; 92 return -1;
91 b->d = tmp; 93 b->d = tmp;
92 memset(b->d + b->len, 0, (nlen - b->len) * BITMAP_BYTES);
93 b->len = nlen; 94 b->len = nlen;
94 } 95 }
95 return 0; 96 return 0;
@@ -188,7 +189,7 @@ bitmap_from_string(struct bitmap *b, const void *p, size_t l)
188{ 189{
189 int r; 190 int r;
190 size_t i, offset, shift; 191 size_t i, offset, shift;
191 u_char *s = (u_char *)p; 192 const u_char *s = (const u_char *)p;
192 193
193 if (l > BITMAP_MAX / 8) 194 if (l > BITMAP_MAX / 8)
194 return -1; 195 return -1;
diff --git a/bufbn.c b/bufbn.c
index 33ae7f73f..98f9466bc 100644
--- a/bufbn.c
+++ b/bufbn.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bufbn.c,v 1.12 2014/04/30 05:29:56 djm Exp $ */ 1/* $OpenBSD: bufbn.c,v 1.13 2017/04/30 23:23:54 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2012 Damien Miller <djm@mindrot.org> 4 * Copyright (c) 2012 Damien Miller <djm@mindrot.org>
@@ -28,46 +28,6 @@
28#include "log.h" 28#include "log.h"
29#include "ssherr.h" 29#include "ssherr.h"
30 30
31#ifdef WITH_SSH1
32int
33buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
34{
35 int ret;
36
37 if ((ret = sshbuf_put_bignum1(buffer, value)) != 0) {
38 error("%s: %s", __func__, ssh_err(ret));
39 return -1;
40 }
41 return 0;
42}
43
44void
45buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
46{
47 if (buffer_put_bignum_ret(buffer, value) == -1)
48 fatal("%s: buffer error", __func__);
49}
50
51int
52buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
53{
54 int ret;
55
56 if ((ret = sshbuf_get_bignum1(buffer, value)) != 0) {
57 error("%s: %s", __func__, ssh_err(ret));
58 return -1;
59 }
60 return 0;
61}
62
63void
64buffer_get_bignum(Buffer *buffer, BIGNUM *value)
65{
66 if (buffer_get_bignum_ret(buffer, value) == -1)
67 fatal("%s: buffer error", __func__);
68}
69#endif /* WITH_SSH1 */
70
71int 31int
72buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) 32buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
73{ 33{
diff --git a/buffer.h b/buffer.h
index df1aebc02..56174394c 100644
--- a/buffer.h
+++ b/buffer.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: buffer.h,v 1.25 2014/04/30 05:29:56 djm Exp $ */ 1/* $OpenBSD: buffer.h,v 1.26 2017/04/30 23:23:54 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2012 Damien Miller <djm@mindrot.org> 4 * Copyright (c) 2012 Damien Miller <djm@mindrot.org>
@@ -49,9 +49,7 @@ int buffer_consume_end_ret(Buffer *, u_int);
49 49
50#include <openssl/objects.h> 50#include <openssl/objects.h>
51#include <openssl/bn.h> 51#include <openssl/bn.h>
52void buffer_put_bignum(Buffer *, const BIGNUM *);
53void buffer_put_bignum2(Buffer *, const BIGNUM *); 52void buffer_put_bignum2(Buffer *, const BIGNUM *);
54void buffer_get_bignum(Buffer *, BIGNUM *);
55void buffer_get_bignum2(Buffer *, BIGNUM *); 53void buffer_get_bignum2(Buffer *, BIGNUM *);
56void buffer_put_bignum2_from_string(Buffer *, const u_char *, u_int); 54void buffer_put_bignum2_from_string(Buffer *, const u_char *, u_int);
57 55
@@ -75,8 +73,6 @@ void buffer_put_cstring(Buffer *, const char *);
75 73
76#define buffer_skip_string(b) (void)buffer_get_string_ptr(b, NULL); 74#define buffer_skip_string(b) (void)buffer_get_string_ptr(b, NULL);
77 75
78int buffer_put_bignum_ret(Buffer *, const BIGNUM *);
79int buffer_get_bignum_ret(Buffer *, BIGNUM *);
80int buffer_put_bignum2_ret(Buffer *, const BIGNUM *); 76int buffer_put_bignum2_ret(Buffer *, const BIGNUM *);
81int buffer_get_bignum2_ret(Buffer *, BIGNUM *); 77int buffer_get_bignum2_ret(Buffer *, BIGNUM *);
82int buffer_get_short_ret(u_short *, Buffer *); 78int buffer_get_short_ret(u_short *, Buffer *);
diff --git a/channels.c b/channels.c
index d030fcdd9..83442be06 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.357 2017/02/01 02:59:09 dtucker Exp $ */ 1/* $OpenBSD: channels.c,v 1.375 2017/09/24 13:45:34 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -55,27 +55,27 @@
55 55
56#include <errno.h> 56#include <errno.h>
57#include <fcntl.h> 57#include <fcntl.h>
58#include <limits.h>
58#include <netdb.h> 59#include <netdb.h>
60#include <stdarg.h>
59#ifdef HAVE_STDINT_H 61#ifdef HAVE_STDINT_H
60#include <stdint.h> 62 #include <stdint.h>
61#endif 63#endif
62#include <stdio.h> 64#include <stdio.h>
63#include <stdlib.h> 65#include <stdlib.h>
64#include <string.h> 66#include <string.h>
65#include <termios.h> 67#include <termios.h>
66#include <unistd.h> 68#include <unistd.h>
67#include <stdarg.h>
68 69
69#include "openbsd-compat/sys-queue.h" 70#include "openbsd-compat/sys-queue.h"
70#include "xmalloc.h" 71#include "xmalloc.h"
71#include "ssh.h" 72#include "ssh.h"
72#include "ssh1.h"
73#include "ssh2.h" 73#include "ssh2.h"
74#include "ssherr.h" 74#include "ssherr.h"
75#include "sshbuf.h"
75#include "packet.h" 76#include "packet.h"
76#include "log.h" 77#include "log.h"
77#include "misc.h" 78#include "misc.h"
78#include "buffer.h"
79#include "channels.h" 79#include "channels.h"
80#include "compat.h" 80#include "compat.h"
81#include "canohost.h" 81#include "canohost.h"
@@ -83,28 +83,19 @@
83#include "authfd.h" 83#include "authfd.h"
84#include "pathnames.h" 84#include "pathnames.h"
85 85
86/* -- channel core */ 86/* -- agent forwarding */
87 87#define NUM_SOCKS 10
88/*
89 * Pointer to an array containing all allocated channels. The array is
90 * dynamically extended as needed.
91 */
92static Channel **channels = NULL;
93
94/*
95 * Size of the channel array. All slots of the array must always be
96 * initialized (at least the type field); unused slots set to NULL
97 */
98static u_int channels_alloc = 0;
99 88
100/* 89/* -- tcp forwarding */
101 * Maximum file descriptor value used in any of the channels. This is 90/* special-case port number meaning allow any port */
102 * updated in channel_new. 91#define FWD_PERMIT_ANY_PORT 0
103 */
104static int channel_max_fd = 0;
105 92
93/* special-case wildcard meaning allow any host */
94#define FWD_PERMIT_ANY_HOST "*"
106 95
107/* -- tcp forwarding */ 96/* -- X11 forwarding */
97/* Maximum number of fake X11 displays to try. */
98#define MAX_DISPLAYS 1000
108 99
109/* 100/*
110 * Data structure for storing which hosts are permitted for forward requests. 101 * Data structure for storing which hosts are permitted for forward requests.
@@ -124,101 +115,153 @@ typedef struct {
124 Channel *downstream; /* Downstream mux*/ 115 Channel *downstream; /* Downstream mux*/
125} ForwardPermission; 116} ForwardPermission;
126 117
127/* List of all permitted host/port pairs to connect by the user. */ 118typedef void chan_fn(struct ssh *, Channel *c,
128static ForwardPermission *permitted_opens = NULL; 119 fd_set *readset, fd_set *writeset);
129
130/* List of all permitted host/port pairs to connect by the admin. */
131static ForwardPermission *permitted_adm_opens = NULL;
132 120
133/* Number of permitted host/port pairs in the array permitted by the user. */ 121/* Master structure for channels state */
134static int num_permitted_opens = 0; 122struct ssh_channels {
123 /*
124 * Pointer to an array containing all allocated channels. The array
125 * is dynamically extended as needed.
126 */
127 Channel **channels;
135 128
136/* Number of permitted host/port pair in the array permitted by the admin. */ 129 /*
137static int num_adm_permitted_opens = 0; 130 * Size of the channel array. All slots of the array must always be
131 * initialized (at least the type field); unused slots set to NULL
132 */
133 u_int channels_alloc;
138 134
139/* special-case port number meaning allow any port */ 135 /*
140#define FWD_PERMIT_ANY_PORT 0 136 * Maximum file descriptor value used in any of the channels. This is
137 * updated in channel_new.
138 */
139 int channel_max_fd;
141 140
142/* special-case wildcard meaning allow any host */ 141 /*
143#define FWD_PERMIT_ANY_HOST "*" 142 * 'channel_pre*' are called just before select() to add any bits
143 * relevant to channels in the select bitmasks.
144 *
145 * 'channel_post*': perform any appropriate operations for
146 * channels which have events pending.
147 */
148 chan_fn **channel_pre;
149 chan_fn **channel_post;
144 150
145/* 151 /* -- tcp forwarding */
146 * If this is true, all opens are permitted. This is the case on the server
147 * on which we have to trust the client anyway, and the user could do
148 * anything after logging in anyway.
149 */
150static int all_opens_permitted = 0;
151 152
153 /* List of all permitted host/port pairs to connect by the user. */
154 ForwardPermission *permitted_opens;
152 155
153/* -- X11 forwarding */ 156 /* List of all permitted host/port pairs to connect by the admin. */
157 ForwardPermission *permitted_adm_opens;
154 158
155/* Maximum number of fake X11 displays to try. */ 159 /*
156#define MAX_DISPLAYS 1000 160 * Number of permitted host/port pairs in the array permitted by
161 * the user.
162 */
163 u_int num_permitted_opens;
157 164
158/* Saved X11 local (client) display. */ 165 /*
159static char *x11_saved_display = NULL; 166 * Number of permitted host/port pair in the array permitted by
167 * the admin.
168 */
169 u_int num_adm_permitted_opens;
160 170
161/* Saved X11 authentication protocol name. */ 171 /*
162static char *x11_saved_proto = NULL; 172 * If this is true, all opens are permitted. This is the case on
173 * the server on which we have to trust the client anyway, and the
174 * user could do anything after logging in anyway.
175 */
176 int all_opens_permitted;
163 177
164/* Saved X11 authentication data. This is the real data. */ 178 /* -- X11 forwarding */
165static char *x11_saved_data = NULL;
166static u_int x11_saved_data_len = 0;
167 179
168/* Deadline after which all X11 connections are refused */ 180 /* Saved X11 local (client) display. */
169static u_int x11_refuse_time; 181 char *x11_saved_display;
170 182
171/* 183 /* Saved X11 authentication protocol name. */
172 * Fake X11 authentication data. This is what the server will be sending us; 184 char *x11_saved_proto;
173 * we should replace any occurrences of this by the real data.
174 */
175static u_char *x11_fake_data = NULL;
176static u_int x11_fake_data_len;
177 185
186 /* Saved X11 authentication data. This is the real data. */
187 char *x11_saved_data;
188 u_int x11_saved_data_len;
178 189
179/* -- agent forwarding */ 190 /* Deadline after which all X11 connections are refused */
191 u_int x11_refuse_time;
180 192
181#define NUM_SOCKS 10 193 /*
194 * Fake X11 authentication data. This is what the server will be
195 * sending us; we should replace any occurrences of this by the
196 * real data.
197 */
198 u_char *x11_fake_data;
199 u_int x11_fake_data_len;
182 200
183/* AF_UNSPEC or AF_INET or AF_INET6 */ 201 /* AF_UNSPEC or AF_INET or AF_INET6 */
184static int IPv4or6 = AF_UNSPEC; 202 int IPv4or6;
203};
185 204
186/* helper */ 205/* helper */
187static void port_open_helper(Channel *c, char *rtype); 206static void port_open_helper(struct ssh *ssh, Channel *c, char *rtype);
188static const char *channel_rfwd_bind_host(const char *listen_host); 207static const char *channel_rfwd_bind_host(const char *listen_host);
189 208
190/* non-blocking connect helpers */ 209/* non-blocking connect helpers */
191static int connect_next(struct channel_connect *); 210static int connect_next(struct channel_connect *);
192static void channel_connect_ctx_free(struct channel_connect *); 211static void channel_connect_ctx_free(struct channel_connect *);
212static Channel *rdynamic_connect_prepare(struct ssh *, char *, char *);
213static int rdynamic_connect_finish(struct ssh *, Channel *);
214
215/* Setup helper */
216static void channel_handler_init(struct ssh_channels *sc);
193 217
194/* -- channel core */ 218/* -- channel core */
195 219
220void
221channel_init_channels(struct ssh *ssh)
222{
223 struct ssh_channels *sc;
224
225 if ((sc = calloc(1, sizeof(*sc))) == NULL ||
226 (sc->channel_pre = calloc(SSH_CHANNEL_MAX_TYPE,
227 sizeof(*sc->channel_pre))) == NULL ||
228 (sc->channel_post = calloc(SSH_CHANNEL_MAX_TYPE,
229 sizeof(*sc->channel_post))) == NULL)
230 fatal("%s: allocation failed", __func__);
231 sc->channels_alloc = 10;
232 sc->channels = xcalloc(sc->channels_alloc, sizeof(*sc->channels));
233 sc->IPv4or6 = AF_UNSPEC;
234 channel_handler_init(sc);
235
236 ssh->chanctxt = sc;
237}
238
196Channel * 239Channel *
197channel_by_id(int id) 240channel_by_id(struct ssh *ssh, int id)
198{ 241{
199 Channel *c; 242 Channel *c;
200 243
201 if (id < 0 || (u_int)id >= channels_alloc) { 244 if (id < 0 || (u_int)id >= ssh->chanctxt->channels_alloc) {
202 logit("channel_by_id: %d: bad id", id); 245 logit("%s: %d: bad id", __func__, id);
203 return NULL; 246 return NULL;
204 } 247 }
205 c = channels[id]; 248 c = ssh->chanctxt->channels[id];
206 if (c == NULL) { 249 if (c == NULL) {
207 logit("channel_by_id: %d: bad id: channel free", id); 250 logit("%s: %d: bad id: channel free", __func__, id);
208 return NULL; 251 return NULL;
209 } 252 }
210 return c; 253 return c;
211} 254}
212 255
213Channel * 256Channel *
214channel_by_remote_id(int remote_id) 257channel_by_remote_id(struct ssh *ssh, u_int remote_id)
215{ 258{
216 Channel *c; 259 Channel *c;
217 u_int i; 260 u_int i;
218 261
219 for (i = 0; i < channels_alloc; i++) { 262 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
220 c = channels[i]; 263 c = ssh->chanctxt->channels[i];
221 if (c != NULL && c->remote_id == remote_id) 264 if (c != NULL && c->have_remote_id && c->remote_id == remote_id)
222 return c; 265 return c;
223 } 266 }
224 return NULL; 267 return NULL;
@@ -229,28 +272,28 @@ channel_by_remote_id(int remote_id)
229 * Private channels, like listening sockets, may not receive messages. 272 * Private channels, like listening sockets, may not receive messages.
230 */ 273 */
231Channel * 274Channel *
232channel_lookup(int id) 275channel_lookup(struct ssh *ssh, int id)
233{ 276{
234 Channel *c; 277 Channel *c;
235 278
236 if ((c = channel_by_id(id)) == NULL) 279 if ((c = channel_by_id(ssh, id)) == NULL)
237 return (NULL); 280 return NULL;
238 281
239 switch (c->type) { 282 switch (c->type) {
240 case SSH_CHANNEL_X11_OPEN: 283 case SSH_CHANNEL_X11_OPEN:
241 case SSH_CHANNEL_LARVAL: 284 case SSH_CHANNEL_LARVAL:
242 case SSH_CHANNEL_CONNECTING: 285 case SSH_CHANNEL_CONNECTING:
243 case SSH_CHANNEL_DYNAMIC: 286 case SSH_CHANNEL_DYNAMIC:
287 case SSH_CHANNEL_RDYNAMIC_OPEN:
288 case SSH_CHANNEL_RDYNAMIC_FINISH:
244 case SSH_CHANNEL_OPENING: 289 case SSH_CHANNEL_OPENING:
245 case SSH_CHANNEL_OPEN: 290 case SSH_CHANNEL_OPEN:
246 case SSH_CHANNEL_INPUT_DRAINING:
247 case SSH_CHANNEL_OUTPUT_DRAINING:
248 case SSH_CHANNEL_ABANDONED: 291 case SSH_CHANNEL_ABANDONED:
249 case SSH_CHANNEL_MUX_PROXY: 292 case SSH_CHANNEL_MUX_PROXY:
250 return (c); 293 return c;
251 } 294 }
252 logit("Non-public channel %d, type %d.", id, c->type); 295 logit("Non-public channel %d, type %d.", id, c->type);
253 return (NULL); 296 return NULL;
254} 297}
255 298
256/* 299/*
@@ -258,13 +301,15 @@ channel_lookup(int id)
258 * when the channel consumer/producer is ready, e.g. shell exec'd 301 * when the channel consumer/producer is ready, e.g. shell exec'd
259 */ 302 */
260static void 303static void
261channel_register_fds(Channel *c, int rfd, int wfd, int efd, 304channel_register_fds(struct ssh *ssh, Channel *c, int rfd, int wfd, int efd,
262 int extusage, int nonblock, int is_tty) 305 int extusage, int nonblock, int is_tty)
263{ 306{
307 struct ssh_channels *sc = ssh->chanctxt;
308
264 /* Update the maximum file descriptor value. */ 309 /* Update the maximum file descriptor value. */
265 channel_max_fd = MAXIMUM(channel_max_fd, rfd); 310 sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, rfd);
266 channel_max_fd = MAXIMUM(channel_max_fd, wfd); 311 sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, wfd);
267 channel_max_fd = MAXIMUM(channel_max_fd, efd); 312 sc->channel_max_fd = MAXIMUM(sc->channel_max_fd, efd);
268 313
269 if (rfd != -1) 314 if (rfd != -1)
270 fcntl(rfd, F_SETFD, FD_CLOEXEC); 315 fcntl(rfd, F_SETFD, FD_CLOEXEC);
@@ -302,192 +347,220 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
302 * remote_name to be freed. 347 * remote_name to be freed.
303 */ 348 */
304Channel * 349Channel *
305channel_new(char *ctype, int type, int rfd, int wfd, int efd, 350channel_new(struct ssh *ssh, char *ctype, int type, int rfd, int wfd, int efd,
306 u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock) 351 u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)
307{ 352{
308 int found; 353 struct ssh_channels *sc = ssh->chanctxt;
309 u_int i; 354 u_int i, found;
310 Channel *c; 355 Channel *c;
311 356
312 /* Do initial allocation if this is the first call. */
313 if (channels_alloc == 0) {
314 channels_alloc = 10;
315 channels = xcalloc(channels_alloc, sizeof(Channel *));
316 for (i = 0; i < channels_alloc; i++)
317 channels[i] = NULL;
318 }
319 /* Try to find a free slot where to put the new channel. */ 357 /* Try to find a free slot where to put the new channel. */
320 for (found = -1, i = 0; i < channels_alloc; i++) 358 for (i = 0; i < sc->channels_alloc; i++) {
321 if (channels[i] == NULL) { 359 if (sc->channels[i] == NULL) {
322 /* Found a free slot. */ 360 /* Found a free slot. */
323 found = (int)i; 361 found = i;
324 break; 362 break;
325 } 363 }
326 if (found < 0) { 364 }
327 /* There are no free slots. Take last+1 slot and expand the array. */ 365 if (i >= sc->channels_alloc) {
328 found = channels_alloc; 366 /*
329 if (channels_alloc > 10000) 367 * There are no free slots. Take last+1 slot and expand
330 fatal("channel_new: internal error: channels_alloc %d " 368 * the array.
331 "too big.", channels_alloc); 369 */
332 channels = xreallocarray(channels, channels_alloc + 10, 370 found = sc->channels_alloc;
333 sizeof(Channel *)); 371 if (sc->channels_alloc > CHANNELS_MAX_CHANNELS)
334 channels_alloc += 10; 372 fatal("%s: internal error: channels_alloc %d too big",
335 debug2("channel: expanding %d", channels_alloc); 373 __func__, sc->channels_alloc);
336 for (i = found; i < channels_alloc; i++) 374 sc->channels = xrecallocarray(sc->channels, sc->channels_alloc,
337 channels[i] = NULL; 375 sc->channels_alloc + 10, sizeof(*sc->channels));
376 sc->channels_alloc += 10;
377 debug2("channel: expanding %d", sc->channels_alloc);
338 } 378 }
339 /* Initialize and return new channel. */ 379 /* Initialize and return new channel. */
340 c = channels[found] = xcalloc(1, sizeof(Channel)); 380 c = sc->channels[found] = xcalloc(1, sizeof(Channel));
341 buffer_init(&c->input); 381 if ((c->input = sshbuf_new()) == NULL ||
342 buffer_init(&c->output); 382 (c->output = sshbuf_new()) == NULL ||
343 buffer_init(&c->extended); 383 (c->extended = sshbuf_new()) == NULL)
344 c->path = NULL; 384 fatal("%s: sshbuf_new failed", __func__);
345 c->listening_addr = NULL;
346 c->listening_port = 0;
347 c->ostate = CHAN_OUTPUT_OPEN; 385 c->ostate = CHAN_OUTPUT_OPEN;
348 c->istate = CHAN_INPUT_OPEN; 386 c->istate = CHAN_INPUT_OPEN;
349 c->flags = 0; 387 channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, 0);
350 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0);
351 c->notbefore = 0;
352 c->self = found; 388 c->self = found;
353 c->type = type; 389 c->type = type;
354 c->ctype = ctype; 390 c->ctype = ctype;
355 c->local_window = window; 391 c->local_window = window;
356 c->local_window_max = window; 392 c->local_window_max = window;
357 c->local_consumed = 0;
358 c->local_maxpacket = maxpack; 393 c->local_maxpacket = maxpack;
359 c->remote_id = -1;
360 c->remote_name = xstrdup(remote_name); 394 c->remote_name = xstrdup(remote_name);
361 c->remote_window = 0;
362 c->remote_maxpacket = 0;
363 c->force_drain = 0;
364 c->single_connection = 0;
365 c->detach_user = NULL;
366 c->detach_close = 0;
367 c->open_confirm = NULL;
368 c->open_confirm_ctx = NULL;
369 c->input_filter = NULL;
370 c->output_filter = NULL;
371 c->filter_ctx = NULL;
372 c->filter_cleanup = NULL;
373 c->ctl_chan = -1; 395 c->ctl_chan = -1;
374 c->mux_rcb = NULL;
375 c->mux_ctx = NULL;
376 c->mux_pause = 0;
377 c->delayed = 1; /* prevent call to channel_post handler */ 396 c->delayed = 1; /* prevent call to channel_post handler */
378 TAILQ_INIT(&c->status_confirms); 397 TAILQ_INIT(&c->status_confirms);
379 debug("channel %d: new [%s]", found, remote_name); 398 debug("channel %d: new [%s]", found, remote_name);
380 return c; 399 return c;
381} 400}
382 401
383static int 402static void
384channel_find_maxfd(void) 403channel_find_maxfd(struct ssh_channels *sc)
385{ 404{
386 u_int i; 405 u_int i;
387 int max = 0; 406 int max = 0;
388 Channel *c; 407 Channel *c;
389 408
390 for (i = 0; i < channels_alloc; i++) { 409 for (i = 0; i < sc->channels_alloc; i++) {
391 c = channels[i]; 410 c = sc->channels[i];
392 if (c != NULL) { 411 if (c != NULL) {
393 max = MAXIMUM(max, c->rfd); 412 max = MAXIMUM(max, c->rfd);
394 max = MAXIMUM(max, c->wfd); 413 max = MAXIMUM(max, c->wfd);
395 max = MAXIMUM(max, c->efd); 414 max = MAXIMUM(max, c->efd);
396 } 415 }
397 } 416 }
398 return max; 417 sc->channel_max_fd = max;
399} 418}
400 419
401int 420int
402channel_close_fd(int *fdp) 421channel_close_fd(struct ssh *ssh, int *fdp)
403{ 422{
423 struct ssh_channels *sc = ssh->chanctxt;
404 int ret = 0, fd = *fdp; 424 int ret = 0, fd = *fdp;
405 425
406 if (fd != -1) { 426 if (fd != -1) {
407 ret = close(fd); 427 ret = close(fd);
408 *fdp = -1; 428 *fdp = -1;
409 if (fd == channel_max_fd) 429 if (fd == sc->channel_max_fd)
410 channel_max_fd = channel_find_maxfd(); 430 channel_find_maxfd(sc);
411 } 431 }
412 return ret; 432 return ret;
413} 433}
414 434
415/* Close all channel fd/socket. */ 435/* Close all channel fd/socket. */
416static void 436static void
417channel_close_fds(Channel *c) 437channel_close_fds(struct ssh *ssh, Channel *c)
438{
439 channel_close_fd(ssh, &c->sock);
440 channel_close_fd(ssh, &c->rfd);
441 channel_close_fd(ssh, &c->wfd);
442 channel_close_fd(ssh, &c->efd);
443}
444
445static void
446fwd_perm_clear(ForwardPermission *fp)
418{ 447{
419 channel_close_fd(&c->sock); 448 free(fp->host_to_connect);
420 channel_close_fd(&c->rfd); 449 free(fp->listen_host);
421 channel_close_fd(&c->wfd); 450 free(fp->listen_path);
422 channel_close_fd(&c->efd); 451 bzero(fp, sizeof(*fp));
452}
453
454enum { FWDPERM_USER, FWDPERM_ADMIN };
455
456static int
457fwd_perm_list_add(struct ssh *ssh, int which,
458 const char *host_to_connect, int port_to_connect,
459 const char *listen_host, const char *listen_path, int listen_port,
460 Channel *downstream)
461{
462 ForwardPermission **fpl;
463 u_int n, *nfpl;
464
465 switch (which) {
466 case FWDPERM_USER:
467 fpl = &ssh->chanctxt->permitted_opens;
468 nfpl = &ssh->chanctxt->num_permitted_opens;
469 break;
470 case FWDPERM_ADMIN:
471 fpl = &ssh->chanctxt->permitted_adm_opens;
472 nfpl = &ssh->chanctxt->num_adm_permitted_opens;
473 break;
474 default:
475 fatal("%s: invalid list %d", __func__, which);
476 }
477
478 if (*nfpl >= INT_MAX)
479 fatal("%s: overflow", __func__);
480
481 *fpl = xrecallocarray(*fpl, *nfpl, *nfpl + 1, sizeof(**fpl));
482 n = (*nfpl)++;
483#define MAYBE_DUP(s) ((s == NULL) ? NULL : xstrdup(s))
484 (*fpl)[n].host_to_connect = MAYBE_DUP(host_to_connect);
485 (*fpl)[n].port_to_connect = port_to_connect;
486 (*fpl)[n].listen_host = MAYBE_DUP(listen_host);
487 (*fpl)[n].listen_path = MAYBE_DUP(listen_path);
488 (*fpl)[n].listen_port = listen_port;
489 (*fpl)[n].downstream = downstream;
490#undef MAYBE_DUP
491 return (int)n;
492}
493
494static void
495mux_remove_remote_forwardings(struct ssh *ssh, Channel *c)
496{
497 struct ssh_channels *sc = ssh->chanctxt;
498 ForwardPermission *fp;
499 int r;
500 u_int i;
501
502 for (i = 0; i < sc->num_permitted_opens; i++) {
503 fp = &sc->permitted_opens[i];
504 if (fp->downstream != c)
505 continue;
506
507 /* cancel on the server, since mux client is gone */
508 debug("channel %d: cleanup remote forward for %s:%u",
509 c->self, fp->listen_host, fp->listen_port);
510 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
511 (r = sshpkt_put_cstring(ssh,
512 "cancel-tcpip-forward")) != 0 ||
513 (r = sshpkt_put_u8(ssh, 0)) != 0 ||
514 (r = sshpkt_put_cstring(ssh,
515 channel_rfwd_bind_host(fp->listen_host))) != 0 ||
516 (r = sshpkt_put_u32(ssh, fp->listen_port)) != 0 ||
517 (r = sshpkt_send(ssh)) != 0) {
518 fatal("%s: channel %i: %s", __func__,
519 c->self, ssh_err(r));
520 }
521 fwd_perm_clear(fp); /* unregister */
522 }
423} 523}
424 524
425/* Free the channel and close its fd/socket. */ 525/* Free the channel and close its fd/socket. */
426void 526void
427channel_free(Channel *c) 527channel_free(struct ssh *ssh, Channel *c)
428{ 528{
529 struct ssh_channels *sc = ssh->chanctxt;
429 char *s; 530 char *s;
430 u_int i, n; 531 u_int i, n;
431 Channel *other; 532 Channel *other;
432 struct channel_confirm *cc; 533 struct channel_confirm *cc;
433 534
434 for (n = 0, i = 0; i < channels_alloc; i++) { 535 for (n = 0, i = 0; i < sc->channels_alloc; i++) {
435 if ((other = channels[i]) != NULL) { 536 if ((other = sc->channels[i]) == NULL)
436 n++; 537 continue;
437 538 n++;
438 /* detach from mux client and prepare for closing */ 539 /* detach from mux client and prepare for closing */
439 if (c->type == SSH_CHANNEL_MUX_CLIENT && 540 if (c->type == SSH_CHANNEL_MUX_CLIENT &&
440 other->type == SSH_CHANNEL_MUX_PROXY && 541 other->type == SSH_CHANNEL_MUX_PROXY &&
441 other->mux_ctx == c) { 542 other->mux_ctx == c) {
442 other->mux_ctx = NULL; 543 other->mux_ctx = NULL;
443 other->type = SSH_CHANNEL_OPEN; 544 other->type = SSH_CHANNEL_OPEN;
444 other->istate = CHAN_INPUT_CLOSED; 545 other->istate = CHAN_INPUT_CLOSED;
445 other->ostate = CHAN_OUTPUT_CLOSED; 546 other->ostate = CHAN_OUTPUT_CLOSED;
446 }
447 } 547 }
448 } 548 }
449 debug("channel %d: free: %s, nchannels %u", c->self, 549 debug("channel %d: free: %s, nchannels %u", c->self,
450 c->remote_name ? c->remote_name : "???", n); 550 c->remote_name ? c->remote_name : "???", n);
451 551
452 /* XXX more MUX cleanup: remove remote forwardings */ 552 if (c->type == SSH_CHANNEL_MUX_CLIENT)
453 if (c->type == SSH_CHANNEL_MUX_CLIENT) { 553 mux_remove_remote_forwardings(ssh, c);
454 for (i = 0; i < (u_int)num_permitted_opens; i++) {
455 if (permitted_opens[i].downstream != c)
456 continue;
457 /* cancel on the server, since mux client is gone */
458 debug("channel %d: cleanup remote forward for %s:%u",
459 c->self,
460 permitted_opens[i].listen_host,
461 permitted_opens[i].listen_port);
462 packet_start(SSH2_MSG_GLOBAL_REQUEST);
463 packet_put_cstring("cancel-tcpip-forward");
464 packet_put_char(0);
465 packet_put_cstring(channel_rfwd_bind_host(
466 permitted_opens[i].listen_host));
467 packet_put_int(permitted_opens[i].listen_port);
468 packet_send();
469 /* unregister */
470 permitted_opens[i].listen_port = 0;
471 permitted_opens[i].port_to_connect = 0;
472 free(permitted_opens[i].host_to_connect);
473 permitted_opens[i].host_to_connect = NULL;
474 free(permitted_opens[i].listen_host);
475 permitted_opens[i].listen_host = NULL;
476 permitted_opens[i].listen_path = NULL;
477 permitted_opens[i].downstream = NULL;
478 }
479 }
480 554
481 s = channel_open_message(); 555 s = channel_open_message(ssh);
482 debug3("channel %d: status: %s", c->self, s); 556 debug3("channel %d: status: %s", c->self, s);
483 free(s); 557 free(s);
484 558
485 if (c->sock != -1) 559 channel_close_fds(ssh, c);
486 shutdown(c->sock, SHUT_RDWR); 560 sshbuf_free(c->input);
487 channel_close_fds(c); 561 sshbuf_free(c->output);
488 buffer_free(&c->input); 562 sshbuf_free(c->extended);
489 buffer_free(&c->output); 563 c->input = c->output = c->extended = NULL;
490 buffer_free(&c->extended);
491 free(c->remote_name); 564 free(c->remote_name);
492 c->remote_name = NULL; 565 c->remote_name = NULL;
493 free(c->path); 566 free(c->path);
@@ -496,25 +569,26 @@ channel_free(Channel *c)
496 c->listening_addr = NULL; 569 c->listening_addr = NULL;
497 while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { 570 while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) {
498 if (cc->abandon_cb != NULL) 571 if (cc->abandon_cb != NULL)
499 cc->abandon_cb(c, cc->ctx); 572 cc->abandon_cb(ssh, c, cc->ctx);
500 TAILQ_REMOVE(&c->status_confirms, cc, entry); 573 TAILQ_REMOVE(&c->status_confirms, cc, entry);
501 explicit_bzero(cc, sizeof(*cc)); 574 explicit_bzero(cc, sizeof(*cc));
502 free(cc); 575 free(cc);
503 } 576 }
504 if (c->filter_cleanup != NULL && c->filter_ctx != NULL) 577 if (c->filter_cleanup != NULL && c->filter_ctx != NULL)
505 c->filter_cleanup(c->self, c->filter_ctx); 578 c->filter_cleanup(ssh, c->self, c->filter_ctx);
506 channels[c->self] = NULL; 579 sc->channels[c->self] = NULL;
580 explicit_bzero(c, sizeof(*c));
507 free(c); 581 free(c);
508} 582}
509 583
510void 584void
511channel_free_all(void) 585channel_free_all(struct ssh *ssh)
512{ 586{
513 u_int i; 587 u_int i;
514 588
515 for (i = 0; i < channels_alloc; i++) 589 for (i = 0; i < ssh->chanctxt->channels_alloc; i++)
516 if (channels[i] != NULL) 590 if (ssh->chanctxt->channels[i] != NULL)
517 channel_free(channels[i]); 591 channel_free(ssh, ssh->chanctxt->channels[i]);
518} 592}
519 593
520/* 594/*
@@ -522,26 +596,26 @@ channel_free_all(void)
522 * descriptors after a fork. 596 * descriptors after a fork.
523 */ 597 */
524void 598void
525channel_close_all(void) 599channel_close_all(struct ssh *ssh)
526{ 600{
527 u_int i; 601 u_int i;
528 602
529 for (i = 0; i < channels_alloc; i++) 603 for (i = 0; i < ssh->chanctxt->channels_alloc; i++)
530 if (channels[i] != NULL) 604 if (ssh->chanctxt->channels[i] != NULL)
531 channel_close_fds(channels[i]); 605 channel_close_fds(ssh, ssh->chanctxt->channels[i]);
532} 606}
533 607
534/* 608/*
535 * Stop listening to channels. 609 * Stop listening to channels.
536 */ 610 */
537void 611void
538channel_stop_listening(void) 612channel_stop_listening(struct ssh *ssh)
539{ 613{
540 u_int i; 614 u_int i;
541 Channel *c; 615 Channel *c;
542 616
543 for (i = 0; i < channels_alloc; i++) { 617 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
544 c = channels[i]; 618 c = ssh->chanctxt->channels[i];
545 if (c != NULL) { 619 if (c != NULL) {
546 switch (c->type) { 620 switch (c->type) {
547 case SSH_CHANNEL_AUTH_SOCKET: 621 case SSH_CHANNEL_AUTH_SOCKET:
@@ -550,8 +624,8 @@ channel_stop_listening(void)
550 case SSH_CHANNEL_X11_LISTENER: 624 case SSH_CHANNEL_X11_LISTENER:
551 case SSH_CHANNEL_UNIX_LISTENER: 625 case SSH_CHANNEL_UNIX_LISTENER:
552 case SSH_CHANNEL_RUNIX_LISTENER: 626 case SSH_CHANNEL_RUNIX_LISTENER:
553 channel_close_fd(&c->sock); 627 channel_close_fd(ssh, &c->sock);
554 channel_free(c); 628 channel_free(ssh, c);
555 break; 629 break;
556 } 630 }
557 } 631 }
@@ -563,28 +637,20 @@ channel_stop_listening(void)
563 * more channel is overfull. 637 * more channel is overfull.
564 */ 638 */
565int 639int
566channel_not_very_much_buffered_data(void) 640channel_not_very_much_buffered_data(struct ssh *ssh)
567{ 641{
568 u_int i; 642 u_int i;
643 u_int maxsize = ssh_packet_get_maxsize(ssh);
569 Channel *c; 644 Channel *c;
570 645
571 for (i = 0; i < channels_alloc; i++) { 646 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
572 c = channels[i]; 647 c = ssh->chanctxt->channels[i];
573 if (c != NULL && c->type == SSH_CHANNEL_OPEN) { 648 if (c == NULL || c->type != SSH_CHANNEL_OPEN)
574#if 0 649 continue;
575 if (!compat20 && 650 if (sshbuf_len(c->output) > maxsize) {
576 buffer_len(&c->input) > packet_get_maxsize()) { 651 debug2("channel %d: big output buffer %zu > %u",
577 debug2("channel %d: big input buffer %d", 652 c->self, sshbuf_len(c->output), maxsize);
578 c->self, buffer_len(&c->input)); 653 return 0;
579 return 0;
580 }
581#endif
582 if (buffer_len(&c->output) > packet_get_maxsize()) {
583 debug2("channel %d: big output buffer %u > %u",
584 c->self, buffer_len(&c->output),
585 packet_get_maxsize());
586 return 0;
587 }
588 } 654 }
589 } 655 }
590 return 1; 656 return 1;
@@ -592,13 +658,13 @@ channel_not_very_much_buffered_data(void)
592 658
593/* Returns true if any channel is still open. */ 659/* Returns true if any channel is still open. */
594int 660int
595channel_still_open(void) 661channel_still_open(struct ssh *ssh)
596{ 662{
597 u_int i; 663 u_int i;
598 Channel *c; 664 Channel *c;
599 665
600 for (i = 0; i < channels_alloc; i++) { 666 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
601 c = channels[i]; 667 c = ssh->chanctxt->channels[i];
602 if (c == NULL) 668 if (c == NULL)
603 continue; 669 continue;
604 switch (c->type) { 670 switch (c->type) {
@@ -609,6 +675,7 @@ channel_still_open(void)
609 case SSH_CHANNEL_CLOSED: 675 case SSH_CHANNEL_CLOSED:
610 case SSH_CHANNEL_AUTH_SOCKET: 676 case SSH_CHANNEL_AUTH_SOCKET:
611 case SSH_CHANNEL_DYNAMIC: 677 case SSH_CHANNEL_DYNAMIC:
678 case SSH_CHANNEL_RDYNAMIC_OPEN:
612 case SSH_CHANNEL_CONNECTING: 679 case SSH_CHANNEL_CONNECTING:
613 case SSH_CHANNEL_ZOMBIE: 680 case SSH_CHANNEL_ZOMBIE:
614 case SSH_CHANNEL_ABANDONED: 681 case SSH_CHANNEL_ABANDONED:
@@ -616,22 +683,16 @@ channel_still_open(void)
616 case SSH_CHANNEL_RUNIX_LISTENER: 683 case SSH_CHANNEL_RUNIX_LISTENER:
617 continue; 684 continue;
618 case SSH_CHANNEL_LARVAL: 685 case SSH_CHANNEL_LARVAL:
619 if (!compat20)
620 fatal("cannot happen: SSH_CHANNEL_LARVAL");
621 continue; 686 continue;
622 case SSH_CHANNEL_OPENING: 687 case SSH_CHANNEL_OPENING:
623 case SSH_CHANNEL_OPEN: 688 case SSH_CHANNEL_OPEN:
689 case SSH_CHANNEL_RDYNAMIC_FINISH:
624 case SSH_CHANNEL_X11_OPEN: 690 case SSH_CHANNEL_X11_OPEN:
625 case SSH_CHANNEL_MUX_CLIENT: 691 case SSH_CHANNEL_MUX_CLIENT:
626 case SSH_CHANNEL_MUX_PROXY: 692 case SSH_CHANNEL_MUX_PROXY:
627 return 1; 693 return 1;
628 case SSH_CHANNEL_INPUT_DRAINING:
629 case SSH_CHANNEL_OUTPUT_DRAINING:
630 if (!compat13)
631 fatal("cannot happen: OUT_DRAIN");
632 return 1;
633 default: 694 default:
634 fatal("channel_still_open: bad channel type %d", c->type); 695 fatal("%s: bad channel type %d", __func__, c->type);
635 /* NOTREACHED */ 696 /* NOTREACHED */
636 } 697 }
637 } 698 }
@@ -640,18 +701,20 @@ channel_still_open(void)
640 701
641/* Returns the id of an open channel suitable for keepaliving */ 702/* Returns the id of an open channel suitable for keepaliving */
642int 703int
643channel_find_open(void) 704channel_find_open(struct ssh *ssh)
644{ 705{
645 u_int i; 706 u_int i;
646 Channel *c; 707 Channel *c;
647 708
648 for (i = 0; i < channels_alloc; i++) { 709 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
649 c = channels[i]; 710 c = ssh->chanctxt->channels[i];
650 if (c == NULL || c->remote_id < 0) 711 if (c == NULL || !c->have_remote_id)
651 continue; 712 continue;
652 switch (c->type) { 713 switch (c->type) {
653 case SSH_CHANNEL_CLOSED: 714 case SSH_CHANNEL_CLOSED:
654 case SSH_CHANNEL_DYNAMIC: 715 case SSH_CHANNEL_DYNAMIC:
716 case SSH_CHANNEL_RDYNAMIC_OPEN:
717 case SSH_CHANNEL_RDYNAMIC_FINISH:
655 case SSH_CHANNEL_X11_LISTENER: 718 case SSH_CHANNEL_X11_LISTENER:
656 case SSH_CHANNEL_PORT_LISTENER: 719 case SSH_CHANNEL_PORT_LISTENER:
657 case SSH_CHANNEL_RPORT_LISTENER: 720 case SSH_CHANNEL_RPORT_LISTENER:
@@ -670,13 +733,8 @@ channel_find_open(void)
670 case SSH_CHANNEL_OPEN: 733 case SSH_CHANNEL_OPEN:
671 case SSH_CHANNEL_X11_OPEN: 734 case SSH_CHANNEL_X11_OPEN:
672 return i; 735 return i;
673 case SSH_CHANNEL_INPUT_DRAINING:
674 case SSH_CHANNEL_OUTPUT_DRAINING:
675 if (!compat13)
676 fatal("cannot happen: OUT_DRAIN");
677 return i;
678 default: 736 default:
679 fatal("channel_find_open: bad channel type %d", c->type); 737 fatal("%s: bad channel type %d", __func__, c->type);
680 /* NOTREACHED */ 738 /* NOTREACHED */
681 } 739 }
682 } 740 }
@@ -689,18 +747,21 @@ channel_find_open(void)
689 * newlines. 747 * newlines.
690 */ 748 */
691char * 749char *
692channel_open_message(void) 750channel_open_message(struct ssh *ssh)
693{ 751{
694 Buffer buffer; 752 struct sshbuf *buf;
695 Channel *c; 753 Channel *c;
696 char buf[1024], *cp;
697 u_int i; 754 u_int i;
698 755 int r;
699 buffer_init(&buffer); 756 char *ret;
700 snprintf(buf, sizeof buf, "The following connections are open:\r\n"); 757
701 buffer_append(&buffer, buf, strlen(buf)); 758 if ((buf = sshbuf_new()) == NULL)
702 for (i = 0; i < channels_alloc; i++) { 759 fatal("%s: sshbuf_new", __func__);
703 c = channels[i]; 760 if ((r = sshbuf_putf(buf,
761 "The following connections are open:\r\n")) != 0)
762 fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r));
763 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
764 c = ssh->chanctxt->channels[i];
704 if (c == NULL) 765 if (c == NULL)
705 continue; 766 continue;
706 switch (c->type) { 767 switch (c->type) {
@@ -719,75 +780,95 @@ channel_open_message(void)
719 case SSH_CHANNEL_OPENING: 780 case SSH_CHANNEL_OPENING:
720 case SSH_CHANNEL_CONNECTING: 781 case SSH_CHANNEL_CONNECTING:
721 case SSH_CHANNEL_DYNAMIC: 782 case SSH_CHANNEL_DYNAMIC:
783 case SSH_CHANNEL_RDYNAMIC_OPEN:
784 case SSH_CHANNEL_RDYNAMIC_FINISH:
722 case SSH_CHANNEL_OPEN: 785 case SSH_CHANNEL_OPEN:
723 case SSH_CHANNEL_X11_OPEN: 786 case SSH_CHANNEL_X11_OPEN:
724 case SSH_CHANNEL_INPUT_DRAINING:
725 case SSH_CHANNEL_OUTPUT_DRAINING:
726 case SSH_CHANNEL_MUX_PROXY: 787 case SSH_CHANNEL_MUX_PROXY:
727 case SSH_CHANNEL_MUX_CLIENT: 788 case SSH_CHANNEL_MUX_CLIENT:
728 snprintf(buf, sizeof buf, 789 if ((r = sshbuf_putf(buf, " #%d %.300s "
729 " #%d %.300s (t%d r%d i%u/%d o%u/%d fd %d/%d cc %d)\r\n", 790 "(t%d %s%u i%u/%zu o%u/%zu fd %d/%d cc %d)\r\n",
730 c->self, c->remote_name, 791 c->self, c->remote_name,
731 c->type, c->remote_id, 792 c->type,
732 c->istate, buffer_len(&c->input), 793 c->have_remote_id ? "r" : "nr", c->remote_id,
733 c->ostate, buffer_len(&c->output), 794 c->istate, sshbuf_len(c->input),
734 c->rfd, c->wfd, c->ctl_chan); 795 c->ostate, sshbuf_len(c->output),
735 buffer_append(&buffer, buf, strlen(buf)); 796 c->rfd, c->wfd, c->ctl_chan)) != 0)
797 fatal("%s: sshbuf_putf: %s",
798 __func__, ssh_err(r));
736 continue; 799 continue;
737 default: 800 default:
738 fatal("channel_open_message: bad channel type %d", c->type); 801 fatal("%s: bad channel type %d", __func__, c->type);
739 /* NOTREACHED */ 802 /* NOTREACHED */
740 } 803 }
741 } 804 }
742 buffer_append(&buffer, "\0", 1); 805 if ((ret = sshbuf_dup_string(buf)) == NULL)
743 cp = xstrdup((char *)buffer_ptr(&buffer)); 806 fatal("%s: sshbuf_dup_string", __func__);
744 buffer_free(&buffer); 807 sshbuf_free(buf);
745 return cp; 808 return ret;
809}
810
811static void
812open_preamble(struct ssh *ssh, const char *where, Channel *c, const char *type)
813{
814 int r;
815
816 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
817 (r = sshpkt_put_cstring(ssh, type)) != 0 ||
818 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
819 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
820 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {
821 fatal("%s: channel %i: open: %s", where, c->self, ssh_err(r));
822 }
746} 823}
747 824
748void 825void
749channel_send_open(int id) 826channel_send_open(struct ssh *ssh, int id)
750{ 827{
751 Channel *c = channel_lookup(id); 828 Channel *c = channel_lookup(ssh, id);
829 int r;
752 830
753 if (c == NULL) { 831 if (c == NULL) {
754 logit("channel_send_open: %d: bad id", id); 832 logit("channel_send_open: %d: bad id", id);
755 return; 833 return;
756 } 834 }
757 debug2("channel %d: send open", id); 835 debug2("channel %d: send open", id);
758 packet_start(SSH2_MSG_CHANNEL_OPEN); 836 open_preamble(ssh, __func__, c, c->ctype);
759 packet_put_cstring(c->ctype); 837 if ((r = sshpkt_send(ssh)) != 0)
760 packet_put_int(c->self); 838 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
761 packet_put_int(c->local_window);
762 packet_put_int(c->local_maxpacket);
763 packet_send();
764} 839}
765 840
766void 841void
767channel_request_start(int id, char *service, int wantconfirm) 842channel_request_start(struct ssh *ssh, int id, char *service, int wantconfirm)
768{ 843{
769 Channel *c = channel_lookup(id); 844 Channel *c = channel_lookup(ssh, id);
845 int r;
770 846
771 if (c == NULL) { 847 if (c == NULL) {
772 logit("channel_request_start: %d: unknown channel id", id); 848 logit("%s: %d: unknown channel id", __func__, id);
773 return; 849 return;
774 } 850 }
851 if (!c->have_remote_id)
852 fatal(":%s: channel %d: no remote id", __func__, c->self);
853
775 debug2("channel %d: request %s confirm %d", id, service, wantconfirm); 854 debug2("channel %d: request %s confirm %d", id, service, wantconfirm);
776 packet_start(SSH2_MSG_CHANNEL_REQUEST); 855 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
777 packet_put_int(c->remote_id); 856 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
778 packet_put_cstring(service); 857 (r = sshpkt_put_cstring(ssh, service)) != 0 ||
779 packet_put_char(wantconfirm); 858 (r = sshpkt_put_u8(ssh, wantconfirm)) != 0) {
859 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
860 }
780} 861}
781 862
782void 863void
783channel_register_status_confirm(int id, channel_confirm_cb *cb, 864channel_register_status_confirm(struct ssh *ssh, int id,
784 channel_confirm_abandon_cb *abandon_cb, void *ctx) 865 channel_confirm_cb *cb, channel_confirm_abandon_cb *abandon_cb, void *ctx)
785{ 866{
786 struct channel_confirm *cc; 867 struct channel_confirm *cc;
787 Channel *c; 868 Channel *c;
788 869
789 if ((c = channel_lookup(id)) == NULL) 870 if ((c = channel_lookup(ssh, id)) == NULL)
790 fatal("channel_register_expect: %d: bad id", id); 871 fatal("%s: %d: bad id", __func__, id);
791 872
792 cc = xcalloc(1, sizeof(*cc)); 873 cc = xcalloc(1, sizeof(*cc));
793 cc->cb = cb; 874 cc->cb = cb;
@@ -797,12 +878,13 @@ channel_register_status_confirm(int id, channel_confirm_cb *cb,
797} 878}
798 879
799void 880void
800channel_register_open_confirm(int id, channel_open_fn *fn, void *ctx) 881channel_register_open_confirm(struct ssh *ssh, int id,
882 channel_open_fn *fn, void *ctx)
801{ 883{
802 Channel *c = channel_lookup(id); 884 Channel *c = channel_lookup(ssh, id);
803 885
804 if (c == NULL) { 886 if (c == NULL) {
805 logit("channel_register_open_confirm: %d: bad id", id); 887 logit("%s: %d: bad id", __func__, id);
806 return; 888 return;
807 } 889 }
808 c->open_confirm = fn; 890 c->open_confirm = fn;
@@ -810,12 +892,13 @@ channel_register_open_confirm(int id, channel_open_fn *fn, void *ctx)
810} 892}
811 893
812void 894void
813channel_register_cleanup(int id, channel_callback_fn *fn, int do_close) 895channel_register_cleanup(struct ssh *ssh, int id,
896 channel_callback_fn *fn, int do_close)
814{ 897{
815 Channel *c = channel_by_id(id); 898 Channel *c = channel_by_id(ssh, id);
816 899
817 if (c == NULL) { 900 if (c == NULL) {
818 logit("channel_register_cleanup: %d: bad id", id); 901 logit("%s: %d: bad id", __func__, id);
819 return; 902 return;
820 } 903 }
821 c->detach_user = fn; 904 c->detach_user = fn;
@@ -823,12 +906,12 @@ channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
823} 906}
824 907
825void 908void
826channel_cancel_cleanup(int id) 909channel_cancel_cleanup(struct ssh *ssh, int id)
827{ 910{
828 Channel *c = channel_by_id(id); 911 Channel *c = channel_by_id(ssh, id);
829 912
830 if (c == NULL) { 913 if (c == NULL) {
831 logit("channel_cancel_cleanup: %d: bad id", id); 914 logit("%s: %d: bad id", __func__, id);
832 return; 915 return;
833 } 916 }
834 c->detach_user = NULL; 917 c->detach_user = NULL;
@@ -836,13 +919,13 @@ channel_cancel_cleanup(int id)
836} 919}
837 920
838void 921void
839channel_register_filter(int id, channel_infilter_fn *ifn, 922channel_register_filter(struct ssh *ssh, int id, channel_infilter_fn *ifn,
840 channel_outfilter_fn *ofn, channel_filter_cleanup_fn *cfn, void *ctx) 923 channel_outfilter_fn *ofn, channel_filter_cleanup_fn *cfn, void *ctx)
841{ 924{
842 Channel *c = channel_lookup(id); 925 Channel *c = channel_lookup(ssh, id);
843 926
844 if (c == NULL) { 927 if (c == NULL) {
845 logit("channel_register_filter: %d: bad id", id); 928 logit("%s: %d: bad id", __func__, id);
846 return; 929 return;
847 } 930 }
848 c->input_filter = ifn; 931 c->input_filter = ifn;
@@ -852,118 +935,80 @@ channel_register_filter(int id, channel_infilter_fn *ifn,
852} 935}
853 936
854void 937void
855channel_set_fds(int id, int rfd, int wfd, int efd, 938channel_set_fds(struct ssh *ssh, int id, int rfd, int wfd, int efd,
856 int extusage, int nonblock, int is_tty, u_int window_max) 939 int extusage, int nonblock, int is_tty, u_int window_max)
857{ 940{
858 Channel *c = channel_lookup(id); 941 Channel *c = channel_lookup(ssh, id);
942 int r;
859 943
860 if (c == NULL || c->type != SSH_CHANNEL_LARVAL) 944 if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
861 fatal("channel_activate for non-larval channel %d.", id); 945 fatal("channel_activate for non-larval channel %d.", id);
862 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, is_tty); 946 if (!c->have_remote_id)
947 fatal(":%s: channel %d: no remote id", __func__, c->self);
948
949 channel_register_fds(ssh, c, rfd, wfd, efd, extusage, nonblock, is_tty);
863 c->type = SSH_CHANNEL_OPEN; 950 c->type = SSH_CHANNEL_OPEN;
864 c->local_window = c->local_window_max = window_max; 951 c->local_window = c->local_window_max = window_max;
865 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
866 packet_put_int(c->remote_id);
867 packet_put_int(c->local_window);
868 packet_send();
869}
870 952
871/* 953 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
872 * 'channel_pre*' are called just before select() to add any bits relevant to 954 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
873 * channels in the select bitmasks. 955 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
874 */ 956 (r = sshpkt_send(ssh)) != 0)
875/* 957 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
876 * 'channel_post*': perform any appropriate operations for channels which 958}
877 * have events pending.
878 */
879typedef void chan_fn(Channel *c, fd_set *readset, fd_set *writeset);
880chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE];
881chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE];
882 959
883/* ARGSUSED */
884static void 960static void
885channel_pre_listener(Channel *c, fd_set *readset, fd_set *writeset) 961channel_pre_listener(struct ssh *ssh, Channel *c,
962 fd_set *readset, fd_set *writeset)
886{ 963{
887 FD_SET(c->sock, readset); 964 FD_SET(c->sock, readset);
888} 965}
889 966
890/* ARGSUSED */
891static void 967static void
892channel_pre_connecting(Channel *c, fd_set *readset, fd_set *writeset) 968channel_pre_connecting(struct ssh *ssh, Channel *c,
969 fd_set *readset, fd_set *writeset)
893{ 970{
894 debug3("channel %d: waiting for connection", c->self); 971 debug3("channel %d: waiting for connection", c->self);
895 FD_SET(c->sock, writeset); 972 FD_SET(c->sock, writeset);
896} 973}
897 974
898static void 975static void
899channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset) 976channel_pre_open(struct ssh *ssh, Channel *c,
977 fd_set *readset, fd_set *writeset)
900{ 978{
901 if (buffer_len(&c->input) < packet_get_maxsize())
902 FD_SET(c->sock, readset);
903 if (buffer_len(&c->output) > 0)
904 FD_SET(c->sock, writeset);
905}
906
907static void
908channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
909{
910 u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
911
912 if (c->istate == CHAN_INPUT_OPEN && 979 if (c->istate == CHAN_INPUT_OPEN &&
913 limit > 0 && 980 c->remote_window > 0 &&
914 buffer_len(&c->input) < limit && 981 sshbuf_len(c->input) < c->remote_window &&
915 buffer_check_alloc(&c->input, CHAN_RBUF)) 982 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0)
916 FD_SET(c->rfd, readset); 983 FD_SET(c->rfd, readset);
917 if (c->ostate == CHAN_OUTPUT_OPEN || 984 if (c->ostate == CHAN_OUTPUT_OPEN ||
918 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { 985 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
919 if (buffer_len(&c->output) > 0) { 986 if (sshbuf_len(c->output) > 0) {
920 FD_SET(c->wfd, writeset); 987 FD_SET(c->wfd, writeset);
921 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { 988 } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
922 if (CHANNEL_EFD_OUTPUT_ACTIVE(c)) 989 if (CHANNEL_EFD_OUTPUT_ACTIVE(c))
923 debug2("channel %d: obuf_empty delayed efd %d/(%d)", 990 debug2("channel %d: "
924 c->self, c->efd, buffer_len(&c->extended)); 991 "obuf_empty delayed efd %d/(%zu)", c->self,
992 c->efd, sshbuf_len(c->extended));
925 else 993 else
926 chan_obuf_empty(c); 994 chan_obuf_empty(ssh, c);
927 } 995 }
928 } 996 }
929 /** XXX check close conditions, too */ 997 /** XXX check close conditions, too */
930 if (compat20 && c->efd != -1 && 998 if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED &&
931 !(c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED)) { 999 c->ostate == CHAN_OUTPUT_CLOSED)) {
932 if (c->extended_usage == CHAN_EXTENDED_WRITE && 1000 if (c->extended_usage == CHAN_EXTENDED_WRITE &&
933 buffer_len(&c->extended) > 0) 1001 sshbuf_len(c->extended) > 0)
934 FD_SET(c->efd, writeset); 1002 FD_SET(c->efd, writeset);
935 else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) && 1003 else if (c->efd != -1 && !(c->flags & CHAN_EOF_SENT) &&
936 (c->extended_usage == CHAN_EXTENDED_READ || 1004 (c->extended_usage == CHAN_EXTENDED_READ ||
937 c->extended_usage == CHAN_EXTENDED_IGNORE) && 1005 c->extended_usage == CHAN_EXTENDED_IGNORE) &&
938 buffer_len(&c->extended) < c->remote_window) 1006 sshbuf_len(c->extended) < c->remote_window)
939 FD_SET(c->efd, readset); 1007 FD_SET(c->efd, readset);
940 } 1008 }
941 /* XXX: What about efd? races? */ 1009 /* XXX: What about efd? races? */
942} 1010}
943 1011
944/* ARGSUSED */
945static void
946channel_pre_input_draining(Channel *c, fd_set *readset, fd_set *writeset)
947{
948 if (buffer_len(&c->input) == 0) {
949 packet_start(SSH_MSG_CHANNEL_CLOSE);
950 packet_put_int(c->remote_id);
951 packet_send();
952 c->type = SSH_CHANNEL_CLOSED;
953 debug2("channel %d: closing after input drain.", c->self);
954 }
955}
956
957/* ARGSUSED */
958static void
959channel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset)
960{
961 if (buffer_len(&c->output) == 0)
962 chan_mark_dead(c);
963 else
964 FD_SET(c->sock, writeset);
965}
966
967/* 1012/*
968 * This is a special state for X11 authentication spoofing. An opened X11 1013 * This is a special state for X11 authentication spoofing. An opened X11
969 * connection (when authentication spoofing is being done) remains in this 1014 * connection (when authentication spoofing is being done) remains in this
@@ -974,24 +1019,26 @@ channel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset)
974 * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok 1019 * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok
975 */ 1020 */
976static int 1021static int
977x11_open_helper(Buffer *b) 1022x11_open_helper(struct ssh *ssh, struct sshbuf *b)
978{ 1023{
1024 struct ssh_channels *sc = ssh->chanctxt;
979 u_char *ucp; 1025 u_char *ucp;
980 u_int proto_len, data_len; 1026 u_int proto_len, data_len;
981 1027
982 /* Is this being called after the refusal deadline? */ 1028 /* Is this being called after the refusal deadline? */
983 if (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) { 1029 if (sc->x11_refuse_time != 0 &&
1030 (u_int)monotime() >= sc->x11_refuse_time) {
984 verbose("Rejected X11 connection after ForwardX11Timeout " 1031 verbose("Rejected X11 connection after ForwardX11Timeout "
985 "expired"); 1032 "expired");
986 return -1; 1033 return -1;
987 } 1034 }
988 1035
989 /* Check if the fixed size part of the packet is in buffer. */ 1036 /* Check if the fixed size part of the packet is in buffer. */
990 if (buffer_len(b) < 12) 1037 if (sshbuf_len(b) < 12)
991 return 0; 1038 return 0;
992 1039
993 /* Parse the lengths of variable-length fields. */ 1040 /* Parse the lengths of variable-length fields. */
994 ucp = buffer_ptr(b); 1041 ucp = sshbuf_mutable_ptr(b);
995 if (ucp[0] == 0x42) { /* Byte order MSB first. */ 1042 if (ucp[0] == 0x42) { /* Byte order MSB first. */
996 proto_len = 256 * ucp[6] + ucp[7]; 1043 proto_len = 256 * ucp[6] + ucp[7];
997 data_len = 256 * ucp[8] + ucp[9]; 1044 data_len = 256 * ucp[8] + ucp[9];
@@ -1005,27 +1052,27 @@ x11_open_helper(Buffer *b)
1005 } 1052 }
1006 1053
1007 /* Check if the whole packet is in buffer. */ 1054 /* Check if the whole packet is in buffer. */
1008 if (buffer_len(b) < 1055 if (sshbuf_len(b) <
1009 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) 1056 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
1010 return 0; 1057 return 0;
1011 1058
1012 /* Check if authentication protocol matches. */ 1059 /* Check if authentication protocol matches. */
1013 if (proto_len != strlen(x11_saved_proto) || 1060 if (proto_len != strlen(sc->x11_saved_proto) ||
1014 memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) { 1061 memcmp(ucp + 12, sc->x11_saved_proto, proto_len) != 0) {
1015 debug2("X11 connection uses different authentication protocol."); 1062 debug2("X11 connection uses different authentication protocol.");
1016 return -1; 1063 return -1;
1017 } 1064 }
1018 /* Check if authentication data matches our fake data. */ 1065 /* Check if authentication data matches our fake data. */
1019 if (data_len != x11_fake_data_len || 1066 if (data_len != sc->x11_fake_data_len ||
1020 timingsafe_bcmp(ucp + 12 + ((proto_len + 3) & ~3), 1067 timingsafe_bcmp(ucp + 12 + ((proto_len + 3) & ~3),
1021 x11_fake_data, x11_fake_data_len) != 0) { 1068 sc->x11_fake_data, sc->x11_fake_data_len) != 0) {
1022 debug2("X11 auth data does not match fake data."); 1069 debug2("X11 auth data does not match fake data.");
1023 return -1; 1070 return -1;
1024 } 1071 }
1025 /* Check fake data length */ 1072 /* Check fake data length */
1026 if (x11_fake_data_len != x11_saved_data_len) { 1073 if (sc->x11_fake_data_len != sc->x11_saved_data_len) {
1027 error("X11 fake_data_len %d != saved_data_len %d", 1074 error("X11 fake_data_len %d != saved_data_len %d",
1028 x11_fake_data_len, x11_saved_data_len); 1075 sc->x11_fake_data_len, sc->x11_saved_data_len);
1029 return -1; 1076 return -1;
1030 } 1077 }
1031 /* 1078 /*
@@ -1034,90 +1081,63 @@ x11_open_helper(Buffer *b)
1034 * data. 1081 * data.
1035 */ 1082 */
1036 memcpy(ucp + 12 + ((proto_len + 3) & ~3), 1083 memcpy(ucp + 12 + ((proto_len + 3) & ~3),
1037 x11_saved_data, x11_saved_data_len); 1084 sc->x11_saved_data, sc->x11_saved_data_len);
1038 return 1; 1085 return 1;
1039} 1086}
1040 1087
1041static void 1088static void
1042channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset) 1089channel_pre_x11_open(struct ssh *ssh, Channel *c,
1090 fd_set *readset, fd_set *writeset)
1043{ 1091{
1044 int ret = x11_open_helper(&c->output); 1092 int ret = x11_open_helper(ssh, c->output);
1045
1046 if (ret == 1) {
1047 /* Start normal processing for the channel. */
1048 c->type = SSH_CHANNEL_OPEN;
1049 channel_pre_open_13(c, readset, writeset);
1050 } else if (ret == -1) {
1051 /*
1052 * We have received an X11 connection that has bad
1053 * authentication information.
1054 */
1055 logit("X11 connection rejected because of wrong authentication.");
1056 buffer_clear(&c->input);
1057 buffer_clear(&c->output);
1058 channel_close_fd(&c->sock);
1059 c->sock = -1;
1060 c->type = SSH_CHANNEL_CLOSED;
1061 packet_start(SSH_MSG_CHANNEL_CLOSE);
1062 packet_put_int(c->remote_id);
1063 packet_send();
1064 }
1065}
1066
1067static void
1068channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
1069{
1070 int ret = x11_open_helper(&c->output);
1071 1093
1072 /* c->force_drain = 1; */ 1094 /* c->force_drain = 1; */
1073 1095
1074 if (ret == 1) { 1096 if (ret == 1) {
1075 c->type = SSH_CHANNEL_OPEN; 1097 c->type = SSH_CHANNEL_OPEN;
1076 channel_pre_open(c, readset, writeset); 1098 channel_pre_open(ssh, c, readset, writeset);
1077 } else if (ret == -1) { 1099 } else if (ret == -1) {
1078 logit("X11 connection rejected because of wrong authentication."); 1100 logit("X11 connection rejected because of wrong authentication.");
1079 debug2("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); 1101 debug2("X11 rejected %d i%d/o%d",
1080 chan_read_failed(c); 1102 c->self, c->istate, c->ostate);
1081 buffer_clear(&c->input); 1103 chan_read_failed(ssh, c);
1082 chan_ibuf_empty(c); 1104 sshbuf_reset(c->input);
1083 buffer_clear(&c->output); 1105 chan_ibuf_empty(ssh, c);
1084 /* for proto v1, the peer will send an IEOF */ 1106 sshbuf_reset(c->output);
1085 if (compat20) 1107 chan_write_failed(ssh, c);
1086 chan_write_failed(c);
1087 else
1088 c->type = SSH_CHANNEL_OPEN;
1089 debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); 1108 debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
1090 } 1109 }
1091} 1110}
1092 1111
1093static void 1112static void
1094channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset) 1113channel_pre_mux_client(struct ssh *ssh,
1114 Channel *c, fd_set *readset, fd_set *writeset)
1095{ 1115{
1096 if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause && 1116 if (c->istate == CHAN_INPUT_OPEN && !c->mux_pause &&
1097 buffer_check_alloc(&c->input, CHAN_RBUF)) 1117 sshbuf_check_reserve(c->input, CHAN_RBUF) == 0)
1098 FD_SET(c->rfd, readset); 1118 FD_SET(c->rfd, readset);
1099 if (c->istate == CHAN_INPUT_WAIT_DRAIN) { 1119 if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
1100 /* clear buffer immediately (discard any partial packet) */ 1120 /* clear buffer immediately (discard any partial packet) */
1101 buffer_clear(&c->input); 1121 sshbuf_reset(c->input);
1102 chan_ibuf_empty(c); 1122 chan_ibuf_empty(ssh, c);
1103 /* Start output drain. XXX just kill chan? */ 1123 /* Start output drain. XXX just kill chan? */
1104 chan_rcvd_oclose(c); 1124 chan_rcvd_oclose(ssh, c);
1105 } 1125 }
1106 if (c->ostate == CHAN_OUTPUT_OPEN || 1126 if (c->ostate == CHAN_OUTPUT_OPEN ||
1107 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) { 1127 c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
1108 if (buffer_len(&c->output) > 0) 1128 if (sshbuf_len(c->output) > 0)
1109 FD_SET(c->wfd, writeset); 1129 FD_SET(c->wfd, writeset);
1110 else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) 1130 else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN)
1111 chan_obuf_empty(c); 1131 chan_obuf_empty(ssh, c);
1112 } 1132 }
1113} 1133}
1114 1134
1115/* try to decode a socks4 header */ 1135/* try to decode a socks4 header */
1116/* ARGSUSED */
1117static int 1136static int
1118channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) 1137channel_decode_socks4(Channel *c, struct sshbuf *input, struct sshbuf *output)
1119{ 1138{
1120 char *p, *host; 1139 const u_char *p;
1140 char *host;
1121 u_int len, have, i, found, need; 1141 u_int len, have, i, found, need;
1122 char username[256]; 1142 char username[256];
1123 struct { 1143 struct {
@@ -1126,14 +1146,15 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
1126 u_int16_t dest_port; 1146 u_int16_t dest_port;
1127 struct in_addr dest_addr; 1147 struct in_addr dest_addr;
1128 } s4_req, s4_rsp; 1148 } s4_req, s4_rsp;
1149 int r;
1129 1150
1130 debug2("channel %d: decode socks4", c->self); 1151 debug2("channel %d: decode socks4", c->self);
1131 1152
1132 have = buffer_len(&c->input); 1153 have = sshbuf_len(input);
1133 len = sizeof(s4_req); 1154 len = sizeof(s4_req);
1134 if (have < len) 1155 if (have < len)
1135 return 0; 1156 return 0;
1136 p = (char *)buffer_ptr(&c->input); 1157 p = sshbuf_ptr(input);
1137 1158
1138 need = 1; 1159 need = 1;
1139 /* SOCKS4A uses an invalid IP address 0.0.0.x */ 1160 /* SOCKS4A uses an invalid IP address 0.0.0.x */
@@ -1158,46 +1179,55 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
1158 } 1179 }
1159 if (found < need) 1180 if (found < need)
1160 return 0; 1181 return 0;
1161 buffer_get(&c->input, (char *)&s4_req.version, 1); 1182 if ((r = sshbuf_get(input, &s4_req.version, 1)) != 0 ||
1162 buffer_get(&c->input, (char *)&s4_req.command, 1); 1183 (r = sshbuf_get(input, &s4_req.command, 1)) != 0 ||
1163 buffer_get(&c->input, (char *)&s4_req.dest_port, 2); 1184 (r = sshbuf_get(input, &s4_req.dest_port, 2)) != 0 ||
1164 buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); 1185 (r = sshbuf_get(input, &s4_req.dest_addr, 4)) != 0) {
1165 have = buffer_len(&c->input); 1186 debug("channels %d: decode socks4: %s", c->self, ssh_err(r));
1166 p = (char *)buffer_ptr(&c->input); 1187 return -1;
1167 if (memchr(p, '\0', have) == NULL) 1188 }
1168 fatal("channel %d: decode socks4: user not nul terminated", 1189 have = sshbuf_len(input);
1190 p = sshbuf_ptr(input);
1191 if (memchr(p, '\0', have) == NULL) {
1192 error("channel %d: decode socks4: user not nul terminated",
1169 c->self); 1193 c->self);
1194 return -1;
1195 }
1170 len = strlen(p); 1196 len = strlen(p);
1171 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); 1197 debug2("channel %d: decode socks4: user %s/%d", c->self, p, len);
1172 len++; /* trailing '\0' */ 1198 len++; /* trailing '\0' */
1173 if (len > have)
1174 fatal("channel %d: decode socks4: len %d > have %d",
1175 c->self, len, have);
1176 strlcpy(username, p, sizeof(username)); 1199 strlcpy(username, p, sizeof(username));
1177 buffer_consume(&c->input, len); 1200 if ((r = sshbuf_consume(input, len)) != 0) {
1178 1201 fatal("%s: channel %d: consume: %s", __func__,
1202 c->self, ssh_err(r));
1203 }
1179 free(c->path); 1204 free(c->path);
1180 c->path = NULL; 1205 c->path = NULL;
1181 if (need == 1) { /* SOCKS4: one string */ 1206 if (need == 1) { /* SOCKS4: one string */
1182 host = inet_ntoa(s4_req.dest_addr); 1207 host = inet_ntoa(s4_req.dest_addr);
1183 c->path = xstrdup(host); 1208 c->path = xstrdup(host);
1184 } else { /* SOCKS4A: two strings */ 1209 } else { /* SOCKS4A: two strings */
1185 have = buffer_len(&c->input); 1210 have = sshbuf_len(input);
1186 p = (char *)buffer_ptr(&c->input); 1211 p = sshbuf_ptr(input);
1212 if (memchr(p, '\0', have) == NULL) {
1213 error("channel %d: decode socks4a: host not nul "
1214 "terminated", c->self);
1215 return -1;
1216 }
1187 len = strlen(p); 1217 len = strlen(p);
1188 debug2("channel %d: decode socks4a: host %s/%d", 1218 debug2("channel %d: decode socks4a: host %s/%d",
1189 c->self, p, len); 1219 c->self, p, len);
1190 len++; /* trailing '\0' */ 1220 len++; /* trailing '\0' */
1191 if (len > have)
1192 fatal("channel %d: decode socks4a: len %d > have %d",
1193 c->self, len, have);
1194 if (len > NI_MAXHOST) { 1221 if (len > NI_MAXHOST) {
1195 error("channel %d: hostname \"%.100s\" too long", 1222 error("channel %d: hostname \"%.100s\" too long",
1196 c->self, p); 1223 c->self, p);
1197 return -1; 1224 return -1;
1198 } 1225 }
1199 c->path = xstrdup(p); 1226 c->path = xstrdup(p);
1200 buffer_consume(&c->input, len); 1227 if ((r = sshbuf_consume(input, len)) != 0) {
1228 fatal("%s: channel %d: consume: %s", __func__,
1229 c->self, ssh_err(r));
1230 }
1201 } 1231 }
1202 c->host_port = ntohs(s4_req.dest_port); 1232 c->host_port = ntohs(s4_req.dest_port);
1203 1233
@@ -1213,7 +1243,10 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
1213 s4_rsp.command = 90; /* cd: req granted */ 1243 s4_rsp.command = 90; /* cd: req granted */
1214 s4_rsp.dest_port = 0; /* ignored */ 1244 s4_rsp.dest_port = 0; /* ignored */
1215 s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */ 1245 s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */
1216 buffer_append(&c->output, &s4_rsp, sizeof(s4_rsp)); 1246 if ((r = sshbuf_put(output, &s4_rsp, sizeof(s4_rsp))) != 0) {
1247 fatal("%s: channel %d: append reply: %s", __func__,
1248 c->self, ssh_err(r));
1249 }
1217 return 1; 1250 return 1;
1218} 1251}
1219 1252
@@ -1226,10 +1259,10 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
1226#define SSH_SOCKS5_CONNECT 0x01 1259#define SSH_SOCKS5_CONNECT 0x01
1227#define SSH_SOCKS5_SUCCESS 0x00 1260#define SSH_SOCKS5_SUCCESS 0x00
1228 1261
1229/* ARGSUSED */
1230static int 1262static int
1231channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) 1263channel_decode_socks5(Channel *c, struct sshbuf *input, struct sshbuf *output)
1232{ 1264{
1265 /* XXX use get/put_u8 instead of trusting struct padding */
1233 struct { 1266 struct {
1234 u_int8_t version; 1267 u_int8_t version;
1235 u_int8_t command; 1268 u_int8_t command;
@@ -1238,14 +1271,15 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
1238 } s5_req, s5_rsp; 1271 } s5_req, s5_rsp;
1239 u_int16_t dest_port; 1272 u_int16_t dest_port;
1240 char dest_addr[255+1], ntop[INET6_ADDRSTRLEN]; 1273 char dest_addr[255+1], ntop[INET6_ADDRSTRLEN];
1241 u_char *p; 1274 const u_char *p;
1242 u_int have, need, i, found, nmethods, addrlen, af; 1275 u_int have, need, i, found, nmethods, addrlen, af;
1276 int r;
1243 1277
1244 debug2("channel %d: decode socks5", c->self); 1278 debug2("channel %d: decode socks5", c->self);
1245 p = buffer_ptr(&c->input); 1279 p = sshbuf_ptr(input);
1246 if (p[0] != 0x05) 1280 if (p[0] != 0x05)
1247 return -1; 1281 return -1;
1248 have = buffer_len(&c->input); 1282 have = sshbuf_len(input);
1249 if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { 1283 if (!(c->flags & SSH_SOCKS5_AUTHDONE)) {
1250 /* format: ver | nmethods | methods */ 1284 /* format: ver | nmethods | methods */
1251 if (have < 2) 1285 if (have < 2)
@@ -1265,10 +1299,16 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
1265 c->self); 1299 c->self);
1266 return -1; 1300 return -1;
1267 } 1301 }
1268 buffer_consume(&c->input, nmethods + 2); 1302 if ((r = sshbuf_consume(input, nmethods + 2)) != 0) {
1269 buffer_put_char(&c->output, 0x05); /* version */ 1303 fatal("%s: channel %d: consume: %s", __func__,
1270 buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */ 1304 c->self, ssh_err(r));
1271 FD_SET(c->sock, writeset); 1305 }
1306 /* version, method */
1307 if ((r = sshbuf_put_u8(output, 0x05)) != 0 ||
1308 (r = sshbuf_put_u8(output, SSH_SOCKS5_NOAUTH)) != 0) {
1309 fatal("%s: channel %d: append reply: %s", __func__,
1310 c->self, ssh_err(r));
1311 }
1272 c->flags |= SSH_SOCKS5_AUTHDONE; 1312 c->flags |= SSH_SOCKS5_AUTHDONE;
1273 debug2("channel %d: socks5 auth done", c->self); 1313 debug2("channel %d: socks5 auth done", c->self);
1274 return 0; /* need more */ 1314 return 0; /* need more */
@@ -1305,11 +1345,22 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
1305 need++; 1345 need++;
1306 if (have < need) 1346 if (have < need)
1307 return 0; 1347 return 0;
1308 buffer_consume(&c->input, sizeof(s5_req)); 1348 if ((r = sshbuf_consume(input, sizeof(s5_req))) != 0) {
1309 if (s5_req.atyp == SSH_SOCKS5_DOMAIN) 1349 fatal("%s: channel %d: consume: %s", __func__,
1310 buffer_consume(&c->input, 1); /* host string length */ 1350 c->self, ssh_err(r));
1311 buffer_get(&c->input, &dest_addr, addrlen); 1351 }
1312 buffer_get(&c->input, (char *)&dest_port, 2); 1352 if (s5_req.atyp == SSH_SOCKS5_DOMAIN) {
1353 /* host string length */
1354 if ((r = sshbuf_consume(input, 1)) != 0) {
1355 fatal("%s: channel %d: consume: %s", __func__,
1356 c->self, ssh_err(r));
1357 }
1358 }
1359 if ((r = sshbuf_get(input, &dest_addr, addrlen)) != 0 ||
1360 (r = sshbuf_get(input, &dest_port, 2)) != 0) {
1361 debug("channel %d: parse addr/port: %s", c->self, ssh_err(r));
1362 return -1;
1363 }
1313 dest_addr[addrlen] = '\0'; 1364 dest_addr[addrlen] = '\0';
1314 free(c->path); 1365 free(c->path);
1315 c->path = NULL; 1366 c->path = NULL;
@@ -1336,22 +1387,23 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
1336 s5_rsp.atyp = SSH_SOCKS5_IPV4; 1387 s5_rsp.atyp = SSH_SOCKS5_IPV4;
1337 dest_port = 0; /* ignored */ 1388 dest_port = 0; /* ignored */
1338 1389
1339 buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp)); 1390 if ((r = sshbuf_put(output, &s5_rsp, sizeof(s5_rsp))) != 0 ||
1340 buffer_put_int(&c->output, ntohl(INADDR_ANY)); /* bind address */ 1391 (r = sshbuf_put_u32(output, ntohl(INADDR_ANY))) != 0 ||
1341 buffer_append(&c->output, &dest_port, sizeof(dest_port)); 1392 (r = sshbuf_put(output, &dest_port, sizeof(dest_port))) != 0)
1393 fatal("%s: channel %d: append reply: %s", __func__,
1394 c->self, ssh_err(r));
1342 return 1; 1395 return 1;
1343} 1396}
1344 1397
1345Channel * 1398Channel *
1346channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect, 1399channel_connect_stdio_fwd(struct ssh *ssh,
1347 int in, int out) 1400 const char *host_to_connect, u_short port_to_connect, int in, int out)
1348{ 1401{
1349 Channel *c; 1402 Channel *c;
1350 1403
1351 debug("channel_connect_stdio_fwd %s:%d", host_to_connect, 1404 debug("%s %s:%d", __func__, host_to_connect, port_to_connect);
1352 port_to_connect);
1353 1405
1354 c = channel_new("stdio-forward", SSH_CHANNEL_OPENING, in, out, 1406 c = channel_new(ssh, "stdio-forward", SSH_CHANNEL_OPENING, in, out,
1355 -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 1407 -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1356 0, "stdio-forward", /*nonblock*/0); 1408 0, "stdio-forward", /*nonblock*/0);
1357 1409
@@ -1360,23 +1412,24 @@ channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect,
1360 c->listening_port = 0; 1412 c->listening_port = 0;
1361 c->force_drain = 1; 1413 c->force_drain = 1;
1362 1414
1363 channel_register_fds(c, in, out, -1, 0, 1, 0); 1415 channel_register_fds(ssh, c, in, out, -1, 0, 1, 0);
1364 port_open_helper(c, "direct-tcpip"); 1416 port_open_helper(ssh, c, "direct-tcpip");
1365 1417
1366 return c; 1418 return c;
1367} 1419}
1368 1420
1369/* dynamic port forwarding */ 1421/* dynamic port forwarding */
1370static void 1422static void
1371channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset) 1423channel_pre_dynamic(struct ssh *ssh, Channel *c,
1424 fd_set *readset, fd_set *writeset)
1372{ 1425{
1373 u_char *p; 1426 const u_char *p;
1374 u_int have; 1427 u_int have;
1375 int ret; 1428 int ret;
1376 1429
1377 have = buffer_len(&c->input); 1430 have = sshbuf_len(c->input);
1378 debug2("channel %d: pre_dynamic: have %d", c->self, have); 1431 debug2("channel %d: pre_dynamic: have %d", c->self, have);
1379 /* buffer_dump(&c->input); */ 1432 /* sshbuf_dump(c->input, stderr); */
1380 /* check if the fixed size part of the packet is in buffer. */ 1433 /* check if the fixed size part of the packet is in buffer. */
1381 if (have < 3) { 1434 if (have < 3) {
1382 /* need more */ 1435 /* need more */
@@ -1384,105 +1437,174 @@ channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
1384 return; 1437 return;
1385 } 1438 }
1386 /* try to guess the protocol */ 1439 /* try to guess the protocol */
1387 p = buffer_ptr(&c->input); 1440 p = sshbuf_ptr(c->input);
1441 /* XXX sshbuf_peek_u8? */
1388 switch (p[0]) { 1442 switch (p[0]) {
1389 case 0x04: 1443 case 0x04:
1390 ret = channel_decode_socks4(c, readset, writeset); 1444 ret = channel_decode_socks4(c, c->input, c->output);
1391 break; 1445 break;
1392 case 0x05: 1446 case 0x05:
1393 ret = channel_decode_socks5(c, readset, writeset); 1447 ret = channel_decode_socks5(c, c->input, c->output);
1394 break; 1448 break;
1395 default: 1449 default:
1396 ret = -1; 1450 ret = -1;
1397 break; 1451 break;
1398 } 1452 }
1399 if (ret < 0) { 1453 if (ret < 0) {
1400 chan_mark_dead(c); 1454 chan_mark_dead(ssh, c);
1401 } else if (ret == 0) { 1455 } else if (ret == 0) {
1402 debug2("channel %d: pre_dynamic: need more", c->self); 1456 debug2("channel %d: pre_dynamic: need more", c->self);
1403 /* need more */ 1457 /* need more */
1404 FD_SET(c->sock, readset); 1458 FD_SET(c->sock, readset);
1459 if (sshbuf_len(c->output))
1460 FD_SET(c->sock, writeset);
1405 } else { 1461 } else {
1406 /* switch to the next state */ 1462 /* switch to the next state */
1407 c->type = SSH_CHANNEL_OPENING; 1463 c->type = SSH_CHANNEL_OPENING;
1408 port_open_helper(c, "direct-tcpip"); 1464 port_open_helper(ssh, c, "direct-tcpip");
1465 }
1466}
1467
1468/* simulate read-error */
1469static void
1470rdynamic_close(struct ssh *ssh, Channel *c)
1471{
1472 c->type = SSH_CHANNEL_OPEN;
1473 chan_read_failed(ssh, c);
1474 sshbuf_reset(c->input);
1475 chan_ibuf_empty(ssh, c);
1476 sshbuf_reset(c->output);
1477 chan_write_failed(ssh, c);
1478}
1479
1480/* reverse dynamic port forwarding */
1481static void
1482channel_before_prepare_select_rdynamic(struct ssh *ssh, Channel *c)
1483{
1484 const u_char *p;
1485 u_int have, len;
1486 int r, ret;
1487
1488 have = sshbuf_len(c->output);
1489 debug2("channel %d: pre_rdynamic: have %d", c->self, have);
1490 /* sshbuf_dump(c->output, stderr); */
1491 /* EOF received */
1492 if (c->flags & CHAN_EOF_RCVD) {
1493 if ((r = sshbuf_consume(c->output, have)) != 0) {
1494 fatal("%s: channel %d: consume: %s",
1495 __func__, c->self, ssh_err(r));
1496 }
1497 rdynamic_close(ssh, c);
1498 return;
1499 }
1500 /* check if the fixed size part of the packet is in buffer. */
1501 if (have < 3)
1502 return;
1503 /* try to guess the protocol */
1504 p = sshbuf_ptr(c->output);
1505 switch (p[0]) {
1506 case 0x04:
1507 /* switch input/output for reverse forwarding */
1508 ret = channel_decode_socks4(c, c->output, c->input);
1509 break;
1510 case 0x05:
1511 ret = channel_decode_socks5(c, c->output, c->input);
1512 break;
1513 default:
1514 ret = -1;
1515 break;
1516 }
1517 if (ret < 0) {
1518 rdynamic_close(ssh, c);
1519 } else if (ret == 0) {
1520 debug2("channel %d: pre_rdynamic: need more", c->self);
1521 /* send socks request to peer */
1522 len = sshbuf_len(c->input);
1523 if (len > 0 && len < c->remote_window) {
1524 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
1525 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1526 (r = sshpkt_put_stringb(ssh, c->input)) != 0 ||
1527 (r = sshpkt_send(ssh)) != 0) {
1528 fatal("%s: channel %i: rdynamic: %s", __func__,
1529 c->self, ssh_err(r));
1530 }
1531 if ((r = sshbuf_consume(c->input, len)) != 0) {
1532 fatal("%s: channel %d: consume: %s",
1533 __func__, c->self, ssh_err(r));
1534 }
1535 c->remote_window -= len;
1536 }
1537 } else if (rdynamic_connect_finish(ssh, c) < 0) {
1538 /* the connect failed */
1539 rdynamic_close(ssh, c);
1409 } 1540 }
1410} 1541}
1411 1542
1412/* This is our fake X11 server socket. */ 1543/* This is our fake X11 server socket. */
1413/* ARGSUSED */
1414static void 1544static void
1415channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset) 1545channel_post_x11_listener(struct ssh *ssh, Channel *c,
1546 fd_set *readset, fd_set *writeset)
1416{ 1547{
1417 Channel *nc; 1548 Channel *nc;
1418 struct sockaddr_storage addr; 1549 struct sockaddr_storage addr;
1419 int newsock, oerrno; 1550 int r, newsock, oerrno, remote_port;
1420 socklen_t addrlen; 1551 socklen_t addrlen;
1421 char buf[16384], *remote_ipaddr; 1552 char buf[16384], *remote_ipaddr;
1422 int remote_port; 1553
1423 1554 if (!FD_ISSET(c->sock, readset))
1424 if (FD_ISSET(c->sock, readset)) { 1555 return;
1425 debug("X11 connection requested."); 1556
1426 addrlen = sizeof(addr); 1557 debug("X11 connection requested.");
1427 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); 1558 addrlen = sizeof(addr);
1428 if (c->single_connection) { 1559 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
1429 oerrno = errno; 1560 if (c->single_connection) {
1430 debug2("single_connection: closing X11 listener."); 1561 oerrno = errno;
1431 channel_close_fd(&c->sock); 1562 debug2("single_connection: closing X11 listener.");
1432 chan_mark_dead(c); 1563 channel_close_fd(ssh, &c->sock);
1433 errno = oerrno; 1564 chan_mark_dead(ssh, c);
1434 } 1565 errno = oerrno;
1435 if (newsock < 0) { 1566 }
1436 if (errno != EINTR && errno != EWOULDBLOCK && 1567 if (newsock < 0) {
1437 errno != ECONNABORTED) 1568 if (errno != EINTR && errno != EWOULDBLOCK &&
1438 error("accept: %.100s", strerror(errno)); 1569 errno != ECONNABORTED)
1439 if (errno == EMFILE || errno == ENFILE) 1570 error("accept: %.100s", strerror(errno));
1440 c->notbefore = monotime() + 1; 1571 if (errno == EMFILE || errno == ENFILE)
1441 return; 1572 c->notbefore = monotime() + 1;
1442 } 1573 return;
1443 set_nodelay(newsock);
1444 remote_ipaddr = get_peer_ipaddr(newsock);
1445 remote_port = get_peer_port(newsock);
1446 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
1447 remote_ipaddr, remote_port);
1448
1449 nc = channel_new("accepted x11 socket",
1450 SSH_CHANNEL_OPENING, newsock, newsock, -1,
1451 c->local_window_max, c->local_maxpacket, 0, buf, 1);
1452 if (compat20) {
1453 packet_start(SSH2_MSG_CHANNEL_OPEN);
1454 packet_put_cstring("x11");
1455 packet_put_int(nc->self);
1456 packet_put_int(nc->local_window_max);
1457 packet_put_int(nc->local_maxpacket);
1458 /* originator ipaddr and port */
1459 packet_put_cstring(remote_ipaddr);
1460 if (datafellows & SSH_BUG_X11FWD) {
1461 debug2("ssh2 x11 bug compat mode");
1462 } else {
1463 packet_put_int(remote_port);
1464 }
1465 packet_send();
1466 } else {
1467 packet_start(SSH_SMSG_X11_OPEN);
1468 packet_put_int(nc->self);
1469 if (packet_get_protocol_flags() &
1470 SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
1471 packet_put_cstring(buf);
1472 packet_send();
1473 }
1474 free(remote_ipaddr);
1475 } 1574 }
1575 set_nodelay(newsock);
1576 remote_ipaddr = get_peer_ipaddr(newsock);
1577 remote_port = get_peer_port(newsock);
1578 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
1579 remote_ipaddr, remote_port);
1580
1581 nc = channel_new(ssh, "accepted x11 socket",
1582 SSH_CHANNEL_OPENING, newsock, newsock, -1,
1583 c->local_window_max, c->local_maxpacket, 0, buf, 1);
1584 open_preamble(ssh, __func__, nc, "x11");
1585 if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0) {
1586 fatal("%s: channel %i: reply %s", __func__,
1587 c->self, ssh_err(r));
1588 }
1589 if ((datafellows & SSH_BUG_X11FWD) != 0)
1590 debug2("channel %d: ssh2 x11 bug compat mode", nc->self);
1591 else if ((r = sshpkt_put_u32(ssh, remote_port)) != 0) {
1592 fatal("%s: channel %i: reply %s", __func__,
1593 c->self, ssh_err(r));
1594 }
1595 if ((r = sshpkt_send(ssh)) != 0)
1596 fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));
1597 free(remote_ipaddr);
1476} 1598}
1477 1599
1478static void 1600static void
1479port_open_helper(Channel *c, char *rtype) 1601port_open_helper(struct ssh *ssh, Channel *c, char *rtype)
1480{ 1602{
1481 char buf[1024];
1482 char *local_ipaddr = get_local_ipaddr(c->sock); 1603 char *local_ipaddr = get_local_ipaddr(c->sock);
1483 int local_port = c->sock == -1 ? 65536 : get_local_port(c->sock); 1604 int local_port = c->sock == -1 ? 65536 : get_local_port(c->sock);
1484 char *remote_ipaddr = get_peer_ipaddr(c->sock); 1605 char *remote_ipaddr = get_peer_ipaddr(c->sock);
1485 int remote_port = get_peer_port(c->sock); 1606 int remote_port = get_peer_port(c->sock);
1607 int r;
1486 1608
1487 if (remote_port == -1) { 1609 if (remote_port == -1) {
1488 /* Fake addr/port to appease peers that validate it (Tectia) */ 1610 /* Fake addr/port to appease peers that validate it (Tectia) */
@@ -1491,55 +1613,57 @@ port_open_helper(Channel *c, char *rtype)
1491 remote_port = 65535; 1613 remote_port = 65535;
1492 } 1614 }
1493 1615
1494 snprintf(buf, sizeof buf, 1616 free(c->remote_name);
1617 xasprintf(&c->remote_name,
1495 "%s: listening port %d for %.100s port %d, " 1618 "%s: listening port %d for %.100s port %d, "
1496 "connect from %.200s port %d to %.100s port %d", 1619 "connect from %.200s port %d to %.100s port %d",
1497 rtype, c->listening_port, c->path, c->host_port, 1620 rtype, c->listening_port, c->path, c->host_port,
1498 remote_ipaddr, remote_port, local_ipaddr, local_port); 1621 remote_ipaddr, remote_port, local_ipaddr, local_port);
1499 1622
1500 free(c->remote_name); 1623 open_preamble(ssh, __func__, c, rtype);
1501 c->remote_name = xstrdup(buf); 1624 if (strcmp(rtype, "direct-tcpip") == 0) {
1502 1625 /* target host, port */
1503 if (compat20) { 1626 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
1504 packet_start(SSH2_MSG_CHANNEL_OPEN); 1627 (r = sshpkt_put_u32(ssh, c->host_port)) != 0) {
1505 packet_put_cstring(rtype); 1628 fatal("%s: channel %i: reply %s", __func__,
1506 packet_put_int(c->self); 1629 c->self, ssh_err(r));
1507 packet_put_int(c->local_window_max);
1508 packet_put_int(c->local_maxpacket);
1509 if (strcmp(rtype, "direct-tcpip") == 0) {
1510 /* target host, port */
1511 packet_put_cstring(c->path);
1512 packet_put_int(c->host_port);
1513 } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
1514 /* target path */
1515 packet_put_cstring(c->path);
1516 } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
1517 /* listen path */
1518 packet_put_cstring(c->path);
1519 } else {
1520 /* listen address, port */
1521 packet_put_cstring(c->path);
1522 packet_put_int(local_port);
1523 } 1630 }
1524 if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) { 1631 } else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
1525 /* reserved for future owner/mode info */ 1632 /* target path */
1526 packet_put_cstring(""); 1633 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) {
1527 } else { 1634 fatal("%s: channel %i: reply %s", __func__,
1528 /* originator host and port */ 1635 c->self, ssh_err(r));
1529 packet_put_cstring(remote_ipaddr); 1636 }
1530 packet_put_int((u_int)remote_port); 1637 } else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
1638 /* listen path */
1639 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0) {
1640 fatal("%s: channel %i: reply %s", __func__,
1641 c->self, ssh_err(r));
1531 } 1642 }
1532 packet_send();
1533 } else { 1643 } else {
1534 packet_start(SSH_MSG_PORT_OPEN); 1644 /* listen address, port */
1535 packet_put_int(c->self); 1645 if ((r = sshpkt_put_cstring(ssh, c->path)) != 0 ||
1536 packet_put_cstring(c->path); 1646 (r = sshpkt_put_u32(ssh, local_port)) != 0) {
1537 packet_put_int(c->host_port); 1647 fatal("%s: channel %i: reply %s", __func__,
1538 if (packet_get_protocol_flags() & 1648 c->self, ssh_err(r));
1539 SSH_PROTOFLAG_HOST_IN_FWD_OPEN) 1649 }
1540 packet_put_cstring(c->remote_name);
1541 packet_send();
1542 } 1650 }
1651 if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
1652 /* reserved for future owner/mode info */
1653 if ((r = sshpkt_put_cstring(ssh, "")) != 0) {
1654 fatal("%s: channel %i: reply %s", __func__,
1655 c->self, ssh_err(r));
1656 }
1657 } else {
1658 /* originator host and port */
1659 if ((r = sshpkt_put_cstring(ssh, remote_ipaddr)) != 0 ||
1660 (r = sshpkt_put_u32(ssh, (u_int)remote_port)) != 0) {
1661 fatal("%s: channel %i: reply %s", __func__,
1662 c->self, ssh_err(r));
1663 }
1664 }
1665 if ((r = sshpkt_send(ssh)) != 0)
1666 fatal("%s: channel %i: send %s", __func__, c->self, ssh_err(r));
1543 free(remote_ipaddr); 1667 free(remote_ipaddr);
1544 free(local_ipaddr); 1668 free(local_ipaddr);
1545} 1669}
@@ -1558,17 +1682,17 @@ channel_set_reuseaddr(int fd)
1558} 1682}
1559 1683
1560void 1684void
1561channel_set_x11_refuse_time(u_int refuse_time) 1685channel_set_x11_refuse_time(struct ssh *ssh, u_int refuse_time)
1562{ 1686{
1563 x11_refuse_time = refuse_time; 1687 ssh->chanctxt->x11_refuse_time = refuse_time;
1564} 1688}
1565 1689
1566/* 1690/*
1567 * This socket is listening for connections to a forwarded TCP/IP port. 1691 * This socket is listening for connections to a forwarded TCP/IP port.
1568 */ 1692 */
1569/* ARGSUSED */
1570static void 1693static void
1571channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) 1694channel_post_port_listener(struct ssh *ssh, Channel *c,
1695 fd_set *readset, fd_set *writeset)
1572{ 1696{
1573 Channel *nc; 1697 Channel *nc;
1574 struct sockaddr_storage addr; 1698 struct sockaddr_storage addr;
@@ -1576,360 +1700,406 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
1576 socklen_t addrlen; 1700 socklen_t addrlen;
1577 char *rtype; 1701 char *rtype;
1578 1702
1579 if (FD_ISSET(c->sock, readset)) { 1703 if (!FD_ISSET(c->sock, readset))
1580 debug("Connection to port %d forwarding " 1704 return;
1581 "to %.100s port %d requested.",
1582 c->listening_port, c->path, c->host_port);
1583
1584 if (c->type == SSH_CHANNEL_RPORT_LISTENER) {
1585 nextstate = SSH_CHANNEL_OPENING;
1586 rtype = "forwarded-tcpip";
1587 } else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) {
1588 nextstate = SSH_CHANNEL_OPENING;
1589 rtype = "forwarded-streamlocal@openssh.com";
1590 } else if (c->host_port == PORT_STREAMLOCAL) {
1591 nextstate = SSH_CHANNEL_OPENING;
1592 rtype = "direct-streamlocal@openssh.com";
1593 } else if (c->host_port == 0) {
1594 nextstate = SSH_CHANNEL_DYNAMIC;
1595 rtype = "dynamic-tcpip";
1596 } else {
1597 nextstate = SSH_CHANNEL_OPENING;
1598 rtype = "direct-tcpip";
1599 }
1600 1705
1601 addrlen = sizeof(addr); 1706 debug("Connection to port %d forwarding to %.100s port %d requested.",
1602 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); 1707 c->listening_port, c->path, c->host_port);
1603 if (newsock < 0) { 1708
1604 if (errno != EINTR && errno != EWOULDBLOCK && 1709 if (c->type == SSH_CHANNEL_RPORT_LISTENER) {
1605 errno != ECONNABORTED) 1710 nextstate = SSH_CHANNEL_OPENING;
1606 error("accept: %.100s", strerror(errno)); 1711 rtype = "forwarded-tcpip";
1607 if (errno == EMFILE || errno == ENFILE) 1712 } else if (c->type == SSH_CHANNEL_RUNIX_LISTENER) {
1608 c->notbefore = monotime() + 1; 1713 nextstate = SSH_CHANNEL_OPENING;
1609 return; 1714 rtype = "forwarded-streamlocal@openssh.com";
1610 } 1715 } else if (c->host_port == PORT_STREAMLOCAL) {
1611 if (c->host_port != PORT_STREAMLOCAL) 1716 nextstate = SSH_CHANNEL_OPENING;
1612 set_nodelay(newsock); 1717 rtype = "direct-streamlocal@openssh.com";
1613 nc = channel_new(rtype, nextstate, newsock, newsock, -1, 1718 } else if (c->host_port == 0) {
1614 c->local_window_max, c->local_maxpacket, 0, rtype, 1); 1719 nextstate = SSH_CHANNEL_DYNAMIC;
1615 nc->listening_port = c->listening_port; 1720 rtype = "dynamic-tcpip";
1616 nc->host_port = c->host_port; 1721 } else {
1617 if (c->path != NULL) 1722 nextstate = SSH_CHANNEL_OPENING;
1618 nc->path = xstrdup(c->path); 1723 rtype = "direct-tcpip";
1619 1724 }
1620 if (nextstate != SSH_CHANNEL_DYNAMIC) 1725
1621 port_open_helper(nc, rtype); 1726 addrlen = sizeof(addr);
1727 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
1728 if (newsock < 0) {
1729 if (errno != EINTR && errno != EWOULDBLOCK &&
1730 errno != ECONNABORTED)
1731 error("accept: %.100s", strerror(errno));
1732 if (errno == EMFILE || errno == ENFILE)
1733 c->notbefore = monotime() + 1;
1734 return;
1622 } 1735 }
1736 if (c->host_port != PORT_STREAMLOCAL)
1737 set_nodelay(newsock);
1738 nc = channel_new(ssh, rtype, nextstate, newsock, newsock, -1,
1739 c->local_window_max, c->local_maxpacket, 0, rtype, 1);
1740 nc->listening_port = c->listening_port;
1741 nc->host_port = c->host_port;
1742 if (c->path != NULL)
1743 nc->path = xstrdup(c->path);
1744
1745 if (nextstate != SSH_CHANNEL_DYNAMIC)
1746 port_open_helper(ssh, nc, rtype);
1623} 1747}
1624 1748
1625/* 1749/*
1626 * This is the authentication agent socket listening for connections from 1750 * This is the authentication agent socket listening for connections from
1627 * clients. 1751 * clients.
1628 */ 1752 */
1629/* ARGSUSED */
1630static void 1753static void
1631channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset) 1754channel_post_auth_listener(struct ssh *ssh, Channel *c,
1755 fd_set *readset, fd_set *writeset)
1632{ 1756{
1633 Channel *nc; 1757 Channel *nc;
1634 int newsock; 1758 int r, newsock;
1635 struct sockaddr_storage addr; 1759 struct sockaddr_storage addr;
1636 socklen_t addrlen; 1760 socklen_t addrlen;
1637 1761
1638 if (FD_ISSET(c->sock, readset)) { 1762 if (!FD_ISSET(c->sock, readset))
1639 addrlen = sizeof(addr); 1763 return;
1640 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); 1764
1641 if (newsock < 0) { 1765 addrlen = sizeof(addr);
1642 error("accept from auth socket: %.100s", 1766 newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen);
1643 strerror(errno)); 1767 if (newsock < 0) {
1644 if (errno == EMFILE || errno == ENFILE) 1768 error("accept from auth socket: %.100s", strerror(errno));
1645 c->notbefore = monotime() + 1; 1769 if (errno == EMFILE || errno == ENFILE)
1646 return; 1770 c->notbefore = monotime() + 1;
1647 } 1771 return;
1648 nc = channel_new("accepted auth socket",
1649 SSH_CHANNEL_OPENING, newsock, newsock, -1,
1650 c->local_window_max, c->local_maxpacket,
1651 0, "accepted auth socket", 1);
1652 if (compat20) {
1653 packet_start(SSH2_MSG_CHANNEL_OPEN);
1654 packet_put_cstring("auth-agent@openssh.com");
1655 packet_put_int(nc->self);
1656 packet_put_int(c->local_window_max);
1657 packet_put_int(c->local_maxpacket);
1658 } else {
1659 packet_start(SSH_SMSG_AGENT_OPEN);
1660 packet_put_int(nc->self);
1661 }
1662 packet_send();
1663 } 1772 }
1773 nc = channel_new(ssh, "accepted auth socket",
1774 SSH_CHANNEL_OPENING, newsock, newsock, -1,
1775 c->local_window_max, c->local_maxpacket,
1776 0, "accepted auth socket", 1);
1777 open_preamble(ssh, __func__, nc, "auth-agent@openssh.com");
1778 if ((r = sshpkt_send(ssh)) != 0)
1779 fatal("%s: channel %i: %s", __func__, c->self, ssh_err(r));
1664} 1780}
1665 1781
1666/* ARGSUSED */
1667static void 1782static void
1668channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) 1783channel_post_connecting(struct ssh *ssh, Channel *c,
1784 fd_set *readset, fd_set *writeset)
1669{ 1785{
1670 int err = 0, sock; 1786 int err = 0, sock, isopen, r;
1671 socklen_t sz = sizeof(err); 1787 socklen_t sz = sizeof(err);
1672 1788
1673 if (FD_ISSET(c->sock, writeset)) { 1789 if (!FD_ISSET(c->sock, writeset))
1674 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) { 1790 return;
1675 err = errno; 1791 if (!c->have_remote_id)
1676 error("getsockopt SO_ERROR failed"); 1792 fatal(":%s: channel %d: no remote id", __func__, c->self);
1793 /* for rdynamic the OPEN_CONFIRMATION has been sent already */
1794 isopen = (c->type == SSH_CHANNEL_RDYNAMIC_FINISH);
1795 if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) {
1796 err = errno;
1797 error("getsockopt SO_ERROR failed");
1798 }
1799 if (err == 0) {
1800 debug("channel %d: connected to %s port %d",
1801 c->self, c->connect_ctx.host, c->connect_ctx.port);
1802 channel_connect_ctx_free(&c->connect_ctx);
1803 c->type = SSH_CHANNEL_OPEN;
1804 if (isopen) {
1805 /* no message necessary */
1806 } else {
1807 if ((r = sshpkt_start(ssh,
1808 SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
1809 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1810 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
1811 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
1812 (r = sshpkt_put_u32(ssh, c->local_maxpacket))
1813 != 0)
1814 fatal("%s: channel %i: confirm: %s", __func__,
1815 c->self, ssh_err(r));
1816 if ((r = sshpkt_send(ssh)) != 0)
1817 fatal("%s: channel %i: %s", __func__, c->self,
1818 ssh_err(r));
1677 } 1819 }
1678 if (err == 0) { 1820 } else {
1679 debug("channel %d: connected to %s port %d", 1821 debug("channel %d: connection failed: %s",
1680 c->self, c->connect_ctx.host, c->connect_ctx.port); 1822 c->self, strerror(err));
1681 channel_connect_ctx_free(&c->connect_ctx); 1823 /* Try next address, if any */
1682 c->type = SSH_CHANNEL_OPEN; 1824 if ((sock = connect_next(&c->connect_ctx)) > 0) {
1683 if (compat20) { 1825 close(c->sock);
1684 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 1826 c->sock = c->rfd = c->wfd = sock;
1685 packet_put_int(c->remote_id); 1827 channel_find_maxfd(ssh->chanctxt);
1686 packet_put_int(c->self); 1828 return;
1687 packet_put_int(c->local_window); 1829 }
1688 packet_put_int(c->local_maxpacket); 1830 /* Exhausted all addresses */
1689 } else { 1831 error("connect_to %.100s port %d: failed.",
1690 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 1832 c->connect_ctx.host, c->connect_ctx.port);
1691 packet_put_int(c->remote_id); 1833 channel_connect_ctx_free(&c->connect_ctx);
1692 packet_put_int(c->self); 1834 if (isopen) {
1693 } 1835 rdynamic_close(ssh, c);
1694 } else { 1836 } else {
1695 debug("channel %d: connection failed: %s", 1837 if ((r = sshpkt_start(ssh,
1696 c->self, strerror(err)); 1838 SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
1697 /* Try next address, if any */ 1839 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1698 if ((sock = connect_next(&c->connect_ctx)) > 0) { 1840 (r = sshpkt_put_u32(ssh, SSH2_OPEN_CONNECT_FAILED))
1699 close(c->sock); 1841 != 0)
1700 c->sock = c->rfd = c->wfd = sock; 1842 fatal("%s: channel %i: failure: %s", __func__,
1701 channel_max_fd = channel_find_maxfd(); 1843 c->self, ssh_err(r));
1702 return; 1844 if ((datafellows & SSH_BUG_OPENFAILURE) == 0 &&
1703 } 1845 ((r = sshpkt_put_cstring(ssh, strerror(err))) != 0 ||
1704 /* Exhausted all addresses */ 1846 (r = sshpkt_put_cstring(ssh, "")) != 0))
1705 error("connect_to %.100s port %d: failed.", 1847 fatal("%s: channel %i: failure: %s", __func__,
1706 c->connect_ctx.host, c->connect_ctx.port); 1848 c->self, ssh_err(r));
1707 channel_connect_ctx_free(&c->connect_ctx); 1849 if ((r = sshpkt_send(ssh)) != 0)
1708 if (compat20) { 1850 fatal("%s: channel %i: %s", __func__, c->self,
1709 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 1851 ssh_err(r));
1710 packet_put_int(c->remote_id); 1852 chan_mark_dead(ssh, c);
1711 packet_put_int(SSH2_OPEN_CONNECT_FAILED);
1712 if (!(datafellows & SSH_BUG_OPENFAILURE)) {
1713 packet_put_cstring(strerror(err));
1714 packet_put_cstring("");
1715 }
1716 } else {
1717 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1718 packet_put_int(c->remote_id);
1719 }
1720 chan_mark_dead(c);
1721 } 1853 }
1722 packet_send();
1723 } 1854 }
1724} 1855}
1725 1856
1726/* ARGSUSED */
1727static int 1857static int
1728channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset) 1858channel_handle_rfd(struct ssh *ssh, Channel *c,
1859 fd_set *readset, fd_set *writeset)
1729{ 1860{
1730 char buf[CHAN_RBUF]; 1861 char buf[CHAN_RBUF];
1731 int len, force; 1862 ssize_t len;
1863 int r, force;
1732 1864
1733 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED; 1865 force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
1734 if (c->rfd != -1 && (force || FD_ISSET(c->rfd, readset))) { 1866
1735 errno = 0; 1867 if (c->rfd == -1 || (!force && !FD_ISSET(c->rfd, readset)))
1736 len = read(c->rfd, buf, sizeof(buf)); 1868 return 1;
1737 if (len < 0 && (errno == EINTR || 1869
1738 ((errno == EAGAIN || errno == EWOULDBLOCK) && !force))) 1870 errno = 0;
1739 return 1; 1871 len = read(c->rfd, buf, sizeof(buf));
1872 if (len < 0 && (errno == EINTR ||
1873 ((errno == EAGAIN || errno == EWOULDBLOCK) && !force)))
1874 return 1;
1740#ifndef PTY_ZEROREAD 1875#ifndef PTY_ZEROREAD
1741 if (len <= 0) { 1876 if (len <= 0) {
1742#else 1877#else
1743 if ((!c->isatty && len <= 0) || 1878 if ((!c->isatty && len <= 0) ||
1744 (c->isatty && (len < 0 || (len == 0 && errno != 0)))) { 1879 (c->isatty && (len < 0 || (len == 0 && errno != 0)))) {
1745#endif 1880#endif
1746 debug2("channel %d: read<=0 rfd %d len %d", 1881 debug2("channel %d: read<=0 rfd %d len %zd",
1747 c->self, c->rfd, len); 1882 c->self, c->rfd, len);
1748 if (c->type != SSH_CHANNEL_OPEN) { 1883 if (c->type != SSH_CHANNEL_OPEN) {
1749 debug2("channel %d: not open", c->self); 1884 debug2("channel %d: not open", c->self);
1750 chan_mark_dead(c); 1885 chan_mark_dead(ssh, c);
1751 return -1;
1752 } else if (compat13) {
1753 buffer_clear(&c->output);
1754 c->type = SSH_CHANNEL_INPUT_DRAINING;
1755 debug2("channel %d: input draining.", c->self);
1756 } else {
1757 chan_read_failed(c);
1758 }
1759 return -1; 1886 return -1;
1760 }
1761 if (c->input_filter != NULL) {
1762 if (c->input_filter(c, buf, len) == -1) {
1763 debug2("channel %d: filter stops", c->self);
1764 chan_read_failed(c);
1765 }
1766 } else if (c->datagram) {
1767 buffer_put_string(&c->input, buf, len);
1768 } else { 1887 } else {
1769 buffer_append(&c->input, buf, len); 1888 chan_read_failed(ssh, c);
1889 }
1890 return -1;
1891 }
1892 if (c->input_filter != NULL) {
1893 if (c->input_filter(ssh, c, buf, len) == -1) {
1894 debug2("channel %d: filter stops", c->self);
1895 chan_read_failed(ssh, c);
1770 } 1896 }
1897 } else if (c->datagram) {
1898 if ((r = sshbuf_put_string(c->input, buf, len)) != 0)
1899 fatal("%s: channel %d: put datagram: %s", __func__,
1900 c->self, ssh_err(r));
1901 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) {
1902 fatal("%s: channel %d: put data: %s", __func__,
1903 c->self, ssh_err(r));
1771 } 1904 }
1772 return 1; 1905 return 1;
1773} 1906}
1774 1907
1775/* ARGSUSED */
1776static int 1908static int
1777channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset) 1909channel_handle_wfd(struct ssh *ssh, Channel *c,
1910 fd_set *readset, fd_set *writeset)
1778{ 1911{
1779 struct termios tio; 1912 struct termios tio;
1780 u_char *data = NULL, *buf; 1913 u_char *data = NULL, *buf; /* XXX const; need filter API change */
1781 u_int dlen, olen = 0; 1914 size_t dlen, olen = 0;
1782 int len; 1915 int r, len;
1916
1917 if (c->wfd == -1 || !FD_ISSET(c->wfd, writeset) ||
1918 sshbuf_len(c->output) == 0)
1919 return 1;
1783 1920
1784 /* Send buffered output data to the socket. */ 1921 /* Send buffered output data to the socket. */
1785 if (c->wfd != -1 && 1922 olen = sshbuf_len(c->output);
1786 FD_ISSET(c->wfd, writeset) && 1923 if (c->output_filter != NULL) {
1787 buffer_len(&c->output) > 0) { 1924 if ((buf = c->output_filter(ssh, c, &data, &dlen)) == NULL) {
1788 olen = buffer_len(&c->output); 1925 debug2("channel %d: filter stops", c->self);
1789 if (c->output_filter != NULL) { 1926 if (c->type != SSH_CHANNEL_OPEN)
1790 if ((buf = c->output_filter(c, &data, &dlen)) == NULL) { 1927 chan_mark_dead(ssh, c);
1791 debug2("channel %d: filter stops", c->self); 1928 else
1792 if (c->type != SSH_CHANNEL_OPEN) 1929 chan_write_failed(ssh, c);
1793 chan_mark_dead(c); 1930 return -1;
1794 else
1795 chan_write_failed(c);
1796 return -1;
1797 }
1798 } else if (c->datagram) {
1799 buf = data = buffer_get_string(&c->output, &dlen);
1800 } else {
1801 buf = data = buffer_ptr(&c->output);
1802 dlen = buffer_len(&c->output);
1803 } 1931 }
1932 } else if (c->datagram) {
1933 if ((r = sshbuf_get_string(c->output, &data, &dlen)) != 0)
1934 fatal("%s: channel %d: get datagram: %s", __func__,
1935 c->self, ssh_err(r));
1936 buf = data;
1937 } else {
1938 buf = data = sshbuf_mutable_ptr(c->output);
1939 dlen = sshbuf_len(c->output);
1940 }
1941
1942 if (c->datagram) {
1943 /* ignore truncated writes, datagrams might get lost */
1944 len = write(c->wfd, buf, dlen);
1945 free(data);
1946 if (len < 0 && (errno == EINTR || errno == EAGAIN ||
1947 errno == EWOULDBLOCK))
1948 return 1;
1949 if (len <= 0)
1950 goto write_fail;
1951 goto out;
1952 }
1804 1953
1805 if (c->datagram) {
1806 /* ignore truncated writes, datagrams might get lost */
1807 len = write(c->wfd, buf, dlen);
1808 free(data);
1809 if (len < 0 && (errno == EINTR || errno == EAGAIN ||
1810 errno == EWOULDBLOCK))
1811 return 1;
1812 if (len <= 0) {
1813 if (c->type != SSH_CHANNEL_OPEN)
1814 chan_mark_dead(c);
1815 else
1816 chan_write_failed(c);
1817 return -1;
1818 }
1819 goto out;
1820 }
1821#ifdef _AIX 1954#ifdef _AIX
1822 /* XXX: Later AIX versions can't push as much data to tty */ 1955 /* XXX: Later AIX versions can't push as much data to tty */
1823 if (compat20 && c->wfd_isatty) 1956 if (c->wfd_isatty)
1824 dlen = MIN(dlen, 8*1024); 1957 dlen = MIN(dlen, 8*1024);
1825#endif 1958#endif
1826 1959
1827 len = write(c->wfd, buf, dlen); 1960 len = write(c->wfd, buf, dlen);
1828 if (len < 0 && 1961 if (len < 0 &&
1829 (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) 1962 (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
1830 return 1; 1963 return 1;
1831 if (len <= 0) { 1964 if (len <= 0) {
1832 if (c->type != SSH_CHANNEL_OPEN) { 1965 write_fail:
1833 debug2("channel %d: not open", c->self); 1966 if (c->type != SSH_CHANNEL_OPEN) {
1834 chan_mark_dead(c); 1967 debug2("channel %d: not open", c->self);
1835 return -1; 1968 chan_mark_dead(ssh, c);
1836 } else if (compat13) {
1837 buffer_clear(&c->output);
1838 debug2("channel %d: input draining.", c->self);
1839 c->type = SSH_CHANNEL_INPUT_DRAINING;
1840 } else {
1841 chan_write_failed(c);
1842 }
1843 return -1; 1969 return -1;
1970 } else {
1971 chan_write_failed(ssh, c);
1844 } 1972 }
1973 return -1;
1974 }
1845#ifndef BROKEN_TCGETATTR_ICANON 1975#ifndef BROKEN_TCGETATTR_ICANON
1846 if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') { 1976 if (c->isatty && dlen >= 1 && buf[0] != '\r') {
1847 if (tcgetattr(c->wfd, &tio) == 0 && 1977 if (tcgetattr(c->wfd, &tio) == 0 &&
1848 !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { 1978 !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
1849 /* 1979 /*
1850 * Simulate echo to reduce the impact of 1980 * Simulate echo to reduce the impact of
1851 * traffic analysis. We need to match the 1981 * traffic analysis. We need to match the
1852 * size of a SSH2_MSG_CHANNEL_DATA message 1982 * size of a SSH2_MSG_CHANNEL_DATA message
1853 * (4 byte channel id + buf) 1983 * (4 byte channel id + buf)
1854 */ 1984 */
1855 packet_send_ignore(4 + len); 1985 if ((r = sshpkt_msg_ignore(ssh, 4+len)) != 0 ||
1856 packet_send(); 1986 (r = sshpkt_send(ssh)) != 0)
1857 } 1987 fatal("%s: channel %d: ignore: %s",
1988 __func__, c->self, ssh_err(r));
1858 } 1989 }
1859#endif 1990 }
1860 buffer_consume(&c->output, len); 1991#endif /* BROKEN_TCGETATTR_ICANON */
1992 if ((r = sshbuf_consume(c->output, len)) != 0) {
1993 fatal("%s: channel %d: consume: %s",
1994 __func__, c->self, ssh_err(r));
1861 } 1995 }
1862 out: 1996 out:
1863 if (compat20 && olen > 0) 1997 c->local_consumed += olen - sshbuf_len(c->output);
1864 c->local_consumed += olen - buffer_len(&c->output); 1998
1865 return 1; 1999 return 1;
1866} 2000}
1867 2001
1868static int 2002static int
1869channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset) 2003channel_handle_efd_write(struct ssh *ssh, Channel *c,
2004 fd_set *readset, fd_set *writeset)
2005{
2006 int r;
2007 ssize_t len;
2008
2009 if (!FD_ISSET(c->efd, writeset) || sshbuf_len(c->extended) == 0)
2010 return 1;
2011
2012 len = write(c->efd, sshbuf_ptr(c->extended),
2013 sshbuf_len(c->extended));
2014 debug2("channel %d: written %zd to efd %d", c->self, len, c->efd);
2015 if (len < 0 && (errno == EINTR || errno == EAGAIN ||
2016 errno == EWOULDBLOCK))
2017 return 1;
2018 if (len <= 0) {
2019 debug2("channel %d: closing write-efd %d", c->self, c->efd);
2020 channel_close_fd(ssh, &c->efd);
2021 } else {
2022 if ((r = sshbuf_consume(c->extended, len)) != 0) {
2023 fatal("%s: channel %d: consume: %s",
2024 __func__, c->self, ssh_err(r));
2025 }
2026 c->local_consumed += len;
2027 }
2028 return 1;
2029}
2030
2031static int
2032channel_handle_efd_read(struct ssh *ssh, Channel *c,
2033 fd_set *readset, fd_set *writeset)
1870{ 2034{
1871 char buf[CHAN_RBUF]; 2035 char buf[CHAN_RBUF];
1872 int len; 2036 int r;
2037 ssize_t len;
1873 2038
1874/** XXX handle drain efd, too */ 2039 if (!c->detach_close && !FD_ISSET(c->efd, readset))
1875 if (c->efd != -1) { 2040 return 1;
1876 if (c->extended_usage == CHAN_EXTENDED_WRITE && 2041
1877 FD_ISSET(c->efd, writeset) && 2042 len = read(c->efd, buf, sizeof(buf));
1878 buffer_len(&c->extended) > 0) { 2043 debug2("channel %d: read %zd from efd %d", c->self, len, c->efd);
1879 len = write(c->efd, buffer_ptr(&c->extended), 2044 if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
1880 buffer_len(&c->extended)); 2045 errno == EWOULDBLOCK) && !c->detach_close)))
1881 debug2("channel %d: written %d to efd %d", 2046 return 1;
1882 c->self, len, c->efd); 2047 if (len <= 0) {
1883 if (len < 0 && (errno == EINTR || errno == EAGAIN || 2048 debug2("channel %d: closing read-efd %d",
1884 errno == EWOULDBLOCK)) 2049 c->self, c->efd);
1885 return 1; 2050 channel_close_fd(ssh, &c->efd);
1886 if (len <= 0) { 2051 } else {
1887 debug2("channel %d: closing write-efd %d", 2052 if (c->extended_usage == CHAN_EXTENDED_IGNORE) {
1888 c->self, c->efd); 2053 debug3("channel %d: discard efd",
1889 channel_close_fd(&c->efd); 2054 c->self);
1890 } else { 2055 } else if ((r = sshbuf_put(c->extended, buf, len)) != 0) {
1891 buffer_consume(&c->extended, len); 2056 fatal("%s: channel %d: append: %s",
1892 c->local_consumed += len; 2057 __func__, c->self, ssh_err(r));
1893 }
1894 } else if (c->efd != -1 &&
1895 (c->extended_usage == CHAN_EXTENDED_READ ||
1896 c->extended_usage == CHAN_EXTENDED_IGNORE) &&
1897 (c->detach_close || FD_ISSET(c->efd, readset))) {
1898 len = read(c->efd, buf, sizeof(buf));
1899 debug2("channel %d: read %d from efd %d",
1900 c->self, len, c->efd);
1901 if (len < 0 && (errno == EINTR || ((errno == EAGAIN ||
1902 errno == EWOULDBLOCK) && !c->detach_close)))
1903 return 1;
1904 if (len <= 0) {
1905 debug2("channel %d: closing read-efd %d",
1906 c->self, c->efd);
1907 channel_close_fd(&c->efd);
1908 } else {
1909 if (c->extended_usage == CHAN_EXTENDED_IGNORE) {
1910 debug3("channel %d: discard efd",
1911 c->self);
1912 } else
1913 buffer_append(&c->extended, buf, len);
1914 }
1915 } 2058 }
1916 } 2059 }
1917 return 1; 2060 return 1;
1918} 2061}
1919 2062
1920static int 2063static int
1921channel_check_window(Channel *c) 2064channel_handle_efd(struct ssh *ssh, Channel *c,
2065 fd_set *readset, fd_set *writeset)
1922{ 2066{
2067 if (c->efd == -1)
2068 return 1;
2069
2070 /** XXX handle drain efd, too */
2071
2072 if (c->extended_usage == CHAN_EXTENDED_WRITE)
2073 return channel_handle_efd_write(ssh, c, readset, writeset);
2074 else if (c->extended_usage == CHAN_EXTENDED_READ ||
2075 c->extended_usage == CHAN_EXTENDED_IGNORE)
2076 return channel_handle_efd_read(ssh, c, readset, writeset);
2077
2078 return 1;
2079}
2080
2081static int
2082channel_check_window(struct ssh *ssh, Channel *c)
2083{
2084 int r;
2085
1923 if (c->type == SSH_CHANNEL_OPEN && 2086 if (c->type == SSH_CHANNEL_OPEN &&
1924 !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && 2087 !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
1925 ((c->local_window_max - c->local_window > 2088 ((c->local_window_max - c->local_window >
1926 c->local_maxpacket*3) || 2089 c->local_maxpacket*3) ||
1927 c->local_window < c->local_window_max/2) && 2090 c->local_window < c->local_window_max/2) &&
1928 c->local_consumed > 0) { 2091 c->local_consumed > 0) {
1929 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); 2092 if (!c->have_remote_id)
1930 packet_put_int(c->remote_id); 2093 fatal(":%s: channel %d: no remote id",
1931 packet_put_int(c->local_consumed); 2094 __func__, c->self);
1932 packet_send(); 2095 if ((r = sshpkt_start(ssh,
2096 SSH2_MSG_CHANNEL_WINDOW_ADJUST)) != 0 ||
2097 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
2098 (r = sshpkt_put_u32(ssh, c->local_consumed)) != 0 ||
2099 (r = sshpkt_send(ssh)) != 0) {
2100 fatal("%s: channel %i: %s", __func__,
2101 c->self, ssh_err(r));
2102 }
1933 debug2("channel %d: window %d sent adjust %d", 2103 debug2("channel %d: window %d sent adjust %d",
1934 c->self, c->local_window, 2104 c->self, c->local_window,
1935 c->local_consumed); 2105 c->local_consumed);
@@ -1940,90 +2110,112 @@ channel_check_window(Channel *c)
1940} 2110}
1941 2111
1942static void 2112static void
1943channel_post_open(Channel *c, fd_set *readset, fd_set *writeset) 2113channel_post_open(struct ssh *ssh, Channel *c,
2114 fd_set *readset, fd_set *writeset)
1944{ 2115{
1945 channel_handle_rfd(c, readset, writeset); 2116 channel_handle_rfd(ssh, c, readset, writeset);
1946 channel_handle_wfd(c, readset, writeset); 2117 channel_handle_wfd(ssh, c, readset, writeset);
1947 if (!compat20) 2118 channel_handle_efd(ssh, c, readset, writeset);
1948 return; 2119 channel_check_window(ssh, c);
1949 channel_handle_efd(c, readset, writeset);
1950 channel_check_window(c);
1951} 2120}
1952 2121
1953static u_int 2122static u_int
1954read_mux(Channel *c, u_int need) 2123read_mux(struct ssh *ssh, Channel *c, u_int need)
1955{ 2124{
1956 char buf[CHAN_RBUF]; 2125 char buf[CHAN_RBUF];
1957 int len; 2126 ssize_t len;
1958 u_int rlen; 2127 u_int rlen;
2128 int r;
1959 2129
1960 if (buffer_len(&c->input) < need) { 2130 if (sshbuf_len(c->input) < need) {
1961 rlen = need - buffer_len(&c->input); 2131 rlen = need - sshbuf_len(c->input);
1962 len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF)); 2132 len = read(c->rfd, buf, MINIMUM(rlen, CHAN_RBUF));
1963 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 2133 if (len < 0 && (errno == EINTR || errno == EAGAIN))
1964 return buffer_len(&c->input); 2134 return sshbuf_len(c->input);
1965 if (len <= 0) { 2135 if (len <= 0) {
1966 debug2("channel %d: ctl read<=0 rfd %d len %d", 2136 debug2("channel %d: ctl read<=0 rfd %d len %zd",
1967 c->self, c->rfd, len); 2137 c->self, c->rfd, len);
1968 chan_read_failed(c); 2138 chan_read_failed(ssh, c);
1969 return 0; 2139 return 0;
1970 } else 2140 } else if ((r = sshbuf_put(c->input, buf, len)) != 0) {
1971 buffer_append(&c->input, buf, len); 2141 fatal("%s: channel %d: append: %s",
2142 __func__, c->self, ssh_err(r));
2143 }
1972 } 2144 }
1973 return buffer_len(&c->input); 2145 return sshbuf_len(c->input);
1974} 2146}
1975 2147
1976static void 2148static void
1977channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset) 2149channel_post_mux_client_read(struct ssh *ssh, Channel *c,
2150 fd_set *readset, fd_set *writeset)
1978{ 2151{
1979 u_int need; 2152 u_int need;
1980 ssize_t len;
1981 2153
1982 if (!compat20) 2154 if (c->rfd == -1 || !FD_ISSET(c->rfd, readset))
1983 fatal("%s: entered with !compat20", __func__); 2155 return;
2156 if (c->istate != CHAN_INPUT_OPEN && c->istate != CHAN_INPUT_WAIT_DRAIN)
2157 return;
2158 if (c->mux_pause)
2159 return;
1984 2160
1985 if (c->rfd != -1 && !c->mux_pause && FD_ISSET(c->rfd, readset) && 2161 /*
1986 (c->istate == CHAN_INPUT_OPEN || 2162 * Don't not read past the precise end of packets to
1987 c->istate == CHAN_INPUT_WAIT_DRAIN)) { 2163 * avoid disrupting fd passing.
1988 /* 2164 */
1989 * Don't not read past the precise end of packets to 2165 if (read_mux(ssh, c, 4) < 4) /* read header */
1990 * avoid disrupting fd passing. 2166 return;
1991 */ 2167 /* XXX sshbuf_peek_u32 */
1992 if (read_mux(c, 4) < 4) /* read header */ 2168 need = PEEK_U32(sshbuf_ptr(c->input));
1993 return;
1994 need = get_u32(buffer_ptr(&c->input));
1995#define CHANNEL_MUX_MAX_PACKET (256 * 1024) 2169#define CHANNEL_MUX_MAX_PACKET (256 * 1024)
1996 if (need > CHANNEL_MUX_MAX_PACKET) { 2170 if (need > CHANNEL_MUX_MAX_PACKET) {
1997 debug2("channel %d: packet too big %u > %u", 2171 debug2("channel %d: packet too big %u > %u",
1998 c->self, CHANNEL_MUX_MAX_PACKET, need); 2172 c->self, CHANNEL_MUX_MAX_PACKET, need);
1999 chan_rcvd_oclose(c); 2173 chan_rcvd_oclose(ssh, c);
2000 return; 2174 return;
2001 } 2175 }
2002 if (read_mux(c, need + 4) < need + 4) /* read body */ 2176 if (read_mux(ssh, c, need + 4) < need + 4) /* read body */
2003 return; 2177 return;
2004 if (c->mux_rcb(c) != 0) { 2178 if (c->mux_rcb(ssh, c) != 0) {
2005 debug("channel %d: mux_rcb failed", c->self); 2179 debug("channel %d: mux_rcb failed", c->self);
2006 chan_mark_dead(c); 2180 chan_mark_dead(ssh, c);
2007 return; 2181 return;
2008 }
2009 } 2182 }
2183}
2010 2184
2011 if (c->wfd != -1 && FD_ISSET(c->wfd, writeset) && 2185static void
2012 buffer_len(&c->output) > 0) { 2186channel_post_mux_client_write(struct ssh *ssh, Channel *c,
2013 len = write(c->wfd, buffer_ptr(&c->output), 2187 fd_set *readset, fd_set *writeset)
2014 buffer_len(&c->output)); 2188{
2015 if (len < 0 && (errno == EINTR || errno == EAGAIN)) 2189 ssize_t len;
2016 return; 2190 int r;
2017 if (len <= 0) { 2191
2018 chan_mark_dead(c); 2192 if (c->wfd == -1 || !FD_ISSET(c->wfd, writeset) ||
2019 return; 2193 sshbuf_len(c->output) == 0)
2020 } 2194 return;
2021 buffer_consume(&c->output, len); 2195
2196 len = write(c->wfd, sshbuf_ptr(c->output), sshbuf_len(c->output));
2197 if (len < 0 && (errno == EINTR || errno == EAGAIN))
2198 return;
2199 if (len <= 0) {
2200 chan_mark_dead(ssh, c);
2201 return;
2022 } 2202 }
2203 if ((r = sshbuf_consume(c->output, len)) != 0)
2204 fatal("%s: channel %d: consume: %s", __func__,
2205 c->self, ssh_err(r));
2206}
2207
2208static void
2209channel_post_mux_client(struct ssh *ssh, Channel *c,
2210 fd_set *readset, fd_set *writeset)
2211{
2212 channel_post_mux_client_read(ssh, c, readset, writeset);
2213 channel_post_mux_client_write(ssh, c, readset, writeset);
2023} 2214}
2024 2215
2025static void 2216static void
2026channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset) 2217channel_post_mux_listener(struct ssh *ssh, Channel *c,
2218 fd_set *readset, fd_set *writeset)
2027{ 2219{
2028 Channel *nc; 2220 Channel *nc;
2029 struct sockaddr_storage addr; 2221 struct sockaddr_storage addr;
@@ -2062,166 +2254,100 @@ channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
2062 close(newsock); 2254 close(newsock);
2063 return; 2255 return;
2064 } 2256 }
2065 nc = channel_new("multiplex client", SSH_CHANNEL_MUX_CLIENT, 2257 nc = channel_new(ssh, "multiplex client", SSH_CHANNEL_MUX_CLIENT,
2066 newsock, newsock, -1, c->local_window_max, 2258 newsock, newsock, -1, c->local_window_max,
2067 c->local_maxpacket, 0, "mux-control", 1); 2259 c->local_maxpacket, 0, "mux-control", 1);
2068 nc->mux_rcb = c->mux_rcb; 2260 nc->mux_rcb = c->mux_rcb;
2069 debug3("%s: new mux channel %d fd %d", __func__, 2261 debug3("%s: new mux channel %d fd %d", __func__, nc->self, nc->sock);
2070 nc->self, nc->sock);
2071 /* establish state */ 2262 /* establish state */
2072 nc->mux_rcb(nc); 2263 nc->mux_rcb(ssh, nc);
2073 /* mux state transitions must not elicit protocol messages */ 2264 /* mux state transitions must not elicit protocol messages */
2074 nc->flags |= CHAN_LOCAL; 2265 nc->flags |= CHAN_LOCAL;
2075} 2266}
2076 2267
2077/* ARGSUSED */
2078static void 2268static void
2079channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset) 2269channel_handler_init(struct ssh_channels *sc)
2080{ 2270{
2081 int len; 2271 chan_fn **pre, **post;
2082 2272
2083 /* Send buffered output data to the socket. */ 2273 if ((pre = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*pre))) == NULL ||
2084 if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) { 2274 (post = calloc(SSH_CHANNEL_MAX_TYPE, sizeof(*post))) == NULL)
2085 len = write(c->sock, buffer_ptr(&c->output), 2275 fatal("%s: allocation failed", __func__);
2086 buffer_len(&c->output)); 2276
2087 if (len <= 0) 2277 pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
2088 buffer_clear(&c->output); 2278 pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
2089 else 2279 pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
2090 buffer_consume(&c->output, len); 2280 pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener;
2091 } 2281 pre[SSH_CHANNEL_UNIX_LISTENER] = &channel_pre_listener;
2092} 2282 pre[SSH_CHANNEL_RUNIX_LISTENER] = &channel_pre_listener;
2093 2283 pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
2094static void 2284 pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
2095channel_handler_init_20(void) 2285 pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
2096{ 2286 pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
2097 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open; 2287 pre[SSH_CHANNEL_RDYNAMIC_FINISH] = &channel_pre_connecting;
2098 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; 2288 pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener;
2099 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; 2289 pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client;
2100 channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener; 2290
2101 channel_pre[SSH_CHANNEL_UNIX_LISTENER] = &channel_pre_listener; 2291 post[SSH_CHANNEL_OPEN] = &channel_post_open;
2102 channel_pre[SSH_CHANNEL_RUNIX_LISTENER] = &channel_pre_listener; 2292 post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
2103 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; 2293 post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener;
2104 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; 2294 post[SSH_CHANNEL_UNIX_LISTENER] = &channel_post_port_listener;
2105 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting; 2295 post[SSH_CHANNEL_RUNIX_LISTENER] = &channel_post_port_listener;
2106 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic; 2296 post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
2107 channel_pre[SSH_CHANNEL_MUX_LISTENER] = &channel_pre_listener; 2297 post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
2108 channel_pre[SSH_CHANNEL_MUX_CLIENT] = &channel_pre_mux_client; 2298 post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
2109 2299 post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
2110 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open; 2300 post[SSH_CHANNEL_RDYNAMIC_FINISH] = &channel_post_connecting;
2111 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; 2301 post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener;
2112 channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener; 2302 post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client;
2113 channel_post[SSH_CHANNEL_UNIX_LISTENER] = &channel_post_port_listener; 2303
2114 channel_post[SSH_CHANNEL_RUNIX_LISTENER] = &channel_post_port_listener; 2304 sc->channel_pre = pre;
2115 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; 2305 sc->channel_post = post;
2116 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
2117 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
2118 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
2119 channel_post[SSH_CHANNEL_MUX_LISTENER] = &channel_post_mux_listener;
2120 channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client;
2121}
2122
2123static void
2124channel_handler_init_13(void)
2125{
2126 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13;
2127 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13;
2128 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
2129 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
2130 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
2131 channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining;
2132 channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining;
2133 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
2134 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
2135
2136 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
2137 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
2138 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
2139 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
2140 channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13;
2141 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
2142 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
2143}
2144
2145static void
2146channel_handler_init_15(void)
2147{
2148 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
2149 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
2150 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
2151 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
2152 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
2153 channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
2154 channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
2155
2156 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
2157 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
2158 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
2159 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
2160 channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
2161 channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
2162}
2163
2164static void
2165channel_handler_init(void)
2166{
2167 int i;
2168
2169 for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
2170 channel_pre[i] = NULL;
2171 channel_post[i] = NULL;
2172 }
2173 if (compat20)
2174 channel_handler_init_20();
2175 else if (compat13)
2176 channel_handler_init_13();
2177 else
2178 channel_handler_init_15();
2179} 2306}
2180 2307
2181/* gc dead channels */ 2308/* gc dead channels */
2182static void 2309static void
2183channel_garbage_collect(Channel *c) 2310channel_garbage_collect(struct ssh *ssh, Channel *c)
2184{ 2311{
2185 if (c == NULL) 2312 if (c == NULL)
2186 return; 2313 return;
2187 if (c->detach_user != NULL) { 2314 if (c->detach_user != NULL) {
2188 if (!chan_is_dead(c, c->detach_close)) 2315 if (!chan_is_dead(ssh, c, c->detach_close))
2189 return; 2316 return;
2190 debug2("channel %d: gc: notify user", c->self); 2317 debug2("channel %d: gc: notify user", c->self);
2191 c->detach_user(c->self, NULL); 2318 c->detach_user(ssh, c->self, NULL);
2192 /* if we still have a callback */ 2319 /* if we still have a callback */
2193 if (c->detach_user != NULL) 2320 if (c->detach_user != NULL)
2194 return; 2321 return;
2195 debug2("channel %d: gc: user detached", c->self); 2322 debug2("channel %d: gc: user detached", c->self);
2196 } 2323 }
2197 if (!chan_is_dead(c, 1)) 2324 if (!chan_is_dead(ssh, c, 1))
2198 return; 2325 return;
2199 debug2("channel %d: garbage collecting", c->self); 2326 debug2("channel %d: garbage collecting", c->self);
2200 channel_free(c); 2327 channel_free(ssh, c);
2201} 2328}
2202 2329
2330enum channel_table { CHAN_PRE, CHAN_POST };
2331
2203static void 2332static void
2204channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset, 2333channel_handler(struct ssh *ssh, int table,
2205 time_t *unpause_secs) 2334 fd_set *readset, fd_set *writeset, time_t *unpause_secs)
2206{ 2335{
2207 static int did_init = 0; 2336 struct ssh_channels *sc = ssh->chanctxt;
2337 chan_fn **ftab = table == CHAN_PRE ? sc->channel_pre : sc->channel_post;
2208 u_int i, oalloc; 2338 u_int i, oalloc;
2209 Channel *c; 2339 Channel *c;
2210 time_t now; 2340 time_t now;
2211 2341
2212 if (!did_init) {
2213 channel_handler_init();
2214 did_init = 1;
2215 }
2216 now = monotime(); 2342 now = monotime();
2217 if (unpause_secs != NULL) 2343 if (unpause_secs != NULL)
2218 *unpause_secs = 0; 2344 *unpause_secs = 0;
2219 for (i = 0, oalloc = channels_alloc; i < oalloc; i++) { 2345 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) {
2220 c = channels[i]; 2346 c = sc->channels[i];
2221 if (c == NULL) 2347 if (c == NULL)
2222 continue; 2348 continue;
2223 if (c->delayed) { 2349 if (c->delayed) {
2224 if (ftab == channel_pre) 2350 if (table == CHAN_PRE)
2225 c->delayed = 0; 2351 c->delayed = 0;
2226 else 2352 else
2227 continue; 2353 continue;
@@ -2231,7 +2357,7 @@ channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset,
2231 * Run handlers that are not paused. 2357 * Run handlers that are not paused.
2232 */ 2358 */
2233 if (c->notbefore <= now) 2359 if (c->notbefore <= now)
2234 (*ftab[c->type])(c, readset, writeset); 2360 (*ftab[c->type])(ssh, c, readset, writeset);
2235 else if (unpause_secs != NULL) { 2361 else if (unpause_secs != NULL) {
2236 /* 2362 /*
2237 * Collect the time that the earliest 2363 * Collect the time that the earliest
@@ -2245,7 +2371,7 @@ channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset,
2245 *unpause_secs = c->notbefore - now; 2371 *unpause_secs = c->notbefore - now;
2246 } 2372 }
2247 } 2373 }
2248 channel_garbage_collect(c); 2374 channel_garbage_collect(ssh, c);
2249 } 2375 }
2250 if (unpause_secs != NULL && *unpause_secs != 0) 2376 if (unpause_secs != NULL && *unpause_secs != 0)
2251 debug3("%s: first channel unpauses in %d seconds", 2377 debug3("%s: first channel unpauses in %d seconds",
@@ -2253,16 +2379,39 @@ channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset,
2253} 2379}
2254 2380
2255/* 2381/*
2382 * Create sockets before allocating the select bitmasks.
2383 * This is necessary for things that need to happen after reading
2384 * the network-input but before channel_prepare_select().
2385 */
2386static void
2387channel_before_prepare_select(struct ssh *ssh)
2388{
2389 struct ssh_channels *sc = ssh->chanctxt;
2390 Channel *c;
2391 u_int i, oalloc;
2392
2393 for (i = 0, oalloc = sc->channels_alloc; i < oalloc; i++) {
2394 c = sc->channels[i];
2395 if (c == NULL)
2396 continue;
2397 if (c->type == SSH_CHANNEL_RDYNAMIC_OPEN)
2398 channel_before_prepare_select_rdynamic(ssh, c);
2399 }
2400}
2401
2402/*
2256 * Allocate/update select bitmasks and add any bits relevant to channels in 2403 * Allocate/update select bitmasks and add any bits relevant to channels in
2257 * select bitmasks. 2404 * select bitmasks.
2258 */ 2405 */
2259void 2406void
2260channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, 2407channel_prepare_select(struct ssh *ssh, fd_set **readsetp, fd_set **writesetp,
2261 u_int *nallocp, time_t *minwait_secs, int rekeying) 2408 int *maxfdp, u_int *nallocp, time_t *minwait_secs)
2262{ 2409{
2263 u_int n, sz, nfdset; 2410 u_int n, sz, nfdset;
2264 2411
2265 n = MAXIMUM(*maxfdp, channel_max_fd); 2412 channel_before_prepare_select(ssh); /* might update channel_max_fd */
2413
2414 n = MAXIMUM(*maxfdp, ssh->chanctxt->channel_max_fd);
2266 2415
2267 nfdset = howmany(n+1, NFDBITS); 2416 nfdset = howmany(n+1, NFDBITS);
2268 /* Explicitly test here, because xrealloc isn't always called */ 2417 /* Explicitly test here, because xrealloc isn't always called */
@@ -2280,8 +2429,8 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
2280 memset(*readsetp, 0, sz); 2429 memset(*readsetp, 0, sz);
2281 memset(*writesetp, 0, sz); 2430 memset(*writesetp, 0, sz);
2282 2431
2283 if (!rekeying) 2432 if (!ssh_packet_is_rekeying(ssh))
2284 channel_handler(channel_pre, *readsetp, *writesetp, 2433 channel_handler(ssh, CHAN_PRE, *readsetp, *writesetp,
2285 minwait_secs); 2434 minwait_secs);
2286} 2435}
2287 2436
@@ -2290,21 +2439,136 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
2290 * events pending. 2439 * events pending.
2291 */ 2440 */
2292void 2441void
2293channel_after_select(fd_set *readset, fd_set *writeset) 2442channel_after_select(struct ssh *ssh, fd_set *readset, fd_set *writeset)
2294{ 2443{
2295 channel_handler(channel_post, readset, writeset, NULL); 2444 channel_handler(ssh, CHAN_POST, readset, writeset, NULL);
2296} 2445}
2297 2446
2447/*
2448 * Enqueue data for channels with open or draining c->input.
2449 */
2450static void
2451channel_output_poll_input_open(struct ssh *ssh, Channel *c)
2452{
2453 size_t len, plen;
2454 const u_char *pkt;
2455 int r;
2456
2457 if ((len = sshbuf_len(c->input)) == 0) {
2458 if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
2459 /*
2460 * input-buffer is empty and read-socket shutdown:
2461 * tell peer, that we will not send more data:
2462 * send IEOF.
2463 * hack for extended data: delay EOF if EFD still
2464 * in use.
2465 */
2466 if (CHANNEL_EFD_INPUT_ACTIVE(c))
2467 debug2("channel %d: "
2468 "ibuf_empty delayed efd %d/(%zu)",
2469 c->self, c->efd, sshbuf_len(c->extended));
2470 else
2471 chan_ibuf_empty(ssh, c);
2472 }
2473 return;
2474 }
2475
2476 if (!c->have_remote_id)
2477 fatal(":%s: channel %d: no remote id", __func__, c->self);
2478
2479 if (c->datagram) {
2480 /* Check datagram will fit; drop if not */
2481 if ((r = sshbuf_get_string_direct(c->input, &pkt, &plen)) != 0)
2482 fatal("%s: channel %d: get datagram: %s", __func__,
2483 c->self, ssh_err(r));
2484 /*
2485 * XXX this does tail-drop on the datagram queue which is
2486 * usually suboptimal compared to head-drop. Better to have
2487 * backpressure at read time? (i.e. read + discard)
2488 */
2489 if (plen > c->remote_window || plen > c->remote_maxpacket) {
2490 debug("channel %d: datagram too big", c->self);
2491 return;
2492 }
2493 /* Enqueue it */
2494 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
2495 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
2496 (r = sshpkt_put_string(ssh, pkt, plen)) != 0 ||
2497 (r = sshpkt_send(ssh)) != 0) {
2498 fatal("%s: channel %i: datagram: %s", __func__,
2499 c->self, ssh_err(r));
2500 }
2501 c->remote_window -= plen;
2502 return;
2503 }
2504
2505 /* Enqueue packet for buffered data. */
2506 if (len > c->remote_window)
2507 len = c->remote_window;
2508 if (len > c->remote_maxpacket)
2509 len = c->remote_maxpacket;
2510 if (len == 0)
2511 return;
2512 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
2513 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
2514 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 ||
2515 (r = sshpkt_send(ssh)) != 0) {
2516 fatal("%s: channel %i: data: %s", __func__,
2517 c->self, ssh_err(r));
2518 }
2519 if ((r = sshbuf_consume(c->input, len)) != 0)
2520 fatal("%s: channel %i: consume: %s", __func__,
2521 c->self, ssh_err(r));
2522 c->remote_window -= len;
2523}
2524
2525/*
2526 * Enqueue data for channels with open c->extended in read mode.
2527 */
2528static void
2529channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
2530{
2531 size_t len;
2532 int r;
2533
2534 if ((len = sshbuf_len(c->extended)) == 0)
2535 return;
2536
2537 debug2("channel %d: rwin %u elen %zu euse %d", c->self,
2538 c->remote_window, sshbuf_len(c->extended), c->extended_usage);
2539 if (len > c->remote_window)
2540 len = c->remote_window;
2541 if (len > c->remote_maxpacket)
2542 len = c->remote_maxpacket;
2543 if (len == 0)
2544 return;
2545 if (!c->have_remote_id)
2546 fatal(":%s: channel %d: no remote id", __func__, c->self);
2547 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||
2548 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
2549 (r = sshpkt_put_u32(ssh, SSH2_EXTENDED_DATA_STDERR)) != 0 ||
2550 (r = sshpkt_put_string(ssh, sshbuf_ptr(c->extended), len)) != 0 ||
2551 (r = sshpkt_send(ssh)) != 0) {
2552 fatal("%s: channel %i: data: %s", __func__,
2553 c->self, ssh_err(r));
2554 }
2555 if ((r = sshbuf_consume(c->extended, len)) != 0)
2556 fatal("%s: channel %i: consume: %s", __func__,
2557 c->self, ssh_err(r));
2558 c->remote_window -= len;
2559 debug2("channel %d: sent ext data %zu", c->self, len);
2560}
2298 2561
2299/* If there is data to send to the connection, enqueue some of it now. */ 2562/* If there is data to send to the connection, enqueue some of it now. */
2300void 2563void
2301channel_output_poll(void) 2564channel_output_poll(struct ssh *ssh)
2302{ 2565{
2566 struct ssh_channels *sc = ssh->chanctxt;
2303 Channel *c; 2567 Channel *c;
2304 u_int i, len; 2568 u_int i;
2305 2569
2306 for (i = 0; i < channels_alloc; i++) { 2570 for (i = 0; i < sc->channels_alloc; i++) {
2307 c = channels[i]; 2571 c = sc->channels[i];
2308 if (c == NULL) 2572 if (c == NULL)
2309 continue; 2573 continue;
2310 2574
@@ -2312,113 +2576,23 @@ channel_output_poll(void)
2312 * We are only interested in channels that can have buffered 2576 * We are only interested in channels that can have buffered
2313 * incoming data. 2577 * incoming data.
2314 */ 2578 */
2315 if (compat13) { 2579 if (c->type != SSH_CHANNEL_OPEN)
2316 if (c->type != SSH_CHANNEL_OPEN && 2580 continue;
2317 c->type != SSH_CHANNEL_INPUT_DRAINING) 2581 if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
2318 continue;
2319 } else {
2320 if (c->type != SSH_CHANNEL_OPEN)
2321 continue;
2322 }
2323 if (compat20 &&
2324 (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
2325 /* XXX is this true? */ 2582 /* XXX is this true? */
2326 debug3("channel %d: will not send data after close", c->self); 2583 debug3("channel %d: will not send data after close",
2584 c->self);
2327 continue; 2585 continue;
2328 } 2586 }
2329 2587
2330 /* Get the amount of buffered data for this channel. */ 2588 /* Get the amount of buffered data for this channel. */
2331 if ((c->istate == CHAN_INPUT_OPEN || 2589 if (c->istate == CHAN_INPUT_OPEN ||
2332 c->istate == CHAN_INPUT_WAIT_DRAIN) && 2590 c->istate == CHAN_INPUT_WAIT_DRAIN)
2333 (len = buffer_len(&c->input)) > 0) { 2591 channel_output_poll_input_open(ssh, c);
2334 if (c->datagram) {
2335 if (len > 0) {
2336 u_char *data;
2337 u_int dlen;
2338
2339 data = buffer_get_string(&c->input,
2340 &dlen);
2341 if (dlen > c->remote_window ||
2342 dlen > c->remote_maxpacket) {
2343 debug("channel %d: datagram "
2344 "too big for channel",
2345 c->self);
2346 free(data);
2347 continue;
2348 }
2349 packet_start(SSH2_MSG_CHANNEL_DATA);
2350 packet_put_int(c->remote_id);
2351 packet_put_string(data, dlen);
2352 packet_send();
2353 c->remote_window -= dlen;
2354 free(data);
2355 }
2356 continue;
2357 }
2358 /*
2359 * Send some data for the other side over the secure
2360 * connection.
2361 */
2362 if (compat20) {
2363 if (len > c->remote_window)
2364 len = c->remote_window;
2365 if (len > c->remote_maxpacket)
2366 len = c->remote_maxpacket;
2367 } else {
2368 if (packet_is_interactive()) {
2369 if (len > 1024)
2370 len = 512;
2371 } else {
2372 /* Keep the packets at reasonable size. */
2373 if (len > packet_get_maxsize()/2)
2374 len = packet_get_maxsize()/2;
2375 }
2376 }
2377 if (len > 0) {
2378 packet_start(compat20 ?
2379 SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
2380 packet_put_int(c->remote_id);
2381 packet_put_string(buffer_ptr(&c->input), len);
2382 packet_send();
2383 buffer_consume(&c->input, len);
2384 c->remote_window -= len;
2385 }
2386 } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
2387 if (compat13)
2388 fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
2389 /*
2390 * input-buffer is empty and read-socket shutdown:
2391 * tell peer, that we will not send more data: send IEOF.
2392 * hack for extended data: delay EOF if EFD still in use.
2393 */
2394 if (CHANNEL_EFD_INPUT_ACTIVE(c))
2395 debug2("channel %d: ibuf_empty delayed efd %d/(%d)",
2396 c->self, c->efd, buffer_len(&c->extended));
2397 else
2398 chan_ibuf_empty(c);
2399 }
2400 /* Send extended data, i.e. stderr */ 2592 /* Send extended data, i.e. stderr */
2401 if (compat20 && 2593 if (!(c->flags & CHAN_EOF_SENT) &&
2402 !(c->flags & CHAN_EOF_SENT) && 2594 c->extended_usage == CHAN_EXTENDED_READ)
2403 c->remote_window > 0 && 2595 channel_output_poll_extended_read(ssh, c);
2404 (len = buffer_len(&c->extended)) > 0 &&
2405 c->extended_usage == CHAN_EXTENDED_READ) {
2406 debug2("channel %d: rwin %u elen %u euse %d",
2407 c->self, c->remote_window, buffer_len(&c->extended),
2408 c->extended_usage);
2409 if (len > c->remote_window)
2410 len = c->remote_window;
2411 if (len > c->remote_maxpacket)
2412 len = c->remote_maxpacket;
2413 packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA);
2414 packet_put_int(c->remote_id);
2415 packet_put_int(SSH2_EXTENDED_DATA_STDERR);
2416 packet_put_string(buffer_ptr(&c->extended), len);
2417 packet_send();
2418 buffer_consume(&c->extended, len);
2419 c->remote_window -= len;
2420 debug2("channel %d: sent ext data %d", c->self, len);
2421 }
2422 } 2596 }
2423} 2597}
2424 2598
@@ -2463,20 +2637,19 @@ channel_output_poll(void)
2463 * on channel creation. 2637 * on channel creation.
2464 */ 2638 */
2465int 2639int
2466channel_proxy_downstream(Channel *downstream) 2640channel_proxy_downstream(struct ssh *ssh, Channel *downstream)
2467{ 2641{
2468 Channel *c = NULL; 2642 Channel *c = NULL;
2469 struct ssh *ssh = active_state;
2470 struct sshbuf *original = NULL, *modified = NULL; 2643 struct sshbuf *original = NULL, *modified = NULL;
2471 const u_char *cp; 2644 const u_char *cp;
2472 char *ctype = NULL, *listen_host = NULL; 2645 char *ctype = NULL, *listen_host = NULL;
2473 u_char type; 2646 u_char type;
2474 size_t have; 2647 size_t have;
2475 int ret = -1, r, idx; 2648 int ret = -1, r;
2476 u_int id, remote_id, listen_port; 2649 u_int id, remote_id, listen_port;
2477 2650
2478 /* sshbuf_dump(&downstream->input, stderr); */ 2651 /* sshbuf_dump(downstream->input, stderr); */
2479 if ((r = sshbuf_get_string_direct(&downstream->input, &cp, &have)) 2652 if ((r = sshbuf_get_string_direct(downstream->input, &cp, &have))
2480 != 0) { 2653 != 0) {
2481 error("%s: malformed message: %s", __func__, ssh_err(r)); 2654 error("%s: malformed message: %s", __func__, ssh_err(r));
2482 return -1; 2655 return -1;
@@ -2505,7 +2678,7 @@ channel_proxy_downstream(Channel *downstream)
2505 error("%s: parse error %s", __func__, ssh_err(r)); 2678 error("%s: parse error %s", __func__, ssh_err(r));
2506 goto out; 2679 goto out;
2507 } 2680 }
2508 c = channel_new("mux proxy", SSH_CHANNEL_MUX_PROXY, 2681 c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,
2509 -1, -1, -1, 0, 0, 0, ctype, 1); 2682 -1, -1, -1, 0, 0, 0, ctype, 1);
2510 c->mux_ctx = downstream; /* point to mux client */ 2683 c->mux_ctx = downstream; /* point to mux client */
2511 c->mux_downstream_id = id; /* original downstream id */ 2684 c->mux_downstream_id = id; /* original downstream id */
@@ -2513,7 +2686,7 @@ channel_proxy_downstream(Channel *downstream)
2513 (r = sshbuf_put_u32(modified, c->self)) != 0 || 2686 (r = sshbuf_put_u32(modified, c->self)) != 0 ||
2514 (r = sshbuf_putb(modified, original)) != 0) { 2687 (r = sshbuf_putb(modified, original)) != 0) {
2515 error("%s: compose error %s", __func__, ssh_err(r)); 2688 error("%s: compose error %s", __func__, ssh_err(r));
2516 channel_free(c); 2689 channel_free(ssh, c);
2517 goto out; 2690 goto out;
2518 } 2691 }
2519 break; 2692 break;
@@ -2532,16 +2705,17 @@ channel_proxy_downstream(Channel *downstream)
2532 error("%s: parse error %s", __func__, ssh_err(r)); 2705 error("%s: parse error %s", __func__, ssh_err(r));
2533 goto out; 2706 goto out;
2534 } 2707 }
2535 c = channel_new("mux proxy", SSH_CHANNEL_MUX_PROXY, 2708 c = channel_new(ssh, "mux proxy", SSH_CHANNEL_MUX_PROXY,
2536 -1, -1, -1, 0, 0, 0, "mux-down-connect", 1); 2709 -1, -1, -1, 0, 0, 0, "mux-down-connect", 1);
2537 c->mux_ctx = downstream; /* point to mux client */ 2710 c->mux_ctx = downstream; /* point to mux client */
2538 c->mux_downstream_id = id; 2711 c->mux_downstream_id = id;
2539 c->remote_id = remote_id; 2712 c->remote_id = remote_id;
2713 c->have_remote_id = 1;
2540 if ((r = sshbuf_put_u32(modified, remote_id)) != 0 || 2714 if ((r = sshbuf_put_u32(modified, remote_id)) != 0 ||
2541 (r = sshbuf_put_u32(modified, c->self)) != 0 || 2715 (r = sshbuf_put_u32(modified, c->self)) != 0 ||
2542 (r = sshbuf_putb(modified, original)) != 0) { 2716 (r = sshbuf_putb(modified, original)) != 0) {
2543 error("%s: compose error %s", __func__, ssh_err(r)); 2717 error("%s: compose error %s", __func__, ssh_err(r));
2544 channel_free(c); 2718 channel_free(ssh, c);
2545 goto out; 2719 goto out;
2546 } 2720 }
2547 break; 2721 break;
@@ -2570,23 +2744,17 @@ channel_proxy_downstream(Channel *downstream)
2570 goto out; 2744 goto out;
2571 } 2745 }
2572 /* Record that connection to this host/port is permitted. */ 2746 /* Record that connection to this host/port is permitted. */
2573 permitted_opens = xreallocarray(permitted_opens, 2747 fwd_perm_list_add(ssh, FWDPERM_USER, "<mux>", -1,
2574 num_permitted_opens + 1, sizeof(*permitted_opens)); 2748 listen_host, NULL, (int)listen_port, downstream);
2575 idx = num_permitted_opens++;
2576 permitted_opens[idx].host_to_connect = xstrdup("<mux>");
2577 permitted_opens[idx].port_to_connect = -1;
2578 permitted_opens[idx].listen_host = listen_host;
2579 permitted_opens[idx].listen_port = (int)listen_port;
2580 permitted_opens[idx].downstream = downstream;
2581 listen_host = NULL; 2749 listen_host = NULL;
2582 break; 2750 break;
2583 case SSH2_MSG_CHANNEL_CLOSE: 2751 case SSH2_MSG_CHANNEL_CLOSE:
2584 if (have < 4) 2752 if (have < 4)
2585 break; 2753 break;
2586 remote_id = PEEK_U32(cp); 2754 remote_id = PEEK_U32(cp);
2587 if ((c = channel_by_remote_id(remote_id)) != NULL) { 2755 if ((c = channel_by_remote_id(ssh, remote_id)) != NULL) {
2588 if (c->flags & CHAN_CLOSE_RCVD) 2756 if (c->flags & CHAN_CLOSE_RCVD)
2589 channel_free(c); 2757 channel_free(ssh, c);
2590 else 2758 else
2591 c->flags |= CHAN_CLOSE_SENT; 2759 c->flags |= CHAN_CLOSE_SENT;
2592 } 2760 }
@@ -2623,9 +2791,8 @@ channel_proxy_downstream(Channel *downstream)
2623 * replaces local (proxy) channel ID with downstream channel ID. 2791 * replaces local (proxy) channel ID with downstream channel ID.
2624 */ 2792 */
2625int 2793int
2626channel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt) 2794channel_proxy_upstream(Channel *c, int type, u_int32_t seq, struct ssh *ssh)
2627{ 2795{
2628 struct ssh *ssh = active_state;
2629 struct sshbuf *b = NULL; 2796 struct sshbuf *b = NULL;
2630 Channel *downstream; 2797 Channel *downstream;
2631 const u_char *cp = NULL; 2798 const u_char *cp = NULL;
@@ -2674,7 +2841,7 @@ channel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt)
2674 (r = sshbuf_put_u8(b, type)) != 0 || 2841 (r = sshbuf_put_u8(b, type)) != 0 ||
2675 (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 || 2842 (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 ||
2676 (r = sshbuf_put(b, cp, len)) != 0 || 2843 (r = sshbuf_put(b, cp, len)) != 0 ||
2677 (r = sshbuf_put_stringb(&downstream->output, b)) != 0) { 2844 (r = sshbuf_put_stringb(downstream->output, b)) != 0) {
2678 error("%s: compose for muxclient %s", __func__, ssh_err(r)); 2845 error("%s: compose for muxclient %s", __func__, ssh_err(r));
2679 goto out; 2846 goto out;
2680 } 2847 }
@@ -2687,12 +2854,14 @@ channel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt)
2687 switch (type) { 2854 switch (type) {
2688 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: 2855 case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
2689 /* record remote_id for SSH2_MSG_CHANNEL_CLOSE */ 2856 /* record remote_id for SSH2_MSG_CHANNEL_CLOSE */
2690 if (cp && len > 4) 2857 if (cp && len > 4) {
2691 c->remote_id = PEEK_U32(cp); 2858 c->remote_id = PEEK_U32(cp);
2859 c->have_remote_id = 1;
2860 }
2692 break; 2861 break;
2693 case SSH2_MSG_CHANNEL_CLOSE: 2862 case SSH2_MSG_CHANNEL_CLOSE:
2694 if (c->flags & CHAN_CLOSE_SENT) 2863 if (c->flags & CHAN_CLOSE_SENT)
2695 channel_free(c); 2864 channel_free(ssh, c);
2696 else 2865 else
2697 c->flags |= CHAN_CLOSE_RCVD; 2866 c->flags |= CHAN_CLOSE_RCVD;
2698 break; 2867 break;
@@ -2703,257 +2872,221 @@ channel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt)
2703 2872
2704/* -- protocol input */ 2873/* -- protocol input */
2705 2874
2706/* ARGSUSED */ 2875/* Parse a channel ID from the current packet */
2876static int
2877channel_parse_id(struct ssh *ssh, const char *where, const char *what)
2878{
2879 u_int32_t id;
2880 int r;
2881
2882 if ((r = sshpkt_get_u32(ssh, &id)) != 0) {
2883 error("%s: parse id: %s", where, ssh_err(r));
2884 ssh_packet_disconnect(ssh, "Invalid %s message", what);
2885 }
2886 if (id > INT_MAX) {
2887 error("%s: bad channel id %u: %s", where, id, ssh_err(r));
2888 ssh_packet_disconnect(ssh, "Invalid %s channel id", what);
2889 }
2890 return (int)id;
2891}
2892
2893/* Lookup a channel from an ID in the current packet */
2894static Channel *
2895channel_from_packet_id(struct ssh *ssh, const char *where, const char *what)
2896{
2897 int id = channel_parse_id(ssh, where, what);
2898 Channel *c;
2899
2900 if ((c = channel_lookup(ssh, id)) == NULL) {
2901 ssh_packet_disconnect(ssh,
2902 "%s packet referred to nonexistent channel %d", what, id);
2903 }
2904 return c;
2905}
2906
2707int 2907int
2708channel_input_data(int type, u_int32_t seq, void *ctxt) 2908channel_input_data(int type, u_int32_t seq, struct ssh *ssh)
2709{ 2909{
2710 int id;
2711 const u_char *data; 2910 const u_char *data;
2712 u_int data_len, win_len; 2911 size_t data_len, win_len;
2713 Channel *c; 2912 Channel *c = channel_from_packet_id(ssh, __func__, "data");
2913 int r;
2714 2914
2715 /* Get the channel number and verify it. */ 2915 if (channel_proxy_upstream(c, type, seq, ssh))
2716 id = packet_get_int();
2717 c = channel_lookup(id);
2718 if (c == NULL)
2719 packet_disconnect("Received data for nonexistent channel %d.", id);
2720 if (channel_proxy_upstream(c, type, seq, ctxt))
2721 return 0; 2916 return 0;
2722 2917
2723 /* Ignore any data for non-open channels (might happen on close) */ 2918 /* Ignore any data for non-open channels (might happen on close) */
2724 if (c->type != SSH_CHANNEL_OPEN && 2919 if (c->type != SSH_CHANNEL_OPEN &&
2920 c->type != SSH_CHANNEL_RDYNAMIC_OPEN &&
2921 c->type != SSH_CHANNEL_RDYNAMIC_FINISH &&
2725 c->type != SSH_CHANNEL_X11_OPEN) 2922 c->type != SSH_CHANNEL_X11_OPEN)
2726 return 0; 2923 return 0;
2727 2924
2728 /* Get the data. */ 2925 /* Get the data. */
2729 data = packet_get_string_ptr(&data_len); 2926 if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0)
2927 fatal("%s: channel %d: get data: %s", __func__,
2928 c->self, ssh_err(r));
2929 ssh_packet_check_eom(ssh);
2930
2730 win_len = data_len; 2931 win_len = data_len;
2731 if (c->datagram) 2932 if (c->datagram)
2732 win_len += 4; /* string length header */ 2933 win_len += 4; /* string length header */
2733 2934
2734 /* 2935 /*
2735 * Ignore data for protocol > 1.3 if output end is no longer open. 2936 * The sending side reduces its window as it sends data, so we
2736 * For protocol 2 the sending side is reducing its window as it sends 2937 * must 'fake' consumption of the data in order to ensure that window
2737 * data, so we must 'fake' consumption of the data in order to ensure 2938 * updates are sent back. Otherwise the connection might deadlock.
2738 * that window updates are sent back. Otherwise the connection might
2739 * deadlock.
2740 */ 2939 */
2741 if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) { 2940 if (c->ostate != CHAN_OUTPUT_OPEN) {
2742 if (compat20) { 2941 c->local_window -= win_len;
2743 c->local_window -= win_len; 2942 c->local_consumed += win_len;
2744 c->local_consumed += win_len;
2745 }
2746 return 0; 2943 return 0;
2747 } 2944 }
2748 2945
2749 if (compat20) { 2946 if (win_len > c->local_maxpacket) {
2750 if (win_len > c->local_maxpacket) { 2947 logit("channel %d: rcvd big packet %zu, maxpack %u",
2751 logit("channel %d: rcvd big packet %d, maxpack %d", 2948 c->self, win_len, c->local_maxpacket);
2752 c->self, win_len, c->local_maxpacket); 2949 return 0;
2753 }
2754 if (win_len > c->local_window) {
2755 logit("channel %d: rcvd too much data %d, win %d",
2756 c->self, win_len, c->local_window);
2757 return 0;
2758 }
2759 c->local_window -= win_len;
2760 } 2950 }
2761 if (c->datagram) 2951 if (win_len > c->local_window) {
2762 buffer_put_string(&c->output, data, data_len); 2952 logit("channel %d: rcvd too much data %zu, win %u",
2763 else 2953 c->self, win_len, c->local_window);
2764 buffer_append(&c->output, data, data_len); 2954 return 0;
2765 packet_check_eom(); 2955 }
2956 c->local_window -= win_len;
2957
2958 if (c->datagram) {
2959 if ((r = sshbuf_put_string(c->output, data, data_len)) != 0)
2960 fatal("%s: channel %d: append datagram: %s",
2961 __func__, c->self, ssh_err(r));
2962 } else if ((r = sshbuf_put(c->output, data, data_len)) != 0)
2963 fatal("%s: channel %d: append data: %s",
2964 __func__, c->self, ssh_err(r));
2965
2766 return 0; 2966 return 0;
2767} 2967}
2768 2968
2769/* ARGSUSED */
2770int 2969int
2771channel_input_extended_data(int type, u_int32_t seq, void *ctxt) 2970channel_input_extended_data(int type, u_int32_t seq, struct ssh *ssh)
2772{ 2971{
2773 int id; 2972 const u_char *data;
2774 char *data; 2973 size_t data_len;
2775 u_int data_len, tcode; 2974 u_int32_t tcode;
2776 Channel *c; 2975 Channel *c = channel_from_packet_id(ssh, __func__, "extended data");
2777 2976 int r;
2778 /* Get the channel number and verify it. */
2779 id = packet_get_int();
2780 c = channel_lookup(id);
2781 2977
2782 if (c == NULL) 2978 if (channel_proxy_upstream(c, type, seq, ssh))
2783 packet_disconnect("Received extended_data for bad channel %d.", id);
2784 if (channel_proxy_upstream(c, type, seq, ctxt))
2785 return 0; 2979 return 0;
2786 if (c->type != SSH_CHANNEL_OPEN) { 2980 if (c->type != SSH_CHANNEL_OPEN) {
2787 logit("channel %d: ext data for non open", id); 2981 logit("channel %d: ext data for non open", c->self);
2788 return 0; 2982 return 0;
2789 } 2983 }
2790 if (c->flags & CHAN_EOF_RCVD) { 2984 if (c->flags & CHAN_EOF_RCVD) {
2791 if (datafellows & SSH_BUG_EXTEOF) 2985 if (datafellows & SSH_BUG_EXTEOF)
2792 debug("channel %d: accepting ext data after eof", id); 2986 debug("channel %d: accepting ext data after eof",
2987 c->self);
2793 else 2988 else
2794 packet_disconnect("Received extended_data after EOF " 2989 ssh_packet_disconnect(ssh, "Received extended_data "
2795 "on channel %d.", id); 2990 "after EOF on channel %d.", c->self);
2991 }
2992
2993 if ((r = sshpkt_get_u32(ssh, &tcode)) != 0) {
2994 error("%s: parse tcode: %s", __func__, ssh_err(r));
2995 ssh_packet_disconnect(ssh, "Invalid extended_data message");
2796 } 2996 }
2797 tcode = packet_get_int();
2798 if (c->efd == -1 || 2997 if (c->efd == -1 ||
2799 c->extended_usage != CHAN_EXTENDED_WRITE || 2998 c->extended_usage != CHAN_EXTENDED_WRITE ||
2800 tcode != SSH2_EXTENDED_DATA_STDERR) { 2999 tcode != SSH2_EXTENDED_DATA_STDERR) {
2801 logit("channel %d: bad ext data", c->self); 3000 logit("channel %d: bad ext data", c->self);
2802 return 0; 3001 return 0;
2803 } 3002 }
2804 data = packet_get_string(&data_len); 3003 if ((r = sshpkt_get_string_direct(ssh, &data, &data_len)) != 0) {
2805 packet_check_eom(); 3004 error("%s: parse data: %s", __func__, ssh_err(r));
3005 ssh_packet_disconnect(ssh, "Invalid extended_data message");
3006 }
3007 ssh_packet_check_eom(ssh);
3008
2806 if (data_len > c->local_window) { 3009 if (data_len > c->local_window) {
2807 logit("channel %d: rcvd too much extended_data %d, win %d", 3010 logit("channel %d: rcvd too much extended_data %zu, win %u",
2808 c->self, data_len, c->local_window); 3011 c->self, data_len, c->local_window);
2809 free(data);
2810 return 0; 3012 return 0;
2811 } 3013 }
2812 debug2("channel %d: rcvd ext data %d", c->self, data_len); 3014 debug2("channel %d: rcvd ext data %zu", c->self, data_len);
3015 /* XXX sshpkt_getb? */
3016 if ((r = sshbuf_put(c->extended, data, data_len)) != 0)
3017 error("%s: append: %s", __func__, ssh_err(r));
2813 c->local_window -= data_len; 3018 c->local_window -= data_len;
2814 buffer_append(&c->extended, data, data_len);
2815 free(data);
2816 return 0; 3019 return 0;
2817} 3020}
2818 3021
2819/* ARGSUSED */
2820int 3022int
2821channel_input_ieof(int type, u_int32_t seq, void *ctxt) 3023channel_input_ieof(int type, u_int32_t seq, struct ssh *ssh)
2822{ 3024{
2823 int id; 3025 Channel *c = channel_from_packet_id(ssh, __func__, "ieof");
2824 Channel *c;
2825 3026
2826 id = packet_get_int(); 3027 ssh_packet_check_eom(ssh);
2827 packet_check_eom(); 3028
2828 c = channel_lookup(id); 3029 if (channel_proxy_upstream(c, type, seq, ssh))
2829 if (c == NULL)
2830 packet_disconnect("Received ieof for nonexistent channel %d.", id);
2831 if (channel_proxy_upstream(c, type, seq, ctxt))
2832 return 0; 3030 return 0;
2833 chan_rcvd_ieof(c); 3031 chan_rcvd_ieof(ssh, c);
2834 3032
2835 /* XXX force input close */ 3033 /* XXX force input close */
2836 if (c->force_drain && c->istate == CHAN_INPUT_OPEN) { 3034 if (c->force_drain && c->istate == CHAN_INPUT_OPEN) {
2837 debug("channel %d: FORCE input drain", c->self); 3035 debug("channel %d: FORCE input drain", c->self);
2838 c->istate = CHAN_INPUT_WAIT_DRAIN; 3036 c->istate = CHAN_INPUT_WAIT_DRAIN;
2839 if (buffer_len(&c->input) == 0) 3037 if (sshbuf_len(c->input) == 0)
2840 chan_ibuf_empty(c); 3038 chan_ibuf_empty(ssh, c);
2841 }
2842 return 0;
2843}
2844
2845/* ARGSUSED */
2846int
2847channel_input_close(int type, u_int32_t seq, void *ctxt)
2848{
2849 int id;
2850 Channel *c;
2851
2852 id = packet_get_int();
2853 packet_check_eom();
2854 c = channel_lookup(id);
2855 if (c == NULL)
2856 packet_disconnect("Received close for nonexistent channel %d.", id);
2857 if (channel_proxy_upstream(c, type, seq, ctxt))
2858 return 0;
2859 /*
2860 * Send a confirmation that we have closed the channel and no more
2861 * data is coming for it.
2862 */
2863 packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION);
2864 packet_put_int(c->remote_id);
2865 packet_send();
2866
2867 /*
2868 * If the channel is in closed state, we have sent a close request,
2869 * and the other side will eventually respond with a confirmation.
2870 * Thus, we cannot free the channel here, because then there would be
2871 * no-one to receive the confirmation. The channel gets freed when
2872 * the confirmation arrives.
2873 */
2874 if (c->type != SSH_CHANNEL_CLOSED) {
2875 /*
2876 * Not a closed channel - mark it as draining, which will
2877 * cause it to be freed later.
2878 */
2879 buffer_clear(&c->input);
2880 c->type = SSH_CHANNEL_OUTPUT_DRAINING;
2881 } 3039 }
2882 return 0; 3040 return 0;
2883} 3041}
2884 3042
2885/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
2886/* ARGSUSED */
2887int 3043int
2888channel_input_oclose(int type, u_int32_t seq, void *ctxt) 3044channel_input_oclose(int type, u_int32_t seq, struct ssh *ssh)
2889{ 3045{
2890 int id = packet_get_int(); 3046 Channel *c = channel_from_packet_id(ssh, __func__, "oclose");
2891 Channel *c = channel_lookup(id);
2892 3047
2893 if (c == NULL) 3048 if (channel_proxy_upstream(c, type, seq, ssh))
2894 packet_disconnect("Received oclose for nonexistent channel %d.", id);
2895 if (channel_proxy_upstream(c, type, seq, ctxt))
2896 return 0;
2897 packet_check_eom();
2898 chan_rcvd_oclose(c);
2899 return 0;
2900}
2901
2902/* ARGSUSED */
2903int
2904channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
2905{
2906 int id = packet_get_int();
2907 Channel *c = channel_lookup(id);
2908
2909 if (c == NULL)
2910 packet_disconnect("Received close confirmation for "
2911 "out-of-range channel %d.", id);
2912 if (channel_proxy_upstream(c, type, seq, ctxt))
2913 return 0; 3049 return 0;
2914 packet_check_eom(); 3050 ssh_packet_check_eom(ssh);
2915 if (c->type != SSH_CHANNEL_CLOSED && c->type != SSH_CHANNEL_ABANDONED) 3051 chan_rcvd_oclose(ssh, c);
2916 packet_disconnect("Received close confirmation for "
2917 "non-closed channel %d (type %d).", id, c->type);
2918 channel_free(c);
2919 return 0; 3052 return 0;
2920} 3053}
2921 3054
2922/* ARGSUSED */
2923int 3055int
2924channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) 3056channel_input_open_confirmation(int type, u_int32_t seq, struct ssh *ssh)
2925{ 3057{
2926 int id, remote_id; 3058 Channel *c = channel_from_packet_id(ssh, __func__, "open confirmation");
2927 Channel *c; 3059 u_int32_t remote_window, remote_maxpacket;
2928 3060 int r;
2929 id = packet_get_int();
2930 c = channel_lookup(id);
2931 3061
2932 if (c==NULL) 3062 if (channel_proxy_upstream(c, type, seq, ssh))
2933 packet_disconnect("Received open confirmation for "
2934 "unknown channel %d.", id);
2935 if (channel_proxy_upstream(c, type, seq, ctxt))
2936 return 0; 3063 return 0;
2937 if (c->type != SSH_CHANNEL_OPENING) 3064 if (c->type != SSH_CHANNEL_OPENING)
2938 packet_disconnect("Received open confirmation for " 3065 packet_disconnect("Received open confirmation for "
2939 "non-opening channel %d.", id); 3066 "non-opening channel %d.", c->self);
2940 remote_id = packet_get_int(); 3067 /*
2941 /* Record the remote channel number and mark that the channel is now open. */ 3068 * Record the remote channel number and mark that the channel
2942 c->remote_id = remote_id; 3069 * is now open.
2943 c->type = SSH_CHANNEL_OPEN; 3070 */
3071 if ((r = sshpkt_get_u32(ssh, &c->remote_id)) != 0 ||
3072 (r = sshpkt_get_u32(ssh, &remote_window)) != 0 ||
3073 (r = sshpkt_get_u32(ssh, &remote_maxpacket)) != 0) {
3074 error("%s: window/maxpacket: %s", __func__, ssh_err(r));
3075 packet_disconnect("Invalid open confirmation message");
3076 }
3077 ssh_packet_check_eom(ssh);
2944 3078
2945 if (compat20) { 3079 c->have_remote_id = 1;
2946 c->remote_window = packet_get_int(); 3080 c->remote_window = remote_window;
2947 c->remote_maxpacket = packet_get_int(); 3081 c->remote_maxpacket = remote_maxpacket;
2948 if (c->open_confirm) { 3082 c->type = SSH_CHANNEL_OPEN;
2949 debug2("callback start"); 3083 if (c->open_confirm) {
2950 c->open_confirm(c->self, 1, c->open_confirm_ctx); 3084 debug2("%s: channel %d: callback start", __func__, c->self);
2951 debug2("callback done"); 3085 c->open_confirm(ssh, c->self, 1, c->open_confirm_ctx);
2952 } 3086 debug2("%s: channel %d: callback done", __func__, c->self);
2953 debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
2954 c->remote_window, c->remote_maxpacket);
2955 } 3087 }
2956 packet_check_eom(); 3088 debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
3089 c->remote_window, c->remote_maxpacket);
2957 return 0; 3090 return 0;
2958} 3091}
2959 3092
@@ -2973,134 +3106,97 @@ reason2txt(int reason)
2973 return "unknown reason"; 3106 return "unknown reason";
2974} 3107}
2975 3108
2976/* ARGSUSED */
2977int 3109int
2978channel_input_open_failure(int type, u_int32_t seq, void *ctxt) 3110channel_input_open_failure(int type, u_int32_t seq, struct ssh *ssh)
2979{ 3111{
2980 int id, reason; 3112 Channel *c = channel_from_packet_id(ssh, __func__, "open failure");
2981 char *msg = NULL, *lang = NULL; 3113 u_int32_t reason;
2982 Channel *c; 3114 char *msg = NULL;
2983 3115 int r;
2984 id = packet_get_int();
2985 c = channel_lookup(id);
2986 3116
2987 if (c==NULL) 3117 if (channel_proxy_upstream(c, type, seq, ssh))
2988 packet_disconnect("Received open failure for "
2989 "unknown channel %d.", id);
2990 if (channel_proxy_upstream(c, type, seq, ctxt))
2991 return 0; 3118 return 0;
2992 if (c->type != SSH_CHANNEL_OPENING) 3119 if (c->type != SSH_CHANNEL_OPENING)
2993 packet_disconnect("Received open failure for " 3120 packet_disconnect("Received open failure for "
2994 "non-opening channel %d.", id); 3121 "non-opening channel %d.", c->self);
2995 if (compat20) { 3122 if ((r = sshpkt_get_u32(ssh, &reason)) != 0) {
2996 reason = packet_get_int(); 3123 error("%s: reason: %s", __func__, ssh_err(r));
2997 if (!(datafellows & SSH_BUG_OPENFAILURE)) { 3124 packet_disconnect("Invalid open failure message");
2998 msg = packet_get_string(NULL); 3125 }
2999 lang = packet_get_string(NULL); 3126 if ((datafellows & SSH_BUG_OPENFAILURE) == 0) {
3000 } 3127 /* skip language */
3001 logit("channel %d: open failed: %s%s%s", id, 3128 if ((r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 ||
3002 reason2txt(reason), msg ? ": ": "", msg ? msg : ""); 3129 (r = sshpkt_get_string_direct(ssh, NULL, NULL)) != 0) {
3003 free(msg); 3130 error("%s: message/lang: %s", __func__, ssh_err(r));
3004 free(lang); 3131 packet_disconnect("Invalid open failure message");
3005 if (c->open_confirm) {
3006 debug2("callback start");
3007 c->open_confirm(c->self, 0, c->open_confirm_ctx);
3008 debug2("callback done");
3009 } 3132 }
3010 } 3133 }
3011 packet_check_eom(); 3134 ssh_packet_check_eom(ssh);
3135 logit("channel %d: open failed: %s%s%s", c->self,
3136 reason2txt(reason), msg ? ": ": "", msg ? msg : "");
3137 free(msg);
3138 if (c->open_confirm) {
3139 debug2("%s: channel %d: callback start", __func__, c->self);
3140 c->open_confirm(ssh, c->self, 0, c->open_confirm_ctx);
3141 debug2("%s: channel %d: callback done", __func__, c->self);
3142 }
3012 /* Schedule the channel for cleanup/deletion. */ 3143 /* Schedule the channel for cleanup/deletion. */
3013 chan_mark_dead(c); 3144 chan_mark_dead(ssh, c);
3014 return 0; 3145 return 0;
3015} 3146}
3016 3147
3017/* ARGSUSED */
3018int 3148int
3019channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) 3149channel_input_window_adjust(int type, u_int32_t seq, struct ssh *ssh)
3020{ 3150{
3151 int id = channel_parse_id(ssh, __func__, "window adjust");
3021 Channel *c; 3152 Channel *c;
3022 int id; 3153 u_int32_t adjust;
3023 u_int adjust, tmp; 3154 u_int new_rwin;
3024 3155 int r;
3025 if (!compat20)
3026 return 0;
3027
3028 /* Get the channel number and verify it. */
3029 id = packet_get_int();
3030 c = channel_lookup(id);
3031 3156
3032 if (c == NULL) { 3157 if ((c = channel_lookup(ssh, id)) == NULL) {
3033 logit("Received window adjust for non-open channel %d.", id); 3158 logit("Received window adjust for non-open channel %d.", id);
3034 return 0; 3159 return 0;
3035 } 3160 }
3036 if (channel_proxy_upstream(c, type, seq, ctxt)) 3161
3162 if (channel_proxy_upstream(c, type, seq, ssh))
3037 return 0; 3163 return 0;
3038 adjust = packet_get_int(); 3164 if ((r = sshpkt_get_u32(ssh, &adjust)) != 0) {
3039 packet_check_eom(); 3165 error("%s: adjust: %s", __func__, ssh_err(r));
3040 debug2("channel %d: rcvd adjust %u", id, adjust); 3166 packet_disconnect("Invalid window adjust message");
3041 if ((tmp = c->remote_window + adjust) < c->remote_window) 3167 }
3168 ssh_packet_check_eom(ssh);
3169 debug2("channel %d: rcvd adjust %u", c->self, adjust);
3170 if ((new_rwin = c->remote_window + adjust) < c->remote_window) {
3042 fatal("channel %d: adjust %u overflows remote window %u", 3171 fatal("channel %d: adjust %u overflows remote window %u",
3043 id, adjust, c->remote_window); 3172 c->self, adjust, c->remote_window);
3044 c->remote_window = tmp;
3045 return 0;
3046}
3047
3048/* ARGSUSED */
3049int
3050channel_input_port_open(int type, u_int32_t seq, void *ctxt)
3051{
3052 Channel *c = NULL;
3053 u_short host_port;
3054 char *host, *originator_string;
3055 int remote_id;
3056
3057 remote_id = packet_get_int();
3058 host = packet_get_string(NULL);
3059 host_port = packet_get_int();
3060
3061 if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {
3062 originator_string = packet_get_string(NULL);
3063 } else {
3064 originator_string = xstrdup("unknown (remote did not supply name)");
3065 } 3173 }
3066 packet_check_eom(); 3174 c->remote_window = new_rwin;
3067 c = channel_connect_to_port(host, host_port,
3068 "connected socket", originator_string, NULL, NULL);
3069 free(originator_string);
3070 free(host);
3071 if (c == NULL) {
3072 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
3073 packet_put_int(remote_id);
3074 packet_send();
3075 } else
3076 c->remote_id = remote_id;
3077 return 0; 3175 return 0;
3078} 3176}
3079 3177
3080/* ARGSUSED */
3081int 3178int
3082channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) 3179channel_input_status_confirm(int type, u_int32_t seq, struct ssh *ssh)
3083{ 3180{
3181 int id = channel_parse_id(ssh, __func__, "status confirm");
3084 Channel *c; 3182 Channel *c;
3085 struct channel_confirm *cc; 3183 struct channel_confirm *cc;
3086 int id;
3087 3184
3088 /* Reset keepalive timeout */ 3185 /* Reset keepalive timeout */
3089 packet_set_alive_timeouts(0); 3186 packet_set_alive_timeouts(0);
3090 3187
3091 id = packet_get_int(); 3188 debug2("%s: type %d id %d", __func__, type, id);
3092 debug2("channel_input_status_confirm: type %d id %d", type, id);
3093 3189
3094 if ((c = channel_lookup(id)) == NULL) { 3190 if ((c = channel_lookup(ssh, id)) == NULL) {
3095 logit("channel_input_status_confirm: %d: unknown", id); 3191 logit("%s: %d: unknown", __func__, id);
3096 return 0; 3192 return 0;
3097 } 3193 }
3098 if (channel_proxy_upstream(c, type, seq, ctxt)) 3194 if (channel_proxy_upstream(c, type, seq, ssh))
3099 return 0; 3195 return 0;
3100 packet_check_eom(); 3196 ssh_packet_check_eom(ssh);
3101 if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) 3197 if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL)
3102 return 0; 3198 return 0;
3103 cc->cb(type, c, cc->ctx); 3199 cc->cb(ssh, type, c, cc->ctx);
3104 TAILQ_REMOVE(&c->status_confirms, cc, entry); 3200 TAILQ_REMOVE(&c->status_confirms, cc, entry);
3105 explicit_bzero(cc, sizeof(*cc)); 3201 explicit_bzero(cc, sizeof(*cc));
3106 free(cc); 3202 free(cc);
@@ -3110,9 +3206,9 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
3110/* -- tcp forwarding */ 3206/* -- tcp forwarding */
3111 3207
3112void 3208void
3113channel_set_af(int af) 3209channel_set_af(struct ssh *ssh, int af)
3114{ 3210{
3115 IPv4or6 = af; 3211 ssh->chanctxt->IPv4or6 = af;
3116} 3212}
3117 3213
3118 3214
@@ -3180,8 +3276,9 @@ channel_fwd_bind_addr(const char *listen_addr, int *wildcardp,
3180} 3276}
3181 3277
3182static int 3278static int
3183channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd, 3279channel_setup_fwd_listener_tcpip(struct ssh *ssh, int type,
3184 int *allocated_listen_port, struct ForwardOptions *fwd_opts) 3280 struct Forward *fwd, int *allocated_listen_port,
3281 struct ForwardOptions *fwd_opts)
3185{ 3282{
3186 Channel *c; 3283 Channel *c;
3187 int sock, r, success = 0, wildcard = 0, is_client; 3284 int sock, r, success = 0, wildcard = 0, is_client;
@@ -3218,7 +3315,7 @@ channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd,
3218 * set to NULL and hints.ai_flags is not AI_PASSIVE 3315 * set to NULL and hints.ai_flags is not AI_PASSIVE
3219 */ 3316 */
3220 memset(&hints, 0, sizeof(hints)); 3317 memset(&hints, 0, sizeof(hints));
3221 hints.ai_family = IPv4or6; 3318 hints.ai_family = ssh->chanctxt->IPv4or6;
3222 hints.ai_flags = wildcard ? AI_PASSIVE : 0; 3319 hints.ai_flags = wildcard ? AI_PASSIVE : 0;
3223 hints.ai_socktype = SOCK_STREAM; 3320 hints.ai_socktype = SOCK_STREAM;
3224 snprintf(strport, sizeof strport, "%d", fwd->listen_port); 3321 snprintf(strport, sizeof strport, "%d", fwd->listen_port);
@@ -3252,12 +3349,14 @@ channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd,
3252 * If allocating a port for -R forwards, then use the 3349 * If allocating a port for -R forwards, then use the
3253 * same port for all address families. 3350 * same port for all address families.
3254 */ 3351 */
3255 if (type == SSH_CHANNEL_RPORT_LISTENER && fwd->listen_port == 0 && 3352 if (type == SSH_CHANNEL_RPORT_LISTENER &&
3256 allocated_listen_port != NULL && *allocated_listen_port > 0) 3353 fwd->listen_port == 0 && allocated_listen_port != NULL &&
3354 *allocated_listen_port > 0)
3257 *lport_p = htons(*allocated_listen_port); 3355 *lport_p = htons(*allocated_listen_port);
3258 3356
3259 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), 3357 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
3260 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { 3358 strport, sizeof(strport),
3359 NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
3261 error("%s: getnameinfo failed", __func__); 3360 error("%s: getnameinfo failed", __func__);
3262 continue; 3361 continue;
3263 } 3362 }
@@ -3278,7 +3377,10 @@ channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd,
3278 3377
3279 /* Bind the socket to the address. */ 3378 /* Bind the socket to the address. */
3280 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { 3379 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
3281 /* address can be in use ipv6 address is already bound */ 3380 /*
3381 * address can be in if use ipv6 address is
3382 * already bound
3383 */
3282 if (!ai->ai_next) 3384 if (!ai->ai_next)
3283 error("bind: %.100s", strerror(errno)); 3385 error("bind: %.100s", strerror(errno));
3284 else 3386 else
@@ -3298,7 +3400,8 @@ channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd,
3298 * fwd->listen_port == 0 requests a dynamically allocated port - 3400 * fwd->listen_port == 0 requests a dynamically allocated port -
3299 * record what we got. 3401 * record what we got.
3300 */ 3402 */
3301 if (type == SSH_CHANNEL_RPORT_LISTENER && fwd->listen_port == 0 && 3403 if (type == SSH_CHANNEL_RPORT_LISTENER &&
3404 fwd->listen_port == 0 &&
3302 allocated_listen_port != NULL && 3405 allocated_listen_port != NULL &&
3303 *allocated_listen_port == 0) { 3406 *allocated_listen_port == 0) {
3304 *allocated_listen_port = get_local_port(sock); 3407 *allocated_listen_port = get_local_port(sock);
@@ -3307,7 +3410,7 @@ channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd,
3307 } 3410 }
3308 3411
3309 /* Allocate a channel number for the socket. */ 3412 /* Allocate a channel number for the socket. */
3310 c = channel_new("port listener", type, sock, sock, -1, 3413 c = channel_new(ssh, "port listener", type, sock, sock, -1,
3311 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 3414 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
3312 0, "port listener", 1); 3415 0, "port listener", 1);
3313 c->path = xstrdup(host); 3416 c->path = xstrdup(host);
@@ -3328,8 +3431,8 @@ channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd,
3328} 3431}
3329 3432
3330static int 3433static int
3331channel_setup_fwd_listener_streamlocal(int type, struct Forward *fwd, 3434channel_setup_fwd_listener_streamlocal(struct ssh *ssh, int type,
3332 struct ForwardOptions *fwd_opts) 3435 struct Forward *fwd, struct ForwardOptions *fwd_opts)
3333{ 3436{
3334 struct sockaddr_un sunaddr; 3437 struct sockaddr_un sunaddr;
3335 const char *path; 3438 const char *path;
@@ -3391,7 +3494,7 @@ channel_setup_fwd_listener_streamlocal(int type, struct Forward *fwd,
3391 debug("Local forwarding listening on path %s.", fwd->listen_path); 3494 debug("Local forwarding listening on path %s.", fwd->listen_path);
3392 3495
3393 /* Allocate a channel number for the socket. */ 3496 /* Allocate a channel number for the socket. */
3394 c = channel_new("unix listener", type, sock, sock, -1, 3497 c = channel_new(ssh, "unix listener", type, sock, sock, -1,
3395 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 3498 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
3396 0, "unix listener", 1); 3499 0, "unix listener", 1);
3397 c->path = xstrdup(path); 3500 c->path = xstrdup(path);
@@ -3402,66 +3505,71 @@ channel_setup_fwd_listener_streamlocal(int type, struct Forward *fwd,
3402} 3505}
3403 3506
3404static int 3507static int
3405channel_cancel_rport_listener_tcpip(const char *host, u_short port) 3508channel_cancel_rport_listener_tcpip(struct ssh *ssh,
3509 const char *host, u_short port)
3406{ 3510{
3407 u_int i; 3511 u_int i;
3408 int found = 0; 3512 int found = 0;
3409 3513
3410 for (i = 0; i < channels_alloc; i++) { 3514 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
3411 Channel *c = channels[i]; 3515 Channel *c = ssh->chanctxt->channels[i];
3412 if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER) 3516 if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER)
3413 continue; 3517 continue;
3414 if (strcmp(c->path, host) == 0 && c->listening_port == port) { 3518 if (strcmp(c->path, host) == 0 && c->listening_port == port) {
3415 debug2("%s: close channel %d", __func__, i); 3519 debug2("%s: close channel %d", __func__, i);
3416 channel_free(c); 3520 channel_free(ssh, c);
3417 found = 1; 3521 found = 1;
3418 } 3522 }
3419 } 3523 }
3420 3524
3421 return (found); 3525 return found;
3422} 3526}
3423 3527
3424static int 3528static int
3425channel_cancel_rport_listener_streamlocal(const char *path) 3529channel_cancel_rport_listener_streamlocal(struct ssh *ssh, const char *path)
3426{ 3530{
3427 u_int i; 3531 u_int i;
3428 int found = 0; 3532 int found = 0;
3429 3533
3430 for (i = 0; i < channels_alloc; i++) { 3534 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
3431 Channel *c = channels[i]; 3535 Channel *c = ssh->chanctxt->channels[i];
3432 if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER) 3536 if (c == NULL || c->type != SSH_CHANNEL_RUNIX_LISTENER)
3433 continue; 3537 continue;
3434 if (c->path == NULL) 3538 if (c->path == NULL)
3435 continue; 3539 continue;
3436 if (strcmp(c->path, path) == 0) { 3540 if (strcmp(c->path, path) == 0) {
3437 debug2("%s: close channel %d", __func__, i); 3541 debug2("%s: close channel %d", __func__, i);
3438 channel_free(c); 3542 channel_free(ssh, c);
3439 found = 1; 3543 found = 1;
3440 } 3544 }
3441 } 3545 }
3442 3546
3443 return (found); 3547 return found;
3444} 3548}
3445 3549
3446int 3550int
3447channel_cancel_rport_listener(struct Forward *fwd) 3551channel_cancel_rport_listener(struct ssh *ssh, struct Forward *fwd)
3448{ 3552{
3449 if (fwd->listen_path != NULL) 3553 if (fwd->listen_path != NULL) {
3450 return channel_cancel_rport_listener_streamlocal(fwd->listen_path); 3554 return channel_cancel_rport_listener_streamlocal(ssh,
3451 else 3555 fwd->listen_path);
3452 return channel_cancel_rport_listener_tcpip(fwd->listen_host, fwd->listen_port); 3556 } else {
3557 return channel_cancel_rport_listener_tcpip(ssh,
3558 fwd->listen_host, fwd->listen_port);
3559 }
3453} 3560}
3454 3561
3455static int 3562static int
3456channel_cancel_lport_listener_tcpip(const char *lhost, u_short lport, 3563channel_cancel_lport_listener_tcpip(struct ssh *ssh,
3457 int cport, struct ForwardOptions *fwd_opts) 3564 const char *lhost, u_short lport, int cport,
3565 struct ForwardOptions *fwd_opts)
3458{ 3566{
3459 u_int i; 3567 u_int i;
3460 int found = 0; 3568 int found = 0;
3461 const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, fwd_opts); 3569 const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, fwd_opts);
3462 3570
3463 for (i = 0; i < channels_alloc; i++) { 3571 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
3464 Channel *c = channels[i]; 3572 Channel *c = ssh->chanctxt->channels[i];
3465 if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER) 3573 if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER)
3466 continue; 3574 continue;
3467 if (c->listening_port != lport) 3575 if (c->listening_port != lport)
@@ -3479,16 +3587,16 @@ channel_cancel_lport_listener_tcpip(const char *lhost, u_short lport,
3479 continue; 3587 continue;
3480 if (addr == NULL || strcmp(c->listening_addr, addr) == 0) { 3588 if (addr == NULL || strcmp(c->listening_addr, addr) == 0) {
3481 debug2("%s: close channel %d", __func__, i); 3589 debug2("%s: close channel %d", __func__, i);
3482 channel_free(c); 3590 channel_free(ssh, c);
3483 found = 1; 3591 found = 1;
3484 } 3592 }
3485 } 3593 }
3486 3594
3487 return (found); 3595 return found;
3488} 3596}
3489 3597
3490static int 3598static int
3491channel_cancel_lport_listener_streamlocal(const char *path) 3599channel_cancel_lport_listener_streamlocal(struct ssh *ssh, const char *path)
3492{ 3600{
3493 u_int i; 3601 u_int i;
3494 int found = 0; 3602 int found = 0;
@@ -3498,54 +3606,59 @@ channel_cancel_lport_listener_streamlocal(const char *path)
3498 return 0; 3606 return 0;
3499 } 3607 }
3500 3608
3501 for (i = 0; i < channels_alloc; i++) { 3609 for (i = 0; i < ssh->chanctxt->channels_alloc; i++) {
3502 Channel *c = channels[i]; 3610 Channel *c = ssh->chanctxt->channels[i];
3503 if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER) 3611 if (c == NULL || c->type != SSH_CHANNEL_UNIX_LISTENER)
3504 continue; 3612 continue;
3505 if (c->listening_addr == NULL) 3613 if (c->listening_addr == NULL)
3506 continue; 3614 continue;
3507 if (strcmp(c->listening_addr, path) == 0) { 3615 if (strcmp(c->listening_addr, path) == 0) {
3508 debug2("%s: close channel %d", __func__, i); 3616 debug2("%s: close channel %d", __func__, i);
3509 channel_free(c); 3617 channel_free(ssh, c);
3510 found = 1; 3618 found = 1;
3511 } 3619 }
3512 } 3620 }
3513 3621
3514 return (found); 3622 return found;
3515} 3623}
3516 3624
3517int 3625int
3518channel_cancel_lport_listener(struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts) 3626channel_cancel_lport_listener(struct ssh *ssh,
3627 struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts)
3519{ 3628{
3520 if (fwd->listen_path != NULL) 3629 if (fwd->listen_path != NULL) {
3521 return channel_cancel_lport_listener_streamlocal(fwd->listen_path); 3630 return channel_cancel_lport_listener_streamlocal(ssh,
3522 else 3631 fwd->listen_path);
3523 return channel_cancel_lport_listener_tcpip(fwd->listen_host, fwd->listen_port, cport, fwd_opts); 3632 } else {
3633 return channel_cancel_lport_listener_tcpip(ssh,
3634 fwd->listen_host, fwd->listen_port, cport, fwd_opts);
3635 }
3524} 3636}
3525 3637
3526/* protocol local port fwd, used by ssh (and sshd in v1) */ 3638/* protocol local port fwd, used by ssh */
3527int 3639int
3528channel_setup_local_fwd_listener(struct Forward *fwd, struct ForwardOptions *fwd_opts) 3640channel_setup_local_fwd_listener(struct ssh *ssh,
3641 struct Forward *fwd, struct ForwardOptions *fwd_opts)
3529{ 3642{
3530 if (fwd->listen_path != NULL) { 3643 if (fwd->listen_path != NULL) {
3531 return channel_setup_fwd_listener_streamlocal( 3644 return channel_setup_fwd_listener_streamlocal(ssh,
3532 SSH_CHANNEL_UNIX_LISTENER, fwd, fwd_opts); 3645 SSH_CHANNEL_UNIX_LISTENER, fwd, fwd_opts);
3533 } else { 3646 } else {
3534 return channel_setup_fwd_listener_tcpip(SSH_CHANNEL_PORT_LISTENER, 3647 return channel_setup_fwd_listener_tcpip(ssh,
3535 fwd, NULL, fwd_opts); 3648 SSH_CHANNEL_PORT_LISTENER, fwd, NULL, fwd_opts);
3536 } 3649 }
3537} 3650}
3538 3651
3539/* protocol v2 remote port fwd, used by sshd */ 3652/* protocol v2 remote port fwd, used by sshd */
3540int 3653int
3541channel_setup_remote_fwd_listener(struct Forward *fwd, 3654channel_setup_remote_fwd_listener(struct ssh *ssh, struct Forward *fwd,
3542 int *allocated_listen_port, struct ForwardOptions *fwd_opts) 3655 int *allocated_listen_port, struct ForwardOptions *fwd_opts)
3543{ 3656{
3544 if (fwd->listen_path != NULL) { 3657 if (fwd->listen_path != NULL) {
3545 return channel_setup_fwd_listener_streamlocal( 3658 return channel_setup_fwd_listener_streamlocal(ssh,
3546 SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts); 3659 SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts);
3547 } else { 3660 } else {
3548 return channel_setup_fwd_listener_tcpip( 3661 return channel_setup_fwd_listener_tcpip(ssh,
3549 SSH_CHANNEL_RPORT_LISTENER, fwd, allocated_listen_port, 3662 SSH_CHANNEL_RPORT_LISTENER, fwd, allocated_listen_port,
3550 fwd_opts); 3663 fwd_opts);
3551 } 3664 }
@@ -3579,81 +3692,61 @@ channel_rfwd_bind_host(const char *listen_host)
3579 * channel_update_permitted_opens(). 3692 * channel_update_permitted_opens().
3580 */ 3693 */
3581int 3694int
3582channel_request_remote_forwarding(struct Forward *fwd) 3695channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd)
3583{ 3696{
3584 int type, success = 0, idx = -1; 3697 int r, success = 0, idx = -1;
3698 char *host_to_connect, *listen_host, *listen_path;
3699 int port_to_connect, listen_port;
3585 3700
3586 /* Send the forward request to the remote side. */ 3701 /* Send the forward request to the remote side. */
3587 if (compat20) { 3702 if (fwd->listen_path != NULL) {
3588 packet_start(SSH2_MSG_GLOBAL_REQUEST); 3703 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
3589 if (fwd->listen_path != NULL) { 3704 (r = sshpkt_put_cstring(ssh,
3590 packet_put_cstring("streamlocal-forward@openssh.com"); 3705 "streamlocal-forward@openssh.com")) != 0 ||
3591 packet_put_char(1); /* boolean: want reply */ 3706 (r = sshpkt_put_u8(ssh, 1)) != 0 || /* want reply */
3592 packet_put_cstring(fwd->listen_path); 3707 (r = sshpkt_put_cstring(ssh, fwd->listen_path)) != 0 ||
3593 } else { 3708 (r = sshpkt_send(ssh)) != 0 ||
3594 packet_put_cstring("tcpip-forward"); 3709 (r = ssh_packet_write_wait(ssh)) != 0)
3595 packet_put_char(1); /* boolean: want reply */ 3710 fatal("%s: request streamlocal: %s",
3596 packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host)); 3711 __func__, ssh_err(r));
3597 packet_put_int(fwd->listen_port);
3598 }
3599 packet_send();
3600 packet_write_wait();
3601 /* Assume that server accepts the request */
3602 success = 1;
3603 } else if (fwd->listen_path == NULL) {
3604 packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
3605 packet_put_int(fwd->listen_port);
3606 packet_put_cstring(fwd->connect_host);
3607 packet_put_int(fwd->connect_port);
3608 packet_send();
3609 packet_write_wait();
3610
3611 /* Wait for response from the remote side. */
3612 type = packet_read();
3613 switch (type) {
3614 case SSH_SMSG_SUCCESS:
3615 success = 1;
3616 break;
3617 case SSH_SMSG_FAILURE:
3618 break;
3619 default:
3620 /* Unknown packet */
3621 packet_disconnect("Protocol error for port forward request:"
3622 "received packet type %d.", type);
3623 }
3624 } else { 3712 } else {
3625 logit("Warning: Server does not support remote stream local forwarding."); 3713 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
3626 } 3714 (r = sshpkt_put_cstring(ssh, "tcpip-forward")) != 0 ||
3715 (r = sshpkt_put_u8(ssh, 1)) != 0 || /* want reply */
3716 (r = sshpkt_put_cstring(ssh,
3717 channel_rfwd_bind_host(fwd->listen_host))) != 0 ||
3718 (r = sshpkt_put_u32(ssh, fwd->listen_port)) != 0 ||
3719 (r = sshpkt_send(ssh)) != 0 ||
3720 (r = ssh_packet_write_wait(ssh)) != 0)
3721 fatal("%s: request tcpip-forward: %s",
3722 __func__, ssh_err(r));
3723 }
3724 /* Assume that server accepts the request */
3725 success = 1;
3627 if (success) { 3726 if (success) {
3628 /* Record that connection to this host/port is permitted. */ 3727 /* Record that connection to this host/port is permitted. */
3629 permitted_opens = xreallocarray(permitted_opens, 3728 host_to_connect = listen_host = listen_path = NULL;
3630 num_permitted_opens + 1, sizeof(*permitted_opens)); 3729 port_to_connect = listen_port = 0;
3631 idx = num_permitted_opens++;
3632 if (fwd->connect_path != NULL) { 3730 if (fwd->connect_path != NULL) {
3633 permitted_opens[idx].host_to_connect = 3731 host_to_connect = xstrdup(fwd->connect_path);
3634 xstrdup(fwd->connect_path); 3732 port_to_connect = PORT_STREAMLOCAL;
3635 permitted_opens[idx].port_to_connect =
3636 PORT_STREAMLOCAL;
3637 } else { 3733 } else {
3638 permitted_opens[idx].host_to_connect = 3734 host_to_connect = xstrdup(fwd->connect_host);
3639 xstrdup(fwd->connect_host); 3735 port_to_connect = fwd->connect_port;
3640 permitted_opens[idx].port_to_connect =
3641 fwd->connect_port;
3642 } 3736 }
3643 if (fwd->listen_path != NULL) { 3737 if (fwd->listen_path != NULL) {
3644 permitted_opens[idx].listen_host = NULL; 3738 listen_path = xstrdup(fwd->listen_path);
3645 permitted_opens[idx].listen_path = 3739 listen_port = PORT_STREAMLOCAL;
3646 xstrdup(fwd->listen_path);
3647 permitted_opens[idx].listen_port = PORT_STREAMLOCAL;
3648 } else { 3740 } else {
3649 permitted_opens[idx].listen_host = 3741 if (fwd->listen_host != NULL)
3650 fwd->listen_host ? xstrdup(fwd->listen_host) : NULL; 3742 listen_host = xstrdup(fwd->listen_host);
3651 permitted_opens[idx].listen_path = NULL; 3743 listen_port = fwd->listen_port;
3652 permitted_opens[idx].listen_port = fwd->listen_port;
3653 } 3744 }
3654 permitted_opens[idx].downstream = NULL; 3745 idx = fwd_perm_list_add(ssh, FWDPERM_USER,
3746 host_to_connect, port_to_connect,
3747 listen_host, listen_path, listen_port, NULL);
3655 } 3748 }
3656 return (idx); 3749 return idx;
3657} 3750}
3658 3751
3659static int 3752static int
@@ -3718,36 +3811,33 @@ open_listen_match_streamlocal(ForwardPermission *allowed_open,
3718 * local side. 3811 * local side.
3719 */ 3812 */
3720static int 3813static int
3721channel_request_rforward_cancel_tcpip(const char *host, u_short port) 3814channel_request_rforward_cancel_tcpip(struct ssh *ssh,
3815 const char *host, u_short port)
3722{ 3816{
3723 int i; 3817 struct ssh_channels *sc = ssh->chanctxt;
3724 3818 int r;
3725 if (!compat20) 3819 u_int i;
3726 return -1; 3820 ForwardPermission *fp;
3727 3821
3728 for (i = 0; i < num_permitted_opens; i++) { 3822 for (i = 0; i < sc->num_permitted_opens; i++) {
3729 if (open_listen_match_tcpip(&permitted_opens[i], host, port, 0)) 3823 fp = &sc->permitted_opens[i];
3824 if (open_listen_match_tcpip(fp, host, port, 0))
3730 break; 3825 break;
3826 fp = NULL;
3731 } 3827 }
3732 if (i >= num_permitted_opens) { 3828 if (fp == NULL) {
3733 debug("%s: requested forward not found", __func__); 3829 debug("%s: requested forward not found", __func__);
3734 return -1; 3830 return -1;
3735 } 3831 }
3736 packet_start(SSH2_MSG_GLOBAL_REQUEST); 3832 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
3737 packet_put_cstring("cancel-tcpip-forward"); 3833 (r = sshpkt_put_cstring(ssh, "cancel-tcpip-forward")) != 0 ||
3738 packet_put_char(0); 3834 (r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
3739 packet_put_cstring(channel_rfwd_bind_host(host)); 3835 (r = sshpkt_put_cstring(ssh, channel_rfwd_bind_host(host))) != 0 ||
3740 packet_put_int(port); 3836 (r = sshpkt_put_u32(ssh, port)) != 0 ||
3741 packet_send(); 3837 (r = sshpkt_send(ssh)) != 0)
3742 3838 fatal("%s: send cancel: %s", __func__, ssh_err(r));
3743 permitted_opens[i].listen_port = 0; 3839
3744 permitted_opens[i].port_to_connect = 0; 3840 fwd_perm_clear(fp); /* unregister */
3745 free(permitted_opens[i].host_to_connect);
3746 permitted_opens[i].host_to_connect = NULL;
3747 free(permitted_opens[i].listen_host);
3748 permitted_opens[i].listen_host = NULL;
3749 permitted_opens[i].listen_path = NULL;
3750 permitted_opens[i].downstream = NULL;
3751 3841
3752 return 0; 3842 return 0;
3753} 3843}
@@ -3757,35 +3847,32 @@ channel_request_rforward_cancel_tcpip(const char *host, u_short port)
3757 * path from local side. 3847 * path from local side.
3758 */ 3848 */
3759static int 3849static int
3760channel_request_rforward_cancel_streamlocal(const char *path) 3850channel_request_rforward_cancel_streamlocal(struct ssh *ssh, const char *path)
3761{ 3851{
3762 int i; 3852 struct ssh_channels *sc = ssh->chanctxt;
3763 3853 int r;
3764 if (!compat20) 3854 u_int i;
3765 return -1; 3855 ForwardPermission *fp;
3766 3856
3767 for (i = 0; i < num_permitted_opens; i++) { 3857 for (i = 0; i < sc->num_permitted_opens; i++) {
3768 if (open_listen_match_streamlocal(&permitted_opens[i], path)) 3858 fp = &sc->permitted_opens[i];
3859 if (open_listen_match_streamlocal(fp, path))
3769 break; 3860 break;
3861 fp = NULL;
3770 } 3862 }
3771 if (i >= num_permitted_opens) { 3863 if (fp == NULL) {
3772 debug("%s: requested forward not found", __func__); 3864 debug("%s: requested forward not found", __func__);
3773 return -1; 3865 return -1;
3774 } 3866 }
3775 packet_start(SSH2_MSG_GLOBAL_REQUEST); 3867 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
3776 packet_put_cstring("cancel-streamlocal-forward@openssh.com"); 3868 (r = sshpkt_put_cstring(ssh,
3777 packet_put_char(0); 3869 "cancel-streamlocal-forward@openssh.com")) != 0 ||
3778 packet_put_cstring(path); 3870 (r = sshpkt_put_u8(ssh, 0)) != 0 || /* want reply */
3779 packet_send(); 3871 (r = sshpkt_put_cstring(ssh, path)) != 0 ||
3780 3872 (r = sshpkt_send(ssh)) != 0)
3781 permitted_opens[i].listen_port = 0; 3873 fatal("%s: send cancel: %s", __func__, ssh_err(r));
3782 permitted_opens[i].port_to_connect = 0; 3874
3783 free(permitted_opens[i].host_to_connect); 3875 fwd_perm_clear(fp); /* unregister */
3784 permitted_opens[i].host_to_connect = NULL;
3785 permitted_opens[i].listen_host = NULL;
3786 free(permitted_opens[i].listen_path);
3787 permitted_opens[i].listen_path = NULL;
3788 permitted_opens[i].downstream = NULL;
3789 3876
3790 return 0; 3877 return 0;
3791} 3878}
@@ -3794,14 +3881,15 @@ channel_request_rforward_cancel_streamlocal(const char *path)
3794 * Request cancellation of remote forwarding of a connection from local side. 3881 * Request cancellation of remote forwarding of a connection from local side.
3795 */ 3882 */
3796int 3883int
3797channel_request_rforward_cancel(struct Forward *fwd) 3884channel_request_rforward_cancel(struct ssh *ssh, struct Forward *fwd)
3798{ 3885{
3799 if (fwd->listen_path != NULL) { 3886 if (fwd->listen_path != NULL) {
3800 return (channel_request_rforward_cancel_streamlocal( 3887 return channel_request_rforward_cancel_streamlocal(ssh,
3801 fwd->listen_path)); 3888 fwd->listen_path);
3802 } else { 3889 } else {
3803 return (channel_request_rforward_cancel_tcpip(fwd->listen_host, 3890 return channel_request_rforward_cancel_tcpip(ssh,
3804 fwd->listen_port ? fwd->listen_port : fwd->allocated_port)); 3891 fwd->listen_host,
3892 fwd->listen_port ? fwd->listen_port : fwd->allocated_port);
3805 } 3893 }
3806} 3894}
3807 3895
@@ -3811,28 +3899,20 @@ channel_request_rforward_cancel(struct Forward *fwd)
3811 * anyway, and the server has no way to know but to trust the client anyway. 3899 * anyway, and the server has no way to know but to trust the client anyway.
3812 */ 3900 */
3813void 3901void
3814channel_permit_all_opens(void) 3902channel_permit_all_opens(struct ssh *ssh)
3815{ 3903{
3816 if (num_permitted_opens == 0) 3904 if (ssh->chanctxt->num_permitted_opens == 0)
3817 all_opens_permitted = 1; 3905 ssh->chanctxt->all_opens_permitted = 1;
3818} 3906}
3819 3907
3820void 3908void
3821channel_add_permitted_opens(char *host, int port) 3909channel_add_permitted_opens(struct ssh *ssh, char *host, int port)
3822{ 3910{
3823 debug("allow port forwarding to host %s port %d", host, port); 3911 struct ssh_channels *sc = ssh->chanctxt;
3824 3912
3825 permitted_opens = xreallocarray(permitted_opens, 3913 debug("allow port forwarding to host %s port %d", host, port);
3826 num_permitted_opens + 1, sizeof(*permitted_opens)); 3914 fwd_perm_list_add(ssh, FWDPERM_USER, host, port, NULL, NULL, 0, NULL);
3827 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); 3915 sc->all_opens_permitted = 0;
3828 permitted_opens[num_permitted_opens].port_to_connect = port;
3829 permitted_opens[num_permitted_opens].listen_host = NULL;
3830 permitted_opens[num_permitted_opens].listen_path = NULL;
3831 permitted_opens[num_permitted_opens].listen_port = 0;
3832 permitted_opens[num_permitted_opens].downstream = NULL;
3833 num_permitted_opens++;
3834
3835 all_opens_permitted = 0;
3836} 3916}
3837 3917
3838/* 3918/*
@@ -3841,105 +3921,61 @@ channel_add_permitted_opens(char *host, int port)
3841 * passed then they entry will be invalidated. 3921 * passed then they entry will be invalidated.
3842 */ 3922 */
3843void 3923void
3844channel_update_permitted_opens(int idx, int newport) 3924channel_update_permitted_opens(struct ssh *ssh, int idx, int newport)
3845{ 3925{
3846 if (idx < 0 || idx >= num_permitted_opens) { 3926 struct ssh_channels *sc = ssh->chanctxt;
3847 debug("channel_update_permitted_opens: index out of range:" 3927
3848 " %d num_permitted_opens %d", idx, num_permitted_opens); 3928 if (idx < 0 || (u_int)idx >= sc->num_permitted_opens) {
3929 debug("%s: index out of range: %d num_permitted_opens %d",
3930 __func__, idx, sc->num_permitted_opens);
3849 return; 3931 return;
3850 } 3932 }
3851 debug("%s allowed port %d for forwarding to host %s port %d", 3933 debug("%s allowed port %d for forwarding to host %s port %d",
3852 newport > 0 ? "Updating" : "Removing", 3934 newport > 0 ? "Updating" : "Removing",
3853 newport, 3935 newport,
3854 permitted_opens[idx].host_to_connect, 3936 sc->permitted_opens[idx].host_to_connect,
3855 permitted_opens[idx].port_to_connect); 3937 sc->permitted_opens[idx].port_to_connect);
3856 if (newport >= 0) { 3938 if (newport <= 0)
3857 permitted_opens[idx].listen_port = 3939 fwd_perm_clear(&sc->permitted_opens[idx]);
3940 else {
3941 sc->permitted_opens[idx].listen_port =
3858 (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport; 3942 (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;
3859 } else {
3860 permitted_opens[idx].listen_port = 0;
3861 permitted_opens[idx].port_to_connect = 0;
3862 free(permitted_opens[idx].host_to_connect);
3863 permitted_opens[idx].host_to_connect = NULL;
3864 free(permitted_opens[idx].listen_host);
3865 permitted_opens[idx].listen_host = NULL;
3866 free(permitted_opens[idx].listen_path);
3867 permitted_opens[idx].listen_path = NULL;
3868 } 3943 }
3869} 3944}
3870 3945
3871int 3946int
3872channel_add_adm_permitted_opens(char *host, int port) 3947channel_add_adm_permitted_opens(struct ssh *ssh, char *host, int port)
3873{ 3948{
3874 debug("config allows port forwarding to host %s port %d", host, port); 3949 debug("config allows port forwarding to host %s port %d", host, port);
3875 3950 return fwd_perm_list_add(ssh, FWDPERM_ADMIN, host, port,
3876 permitted_adm_opens = xreallocarray(permitted_adm_opens, 3951 NULL, NULL, 0, NULL);
3877 num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens));
3878 permitted_adm_opens[num_adm_permitted_opens].host_to_connect
3879 = xstrdup(host);
3880 permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port;
3881 permitted_adm_opens[num_adm_permitted_opens].listen_host = NULL;
3882 permitted_adm_opens[num_adm_permitted_opens].listen_path = NULL;
3883 permitted_adm_opens[num_adm_permitted_opens].listen_port = 0;
3884 return ++num_adm_permitted_opens;
3885} 3952}
3886 3953
3887void 3954void
3888channel_disable_adm_local_opens(void) 3955channel_disable_adm_local_opens(struct ssh *ssh)
3889{ 3956{
3890 channel_clear_adm_permitted_opens(); 3957 channel_clear_adm_permitted_opens(ssh);
3891 permitted_adm_opens = xcalloc(sizeof(*permitted_adm_opens), 1); 3958 fwd_perm_list_add(ssh, FWDPERM_ADMIN, NULL, 0, NULL, NULL, 0, NULL);
3892 permitted_adm_opens[num_adm_permitted_opens].host_to_connect = NULL;
3893 num_adm_permitted_opens = 1;
3894} 3959}
3895 3960
3896void 3961void
3897channel_clear_permitted_opens(void) 3962channel_clear_permitted_opens(struct ssh *ssh)
3898{ 3963{
3899 int i; 3964 struct ssh_channels *sc = ssh->chanctxt;
3900 3965
3901 for (i = 0; i < num_permitted_opens; i++) { 3966 sc->permitted_opens = xrecallocarray(sc->permitted_opens,
3902 free(permitted_opens[i].host_to_connect); 3967 sc->num_permitted_opens, 0, sizeof(*sc->permitted_opens));
3903 free(permitted_opens[i].listen_host); 3968 sc->num_permitted_opens = 0;
3904 free(permitted_opens[i].listen_path);
3905 }
3906 free(permitted_opens);
3907 permitted_opens = NULL;
3908 num_permitted_opens = 0;
3909} 3969}
3910 3970
3911void 3971void
3912channel_clear_adm_permitted_opens(void) 3972channel_clear_adm_permitted_opens(struct ssh *ssh)
3913{ 3973{
3914 int i; 3974 struct ssh_channels *sc = ssh->chanctxt;
3915 3975
3916 for (i = 0; i < num_adm_permitted_opens; i++) { 3976 sc->permitted_adm_opens = xrecallocarray(sc->permitted_adm_opens,
3917 free(permitted_adm_opens[i].host_to_connect); 3977 sc->num_adm_permitted_opens, 0, sizeof(*sc->permitted_adm_opens));
3918 free(permitted_adm_opens[i].listen_host); 3978 sc->num_adm_permitted_opens = 0;
3919 free(permitted_adm_opens[i].listen_path);
3920 }
3921 free(permitted_adm_opens);
3922 permitted_adm_opens = NULL;
3923 num_adm_permitted_opens = 0;
3924}
3925
3926void
3927channel_print_adm_permitted_opens(void)
3928{
3929 int i;
3930
3931 printf("permitopen");
3932 if (num_adm_permitted_opens == 0) {
3933 printf(" any\n");
3934 return;
3935 }
3936 for (i = 0; i < num_adm_permitted_opens; i++)
3937 if (permitted_adm_opens[i].host_to_connect == NULL)
3938 printf(" none");
3939 else
3940 printf(" %s:%d", permitted_adm_opens[i].host_to_connect,
3941 permitted_adm_opens[i].port_to_connect);
3942 printf("\n");
3943} 3979}
3944 3980
3945/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */ 3981/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */
@@ -3961,7 +3997,8 @@ connect_next(struct channel_connect *cctx)
3961{ 3997{
3962 int sock, saved_errno; 3998 int sock, saved_errno;
3963 struct sockaddr_un *sunaddr; 3999 struct sockaddr_un *sunaddr;
3964 char ntop[NI_MAXHOST], strport[MAXIMUM(NI_MAXSERV,sizeof(sunaddr->sun_path))]; 4000 char ntop[NI_MAXHOST];
4001 char strport[MAXIMUM(NI_MAXSERV, sizeof(sunaddr->sun_path))];
3965 4002
3966 for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { 4003 for (; cctx->ai; cctx->ai = cctx->ai->ai_next) {
3967 switch (cctx->ai->ai_family) { 4004 switch (cctx->ai->ai_family) {
@@ -4027,21 +4064,18 @@ channel_connect_ctx_free(struct channel_connect *cctx)
4027} 4064}
4028 4065
4029/* 4066/*
4030 * Return CONNECTING channel to remote host:port or local socket path, 4067 * Return connecting socket to remote host:port or local socket path,
4031 * passing back the failure reason if appropriate. 4068 * passing back the failure reason if appropriate.
4032 */ 4069 */
4033static Channel * 4070static int
4034connect_to_reason(const char *name, int port, char *ctype, char *rname, 4071connect_to_helper(struct ssh *ssh, const char *name, int port, int socktype,
4035 int *reason, const char **errmsg) 4072 char *ctype, char *rname, struct channel_connect *cctx,
4073 int *reason, const char **errmsg)
4036{ 4074{
4037 struct addrinfo hints; 4075 struct addrinfo hints;
4038 int gaierr; 4076 int gaierr;
4039 int sock = -1; 4077 int sock = -1;
4040 char strport[NI_MAXSERV]; 4078 char strport[NI_MAXSERV];
4041 struct channel_connect cctx;
4042 Channel *c;
4043
4044 memset(&cctx, 0, sizeof(cctx));
4045 4079
4046 if (port == PORT_STREAMLOCAL) { 4080 if (port == PORT_STREAMLOCAL) {
4047 struct sockaddr_un *sunaddr; 4081 struct sockaddr_un *sunaddr;
@@ -4049,7 +4083,7 @@ connect_to_reason(const char *name, int port, char *ctype, char *rname,
4049 4083
4050 if (strlen(name) > sizeof(sunaddr->sun_path)) { 4084 if (strlen(name) > sizeof(sunaddr->sun_path)) {
4051 error("%.100s: %.100s", name, strerror(ENAMETOOLONG)); 4085 error("%.100s: %.100s", name, strerror(ENAMETOOLONG));
4052 return (NULL); 4086 return -1;
4053 } 4087 }
4054 4088
4055 /* 4089 /*
@@ -4062,18 +4096,18 @@ connect_to_reason(const char *name, int port, char *ctype, char *rname,
4062 ai->ai_addr = (struct sockaddr *)(ai + 1); 4096 ai->ai_addr = (struct sockaddr *)(ai + 1);
4063 ai->ai_addrlen = sizeof(*sunaddr); 4097 ai->ai_addrlen = sizeof(*sunaddr);
4064 ai->ai_family = AF_UNIX; 4098 ai->ai_family = AF_UNIX;
4065 ai->ai_socktype = SOCK_STREAM; 4099 ai->ai_socktype = socktype;
4066 ai->ai_protocol = PF_UNSPEC; 4100 ai->ai_protocol = PF_UNSPEC;
4067 sunaddr = (struct sockaddr_un *)ai->ai_addr; 4101 sunaddr = (struct sockaddr_un *)ai->ai_addr;
4068 sunaddr->sun_family = AF_UNIX; 4102 sunaddr->sun_family = AF_UNIX;
4069 strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path)); 4103 strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path));
4070 cctx.aitop = ai; 4104 cctx->aitop = ai;
4071 } else { 4105 } else {
4072 memset(&hints, 0, sizeof(hints)); 4106 memset(&hints, 0, sizeof(hints));
4073 hints.ai_family = IPv4or6; 4107 hints.ai_family = ssh->chanctxt->IPv4or6;
4074 hints.ai_socktype = SOCK_STREAM; 4108 hints.ai_socktype = socktype;
4075 snprintf(strport, sizeof strport, "%d", port); 4109 snprintf(strport, sizeof strport, "%d", port);
4076 if ((gaierr = getaddrinfo(name, strport, &hints, &cctx.aitop)) 4110 if ((gaierr = getaddrinfo(name, strport, &hints, &cctx->aitop))
4077 != 0) { 4111 != 0) {
4078 if (errmsg != NULL) 4112 if (errmsg != NULL)
4079 *errmsg = ssh_gai_strerror(gaierr); 4113 *errmsg = ssh_gai_strerror(gaierr);
@@ -4081,31 +4115,46 @@ connect_to_reason(const char *name, int port, char *ctype, char *rname,
4081 *reason = SSH2_OPEN_CONNECT_FAILED; 4115 *reason = SSH2_OPEN_CONNECT_FAILED;
4082 error("connect_to %.100s: unknown host (%s)", name, 4116 error("connect_to %.100s: unknown host (%s)", name,
4083 ssh_gai_strerror(gaierr)); 4117 ssh_gai_strerror(gaierr));
4084 return NULL; 4118 return -1;
4085 } 4119 }
4086 } 4120 }
4087 4121
4088 cctx.host = xstrdup(name); 4122 cctx->host = xstrdup(name);
4089 cctx.port = port; 4123 cctx->port = port;
4090 cctx.ai = cctx.aitop; 4124 cctx->ai = cctx->aitop;
4091 4125
4092 if ((sock = connect_next(&cctx)) == -1) { 4126 if ((sock = connect_next(cctx)) == -1) {
4093 error("connect to %.100s port %d failed: %s", 4127 error("connect to %.100s port %d failed: %s",
4094 name, port, strerror(errno)); 4128 name, port, strerror(errno));
4095 channel_connect_ctx_free(&cctx); 4129 return -1;
4096 return NULL;
4097 } 4130 }
4098 c = channel_new(ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, 4131
4099 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1); 4132 return sock;
4100 c->connect_ctx = cctx;
4101 return c;
4102} 4133}
4103 4134
4104/* Return CONNECTING channel to remote host:port or local socket path */ 4135/* Return CONNECTING channel to remote host:port or local socket path */
4105static Channel * 4136static Channel *
4106connect_to(const char *name, int port, char *ctype, char *rname) 4137connect_to(struct ssh *ssh, const char *host, int port,
4138 char *ctype, char *rname)
4107{ 4139{
4108 return connect_to_reason(name, port, ctype, rname, NULL, NULL); 4140 struct channel_connect cctx;
4141 Channel *c;
4142 int sock;
4143
4144 memset(&cctx, 0, sizeof(cctx));
4145 sock = connect_to_helper(ssh, host, port, SOCK_STREAM, ctype, rname,
4146 &cctx, NULL, NULL);
4147 if (sock == -1) {
4148 channel_connect_ctx_free(&cctx);
4149 return NULL;
4150 }
4151 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,
4152 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
4153 c->host_port = port;
4154 c->path = xstrdup(host);
4155 c->connect_ctx = cctx;
4156
4157 return c;
4109} 4158}
4110 4159
4111/* 4160/*
@@ -4113,19 +4162,24 @@ connect_to(const char *name, int port, char *ctype, char *rname)
4113 * that needs to deal with this connection. 4162 * that needs to deal with this connection.
4114 */ 4163 */
4115Channel * 4164Channel *
4116channel_connect_by_listen_address(const char *listen_host, 4165channel_connect_by_listen_address(struct ssh *ssh, const char *listen_host,
4117 u_short listen_port, char *ctype, char *rname) 4166 u_short listen_port, char *ctype, char *rname)
4118{ 4167{
4119 int i; 4168 struct ssh_channels *sc = ssh->chanctxt;
4120 4169 u_int i;
4121 for (i = 0; i < num_permitted_opens; i++) { 4170 ForwardPermission *fp;
4122 if (open_listen_match_tcpip(&permitted_opens[i], listen_host, 4171
4123 listen_port, 1)) { 4172 for (i = 0; i < sc->num_permitted_opens; i++) {
4124 if (permitted_opens[i].downstream) 4173 fp = &sc->permitted_opens[i];
4125 return permitted_opens[i].downstream; 4174 if (open_listen_match_tcpip(fp, listen_host, listen_port, 1)) {
4126 return connect_to( 4175 if (fp->downstream)
4127 permitted_opens[i].host_to_connect, 4176 return fp->downstream;
4128 permitted_opens[i].port_to_connect, ctype, rname); 4177 if (fp->port_to_connect == 0)
4178 return rdynamic_connect_prepare(ssh,
4179 ctype, rname);
4180 return connect_to(ssh,
4181 fp->host_to_connect, fp->port_to_connect,
4182 ctype, rname);
4129 } 4183 }
4130 } 4184 }
4131 error("WARNING: Server requests forwarding for unknown listen_port %d", 4185 error("WARNING: Server requests forwarding for unknown listen_port %d",
@@ -4134,15 +4188,19 @@ channel_connect_by_listen_address(const char *listen_host,
4134} 4188}
4135 4189
4136Channel * 4190Channel *
4137channel_connect_by_listen_path(const char *path, char *ctype, char *rname) 4191channel_connect_by_listen_path(struct ssh *ssh, const char *path,
4192 char *ctype, char *rname)
4138{ 4193{
4139 int i; 4194 struct ssh_channels *sc = ssh->chanctxt;
4140 4195 u_int i;
4141 for (i = 0; i < num_permitted_opens; i++) { 4196 ForwardPermission *fp;
4142 if (open_listen_match_streamlocal(&permitted_opens[i], path)) { 4197
4143 return connect_to( 4198 for (i = 0; i < sc->num_permitted_opens; i++) {
4144 permitted_opens[i].host_to_connect, 4199 fp = &sc->permitted_opens[i];
4145 permitted_opens[i].port_to_connect, ctype, rname); 4200 if (open_listen_match_streamlocal(fp, path)) {
4201 return connect_to(ssh,
4202 fp->host_to_connect, fp->port_to_connect,
4203 ctype, rname);
4146 } 4204 }
4147 } 4205 }
4148 error("WARNING: Server requests forwarding for unknown path %.100s", 4206 error("WARNING: Server requests forwarding for unknown path %.100s",
@@ -4152,27 +4210,36 @@ channel_connect_by_listen_path(const char *path, char *ctype, char *rname)
4152 4210
4153/* Check if connecting to that port is permitted and connect. */ 4211/* Check if connecting to that port is permitted and connect. */
4154Channel * 4212Channel *
4155channel_connect_to_port(const char *host, u_short port, char *ctype, 4213channel_connect_to_port(struct ssh *ssh, const char *host, u_short port,
4156 char *rname, int *reason, const char **errmsg) 4214 char *ctype, char *rname, int *reason, const char **errmsg)
4157{ 4215{
4158 int i, permit, permit_adm = 1; 4216 struct ssh_channels *sc = ssh->chanctxt;
4217 struct channel_connect cctx;
4218 Channel *c;
4219 u_int i, permit, permit_adm = 1;
4220 int sock;
4221 ForwardPermission *fp;
4159 4222
4160 permit = all_opens_permitted; 4223 permit = sc->all_opens_permitted;
4161 if (!permit) { 4224 if (!permit) {
4162 for (i = 0; i < num_permitted_opens; i++) 4225 for (i = 0; i < sc->num_permitted_opens; i++) {
4163 if (open_match(&permitted_opens[i], host, port)) { 4226 fp = &sc->permitted_opens[i];
4227 if (open_match(fp, host, port)) {
4164 permit = 1; 4228 permit = 1;
4165 break; 4229 break;
4166 } 4230 }
4231 }
4167 } 4232 }
4168 4233
4169 if (num_adm_permitted_opens > 0) { 4234 if (sc->num_adm_permitted_opens > 0) {
4170 permit_adm = 0; 4235 permit_adm = 0;
4171 for (i = 0; i < num_adm_permitted_opens; i++) 4236 for (i = 0; i < sc->num_adm_permitted_opens; i++) {
4172 if (open_match(&permitted_adm_opens[i], host, port)) { 4237 fp = &sc->permitted_adm_opens[i];
4238 if (open_match(fp, host, port)) {
4173 permit_adm = 1; 4239 permit_adm = 1;
4174 break; 4240 break;
4175 } 4241 }
4242 }
4176 } 4243 }
4177 4244
4178 if (!permit || !permit_adm) { 4245 if (!permit || !permit_adm) {
@@ -4182,31 +4249,53 @@ channel_connect_to_port(const char *host, u_short port, char *ctype,
4182 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED; 4249 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
4183 return NULL; 4250 return NULL;
4184 } 4251 }
4185 return connect_to_reason(host, port, ctype, rname, reason, errmsg); 4252
4253 memset(&cctx, 0, sizeof(cctx));
4254 sock = connect_to_helper(ssh, host, port, SOCK_STREAM, ctype, rname,
4255 &cctx, reason, errmsg);
4256 if (sock == -1) {
4257 channel_connect_ctx_free(&cctx);
4258 return NULL;
4259 }
4260
4261 c = channel_new(ssh, ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1,
4262 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
4263 c->host_port = port;
4264 c->path = xstrdup(host);
4265 c->connect_ctx = cctx;
4266
4267 return c;
4186} 4268}
4187 4269
4188/* Check if connecting to that path is permitted and connect. */ 4270/* Check if connecting to that path is permitted and connect. */
4189Channel * 4271Channel *
4190channel_connect_to_path(const char *path, char *ctype, char *rname) 4272channel_connect_to_path(struct ssh *ssh, const char *path,
4273 char *ctype, char *rname)
4191{ 4274{
4192 int i, permit, permit_adm = 1; 4275 struct ssh_channels *sc = ssh->chanctxt;
4276 u_int i, permit, permit_adm = 1;
4277 ForwardPermission *fp;
4193 4278
4194 permit = all_opens_permitted; 4279 permit = sc->all_opens_permitted;
4195 if (!permit) { 4280 if (!permit) {
4196 for (i = 0; i < num_permitted_opens; i++) 4281 for (i = 0; i < sc->num_permitted_opens; i++) {
4197 if (open_match(&permitted_opens[i], path, PORT_STREAMLOCAL)) { 4282 fp = &sc->permitted_opens[i];
4283 if (open_match(fp, path, PORT_STREAMLOCAL)) {
4198 permit = 1; 4284 permit = 1;
4199 break; 4285 break;
4200 } 4286 }
4287 }
4201 } 4288 }
4202 4289
4203 if (num_adm_permitted_opens > 0) { 4290 if (sc->num_adm_permitted_opens > 0) {
4204 permit_adm = 0; 4291 permit_adm = 0;
4205 for (i = 0; i < num_adm_permitted_opens; i++) 4292 for (i = 0; i < sc->num_adm_permitted_opens; i++) {
4206 if (open_match(&permitted_adm_opens[i], path, PORT_STREAMLOCAL)) { 4293 fp = &sc->permitted_adm_opens[i];
4294 if (open_match(fp, path, PORT_STREAMLOCAL)) {
4207 permit_adm = 1; 4295 permit_adm = 1;
4208 break; 4296 break;
4209 } 4297 }
4298 }
4210 } 4299 }
4211 4300
4212 if (!permit || !permit_adm) { 4301 if (!permit || !permit_adm) {
@@ -4214,30 +4303,82 @@ channel_connect_to_path(const char *path, char *ctype, char *rname)
4214 "but the request was denied.", path); 4303 "but the request was denied.", path);
4215 return NULL; 4304 return NULL;
4216 } 4305 }
4217 return connect_to(path, PORT_STREAMLOCAL, ctype, rname); 4306 return connect_to(ssh, path, PORT_STREAMLOCAL, ctype, rname);
4218} 4307}
4219 4308
4220void 4309void
4221channel_send_window_changes(void) 4310channel_send_window_changes(struct ssh *ssh)
4222{ 4311{
4223 u_int i; 4312 struct ssh_channels *sc = ssh->chanctxt;
4224 struct winsize ws; 4313 struct winsize ws;
4314 int r;
4315 u_int i;
4225 4316
4226 for (i = 0; i < channels_alloc; i++) { 4317 for (i = 0; i < sc->channels_alloc; i++) {
4227 if (channels[i] == NULL || !channels[i]->client_tty || 4318 if (sc->channels[i] == NULL || !sc->channels[i]->client_tty ||
4228 channels[i]->type != SSH_CHANNEL_OPEN) 4319 sc->channels[i]->type != SSH_CHANNEL_OPEN)
4229 continue; 4320 continue;
4230 if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0) 4321 if (ioctl(sc->channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
4231 continue; 4322 continue;
4232 channel_request_start(i, "window-change", 0); 4323 channel_request_start(ssh, i, "window-change", 0);
4233 packet_put_int((u_int)ws.ws_col); 4324 if ((r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 ||
4234 packet_put_int((u_int)ws.ws_row); 4325 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 ||
4235 packet_put_int((u_int)ws.ws_xpixel); 4326 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
4236 packet_put_int((u_int)ws.ws_ypixel); 4327 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0 ||
4237 packet_send(); 4328 (r = sshpkt_send(ssh)) != 0)
4329 fatal("%s: channel %u: send window-change: %s",
4330 __func__, i, ssh_err(r));
4238 } 4331 }
4239} 4332}
4240 4333
4334/* Return RDYNAMIC_OPEN channel: channel allows SOCKS, but is not connected */
4335static Channel *
4336rdynamic_connect_prepare(struct ssh *ssh, char *ctype, char *rname)
4337{
4338 Channel *c;
4339 int r;
4340
4341 c = channel_new(ssh, ctype, SSH_CHANNEL_RDYNAMIC_OPEN, -1, -1, -1,
4342 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1);
4343 c->host_port = 0;
4344 c->path = NULL;
4345
4346 /*
4347 * We need to open the channel before we have a FD,
4348 * so that we can get SOCKS header from peer.
4349 */
4350 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
4351 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
4352 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
4353 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
4354 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0) {
4355 fatal("%s: channel %i: confirm: %s", __func__,
4356 c->self, ssh_err(r));
4357 }
4358 return c;
4359}
4360
4361/* Return CONNECTING socket to remote host:port or local socket path */
4362static int
4363rdynamic_connect_finish(struct ssh *ssh, Channel *c)
4364{
4365 struct channel_connect cctx;
4366 int sock;
4367
4368 memset(&cctx, 0, sizeof(cctx));
4369 sock = connect_to_helper(ssh, c->path, c->host_port, SOCK_STREAM, NULL,
4370 NULL, &cctx, NULL, NULL);
4371 if (sock == -1)
4372 channel_connect_ctx_free(&cctx);
4373 else {
4374 /* similar to SSH_CHANNEL_CONNECTING but we've already sent the open */
4375 c->type = SSH_CHANNEL_RDYNAMIC_FINISH;
4376 c->connect_ctx = cctx;
4377 channel_register_fds(ssh, c, sock, sock, -1, 0, 1, 0);
4378 }
4379 return sock;
4380}
4381
4241/* -- X11 forwarding */ 4382/* -- X11 forwarding */
4242 4383
4243/* 4384/*
@@ -4246,8 +4387,9 @@ channel_send_window_changes(void)
4246 * stored in display_numberp , or -1 if an error occurs. 4387 * stored in display_numberp , or -1 if an error occurs.
4247 */ 4388 */
4248int 4389int
4249x11_create_display_inet(int x11_display_offset, int x11_use_localhost, 4390x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
4250 int single_connection, u_int *display_numberp, int **chanids) 4391 int x11_use_localhost, int single_connection,
4392 u_int *display_numberp, int **chanids)
4251{ 4393{
4252 Channel *nc = NULL; 4394 Channel *nc = NULL;
4253 int display_number, sock; 4395 int display_number, sock;
@@ -4264,16 +4406,18 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
4264 display_number++) { 4406 display_number++) {
4265 port = 6000 + display_number; 4407 port = 6000 + display_number;
4266 memset(&hints, 0, sizeof(hints)); 4408 memset(&hints, 0, sizeof(hints));
4267 hints.ai_family = IPv4or6; 4409 hints.ai_family = ssh->chanctxt->IPv4or6;
4268 hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; 4410 hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;
4269 hints.ai_socktype = SOCK_STREAM; 4411 hints.ai_socktype = SOCK_STREAM;
4270 snprintf(strport, sizeof strport, "%d", port); 4412 snprintf(strport, sizeof strport, "%d", port);
4271 if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { 4413 if ((gaierr = getaddrinfo(NULL, strport,
4414 &hints, &aitop)) != 0) {
4272 error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr)); 4415 error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr));
4273 return -1; 4416 return -1;
4274 } 4417 }
4275 for (ai = aitop; ai; ai = ai->ai_next) { 4418 for (ai = aitop; ai; ai = ai->ai_next) {
4276 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 4419 if (ai->ai_family != AF_INET &&
4420 ai->ai_family != AF_INET6)
4277 continue; 4421 continue;
4278 sock = socket(ai->ai_family, ai->ai_socktype, 4422 sock = socket(ai->ai_family, ai->ai_socktype,
4279 ai->ai_protocol); 4423 ai->ai_protocol);
@@ -4297,12 +4441,11 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
4297 if (x11_use_localhost) 4441 if (x11_use_localhost)
4298 channel_set_reuseaddr(sock); 4442 channel_set_reuseaddr(sock);
4299 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { 4443 if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
4300 debug2("bind port %d: %.100s", port, strerror(errno)); 4444 debug2("%s: bind port %d: %.100s", __func__,
4445 port, strerror(errno));
4301 close(sock); 4446 close(sock);
4302 4447 for (n = 0; n < num_socks; n++)
4303 for (n = 0; n < num_socks; n++) {
4304 close(socks[n]); 4448 close(socks[n]);
4305 }
4306 num_socks = 0; 4449 num_socks = 0;
4307 break; 4450 break;
4308 } 4451 }
@@ -4332,7 +4475,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
4332 *chanids = xcalloc(num_socks + 1, sizeof(**chanids)); 4475 *chanids = xcalloc(num_socks + 1, sizeof(**chanids));
4333 for (n = 0; n < num_socks; n++) { 4476 for (n = 0; n < num_socks; n++) {
4334 sock = socks[n]; 4477 sock = socks[n];
4335 nc = channel_new("x11 listener", 4478 nc = channel_new(ssh, "x11 listener",
4336 SSH_CHANNEL_X11_LISTENER, sock, sock, -1, 4479 SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
4337 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 4480 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
4338 0, "X11 inet listener", 1); 4481 0, "X11 inet listener", 1);
@@ -4343,7 +4486,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
4343 4486
4344 /* Return the display number for the DISPLAY environment variable. */ 4487 /* Return the display number for the DISPLAY environment variable. */
4345 *display_numberp = display_number; 4488 *display_numberp = display_number;
4346 return (0); 4489 return 0;
4347} 4490}
4348 4491
4349static int 4492static int
@@ -4401,7 +4544,7 @@ is_path_to_xsocket(const char *display, char *path, size_t pathlen)
4401#endif 4544#endif
4402 4545
4403int 4546int
4404x11_connect_display(void) 4547x11_connect_display(struct ssh *ssh)
4405{ 4548{
4406 u_int display_number; 4549 u_int display_number;
4407 const char *display; 4550 const char *display;
@@ -4446,9 +4589,10 @@ x11_connect_display(void)
4446 if (strncmp(display, "unix:", 5) == 0 || 4589 if (strncmp(display, "unix:", 5) == 0 ||
4447 display[0] == ':') { 4590 display[0] == ':') {
4448 /* Connect to the unix domain socket. */ 4591 /* Connect to the unix domain socket. */
4449 if (sscanf(strrchr(display, ':') + 1, "%u", &display_number) != 1) { 4592 if (sscanf(strrchr(display, ':') + 1, "%u",
4450 error("Could not parse display number from DISPLAY: %.100s", 4593 &display_number) != 1) {
4451 display); 4594 error("Could not parse display number from DISPLAY: "
4595 "%.100s", display);
4452 return -1; 4596 return -1;
4453 } 4597 }
4454 /* Create a socket. */ 4598 /* Create a socket. */
@@ -4470,7 +4614,10 @@ x11_connect_display(void)
4470 return -1; 4614 return -1;
4471 } 4615 }
4472 *cp = 0; 4616 *cp = 0;
4473 /* buf now contains the host name. But first we parse the display number. */ 4617 /*
4618 * buf now contains the host name. But first we parse the
4619 * display number.
4620 */
4474 if (sscanf(cp + 1, "%u", &display_number) != 1) { 4621 if (sscanf(cp + 1, "%u", &display_number) != 1) {
4475 error("Could not parse display number from DISPLAY: %.100s", 4622 error("Could not parse display number from DISPLAY: %.100s",
4476 display); 4623 display);
@@ -4479,7 +4626,7 @@ x11_connect_display(void)
4479 4626
4480 /* Look up the host address */ 4627 /* Look up the host address */
4481 memset(&hints, 0, sizeof(hints)); 4628 memset(&hints, 0, sizeof(hints));
4482 hints.ai_family = IPv4or6; 4629 hints.ai_family = ssh->chanctxt->IPv4or6;
4483 hints.ai_socktype = SOCK_STREAM; 4630 hints.ai_socktype = SOCK_STREAM;
4484 snprintf(strport, sizeof strport, "%u", 6000 + display_number); 4631 snprintf(strport, sizeof strport, "%u", 6000 + display_number);
4485 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { 4632 if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
@@ -4506,8 +4653,8 @@ x11_connect_display(void)
4506 } 4653 }
4507 freeaddrinfo(aitop); 4654 freeaddrinfo(aitop);
4508 if (!ai) { 4655 if (!ai) {
4509 error("connect %.100s port %u: %.100s", buf, 6000 + display_number, 4656 error("connect %.100s port %u: %.100s", buf,
4510 strerror(errno)); 4657 6000 + display_number, strerror(errno));
4511 return -1; 4658 return -1;
4512 } 4659 }
4513 set_nodelay(sock); 4660 set_nodelay(sock);
@@ -4515,98 +4662,24 @@ x11_connect_display(void)
4515} 4662}
4516 4663
4517/* 4664/*
4518 * This is called when SSH_SMSG_X11_OPEN is received. The packet contains
4519 * the remote channel number. We should do whatever we want, and respond
4520 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
4521 */
4522
4523/* ARGSUSED */
4524int
4525x11_input_open(int type, u_int32_t seq, void *ctxt)
4526{
4527 Channel *c = NULL;
4528 int remote_id, sock = 0;
4529 char *remote_host;
4530
4531 debug("Received X11 open request.");
4532
4533 remote_id = packet_get_int();
4534
4535 if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {
4536 remote_host = packet_get_string(NULL);
4537 } else {
4538 remote_host = xstrdup("unknown (remote did not supply name)");
4539 }
4540 packet_check_eom();
4541
4542 /* Obtain a connection to the real X display. */
4543 sock = x11_connect_display();
4544 if (sock != -1) {
4545 /* Allocate a channel for this connection. */
4546 c = channel_new("connected x11 socket",
4547 SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0,
4548 remote_host, 1);
4549 c->remote_id = remote_id;
4550 c->force_drain = 1;
4551 }
4552 free(remote_host);
4553 if (c == NULL) {
4554 /* Send refusal to the remote host. */
4555 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
4556 packet_put_int(remote_id);
4557 } else {
4558 /* Send a confirmation to the remote host. */
4559 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
4560 packet_put_int(remote_id);
4561 packet_put_int(c->self);
4562 }
4563 packet_send();
4564 return 0;
4565}
4566
4567/* dummy protocol handler that denies SSH-1 requests (agent/x11) */
4568/* ARGSUSED */
4569int
4570deny_input_open(int type, u_int32_t seq, void *ctxt)
4571{
4572 int rchan = packet_get_int();
4573
4574 switch (type) {
4575 case SSH_SMSG_AGENT_OPEN:
4576 error("Warning: ssh server tried agent forwarding.");
4577 break;
4578 case SSH_SMSG_X11_OPEN:
4579 error("Warning: ssh server tried X11 forwarding.");
4580 break;
4581 default:
4582 error("deny_input_open: type %d", type);
4583 break;
4584 }
4585 error("Warning: this is probably a break-in attempt by a malicious server.");
4586 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
4587 packet_put_int(rchan);
4588 packet_send();
4589 return 0;
4590}
4591
4592/*
4593 * Requests forwarding of X11 connections, generates fake authentication 4665 * Requests forwarding of X11 connections, generates fake authentication
4594 * data, and enables authentication spoofing. 4666 * data, and enables authentication spoofing.
4595 * This should be called in the client only. 4667 * This should be called in the client only.
4596 */ 4668 */
4597void 4669void
4598x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, 4670x11_request_forwarding_with_spoofing(struct ssh *ssh, int client_session_id,
4599 const char *proto, const char *data, int want_reply) 4671 const char *disp, const char *proto, const char *data, int want_reply)
4600{ 4672{
4673 struct ssh_channels *sc = ssh->chanctxt;
4601 u_int data_len = (u_int) strlen(data) / 2; 4674 u_int data_len = (u_int) strlen(data) / 2;
4602 u_int i, value; 4675 u_int i, value;
4603 char *new_data;
4604 int screen_number;
4605 const char *cp; 4676 const char *cp;
4677 char *new_data;
4678 int r, screen_number;
4606 4679
4607 if (x11_saved_display == NULL) 4680 if (sc->x11_saved_display == NULL)
4608 x11_saved_display = xstrdup(disp); 4681 sc->x11_saved_display = xstrdup(disp);
4609 else if (strcmp(disp, x11_saved_display) != 0) { 4682 else if (strcmp(disp, sc->x11_saved_display) != 0) {
4610 error("x11_request_forwarding_with_spoofing: different " 4683 error("x11_request_forwarding_with_spoofing: different "
4611 "$DISPLAY already forwarded"); 4684 "$DISPLAY already forwarded");
4612 return; 4685 return;
@@ -4620,53 +4693,37 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
4620 else 4693 else
4621 screen_number = 0; 4694 screen_number = 0;
4622 4695
4623 if (x11_saved_proto == NULL) { 4696 if (sc->x11_saved_proto == NULL) {
4624 /* Save protocol name. */ 4697 /* Save protocol name. */
4625 x11_saved_proto = xstrdup(proto); 4698 sc->x11_saved_proto = xstrdup(proto);
4626 4699
4627 /* Extract real authentication data. */ 4700 /* Extract real authentication data. */
4628 x11_saved_data = xmalloc(data_len); 4701 sc->x11_saved_data = xmalloc(data_len);
4629 for (i = 0; i < data_len; i++) { 4702 for (i = 0; i < data_len; i++) {
4630 if (sscanf(data + 2 * i, "%2x", &value) != 1) 4703 if (sscanf(data + 2 * i, "%2x", &value) != 1)
4631 fatal("x11_request_forwarding: bad " 4704 fatal("x11_request_forwarding: bad "
4632 "authentication data: %.100s", data); 4705 "authentication data: %.100s", data);
4633 x11_saved_data[i] = value; 4706 sc->x11_saved_data[i] = value;
4634 } 4707 }
4635 x11_saved_data_len = data_len; 4708 sc->x11_saved_data_len = data_len;
4636 4709
4637 /* Generate fake data of the same length. */ 4710 /* Generate fake data of the same length. */
4638 x11_fake_data = xmalloc(data_len); 4711 sc->x11_fake_data = xmalloc(data_len);
4639 arc4random_buf(x11_fake_data, data_len); 4712 arc4random_buf(sc->x11_fake_data, data_len);
4640 x11_fake_data_len = data_len; 4713 sc->x11_fake_data_len = data_len;
4641 } 4714 }
4642 4715
4643 /* Convert the fake data into hex. */ 4716 /* Convert the fake data into hex. */
4644 new_data = tohex(x11_fake_data, data_len); 4717 new_data = tohex(sc->x11_fake_data, data_len);
4645 4718
4646 /* Send the request packet. */ 4719 /* Send the request packet. */
4647 if (compat20) { 4720 channel_request_start(ssh, client_session_id, "x11-req", want_reply);
4648 channel_request_start(client_session_id, "x11-req", want_reply); 4721 if ((r = sshpkt_put_u8(ssh, 0)) != 0 || /* bool: single connection */
4649 packet_put_char(0); /* XXX bool single connection */ 4722 (r = sshpkt_put_cstring(ssh, proto)) != 0 ||
4650 } else { 4723 (r = sshpkt_put_cstring(ssh, new_data)) != 0 ||
4651 packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); 4724 (r = sshpkt_put_u32(ssh, screen_number)) != 0 ||
4652 } 4725 (r = sshpkt_send(ssh)) != 0 ||
4653 packet_put_cstring(proto); 4726 (r = ssh_packet_write_wait(ssh)) != 0)
4654 packet_put_cstring(new_data); 4727 fatal("%s: send x11-req: %s", __func__, ssh_err(r));
4655 packet_put_int(screen_number);
4656 packet_send();
4657 packet_write_wait();
4658 free(new_data); 4728 free(new_data);
4659} 4729}
4660
4661
4662/* -- agent forwarding */
4663
4664/* Sends a message to the server to request authentication fd forwarding. */
4665
4666void
4667auth_request_forwarding(void)
4668{
4669 packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);
4670 packet_send();
4671 packet_write_wait();
4672}
diff --git a/channels.h b/channels.h
index ce43236d5..126b04345 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.121 2017/02/01 02:59:09 dtucker Exp $ */ 1/* $OpenBSD: channels.h,v 1.130 2017/09/21 19:16:53 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -46,8 +46,6 @@
46#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */ 46#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */
47#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */ 47#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */
48#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */ 48#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */
49#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */
50#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */
51#define SSH_CHANNEL_LARVAL 10 /* larval session */ 49#define SSH_CHANNEL_LARVAL 10 /* larval session */
52#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */ 50#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */
53#define SSH_CHANNEL_CONNECTING 12 51#define SSH_CHANNEL_CONNECTING 12
@@ -59,22 +57,27 @@
59#define SSH_CHANNEL_UNIX_LISTENER 18 /* Listening on a domain socket. */ 57#define SSH_CHANNEL_UNIX_LISTENER 18 /* Listening on a domain socket. */
60#define SSH_CHANNEL_RUNIX_LISTENER 19 /* Listening to a R-style domain socket. */ 58#define SSH_CHANNEL_RUNIX_LISTENER 19 /* Listening to a R-style domain socket. */
61#define SSH_CHANNEL_MUX_PROXY 20 /* proxy channel for mux-slave */ 59#define SSH_CHANNEL_MUX_PROXY 20 /* proxy channel for mux-slave */
62#define SSH_CHANNEL_MAX_TYPE 21 60#define SSH_CHANNEL_RDYNAMIC_OPEN 21 /* reverse SOCKS, parsing request */
61#define SSH_CHANNEL_RDYNAMIC_FINISH 22 /* reverse SOCKS, finishing connect */
62#define SSH_CHANNEL_MAX_TYPE 23
63 63
64#define CHANNEL_CANCEL_PORT_STATIC -1 64#define CHANNEL_CANCEL_PORT_STATIC -1
65 65
66struct ssh;
66struct Channel; 67struct Channel;
67typedef struct Channel Channel; 68typedef struct Channel Channel;
69struct fwd_perm_list;
68 70
69typedef void channel_open_fn(int, int, void *); 71typedef void channel_open_fn(struct ssh *, int, int, void *);
70typedef void channel_callback_fn(int, void *); 72typedef void channel_callback_fn(struct ssh *, int, void *);
71typedef int channel_infilter_fn(struct Channel *, char *, int); 73typedef int channel_infilter_fn(struct ssh *, struct Channel *, char *, int);
72typedef void channel_filter_cleanup_fn(int, void *); 74typedef void channel_filter_cleanup_fn(struct ssh *, int, void *);
73typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *); 75typedef u_char *channel_outfilter_fn(struct ssh *, struct Channel *,
76 u_char **, size_t *);
74 77
75/* Channel success/failure callbacks */ 78/* Channel success/failure callbacks */
76typedef void channel_confirm_cb(int, struct Channel *, void *); 79typedef void channel_confirm_cb(struct ssh *, int, struct Channel *, void *);
77typedef void channel_confirm_abandon_cb(struct Channel *, void *); 80typedef void channel_confirm_abandon_cb(struct ssh *, struct Channel *, void *);
78struct channel_confirm { 81struct channel_confirm {
79 TAILQ_ENTRY(channel_confirm) entry; 82 TAILQ_ENTRY(channel_confirm) entry;
80 channel_confirm_cb *cb; 83 channel_confirm_cb *cb;
@@ -91,12 +94,14 @@ struct channel_connect {
91}; 94};
92 95
93/* Callbacks for mux channels back into client-specific code */ 96/* Callbacks for mux channels back into client-specific code */
94typedef int mux_callback_fn(struct Channel *); 97typedef int mux_callback_fn(struct ssh *, struct Channel *);
95 98
96struct Channel { 99struct Channel {
97 int type; /* channel type/state */ 100 int type; /* channel type/state */
98 int self; /* my own channel identifier */ 101 int self; /* my own channel identifier */
99 int remote_id; /* channel identifier for remote peer */ 102 uint32_t remote_id; /* channel identifier for remote peer */
103 int have_remote_id; /* non-zero if remote_id is valid */
104
100 u_int istate; /* input from channel (state of receive half) */ 105 u_int istate; /* input from channel (state of receive half) */
101 u_int ostate; /* output to channel (state of transmit half) */ 106 u_int ostate; /* output to channel (state of transmit half) */
102 int flags; /* close sent/rcvd */ 107 int flags; /* close sent/rcvd */
@@ -117,11 +122,12 @@ struct Channel {
117 * to a matching pre-select handler. 122 * to a matching pre-select handler.
118 * this way post-select handlers are not 123 * this way post-select handlers are not
119 * accidentally called if a FD gets reused */ 124 * accidentally called if a FD gets reused */
120 Buffer input; /* data read from socket, to be sent over 125 struct sshbuf *input; /* data read from socket, to be sent over
121 * encrypted connection */ 126 * encrypted connection */
122 Buffer output; /* data received over encrypted connection for 127 struct sshbuf *output; /* data received over encrypted connection for
123 * send on socket */ 128 * send on socket */
124 Buffer extended; 129 struct sshbuf *extended;
130
125 char *path; 131 char *path;
126 /* path for unix domain sockets, or host name for forwards */ 132 /* path for unix domain sockets, or host name for forwards */
127 int listening_port; /* port being listened for forwards */ 133 int listening_port; /* port being listened for forwards */
@@ -157,6 +163,7 @@ struct Channel {
157 int datagram; 163 int datagram;
158 164
159 /* non-blocking connect */ 165 /* non-blocking connect */
166 /* XXX make this a pointer so the structure can be opaque */
160 struct channel_connect connect_ctx; 167 struct channel_connect connect_ctx;
161 168
162 /* multiplexing protocol hook, called for each packet received */ 169 /* multiplexing protocol hook, called for each packet received */
@@ -196,128 +203,137 @@ struct Channel {
196#define CHAN_EOF_RCVD 0x08 203#define CHAN_EOF_RCVD 0x08
197#define CHAN_LOCAL 0x10 204#define CHAN_LOCAL 0x10
198 205
199#define CHAN_RBUF 16*1024 206/* Read buffer size */
207#define CHAN_RBUF (16*1024)
208
209/* Hard limit on number of channels */
210#define CHANNELS_MAX_CHANNELS (16*1024)
200 211
201/* check whether 'efd' is still in use */ 212/* check whether 'efd' is still in use */
202#define CHANNEL_EFD_INPUT_ACTIVE(c) \ 213#define CHANNEL_EFD_INPUT_ACTIVE(c) \
203 (compat20 && c->extended_usage == CHAN_EXTENDED_READ && \ 214 (c->extended_usage == CHAN_EXTENDED_READ && \
204 (c->efd != -1 || \ 215 (c->efd != -1 || \
205 buffer_len(&c->extended) > 0)) 216 sshbuf_len(c->extended) > 0))
206#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \ 217#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
207 (compat20 && c->extended_usage == CHAN_EXTENDED_WRITE && \ 218 (c->extended_usage == CHAN_EXTENDED_WRITE && \
208 c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \ 219 c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
209 buffer_len(&c->extended) > 0)) 220 sshbuf_len(c->extended) > 0))
221
222/* Add channel management structures to SSH transport instance */
223void channel_init_channels(struct ssh *ssh);
210 224
211/* channel management */ 225/* channel management */
212 226
213Channel *channel_by_id(int); 227Channel *channel_by_id(struct ssh *, int);
214Channel *channel_by_remote_id(int); 228Channel *channel_by_remote_id(struct ssh *, u_int);
215Channel *channel_lookup(int); 229Channel *channel_lookup(struct ssh *, int);
216Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); 230Channel *channel_new(struct ssh *, char *, int, int, int, int,
217void channel_set_fds(int, int, int, int, int, int, int, u_int); 231 u_int, u_int, int, char *, int);
218void channel_free(Channel *); 232void channel_set_fds(struct ssh *, int, int, int, int, int,
219void channel_free_all(void); 233 int, int, u_int);
220void channel_stop_listening(void); 234void channel_free(struct ssh *, Channel *);
221 235void channel_free_all(struct ssh *);
222void channel_send_open(int); 236void channel_stop_listening(struct ssh *);
223void channel_request_start(int, char *, int); 237
224void channel_register_cleanup(int, channel_callback_fn *, int); 238void channel_send_open(struct ssh *, int);
225void channel_register_open_confirm(int, channel_open_fn *, void *); 239void channel_request_start(struct ssh *, int, char *, int);
226void channel_register_filter(int, channel_infilter_fn *, 240void channel_register_cleanup(struct ssh *, int,
227 channel_outfilter_fn *, channel_filter_cleanup_fn *, void *); 241 channel_callback_fn *, int);
228void channel_register_status_confirm(int, channel_confirm_cb *, 242void channel_register_open_confirm(struct ssh *, int,
229 channel_confirm_abandon_cb *, void *); 243 channel_open_fn *, void *);
230void channel_cancel_cleanup(int); 244void channel_register_filter(struct ssh *, int, channel_infilter_fn *,
231int channel_close_fd(int *); 245 channel_outfilter_fn *, channel_filter_cleanup_fn *, void *);
232void channel_send_window_changes(void); 246void channel_register_status_confirm(struct ssh *, int,
247 channel_confirm_cb *, channel_confirm_abandon_cb *, void *);
248void channel_cancel_cleanup(struct ssh *, int);
249int channel_close_fd(struct ssh *, int *);
250void channel_send_window_changes(struct ssh *);
233 251
234/* mux proxy support */ 252/* mux proxy support */
235 253
236int channel_proxy_downstream(Channel *mc); 254int channel_proxy_downstream(struct ssh *, Channel *mc);
237int channel_proxy_upstream(Channel *, int, u_int32_t, void *); 255int channel_proxy_upstream(Channel *, int, u_int32_t, struct ssh *);
238 256
239/* protocol handler */ 257/* protocol handler */
240 258
241int channel_input_close(int, u_int32_t, void *); 259int channel_input_data(int, u_int32_t, struct ssh *);
242int channel_input_close_confirmation(int, u_int32_t, void *); 260int channel_input_extended_data(int, u_int32_t, struct ssh *);
243int channel_input_data(int, u_int32_t, void *); 261int channel_input_ieof(int, u_int32_t, struct ssh *);
244int channel_input_extended_data(int, u_int32_t, void *); 262int channel_input_oclose(int, u_int32_t, struct ssh *);
245int channel_input_ieof(int, u_int32_t, void *); 263int channel_input_open_confirmation(int, u_int32_t, struct ssh *);
246int channel_input_oclose(int, u_int32_t, void *); 264int channel_input_open_failure(int, u_int32_t, struct ssh *);
247int channel_input_open_confirmation(int, u_int32_t, void *); 265int channel_input_port_open(int, u_int32_t, struct ssh *);
248int channel_input_open_failure(int, u_int32_t, void *); 266int channel_input_window_adjust(int, u_int32_t, struct ssh *);
249int channel_input_port_open(int, u_int32_t, void *); 267int channel_input_status_confirm(int, u_int32_t, struct ssh *);
250int channel_input_window_adjust(int, u_int32_t, void *);
251int channel_input_status_confirm(int, u_int32_t, void *);
252 268
253/* file descriptor handling (read/write) */ 269/* file descriptor handling (read/write) */
254 270
255void channel_prepare_select(fd_set **, fd_set **, int *, u_int*, 271void channel_prepare_select(struct ssh *, fd_set **, fd_set **, int *,
256 time_t*, int); 272 u_int*, time_t*);
257void channel_after_select(fd_set *, fd_set *); 273void channel_after_select(struct ssh *, fd_set *, fd_set *);
258void channel_output_poll(void); 274void channel_output_poll(struct ssh *);
259 275
260int channel_not_very_much_buffered_data(void); 276int channel_not_very_much_buffered_data(struct ssh *);
261void channel_close_all(void); 277void channel_close_all(struct ssh *);
262int channel_still_open(void); 278int channel_still_open(struct ssh *);
263char *channel_open_message(void); 279char *channel_open_message(struct ssh *);
264int channel_find_open(void); 280int channel_find_open(struct ssh *);
265 281
266/* tcp forwarding */ 282/* tcp forwarding */
267struct Forward; 283struct Forward;
268struct ForwardOptions; 284struct ForwardOptions;
269void channel_set_af(int af); 285void channel_set_af(struct ssh *, int af);
270void channel_permit_all_opens(void); 286void channel_permit_all_opens(struct ssh *);
271void channel_add_permitted_opens(char *, int); 287void channel_add_permitted_opens(struct ssh *, char *, int);
272int channel_add_adm_permitted_opens(char *, int); 288int channel_add_adm_permitted_opens(struct ssh *, char *, int);
273void channel_disable_adm_local_opens(void); 289void channel_copy_adm_permitted_opens(struct ssh *,
274void channel_update_permitted_opens(int, int); 290 const struct fwd_perm_list *);
275void channel_clear_permitted_opens(void); 291void channel_disable_adm_local_opens(struct ssh *);
276void channel_clear_adm_permitted_opens(void); 292void channel_update_permitted_opens(struct ssh *, int, int);
277void channel_print_adm_permitted_opens(void); 293void channel_clear_permitted_opens(struct ssh *);
278Channel *channel_connect_to_port(const char *, u_short, char *, char *, int *, 294void channel_clear_adm_permitted_opens(struct ssh *);
279 const char **); 295void channel_print_adm_permitted_opens(struct ssh *);
280Channel *channel_connect_to_path(const char *, char *, char *); 296Channel *channel_connect_to_port(struct ssh *, const char *, u_short,
281Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); 297 char *, char *, int *, const char **);
282Channel *channel_connect_by_listen_address(const char *, u_short, 298Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *);
283 char *, char *); 299Channel *channel_connect_stdio_fwd(struct ssh *, const char*,
284Channel *channel_connect_by_listen_path(const char *, char *, char *); 300 u_short, int, int);
285int channel_request_remote_forwarding(struct Forward *); 301Channel *channel_connect_by_listen_address(struct ssh *, const char *,
286int channel_setup_local_fwd_listener(struct Forward *, struct ForwardOptions *); 302 u_short, char *, char *);
287int channel_request_rforward_cancel(struct Forward *); 303Channel *channel_connect_by_listen_path(struct ssh *, const char *,
288int channel_setup_remote_fwd_listener(struct Forward *, int *, struct ForwardOptions *); 304 char *, char *);
289int channel_cancel_rport_listener(struct Forward *); 305int channel_request_remote_forwarding(struct ssh *, struct Forward *);
290int channel_cancel_lport_listener(struct Forward *, int, struct ForwardOptions *); 306int channel_setup_local_fwd_listener(struct ssh *, struct Forward *,
307 struct ForwardOptions *);
308int channel_request_rforward_cancel(struct ssh *, struct Forward *);
309int channel_setup_remote_fwd_listener(struct ssh *, struct Forward *,
310 int *, struct ForwardOptions *);
311int channel_cancel_rport_listener(struct ssh *, struct Forward *);
312int channel_cancel_lport_listener(struct ssh *, struct Forward *,
313 int, struct ForwardOptions *);
291int permitopen_port(const char *); 314int permitopen_port(const char *);
292 315
293/* x11 forwarding */ 316/* x11 forwarding */
294 317
295void channel_set_x11_refuse_time(u_int); 318void channel_set_x11_refuse_time(struct ssh *, u_int);
296int x11_connect_display(void); 319int x11_connect_display(struct ssh *);
297int x11_create_display_inet(int, int, int, u_int *, int **); 320int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);
298int x11_input_open(int, u_int32_t, void *); 321void x11_request_forwarding_with_spoofing(struct ssh *, int,
299void x11_request_forwarding_with_spoofing(int, const char *, const char *, 322 const char *, const char *, const char *, int);
300 const char *, int);
301int deny_input_open(int, u_int32_t, void *);
302
303/* agent forwarding */
304
305void auth_request_forwarding(void);
306 323
307/* channel close */ 324/* channel close */
308 325
309int chan_is_dead(Channel *, int); 326int chan_is_dead(struct ssh *, Channel *, int);
310void chan_mark_dead(Channel *); 327void chan_mark_dead(struct ssh *, Channel *);
311 328
312/* channel events */ 329/* channel events */
313 330
314void chan_rcvd_oclose(Channel *); 331void chan_rcvd_oclose(struct ssh *, Channel *);
315void chan_rcvd_eow(Channel *); /* SSH2-only */ 332void chan_rcvd_eow(struct ssh *, Channel *);
316void chan_read_failed(Channel *); 333void chan_read_failed(struct ssh *, Channel *);
317void chan_ibuf_empty(Channel *); 334void chan_ibuf_empty(struct ssh *, Channel *);
318 335void chan_rcvd_ieof(struct ssh *, Channel *);
319void chan_rcvd_ieof(Channel *); 336void chan_write_failed(struct ssh *, Channel *);
320void chan_write_failed(Channel *); 337void chan_obuf_empty(struct ssh *, Channel *);
321void chan_obuf_empty(Channel *);
322 338
323#endif 339#endif
diff --git a/cipher-3des1.c b/cipher-3des1.c
deleted file mode 100644
index 9fcc2785a..000000000
--- a/cipher-3des1.c
+++ /dev/null
@@ -1,158 +0,0 @@
1/* $OpenBSD: cipher-3des1.c,v 1.12 2015/01/14 10:24:42 markus Exp $ */
2/*
3 * Copyright (c) 2003 Markus Friedl. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
10 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
12 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
13 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
14 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
18 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19 */
20
21#include "includes.h"
22
23#ifdef WITH_SSH1
24
25#include <sys/types.h>
26#include <string.h>
27#include <openssl/evp.h>
28
29#include "ssherr.h"
30
31/*
32 * This is used by SSH1:
33 *
34 * What kind of triple DES are these 2 routines?
35 *
36 * Why is there a redundant initialization vector?
37 *
38 * If only iv3 was used, then, this would till effect have been
39 * outer-cbc. However, there is also a private iv1 == iv2 which
40 * perhaps makes differential analysis easier. On the other hand, the
41 * private iv1 probably makes the CRC-32 attack ineffective. This is a
42 * result of that there is no longer any known iv1 to use when
43 * choosing the X block.
44 */
45struct ssh1_3des_ctx
46{
47 EVP_CIPHER_CTX k1, k2, k3;
48};
49
50const EVP_CIPHER * evp_ssh1_3des(void);
51int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
52
53static int
54ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
55 int enc)
56{
57 struct ssh1_3des_ctx *c;
58 u_char *k1, *k2, *k3;
59
60 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
61 if ((c = calloc(1, sizeof(*c))) == NULL)
62 return 0;
63 EVP_CIPHER_CTX_set_app_data(ctx, c);
64 }
65 if (key == NULL)
66 return 1;
67 if (enc == -1)
68 enc = ctx->encrypt;
69 k1 = k2 = k3 = (u_char *) key;
70 k2 += 8;
71 if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
72 if (enc)
73 k3 += 16;
74 else
75 k1 += 16;
76 }
77 EVP_CIPHER_CTX_init(&c->k1);
78 EVP_CIPHER_CTX_init(&c->k2);
79 EVP_CIPHER_CTX_init(&c->k3);
80 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
81 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
82 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
83 explicit_bzero(c, sizeof(*c));
84 free(c);
85 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
86 return 0;
87 }
88 return 1;
89}
90
91static int
92ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, size_t len)
93{
94 struct ssh1_3des_ctx *c;
95
96 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
97 return 0;
98 if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
99 EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
100 EVP_Cipher(&c->k3, dest, dest, len) == 0)
101 return 0;
102 return 1;
103}
104
105static int
106ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
107{
108 struct ssh1_3des_ctx *c;
109
110 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
111 EVP_CIPHER_CTX_cleanup(&c->k1);
112 EVP_CIPHER_CTX_cleanup(&c->k2);
113 EVP_CIPHER_CTX_cleanup(&c->k3);
114 explicit_bzero(c, sizeof(*c));
115 free(c);
116 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
117 }
118 return 1;
119}
120
121int
122ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
123{
124 struct ssh1_3des_ctx *c;
125
126 if (len != 24)
127 return SSH_ERR_INVALID_ARGUMENT;
128 if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
129 return SSH_ERR_INTERNAL_ERROR;
130 if (doset) {
131 memcpy(c->k1.iv, iv, 8);
132 memcpy(c->k2.iv, iv + 8, 8);
133 memcpy(c->k3.iv, iv + 16, 8);
134 } else {
135 memcpy(iv, c->k1.iv, 8);
136 memcpy(iv + 8, c->k2.iv, 8);
137 memcpy(iv + 16, c->k3.iv, 8);
138 }
139 return 0;
140}
141
142const EVP_CIPHER *
143evp_ssh1_3des(void)
144{
145 static EVP_CIPHER ssh1_3des;
146
147 memset(&ssh1_3des, 0, sizeof(ssh1_3des));
148 ssh1_3des.nid = NID_undef;
149 ssh1_3des.block_size = 8;
150 ssh1_3des.iv_len = 0;
151 ssh1_3des.key_len = 16;
152 ssh1_3des.init = ssh1_3des_init;
153 ssh1_3des.cleanup = ssh1_3des_cleanup;
154 ssh1_3des.do_cipher = ssh1_3des_cbc;
155 ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
156 return &ssh1_3des;
157}
158#endif /* WITH_SSH1 */
diff --git a/cipher-bf1.c b/cipher-bf1.c
deleted file mode 100644
index c205b077c..000000000
--- a/cipher-bf1.c
+++ /dev/null
@@ -1,106 +0,0 @@
1/* $OpenBSD: cipher-bf1.c,v 1.7 2015/01/14 10:24:42 markus Exp $ */
2/*
3 * Copyright (c) 2003 Markus Friedl. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
10 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
12 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
13 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
14 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
18 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19 */
20
21#include "includes.h"
22
23#ifdef WITH_SSH1
24#if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF)
25
26#include <sys/types.h>
27
28#include <stdarg.h>
29#include <string.h>
30
31#include <openssl/evp.h>
32
33#include "openbsd-compat/openssl-compat.h"
34
35/*
36 * SSH1 uses a variation on Blowfish, all bytes must be swapped before
37 * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
38 */
39
40const EVP_CIPHER * evp_ssh1_bf(void);
41
42static void
43swap_bytes(const u_char *src, u_char *dst, int n)
44{
45 u_char c[4];
46
47 /* Process 4 bytes every lap. */
48 for (n = n / 4; n > 0; n--) {
49 c[3] = *src++;
50 c[2] = *src++;
51 c[1] = *src++;
52 c[0] = *src++;
53
54 *dst++ = c[0];
55 *dst++ = c[1];
56 *dst++ = c[2];
57 *dst++ = c[3];
58 }
59}
60
61#ifdef SSH_OLD_EVP
62static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key,
63 const unsigned char *iv, int enc)
64{
65 if (iv != NULL)
66 memcpy (&(ctx->oiv[0]), iv, 8);
67 memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8);
68 if (key != NULL)
69 BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx),
70 key);
71}
72#endif
73
74static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *,
75 const u_char *, LIBCRYPTO_EVP_INL_TYPE) = NULL;
76
77static int
78bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in,
79 LIBCRYPTO_EVP_INL_TYPE len)
80{
81 int ret;
82
83 swap_bytes(in, out, len);
84 ret = (*orig_bf)(ctx, out, out, len);
85 swap_bytes(out, out, len);
86 return (ret);
87}
88
89const EVP_CIPHER *
90evp_ssh1_bf(void)
91{
92 static EVP_CIPHER ssh1_bf;
93
94 memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
95 orig_bf = ssh1_bf.do_cipher;
96 ssh1_bf.nid = NID_undef;
97#ifdef SSH_OLD_EVP
98 ssh1_bf.init = bf_ssh1_init;
99#endif
100 ssh1_bf.do_cipher = bf_ssh1_cipher;
101 ssh1_bf.key_len = 32;
102 return (&ssh1_bf);
103}
104#endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) */
105
106#endif /* WITH_SSH1 */
diff --git a/cipher.c b/cipher.c
index 2def333b1..c3cd5dcf4 100644
--- a/cipher.c
+++ b/cipher.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41:57 djm Exp $ */ 1/* $OpenBSD: cipher.c,v 1.107 2017/05/07 23:12:57 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -51,11 +51,6 @@
51 51
52#include "openbsd-compat/openssl-compat.h" 52#include "openbsd-compat/openssl-compat.h"
53 53
54#ifdef WITH_SSH1
55extern const EVP_CIPHER *evp_ssh1_bf(void);
56extern const EVP_CIPHER *evp_ssh1_3des(void);
57extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
58#endif
59 54
60struct sshcipher_ctx { 55struct sshcipher_ctx {
61 int plaintext; 56 int plaintext;
@@ -68,17 +63,16 @@ struct sshcipher_ctx {
68 63
69struct sshcipher { 64struct sshcipher {
70 char *name; 65 char *name;
71 int number; /* for ssh1 only */
72 u_int block_size; 66 u_int block_size;
73 u_int key_len; 67 u_int key_len;
74 u_int iv_len; /* defaults to block_size */ 68 u_int iv_len; /* defaults to block_size */
75 u_int auth_len; 69 u_int auth_len;
76 u_int discard_len;
77 u_int flags; 70 u_int flags;
78#define CFLAG_CBC (1<<0) 71#define CFLAG_CBC (1<<0)
79#define CFLAG_CHACHAPOLY (1<<1) 72#define CFLAG_CHACHAPOLY (1<<1)
80#define CFLAG_AESCTR (1<<2) 73#define CFLAG_AESCTR (1<<2)
81#define CFLAG_NONE (1<<3) 74#define CFLAG_NONE (1<<3)
75#define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */
82#ifdef WITH_OPENSSL 76#ifdef WITH_OPENSSL
83 const EVP_CIPHER *(*evptype)(void); 77 const EVP_CIPHER *(*evptype)(void);
84#else 78#else
@@ -87,53 +81,32 @@ struct sshcipher {
87}; 81};
88 82
89static const struct sshcipher ciphers[] = { 83static const struct sshcipher ciphers[] = {
90#ifdef WITH_SSH1
91 { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
92 { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
93# ifndef OPENSSL_NO_BF
94 { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
95# endif /* OPENSSL_NO_BF */
96#endif /* WITH_SSH1 */
97#ifdef WITH_OPENSSL 84#ifdef WITH_OPENSSL
98 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, 85 { "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc },
99 { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, 86 { "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc },
100# ifndef OPENSSL_NO_BF 87 { "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc },
101 { "blowfish-cbc", 88 { "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
102 SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
103# endif /* OPENSSL_NO_BF */
104# ifndef OPENSSL_NO_CAST
105 { "cast128-cbc",
106 SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc },
107# endif /* OPENSSL_NO_CAST */
108# ifndef OPENSSL_NO_RC4
109 { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 },
110 { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 },
111 { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 },
112# endif /* OPENSSL_NO_RC4 */
113 { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc },
114 { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc },
115 { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
116 { "rijndael-cbc@lysator.liu.se", 89 { "rijndael-cbc@lysator.liu.se",
117 SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc }, 90 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
118 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr }, 91 { "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr },
119 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr }, 92 { "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr },
120 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr }, 93 { "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr },
121# ifdef OPENSSL_HAVE_EVPGCM 94# ifdef OPENSSL_HAVE_EVPGCM
122 { "aes128-gcm@openssh.com", 95 { "aes128-gcm@openssh.com",
123 SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, 96 16, 16, 12, 16, 0, EVP_aes_128_gcm },
124 { "aes256-gcm@openssh.com", 97 { "aes256-gcm@openssh.com",
125 SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, 98 16, 32, 12, 16, 0, EVP_aes_256_gcm },
126# endif /* OPENSSL_HAVE_EVPGCM */ 99# endif /* OPENSSL_HAVE_EVPGCM */
127#else /* WITH_OPENSSL */ 100#else
128 { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, 101 { "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL },
129 { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, 102 { "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL },
130 { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL }, 103 { "aes256-ctr", 16, 32, 0, 0, CFLAG_AESCTR, NULL },
131 { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL }, 104#endif
132#endif /* WITH_OPENSSL */
133 { "chacha20-poly1305@openssh.com", 105 { "chacha20-poly1305@openssh.com",
134 SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, 106 8, 64, 0, 16, CFLAG_CHACHAPOLY, NULL },
107 { "none", 8, 0, 0, 0, CFLAG_NONE, NULL },
135 108
136 { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } 109 { NULL, 0, 0, 0, 0, 0, NULL }
137}; 110};
138 111
139/*--*/ 112/*--*/
@@ -147,7 +120,7 @@ cipher_alg_list(char sep, int auth_only)
147 const struct sshcipher *c; 120 const struct sshcipher *c;
148 121
149 for (c = ciphers; c->name != NULL; c++) { 122 for (c = ciphers; c->name != NULL; c++) {
150 if (c->number != SSH_CIPHER_SSH2) 123 if ((c->flags & CFLAG_INTERNAL) != 0)
151 continue; 124 continue;
152 if (auth_only && c->auth_len == 0) 125 if (auth_only && c->auth_len == 0)
153 continue; 126 continue;
@@ -203,12 +176,6 @@ cipher_ivlen(const struct sshcipher *c)
203} 176}
204 177
205u_int 178u_int
206cipher_get_number(const struct sshcipher *c)
207{
208 return (c->number);
209}
210
211u_int
212cipher_is_cbc(const struct sshcipher *c) 179cipher_is_cbc(const struct sshcipher *c)
213{ 180{
214 return (c->flags & CFLAG_CBC) != 0; 181 return (c->flags & CFLAG_CBC) != 0;
@@ -220,24 +187,6 @@ cipher_ctx_is_plaintext(struct sshcipher_ctx *cc)
220 return cc->plaintext; 187 return cc->plaintext;
221} 188}
222 189
223u_int
224cipher_ctx_get_number(struct sshcipher_ctx *cc)
225{
226 return cc->cipher->number;
227}
228
229u_int
230cipher_mask_ssh1(int client)
231{
232 u_int mask = 0;
233 mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
234 mask |= 1 << SSH_CIPHER_BLOWFISH;
235 if (client) {
236 mask |= 1 << SSH_CIPHER_DES;
237 }
238 return mask;
239}
240
241const struct sshcipher * 190const struct sshcipher *
242cipher_by_name(const char *name) 191cipher_by_name(const char *name)
243{ 192{
@@ -248,16 +197,6 @@ cipher_by_name(const char *name)
248 return NULL; 197 return NULL;
249} 198}
250 199
251const struct sshcipher *
252cipher_by_number(int id)
253{
254 const struct sshcipher *c;
255 for (c = ciphers; c->name != NULL; c++)
256 if (c->number == id)
257 return c;
258 return NULL;
259}
260
261#define CIPHER_SEP "," 200#define CIPHER_SEP ","
262int 201int
263ciphers_valid(const char *names) 202ciphers_valid(const char *names)
@@ -273,7 +212,7 @@ ciphers_valid(const char *names)
273 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; 212 for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
274 (p = strsep(&cp, CIPHER_SEP))) { 213 (p = strsep(&cp, CIPHER_SEP))) {
275 c = cipher_by_name(p); 214 c = cipher_by_name(p);
276 if (c == NULL || c->number != SSH_CIPHER_SSH2) { 215 if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) {
277 free(cipher_list); 216 free(cipher_list);
278 return 0; 217 return 0;
279 } 218 }
@@ -282,38 +221,12 @@ ciphers_valid(const char *names)
282 return 1; 221 return 1;
283} 222}
284 223
285/*
286 * Parses the name of the cipher. Returns the number of the corresponding
287 * cipher, or -1 on error.
288 */
289
290int
291cipher_number(const char *name)
292{
293 const struct sshcipher *c;
294 if (name == NULL)
295 return -1;
296 for (c = ciphers; c->name != NULL; c++)
297 if (strcasecmp(c->name, name) == 0)
298 return c->number;
299 return -1;
300}
301
302char *
303cipher_name(int id)
304{
305 const struct sshcipher *c = cipher_by_number(id);
306 return (c==NULL) ? "<unknown>" : c->name;
307}
308
309const char * 224const char *
310cipher_warning_message(const struct sshcipher_ctx *cc) 225cipher_warning_message(const struct sshcipher_ctx *cc)
311{ 226{
312 if (cc == NULL || cc->cipher == NULL) 227 if (cc == NULL || cc->cipher == NULL)
313 return NULL; 228 return NULL;
314 if (cc->cipher->number == SSH_CIPHER_DES) 229 /* XXX repurpose for CBC warning */
315 return "use of DES is strongly discouraged due to "
316 "cryptographic weaknesses";
317 return NULL; 230 return NULL;
318} 231}
319 232
@@ -327,19 +240,13 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
327#ifdef WITH_OPENSSL 240#ifdef WITH_OPENSSL
328 const EVP_CIPHER *type; 241 const EVP_CIPHER *type;
329 int klen; 242 int klen;
330 u_char *junk, *discard;
331#endif 243#endif
332 244
333 *ccp = NULL; 245 *ccp = NULL;
334 if ((cc = calloc(sizeof(*cc), 1)) == NULL) 246 if ((cc = calloc(sizeof(*cc), 1)) == NULL)
335 return SSH_ERR_ALLOC_FAIL; 247 return SSH_ERR_ALLOC_FAIL;
336 248
337 if (cipher->number == SSH_CIPHER_DES) { 249 cc->plaintext = (cipher->flags & CFLAG_NONE) != 0;
338 if (keylen > 8)
339 keylen = 8;
340 }
341
342 cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
343 cc->encrypt = do_encrypt; 250 cc->encrypt = do_encrypt;
344 251
345 if (keylen < cipher->key_len || 252 if (keylen < cipher->key_len ||
@@ -353,6 +260,10 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
353 ret = chachapoly_init(&cc->cp_ctx, key, keylen); 260 ret = chachapoly_init(&cc->cp_ctx, key, keylen);
354 goto out; 261 goto out;
355 } 262 }
263 if ((cc->cipher->flags & CFLAG_NONE) != 0) {
264 ret = 0;
265 goto out;
266 }
356#ifndef WITH_OPENSSL 267#ifndef WITH_OPENSSL
357 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 268 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
358 aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); 269 aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
@@ -360,10 +271,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
360 ret = 0; 271 ret = 0;
361 goto out; 272 goto out;
362 } 273 }
363 if ((cc->cipher->flags & CFLAG_NONE) != 0) {
364 ret = 0;
365 goto out;
366 }
367 ret = SSH_ERR_INVALID_ARGUMENT; 274 ret = SSH_ERR_INVALID_ARGUMENT;
368 goto out; 275 goto out;
369#else /* WITH_OPENSSL */ 276#else /* WITH_OPENSSL */
@@ -394,23 +301,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
394 ret = SSH_ERR_LIBCRYPTO_ERROR; 301 ret = SSH_ERR_LIBCRYPTO_ERROR;
395 goto out; 302 goto out;
396 } 303 }
397
398 if (cipher->discard_len > 0) {
399 if ((junk = malloc(cipher->discard_len)) == NULL ||
400 (discard = malloc(cipher->discard_len)) == NULL) {
401 free(junk);
402 ret = SSH_ERR_ALLOC_FAIL;
403 goto out;
404 }
405 ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len);
406 explicit_bzero(discard, cipher->discard_len);
407 free(junk);
408 free(discard);
409 if (ret != 1) {
410 ret = SSH_ERR_LIBCRYPTO_ERROR;
411 goto out;
412 }
413 }
414 ret = 0; 304 ret = 0;
415#endif /* WITH_OPENSSL */ 305#endif /* WITH_OPENSSL */
416 out: 306 out:
@@ -448,6 +338,10 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
448 return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, 338 return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src,
449 len, aadlen, authlen, cc->encrypt); 339 len, aadlen, authlen, cc->encrypt);
450 } 340 }
341 if ((cc->cipher->flags & CFLAG_NONE) != 0) {
342 memcpy(dest, src, aadlen + len);
343 return 0;
344 }
451#ifndef WITH_OPENSSL 345#ifndef WITH_OPENSSL
452 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { 346 if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
453 if (aadlen) 347 if (aadlen)
@@ -456,10 +350,6 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
456 dest + aadlen, len); 350 dest + aadlen, len);
457 return 0; 351 return 0;
458 } 352 }
459 if ((cc->cipher->flags & CFLAG_NONE) != 0) {
460 memcpy(dest, src, aadlen + len);
461 return 0;
462 }
463 return SSH_ERR_INVALID_ARGUMENT; 353 return SSH_ERR_INVALID_ARGUMENT;
464#else 354#else
465 if (authlen) { 355 if (authlen) {
@@ -536,28 +426,6 @@ cipher_free(struct sshcipher_ctx *cc)
536} 426}
537 427
538/* 428/*
539 * Selects the cipher, and keys if by computing the MD5 checksum of the
540 * passphrase and using the resulting 16 bytes as the key.
541 */
542int
543cipher_set_key_string(struct sshcipher_ctx **ccp,
544 const struct sshcipher *cipher, const char *passphrase, int do_encrypt)
545{
546 u_char digest[16];
547 int r = SSH_ERR_INTERNAL_ERROR;
548
549 if ((r = ssh_digest_memory(SSH_DIGEST_MD5,
550 passphrase, strlen(passphrase),
551 digest, sizeof(digest))) != 0)
552 goto out;
553
554 r = cipher_init(ccp, cipher, digest, 16, NULL, 0, do_encrypt);
555 out:
556 explicit_bzero(digest, sizeof(digest));
557 return r;
558}
559
560/*
561 * Exports an IV from the sshcipher_ctx required to export the key 429 * Exports an IV from the sshcipher_ctx required to export the key
562 * state back from the unprivileged child to the privileged parent 430 * state back from the unprivileged child to the privileged parent
563 * process. 431 * process.
@@ -566,19 +434,16 @@ int
566cipher_get_keyiv_len(const struct sshcipher_ctx *cc) 434cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
567{ 435{
568 const struct sshcipher *c = cc->cipher; 436 const struct sshcipher *c = cc->cipher;
569 int ivlen = 0;
570 437
571 if (c->number == SSH_CIPHER_3DES) 438 if ((c->flags & CFLAG_CHACHAPOLY) != 0)
572 ivlen = 24; 439 return 0;
573 else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) 440 else if ((c->flags & CFLAG_AESCTR) != 0)
574 ivlen = 0; 441 return sizeof(cc->ac_ctx.ctr);
575 else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
576 ivlen = sizeof(cc->ac_ctx.ctr);
577#ifdef WITH_OPENSSL 442#ifdef WITH_OPENSSL
578 else 443 return EVP_CIPHER_CTX_iv_length(cc->evp);
579 ivlen = EVP_CIPHER_CTX_iv_length(cc->evp); 444#else
580#endif /* WITH_OPENSSL */ 445 return 0;
581 return (ivlen); 446#endif
582} 447}
583 448
584int 449int
@@ -603,38 +468,26 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
603 if ((cc->cipher->flags & CFLAG_NONE) != 0) 468 if ((cc->cipher->flags & CFLAG_NONE) != 0)
604 return 0; 469 return 0;
605 470
606 switch (c->number) {
607#ifdef WITH_OPENSSL 471#ifdef WITH_OPENSSL
608 case SSH_CIPHER_SSH2: 472 evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
609 case SSH_CIPHER_DES: 473 if (evplen == 0)
610 case SSH_CIPHER_BLOWFISH: 474 return 0;
611 evplen = EVP_CIPHER_CTX_iv_length(cc->evp); 475 else if (evplen < 0)
612 if (evplen == 0) 476 return SSH_ERR_LIBCRYPTO_ERROR;
613 return 0; 477 if ((u_int)evplen != len)
614 else if (evplen < 0) 478 return SSH_ERR_INVALID_ARGUMENT;
615 return SSH_ERR_LIBCRYPTO_ERROR;
616 if ((u_int)evplen != len)
617 return SSH_ERR_INVALID_ARGUMENT;
618#ifndef OPENSSL_HAVE_EVPCTR 479#ifndef OPENSSL_HAVE_EVPCTR
619 if (c->evptype == evp_aes_128_ctr) 480 if (c->evptype == evp_aes_128_ctr)
620 ssh_aes_ctr_iv(cc->evp, 0, iv, len); 481 ssh_aes_ctr_iv(cc->evp, 0, iv, len);
621 else 482 else
622#endif
623 if (cipher_authlen(c)) {
624 if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
625 len, iv))
626 return SSH_ERR_LIBCRYPTO_ERROR;
627 } else
628 memcpy(iv, cc->evp->iv, len);
629 break;
630#endif 483#endif
631#ifdef WITH_SSH1 484 if (cipher_authlen(c)) {
632 case SSH_CIPHER_3DES: 485 if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
633 return ssh1_3des_iv(cc->evp, 0, iv, 24); 486 len, iv))
487 return SSH_ERR_LIBCRYPTO_ERROR;
488 } else
489 memcpy(iv, cc->evp->iv, len);
634#endif 490#endif
635 default:
636 return SSH_ERR_INVALID_ARGUMENT;
637 }
638 return 0; 491 return 0;
639} 492}
640 493
@@ -651,36 +504,24 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
651 if ((cc->cipher->flags & CFLAG_NONE) != 0) 504 if ((cc->cipher->flags & CFLAG_NONE) != 0)
652 return 0; 505 return 0;
653 506
654 switch (c->number) {
655#ifdef WITH_OPENSSL 507#ifdef WITH_OPENSSL
656 case SSH_CIPHER_SSH2: 508 evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
657 case SSH_CIPHER_DES: 509 if (evplen <= 0)
658 case SSH_CIPHER_BLOWFISH: 510 return SSH_ERR_LIBCRYPTO_ERROR;
659 evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
660 if (evplen <= 0)
661 return SSH_ERR_LIBCRYPTO_ERROR;
662#ifndef OPENSSL_HAVE_EVPCTR 511#ifndef OPENSSL_HAVE_EVPCTR
663 /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */ 512 /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */
664 if (c->evptype == evp_aes_128_ctr) 513 if (c->evptype == evp_aes_128_ctr)
665 ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen); 514 ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen);
666 else 515 else
667#endif
668 if (cipher_authlen(c)) {
669 /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
670 if (!EVP_CIPHER_CTX_ctrl(cc->evp,
671 EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
672 return SSH_ERR_LIBCRYPTO_ERROR;
673 } else
674 memcpy(cc->evp->iv, iv, evplen);
675 break;
676#endif 516#endif
677#ifdef WITH_SSH1 517 if (cipher_authlen(c)) {
678 case SSH_CIPHER_3DES: 518 /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
679 return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24); 519 if (!EVP_CIPHER_CTX_ctrl(cc->evp,
520 EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
521 return SSH_ERR_LIBCRYPTO_ERROR;
522 } else
523 memcpy(cc->evp->iv, iv, evplen);
680#endif 524#endif
681 default:
682 return SSH_ERR_INVALID_ARGUMENT;
683 }
684 return 0; 525 return 0;
685} 526}
686 527
diff --git a/cipher.h b/cipher.h
index f4bca6285..dc7ecf113 100644
--- a/cipher.h
+++ b/cipher.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: cipher.h,v 1.49 2016/08/03 05:41:57 djm Exp $ */ 1/* $OpenBSD: cipher.h,v 1.52 2017/05/07 23:12:57 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -42,34 +42,13 @@
42#include "cipher-chachapoly.h" 42#include "cipher-chachapoly.h"
43#include "cipher-aesctr.h" 43#include "cipher-aesctr.h"
44 44
45/*
46 * Cipher types for SSH-1. New types can be added, but old types should not
47 * be removed for compatibility. The maximum allowed value is 31.
48 */
49#define SSH_CIPHER_SSH2 -3
50#define SSH_CIPHER_INVALID -2 /* No valid cipher selected. */
51#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */
52#define SSH_CIPHER_NONE 0 /* no encryption */
53#define SSH_CIPHER_IDEA 1 /* IDEA CFB */
54#define SSH_CIPHER_DES 2 /* DES CBC */
55#define SSH_CIPHER_3DES 3 /* 3DES CBC */
56#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */
57#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */
58#define SSH_CIPHER_BLOWFISH 6
59#define SSH_CIPHER_RESERVED 7
60#define SSH_CIPHER_MAX 31
61
62#define CIPHER_ENCRYPT 1 45#define CIPHER_ENCRYPT 1
63#define CIPHER_DECRYPT 0 46#define CIPHER_DECRYPT 0
64 47
65struct sshcipher; 48struct sshcipher;
66struct sshcipher_ctx; 49struct sshcipher_ctx;
67 50
68u_int cipher_mask_ssh1(int);
69const struct sshcipher *cipher_by_name(const char *); 51const struct sshcipher *cipher_by_name(const char *);
70const struct sshcipher *cipher_by_number(int);
71int cipher_number(const char *);
72char *cipher_name(int);
73const char *cipher_warning_message(const struct sshcipher_ctx *); 52const char *cipher_warning_message(const struct sshcipher_ctx *);
74int ciphers_valid(const char *); 53int ciphers_valid(const char *);
75char *cipher_alg_list(char, int); 54char *cipher_alg_list(char, int);
@@ -80,8 +59,6 @@ int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *,
80int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int, 59int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int,
81 const u_char *, u_int); 60 const u_char *, u_int);
82void cipher_free(struct sshcipher_ctx *); 61void cipher_free(struct sshcipher_ctx *);
83int cipher_set_key_string(struct sshcipher_ctx **,
84 const struct sshcipher *, const char *, int);
85u_int cipher_blocksize(const struct sshcipher *); 62u_int cipher_blocksize(const struct sshcipher *);
86u_int cipher_keylen(const struct sshcipher *); 63u_int cipher_keylen(const struct sshcipher *);
87u_int cipher_seclen(const struct sshcipher *); 64u_int cipher_seclen(const struct sshcipher *);
@@ -90,13 +67,9 @@ u_int cipher_ivlen(const struct sshcipher *);
90u_int cipher_is_cbc(const struct sshcipher *); 67u_int cipher_is_cbc(const struct sshcipher *);
91 68
92u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); 69u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *);
93u_int cipher_ctx_get_number(struct sshcipher_ctx *);
94 70
95u_int cipher_get_number(const struct sshcipher *);
96int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int); 71int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int);
97int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *); 72int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *);
98int cipher_get_keyiv_len(const struct sshcipher_ctx *); 73int cipher_get_keyiv_len(const struct sshcipher_ctx *);
99int cipher_get_keycontext(const struct sshcipher_ctx *, u_char *);
100void cipher_set_keycontext(struct sshcipher_ctx *, const u_char *);
101 74
102#endif /* CIPHER_H */ 75#endif /* CIPHER_H */
diff --git a/clientloop.c b/clientloop.c
index 064816234..791d336e3 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.291 2017/03/10 05:01:13 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.305 2017/09/19 04:24:22 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -89,7 +89,6 @@
89#include "openbsd-compat/sys-queue.h" 89#include "openbsd-compat/sys-queue.h"
90#include "xmalloc.h" 90#include "xmalloc.h"
91#include "ssh.h" 91#include "ssh.h"
92#include "ssh1.h"
93#include "ssh2.h" 92#include "ssh2.h"
94#include "packet.h" 93#include "packet.h"
95#include "buffer.h" 94#include "buffer.h"
@@ -152,15 +151,9 @@ static time_t control_persist_exit_time = 0;
152 151
153/* Common data for the client loop code. */ 152/* Common data for the client loop code. */
154volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ 153volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
155static int escape_char1; /* Escape character. (proto1 only) */
156static int escape_pending1; /* Last character was an escape (proto1 only) */
157static int last_was_cr; /* Last character was a newline. */ 154static int last_was_cr; /* Last character was a newline. */
158static int exit_status; /* Used to store the command exit status. */ 155static int exit_status; /* Used to store the command exit status. */
159static int stdin_eof; /* EOF has been encountered on stderr. */ 156static Buffer stderr_buffer; /* Used for final exit message. */
160static Buffer stdin_buffer; /* Buffer for stdin data. */
161static Buffer stdout_buffer; /* Buffer for stdout data. */
162static Buffer stderr_buffer; /* Buffer for stderr data. */
163static u_int buffer_high; /* Soft max buffer size. */
164static int connection_in; /* Connection to server (input). */ 157static int connection_in; /* Connection to server (input). */
165static int connection_out; /* Connection to server (output). */ 158static int connection_out; /* Connection to server (output). */
166static int need_rekeying; /* Set to non-zero if rekeying is requested. */ 159static int need_rekeying; /* Set to non-zero if rekeying is requested. */
@@ -184,6 +177,7 @@ struct channel_reply_ctx {
184}; 177};
185 178
186/* Global request success/failure callbacks */ 179/* Global request success/failure callbacks */
180/* XXX move to struct ssh? */
187struct global_confirm { 181struct global_confirm {
188 TAILQ_ENTRY(global_confirm) entry; 182 TAILQ_ENTRY(global_confirm) entry;
189 global_confirm_cb *cb; 183 global_confirm_cb *cb;
@@ -207,15 +201,6 @@ leave_non_blocking(void)
207 } 201 }
208} 202}
209 203
210/* Puts stdin terminal in non-blocking mode. */
211
212static void
213enter_non_blocking(void)
214{
215 in_non_blocking_mode = 1;
216 set_nonblock(fileno(stdin));
217}
218
219/* 204/*
220 * Signal handler for the window change signal (SIGWINCH). This just sets a 205 * Signal handler for the window change signal (SIGWINCH). This just sets a
221 * flag indicating that the window has changed. 206 * flag indicating that the window has changed.
@@ -260,13 +245,13 @@ get_current_time(void)
260 * control master process, or if there is no ControlPersist timeout. 245 * control master process, or if there is no ControlPersist timeout.
261 */ 246 */
262static void 247static void
263set_control_persist_exit_time(void) 248set_control_persist_exit_time(struct ssh *ssh)
264{ 249{
265 if (muxserver_sock == -1 || !options.control_persist 250 if (muxserver_sock == -1 || !options.control_persist
266 || options.control_persist_timeout == 0) { 251 || options.control_persist_timeout == 0) {
267 /* not using a ControlPersist timeout */ 252 /* not using a ControlPersist timeout */
268 control_persist_exit_time = 0; 253 control_persist_exit_time = 0;
269 } else if (channel_still_open()) { 254 } else if (channel_still_open(ssh)) {
270 /* some client connections are still open */ 255 /* some client connections are still open */
271 if (control_persist_exit_time > 0) 256 if (control_persist_exit_time > 0)
272 debug2("%s: cancel scheduled exit", __func__); 257 debug2("%s: cancel scheduled exit", __func__);
@@ -304,8 +289,9 @@ client_x11_display_valid(const char *display)
304#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" 289#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
305#define X11_TIMEOUT_SLACK 60 290#define X11_TIMEOUT_SLACK 60
306int 291int
307client_x11_get_proto(const char *display, const char *xauth_path, 292client_x11_get_proto(struct ssh *ssh, const char *display,
308 u_int trusted, u_int timeout, char **_proto, char **_data) 293 const char *xauth_path, u_int trusted, u_int timeout,
294 char **_proto, char **_data)
309{ 295{
310 char cmd[1024], line[512], xdisplay[512]; 296 char cmd[1024], line[512], xdisplay[512];
311 char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; 297 char xauthfile[PATH_MAX], xauthdir[PATH_MAX];
@@ -389,7 +375,8 @@ client_x11_get_proto(const char *display, const char *xauth_path,
389 x11_refuse_time = UINT_MAX; 375 x11_refuse_time = UINT_MAX;
390 else 376 else
391 x11_refuse_time = now + timeout; 377 x11_refuse_time = now + timeout;
392 channel_set_x11_refuse_time(x11_refuse_time); 378 channel_set_x11_refuse_time(ssh,
379 x11_refuse_time);
393 } 380 }
394 if (system(cmd) == 0) 381 if (system(cmd) == 0)
395 generated = 1; 382 generated = 1;
@@ -455,91 +442,6 @@ client_x11_get_proto(const char *display, const char *xauth_path,
455} 442}
456 443
457/* 444/*
458 * This is called when the interactive is entered. This checks if there is
459 * an EOF coming on stdin. We must check this explicitly, as select() does
460 * not appear to wake up when redirecting from /dev/null.
461 */
462
463static void
464client_check_initial_eof_on_stdin(void)
465{
466 int len;
467 char buf[1];
468
469 /*
470 * If standard input is to be "redirected from /dev/null", we simply
471 * mark that we have seen an EOF and send an EOF message to the
472 * server. Otherwise, we try to read a single character; it appears
473 * that for some files, such /dev/null, select() never wakes up for
474 * read for this descriptor, which means that we never get EOF. This
475 * way we will get the EOF if stdin comes from /dev/null or similar.
476 */
477 if (stdin_null_flag) {
478 /* Fake EOF on stdin. */
479 debug("Sending eof.");
480 stdin_eof = 1;
481 packet_start(SSH_CMSG_EOF);
482 packet_send();
483 } else {
484 enter_non_blocking();
485
486 /* Check for immediate EOF on stdin. */
487 len = read(fileno(stdin), buf, 1);
488 if (len == 0) {
489 /*
490 * EOF. Record that we have seen it and send
491 * EOF to server.
492 */
493 debug("Sending eof.");
494 stdin_eof = 1;
495 packet_start(SSH_CMSG_EOF);
496 packet_send();
497 } else if (len > 0) {
498 /*
499 * Got data. We must store the data in the buffer,
500 * and also process it as an escape character if
501 * appropriate.
502 */
503 if ((u_char) buf[0] == escape_char1)
504 escape_pending1 = 1;
505 else
506 buffer_append(&stdin_buffer, buf, 1);
507 }
508 leave_non_blocking();
509 }
510}
511
512
513/*
514 * Make packets from buffered stdin data, and buffer them for sending to the
515 * connection.
516 */
517
518static void
519client_make_packets_from_stdin_data(void)
520{
521 u_int len;
522
523 /* Send buffered stdin data to the server. */
524 while (buffer_len(&stdin_buffer) > 0 &&
525 packet_not_very_much_data_to_write()) {
526 len = buffer_len(&stdin_buffer);
527 /* Keep the packets at reasonable size. */
528 if (len > packet_get_maxsize())
529 len = packet_get_maxsize();
530 packet_start(SSH_CMSG_STDIN_DATA);
531 packet_put_string(buffer_ptr(&stdin_buffer), len);
532 packet_send();
533 buffer_consume(&stdin_buffer, len);
534 /* If we have a pending EOF, send it now. */
535 if (stdin_eof && buffer_len(&stdin_buffer) == 0) {
536 packet_start(SSH_CMSG_EOF);
537 packet_send();
538 }
539 }
540}
541
542/*
543 * Checks if the client window has changed, and sends a packet about it to 445 * Checks if the client window has changed, and sends a packet about it to
544 * the server if so. The actual change is detected elsewhere (by a software 446 * the server if so. The actual change is detected elsewhere (by a software
545 * interrupt on Unix); this just checks the flag and sends a message if 447 * interrupt on Unix); this just checks the flag and sends a message if
@@ -547,40 +449,27 @@ client_make_packets_from_stdin_data(void)
547 */ 449 */
548 450
549static void 451static void
550client_check_window_change(void) 452client_check_window_change(struct ssh *ssh)
551{ 453{
552 struct winsize ws; 454 if (!received_window_change_signal)
553
554 if (! received_window_change_signal)
555 return; 455 return;
556 /** XXX race */ 456 /** XXX race */
557 received_window_change_signal = 0; 457 received_window_change_signal = 0;
558 458
559 debug2("client_check_window_change: changed"); 459 debug2("%s: changed", __func__);
560 460
561 if (compat20) { 461 channel_send_window_changes(ssh);
562 channel_send_window_changes();
563 } else {
564 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
565 return;
566 packet_start(SSH_CMSG_WINDOW_SIZE);
567 packet_put_int((u_int)ws.ws_row);
568 packet_put_int((u_int)ws.ws_col);
569 packet_put_int((u_int)ws.ws_xpixel);
570 packet_put_int((u_int)ws.ws_ypixel);
571 packet_send();
572 }
573} 462}
574 463
575static int 464static int
576client_global_request_reply(int type, u_int32_t seq, void *ctxt) 465client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh)
577{ 466{
578 struct global_confirm *gc; 467 struct global_confirm *gc;
579 468
580 if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) 469 if ((gc = TAILQ_FIRST(&global_confirms)) == NULL)
581 return 0; 470 return 0;
582 if (gc->cb != NULL) 471 if (gc->cb != NULL)
583 gc->cb(type, seq, gc->ctx); 472 gc->cb(ssh, type, seq, gc->ctx);
584 if (--gc->ref_count <= 0) { 473 if (--gc->ref_count <= 0) {
585 TAILQ_REMOVE(&global_confirms, gc, entry); 474 TAILQ_REMOVE(&global_confirms, gc, entry);
586 explicit_bzero(gc, sizeof(*gc)); 475 explicit_bzero(gc, sizeof(*gc));
@@ -611,7 +500,8 @@ server_alive_check(void)
611 * one of the file descriptors). 500 * one of the file descriptors).
612 */ 501 */
613static void 502static void
614client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, 503client_wait_until_can_do_something(struct ssh *ssh,
504 fd_set **readsetp, fd_set **writesetp,
615 int *maxfdp, u_int *nallocp, int rekeying) 505 int *maxfdp, u_int *nallocp, int rekeying)
616{ 506{
617 struct timeval tv, *tvp; 507 struct timeval tv, *tvp;
@@ -620,40 +510,20 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
620 int ret; 510 int ret;
621 511
622 /* Add any selections by the channel mechanism. */ 512 /* Add any selections by the channel mechanism. */
623 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 513 channel_prepare_select(active_state, readsetp, writesetp, maxfdp,
624 &minwait_secs, rekeying); 514 nallocp, &minwait_secs);
625 515
626 if (!compat20) { 516 /* channel_prepare_select could have closed the last channel */
627 /* Read from the connection, unless our buffers are full. */ 517 if (session_closed && !channel_still_open(ssh) &&
628 if (buffer_len(&stdout_buffer) < buffer_high && 518 !packet_have_data_to_write()) {
629 buffer_len(&stderr_buffer) < buffer_high && 519 /* clear mask since we did not call select() */
630 channel_not_very_much_buffered_data()) 520 memset(*readsetp, 0, *nallocp);
631 FD_SET(connection_in, *readsetp); 521 memset(*writesetp, 0, *nallocp);
632 /* 522 return;
633 * Read from stdin, unless we have seen EOF or have very much
634 * buffered data to send to the server.
635 */
636 if (!stdin_eof && packet_not_very_much_data_to_write())
637 FD_SET(fileno(stdin), *readsetp);
638
639 /* Select stdout/stderr if have data in buffer. */
640 if (buffer_len(&stdout_buffer) > 0)
641 FD_SET(fileno(stdout), *writesetp);
642 if (buffer_len(&stderr_buffer) > 0)
643 FD_SET(fileno(stderr), *writesetp);
644 } else {
645 /* channel_prepare_select could have closed the last channel */
646 if (session_closed && !channel_still_open() &&
647 !packet_have_data_to_write()) {
648 /* clear mask since we did not call select() */
649 memset(*readsetp, 0, *nallocp);
650 memset(*writesetp, 0, *nallocp);
651 return;
652 } else {
653 FD_SET(connection_in, *readsetp);
654 }
655 } 523 }
656 524
525 FD_SET(connection_in, *readsetp);
526
657 /* Select server connection if have data to write to the server. */ 527 /* Select server connection if have data to write to the server. */
658 if (packet_have_data_to_write()) 528 if (packet_have_data_to_write())
659 FD_SET(connection_out, *writesetp); 529 FD_SET(connection_out, *writesetp);
@@ -665,13 +535,13 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
665 */ 535 */
666 536
667 timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */ 537 timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
668 if (options.server_alive_interval > 0 && compat20) { 538 if (options.server_alive_interval > 0) {
669 timeout_secs = options.server_alive_interval; 539 timeout_secs = options.server_alive_interval;
670 server_alive_time = now + options.server_alive_interval; 540 server_alive_time = now + options.server_alive_interval;
671 } 541 }
672 if (options.rekey_interval > 0 && compat20 && !rekeying) 542 if (options.rekey_interval > 0 && !rekeying)
673 timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout()); 543 timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout());
674 set_control_persist_exit_time(); 544 set_control_persist_exit_time(ssh);
675 if (control_persist_exit_time > 0) { 545 if (control_persist_exit_time > 0) {
676 timeout_secs = MINIMUM(timeout_secs, 546 timeout_secs = MINIMUM(timeout_secs,
677 control_persist_exit_time - now); 547 control_persist_exit_time - now);
@@ -730,13 +600,9 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
730 600
731 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 601 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
732 602
733 /* 603 sshbuf_reset(bin);
734 * Free (and clear) the buffer to reduce the amount of data that gets 604 sshbuf_reset(bout);
735 * written to swap. 605 sshbuf_reset(berr);
736 */
737 buffer_free(bin);
738 buffer_free(bout);
739 buffer_free(berr);
740 606
741 /* Send the suspend signal to the program itself. */ 607 /* Send the suspend signal to the program itself. */
742 kill(getpid(), SIGTSTP); 608 kill(getpid(), SIGTSTP);
@@ -744,11 +610,6 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
744 /* Reset window sizes in case they have changed */ 610 /* Reset window sizes in case they have changed */
745 received_window_change_signal = 1; 611 received_window_change_signal = 1;
746 612
747 /* OK, we have been continued by the user. Reinitialize buffers. */
748 buffer_init(bin);
749 buffer_init(bout);
750 buffer_init(berr);
751
752 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 613 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
753} 614}
754 615
@@ -802,7 +663,7 @@ client_process_net_input(fd_set *readset)
802} 663}
803 664
804static void 665static void
805client_status_confirm(int type, Channel *c, void *ctx) 666client_status_confirm(struct ssh *ssh, int type, Channel *c, void *ctx)
806{ 667{
807 struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; 668 struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx;
808 char errmsg[256]; 669 char errmsg[256];
@@ -841,8 +702,7 @@ client_status_confirm(int type, Channel *c, void *ctx)
841 * their stderr. 702 * their stderr.
842 */ 703 */
843 if (tochan) { 704 if (tochan) {
844 buffer_append(&c->extended, errmsg, 705 buffer_append(c->extended, errmsg, strlen(errmsg));
845 strlen(errmsg));
846 } else 706 } else
847 error("%s", errmsg); 707 error("%s", errmsg);
848 if (cr->action == CONFIRM_TTY) { 708 if (cr->action == CONFIRM_TTY) {
@@ -853,23 +713,23 @@ client_status_confirm(int type, Channel *c, void *ctx)
853 if (c->self == session_ident) 713 if (c->self == session_ident)
854 leave_raw_mode(0); 714 leave_raw_mode(0);
855 else 715 else
856 mux_tty_alloc_failed(c); 716 mux_tty_alloc_failed(ssh, c);
857 } else if (cr->action == CONFIRM_CLOSE) { 717 } else if (cr->action == CONFIRM_CLOSE) {
858 chan_read_failed(c); 718 chan_read_failed(ssh, c);
859 chan_write_failed(c); 719 chan_write_failed(ssh, c);
860 } 720 }
861 } 721 }
862 free(cr); 722 free(cr);
863} 723}
864 724
865static void 725static void
866client_abandon_status_confirm(Channel *c, void *ctx) 726client_abandon_status_confirm(struct ssh *ssh, Channel *c, void *ctx)
867{ 727{
868 free(ctx); 728 free(ctx);
869} 729}
870 730
871void 731void
872client_expect_confirm(int id, const char *request, 732client_expect_confirm(struct ssh *ssh, int id, const char *request,
873 enum confirm_action action) 733 enum confirm_action action)
874{ 734{
875 struct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr)); 735 struct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr));
@@ -877,7 +737,7 @@ client_expect_confirm(int id, const char *request,
877 cr->request_type = request; 737 cr->request_type = request;
878 cr->action = action; 738 cr->action = action;
879 739
880 channel_register_status_confirm(id, client_status_confirm, 740 channel_register_status_confirm(ssh, id, client_status_confirm,
881 client_abandon_status_confirm, cr); 741 client_abandon_status_confirm, cr);
882} 742}
883 743
@@ -903,7 +763,7 @@ client_register_global_confirm(global_confirm_cb *cb, void *ctx)
903} 763}
904 764
905static void 765static void
906process_cmdline(void) 766process_cmdline(struct ssh *ssh)
907{ 767{
908 void (*handler)(int); 768 void (*handler)(int);
909 char *s, *cmd; 769 char *s, *cmd;
@@ -966,11 +826,6 @@ process_cmdline(void)
966 goto out; 826 goto out;
967 } 827 }
968 828
969 if (delete && !compat20) {
970 logit("Not supported for SSH protocol version 1.");
971 goto out;
972 }
973
974 while (isspace((u_char)*++s)) 829 while (isspace((u_char)*++s))
975 ; 830 ;
976 831
@@ -982,12 +837,12 @@ process_cmdline(void)
982 goto out; 837 goto out;
983 } 838 }
984 if (remote) 839 if (remote)
985 ok = channel_request_rforward_cancel(&fwd) == 0; 840 ok = channel_request_rforward_cancel(ssh, &fwd) == 0;
986 else if (dynamic) 841 else if (dynamic)
987 ok = channel_cancel_lport_listener(&fwd, 842 ok = channel_cancel_lport_listener(ssh, &fwd,
988 0, &options.fwd_opts) > 0; 843 0, &options.fwd_opts) > 0;
989 else 844 else
990 ok = channel_cancel_lport_listener(&fwd, 845 ok = channel_cancel_lport_listener(ssh, &fwd,
991 CHANNEL_CANCEL_PORT_STATIC, 846 CHANNEL_CANCEL_PORT_STATIC,
992 &options.fwd_opts) > 0; 847 &options.fwd_opts) > 0;
993 if (!ok) { 848 if (!ok) {
@@ -1001,13 +856,13 @@ process_cmdline(void)
1001 goto out; 856 goto out;
1002 } 857 }
1003 if (local || dynamic) { 858 if (local || dynamic) {
1004 if (!channel_setup_local_fwd_listener(&fwd, 859 if (!channel_setup_local_fwd_listener(ssh, &fwd,
1005 &options.fwd_opts)) { 860 &options.fwd_opts)) {
1006 logit("Port forwarding failed."); 861 logit("Port forwarding failed.");
1007 goto out; 862 goto out;
1008 } 863 }
1009 } else { 864 } else {
1010 if (channel_request_remote_forwarding(&fwd) < 0) { 865 if (channel_request_remote_forwarding(ssh, &fwd) < 0) {
1011 logit("Port forwarding failed."); 866 logit("Port forwarding failed.");
1012 goto out; 867 goto out;
1013 } 868 }
@@ -1027,10 +882,9 @@ out:
1027 882
1028/* reasons to suppress output of an escape command in help output */ 883/* reasons to suppress output of an escape command in help output */
1029#define SUPPRESS_NEVER 0 /* never suppress, always show */ 884#define SUPPRESS_NEVER 0 /* never suppress, always show */
1030#define SUPPRESS_PROTO1 1 /* don't show in protocol 1 sessions */ 885#define SUPPRESS_MUXCLIENT 1 /* don't show in mux client sessions */
1031#define SUPPRESS_MUXCLIENT 2 /* don't show in mux client sessions */ 886#define SUPPRESS_MUXMASTER 2 /* don't show in mux master sessions */
1032#define SUPPRESS_MUXMASTER 4 /* don't show in mux master sessions */ 887#define SUPPRESS_SYSLOG 4 /* don't show when logging to syslog */
1033#define SUPPRESS_SYSLOG 8 /* don't show when logging to syslog */
1034struct escape_help_text { 888struct escape_help_text {
1035 const char *cmd; 889 const char *cmd;
1036 const char *text; 890 const char *text;
@@ -1040,9 +894,9 @@ static struct escape_help_text esc_txt[] = {
1040 {".", "terminate session", SUPPRESS_MUXMASTER}, 894 {".", "terminate session", SUPPRESS_MUXMASTER},
1041 {".", "terminate connection (and any multiplexed sessions)", 895 {".", "terminate connection (and any multiplexed sessions)",
1042 SUPPRESS_MUXCLIENT}, 896 SUPPRESS_MUXCLIENT},
1043 {"B", "send a BREAK to the remote system", SUPPRESS_PROTO1}, 897 {"B", "send a BREAK to the remote system", SUPPRESS_NEVER},
1044 {"C", "open a command line", SUPPRESS_MUXCLIENT}, 898 {"C", "open a command line", SUPPRESS_MUXCLIENT},
1045 {"R", "request rekey", SUPPRESS_PROTO1}, 899 {"R", "request rekey", SUPPRESS_NEVER},
1046 {"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT}, 900 {"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT},
1047 {"^Z", "suspend ssh", SUPPRESS_MUXCLIENT}, 901 {"^Z", "suspend ssh", SUPPRESS_MUXCLIENT},
1048 {"#", "list forwarded connections", SUPPRESS_NEVER}, 902 {"#", "list forwarded connections", SUPPRESS_NEVER},
@@ -1052,8 +906,7 @@ static struct escape_help_text esc_txt[] = {
1052}; 906};
1053 907
1054static void 908static void
1055print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client, 909print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr)
1056 int using_stderr)
1057{ 910{
1058 unsigned int i, suppress_flags; 911 unsigned int i, suppress_flags;
1059 char string[1024]; 912 char string[1024];
@@ -1062,7 +915,7 @@ print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
1062 "Supported escape sequences:\r\n", escape_char); 915 "Supported escape sequences:\r\n", escape_char);
1063 buffer_append(b, string, strlen(string)); 916 buffer_append(b, string, strlen(string));
1064 917
1065 suppress_flags = (protocol2 ? 0 : SUPPRESS_PROTO1) | 918 suppress_flags =
1066 (mux_client ? SUPPRESS_MUXCLIENT : 0) | 919 (mux_client ? SUPPRESS_MUXCLIENT : 0) |
1067 (mux_client ? 0 : SUPPRESS_MUXMASTER) | 920 (mux_client ? 0 : SUPPRESS_MUXMASTER) |
1068 (using_stderr ? 0 : SUPPRESS_SYSLOG); 921 (using_stderr ? 0 : SUPPRESS_SYSLOG);
@@ -1083,10 +936,11 @@ print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
1083} 936}
1084 937
1085/* 938/*
1086 * Process the characters one by one, call with c==NULL for proto1 case. 939 * Process the characters one by one.
1087 */ 940 */
1088static int 941static int
1089process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, 942process_escapes(struct ssh *ssh, Channel *c,
943 Buffer *bin, Buffer *bout, Buffer *berr,
1090 char *buf, int len) 944 char *buf, int len)
1091{ 945{
1092 char string[1024]; 946 char string[1024];
@@ -1095,19 +949,11 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1095 u_int i; 949 u_int i;
1096 u_char ch; 950 u_char ch;
1097 char *s; 951 char *s;
1098 int *escape_pendingp, escape_char; 952 struct escape_filter_ctx *efc = c->filter_ctx == NULL ?
1099 struct escape_filter_ctx *efc; 953 NULL : (struct escape_filter_ctx *)c->filter_ctx;
1100 954
1101 if (c == NULL) { 955 if (c->filter_ctx == NULL)
1102 escape_pendingp = &escape_pending1; 956 return 0;
1103 escape_char = escape_char1;
1104 } else {
1105 if (c->filter_ctx == NULL)
1106 return 0;
1107 efc = (struct escape_filter_ctx *)c->filter_ctx;
1108 escape_pendingp = &efc->escape_pending;
1109 escape_char = efc->escape_char;
1110 }
1111 957
1112 if (len <= 0) 958 if (len <= 0)
1113 return (0); 959 return (0);
@@ -1116,27 +962,29 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1116 /* Get one character at a time. */ 962 /* Get one character at a time. */
1117 ch = buf[i]; 963 ch = buf[i];
1118 964
1119 if (*escape_pendingp) { 965 if (efc->escape_pending) {
1120 /* We have previously seen an escape character. */ 966 /* We have previously seen an escape character. */
1121 /* Clear the flag now. */ 967 /* Clear the flag now. */
1122 *escape_pendingp = 0; 968 efc->escape_pending = 0;
1123 969
1124 /* Process the escaped character. */ 970 /* Process the escaped character. */
1125 switch (ch) { 971 switch (ch) {
1126 case '.': 972 case '.':
1127 /* Terminate the connection. */ 973 /* Terminate the connection. */
1128 snprintf(string, sizeof string, "%c.\r\n", 974 snprintf(string, sizeof string, "%c.\r\n",
1129 escape_char); 975 efc->escape_char);
1130 buffer_append(berr, string, strlen(string)); 976 buffer_append(berr, string, strlen(string));
1131 977
1132 if (c && c->ctl_chan != -1) { 978 if (c && c->ctl_chan != -1) {
1133 chan_read_failed(c); 979 chan_read_failed(ssh, c);
1134 chan_write_failed(c); 980 chan_write_failed(ssh, c);
1135 if (c->detach_user) 981 if (c->detach_user) {
1136 c->detach_user(c->self, NULL); 982 c->detach_user(ssh,
983 c->self, NULL);
984 }
1137 c->type = SSH_CHANNEL_ABANDONED; 985 c->type = SSH_CHANNEL_ABANDONED;
1138 buffer_clear(&c->input); 986 buffer_clear(c->input);
1139 chan_ibuf_empty(c); 987 chan_ibuf_empty(ssh, c);
1140 return 0; 988 return 0;
1141 } else 989 } else
1142 quit_pending = 1; 990 quit_pending = 1;
@@ -1154,14 +1002,14 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1154 snprintf(string, sizeof string, 1002 snprintf(string, sizeof string,
1155 "%c%s escape not available to " 1003 "%c%s escape not available to "
1156 "multiplexed sessions\r\n", 1004 "multiplexed sessions\r\n",
1157 escape_char, b); 1005 efc->escape_char, b);
1158 buffer_append(berr, string, 1006 buffer_append(berr, string,
1159 strlen(string)); 1007 strlen(string));
1160 continue; 1008 continue;
1161 } 1009 }
1162 /* Suspend the program. Inform the user */ 1010 /* Suspend the program. Inform the user */
1163 snprintf(string, sizeof string, 1011 snprintf(string, sizeof string,
1164 "%c^Z [suspend ssh]\r\n", escape_char); 1012 "%c^Z [suspend ssh]\r\n", efc->escape_char);
1165 buffer_append(berr, string, strlen(string)); 1013 buffer_append(berr, string, strlen(string));
1166 1014
1167 /* Restore terminal modes and suspend. */ 1015 /* Restore terminal modes and suspend. */
@@ -1171,26 +1019,20 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1171 continue; 1019 continue;
1172 1020
1173 case 'B': 1021 case 'B':
1174 if (compat20) { 1022 snprintf(string, sizeof string,
1175 snprintf(string, sizeof string, 1023 "%cB\r\n", efc->escape_char);
1176 "%cB\r\n", escape_char); 1024 buffer_append(berr, string, strlen(string));
1177 buffer_append(berr, string, 1025 channel_request_start(ssh, c->self, "break", 0);
1178 strlen(string)); 1026 packet_put_int(1000);
1179 channel_request_start(c->self, 1027 packet_send();
1180 "break", 0);
1181 packet_put_int(1000);
1182 packet_send();
1183 }
1184 continue; 1028 continue;
1185 1029
1186 case 'R': 1030 case 'R':
1187 if (compat20) { 1031 if (datafellows & SSH_BUG_NOREKEY)
1188 if (datafellows & SSH_BUG_NOREKEY) 1032 logit("Server does not "
1189 logit("Server does not " 1033 "support re-keying");
1190 "support re-keying"); 1034 else
1191 else 1035 need_rekeying = 1;
1192 need_rekeying = 1;
1193 }
1194 continue; 1036 continue;
1195 1037
1196 case 'V': 1038 case 'V':
@@ -1201,7 +1043,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1201 if (!log_is_on_stderr()) { 1043 if (!log_is_on_stderr()) {
1202 snprintf(string, sizeof string, 1044 snprintf(string, sizeof string,
1203 "%c%c [Logging to syslog]\r\n", 1045 "%c%c [Logging to syslog]\r\n",
1204 escape_char, ch); 1046 efc->escape_char, ch);
1205 buffer_append(berr, string, 1047 buffer_append(berr, string,
1206 strlen(string)); 1048 strlen(string));
1207 continue; 1049 continue;
@@ -1213,7 +1055,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1213 SYSLOG_LEVEL_DEBUG3) 1055 SYSLOG_LEVEL_DEBUG3)
1214 log_change_level(++options.log_level); 1056 log_change_level(++options.log_level);
1215 snprintf(string, sizeof string, 1057 snprintf(string, sizeof string,
1216 "%c%c [LogLevel %s]\r\n", escape_char, ch, 1058 "%c%c [LogLevel %s]\r\n",
1059 efc->escape_char, ch,
1217 log_level_name(options.log_level)); 1060 log_level_name(options.log_level));
1218 buffer_append(berr, string, strlen(string)); 1061 buffer_append(berr, string, strlen(string));
1219 continue; 1062 continue;
@@ -1231,10 +1074,10 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1231 options.request_tty == REQUEST_TTY_FORCE); 1074 options.request_tty == REQUEST_TTY_FORCE);
1232 1075
1233 /* Stop listening for new connections. */ 1076 /* Stop listening for new connections. */
1234 channel_stop_listening(); 1077 channel_stop_listening(ssh);
1235 1078
1236 snprintf(string, sizeof string, 1079 snprintf(string, sizeof string,
1237 "%c& [backgrounded]\n", escape_char); 1080 "%c& [backgrounded]\n", efc->escape_char);
1238 buffer_append(berr, string, strlen(string)); 1081 buffer_append(berr, string, strlen(string));
1239 1082
1240 /* Fork into background. */ 1083 /* Fork into background. */
@@ -1248,39 +1091,20 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1248 exit(0); 1091 exit(0);
1249 } 1092 }
1250 /* The child continues serving connections. */ 1093 /* The child continues serving connections. */
1251 if (compat20) { 1094 buffer_append(bin, "\004", 1);
1252 buffer_append(bin, "\004", 1); 1095 /* fake EOF on stdin */
1253 /* fake EOF on stdin */ 1096 return -1;
1254 return -1;
1255 } else if (!stdin_eof) {
1256 /*
1257 * Sending SSH_CMSG_EOF alone does not
1258 * always appear to be enough. So we
1259 * try to send an EOF character first.
1260 */
1261 packet_start(SSH_CMSG_STDIN_DATA);
1262 packet_put_string("\004", 1);
1263 packet_send();
1264 /* Close stdin. */
1265 stdin_eof = 1;
1266 if (buffer_len(bin) == 0) {
1267 packet_start(SSH_CMSG_EOF);
1268 packet_send();
1269 }
1270 }
1271 continue;
1272
1273 case '?': 1097 case '?':
1274 print_escape_help(berr, escape_char, compat20, 1098 print_escape_help(berr, efc->escape_char,
1275 (c && c->ctl_chan != -1), 1099 (c && c->ctl_chan != -1),
1276 log_is_on_stderr()); 1100 log_is_on_stderr());
1277 continue; 1101 continue;
1278 1102
1279 case '#': 1103 case '#':
1280 snprintf(string, sizeof string, "%c#\r\n", 1104 snprintf(string, sizeof string, "%c#\r\n",
1281 escape_char); 1105 efc->escape_char);
1282 buffer_append(berr, string, strlen(string)); 1106 buffer_append(berr, string, strlen(string));
1283 s = channel_open_message(); 1107 s = channel_open_message(ssh);
1284 buffer_append(berr, s, strlen(s)); 1108 buffer_append(berr, s, strlen(s));
1285 free(s); 1109 free(s);
1286 continue; 1110 continue;
@@ -1288,12 +1112,12 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1288 case 'C': 1112 case 'C':
1289 if (c && c->ctl_chan != -1) 1113 if (c && c->ctl_chan != -1)
1290 goto noescape; 1114 goto noescape;
1291 process_cmdline(); 1115 process_cmdline(ssh);
1292 continue; 1116 continue;
1293 1117
1294 default: 1118 default:
1295 if (ch != escape_char) { 1119 if (ch != efc->escape_char) {
1296 buffer_put_char(bin, escape_char); 1120 buffer_put_char(bin, efc->escape_char);
1297 bytes++; 1121 bytes++;
1298 } 1122 }
1299 /* Escaped characters fall through here */ 1123 /* Escaped characters fall through here */
@@ -1304,12 +1128,12 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1304 * The previous character was not an escape char. 1128 * The previous character was not an escape char.
1305 * Check if this is an escape. 1129 * Check if this is an escape.
1306 */ 1130 */
1307 if (last_was_cr && ch == escape_char) { 1131 if (last_was_cr && ch == efc->escape_char) {
1308 /* 1132 /*
1309 * It is. Set the flag and continue to 1133 * It is. Set the flag and continue to
1310 * next character. 1134 * next character.
1311 */ 1135 */
1312 *escape_pendingp = 1; 1136 efc->escape_pending = 1;
1313 continue; 1137 continue;
1314 } 1138 }
1315 } 1139 }
@@ -1325,115 +1149,6 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
1325 return bytes; 1149 return bytes;
1326} 1150}
1327 1151
1328static void
1329client_process_input(fd_set *readset)
1330{
1331 int len;
1332 char buf[SSH_IOBUFSZ];
1333
1334 /* Read input from stdin. */
1335 if (FD_ISSET(fileno(stdin), readset)) {
1336 /* Read as much as possible. */
1337 len = read(fileno(stdin), buf, sizeof(buf));
1338 if (len < 0 &&
1339 (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
1340 return; /* we'll try again later */
1341 if (len <= 0) {
1342 /*
1343 * Received EOF or error. They are treated
1344 * similarly, except that an error message is printed
1345 * if it was an error condition.
1346 */
1347 if (len < 0) {
1348 snprintf(buf, sizeof buf, "read: %.100s\r\n",
1349 strerror(errno));
1350 buffer_append(&stderr_buffer, buf, strlen(buf));
1351 }
1352 /* Mark that we have seen EOF. */
1353 stdin_eof = 1;
1354 /*
1355 * Send an EOF message to the server unless there is
1356 * data in the buffer. If there is data in the
1357 * buffer, no message will be sent now. Code
1358 * elsewhere will send the EOF when the buffer
1359 * becomes empty if stdin_eof is set.
1360 */
1361 if (buffer_len(&stdin_buffer) == 0) {
1362 packet_start(SSH_CMSG_EOF);
1363 packet_send();
1364 }
1365 } else if (escape_char1 == SSH_ESCAPECHAR_NONE) {
1366 /*
1367 * Normal successful read, and no escape character.
1368 * Just append the data to buffer.
1369 */
1370 buffer_append(&stdin_buffer, buf, len);
1371 } else {
1372 /*
1373 * Normal, successful read. But we have an escape
1374 * character and have to process the characters one
1375 * by one.
1376 */
1377 if (process_escapes(NULL, &stdin_buffer,
1378 &stdout_buffer, &stderr_buffer, buf, len) == -1)
1379 return;
1380 }
1381 }
1382}
1383
1384static void
1385client_process_output(fd_set *writeset)
1386{
1387 int len;
1388 char buf[100];
1389
1390 /* Write buffered output to stdout. */
1391 if (FD_ISSET(fileno(stdout), writeset)) {
1392 /* Write as much data as possible. */
1393 len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
1394 buffer_len(&stdout_buffer));
1395 if (len <= 0) {
1396 if (errno == EINTR || errno == EAGAIN ||
1397 errno == EWOULDBLOCK)
1398 len = 0;
1399 else {
1400 /*
1401 * An error or EOF was encountered. Put an
1402 * error message to stderr buffer.
1403 */
1404 snprintf(buf, sizeof buf,
1405 "write stdout: %.50s\r\n", strerror(errno));
1406 buffer_append(&stderr_buffer, buf, strlen(buf));
1407 quit_pending = 1;
1408 return;
1409 }
1410 }
1411 /* Consume printed data from the buffer. */
1412 buffer_consume(&stdout_buffer, len);
1413 }
1414 /* Write buffered output to stderr. */
1415 if (FD_ISSET(fileno(stderr), writeset)) {
1416 /* Write as much data as possible. */
1417 len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
1418 buffer_len(&stderr_buffer));
1419 if (len <= 0) {
1420 if (errno == EINTR || errno == EAGAIN ||
1421 errno == EWOULDBLOCK)
1422 len = 0;
1423 else {
1424 /*
1425 * EOF or error, but can't even print
1426 * error message.
1427 */
1428 quit_pending = 1;
1429 return;
1430 }
1431 }
1432 /* Consume printed characters from the buffer. */
1433 buffer_consume(&stderr_buffer, len);
1434 }
1435}
1436
1437/* 1152/*
1438 * Get packets from the connection input buffer, and process them as long as 1153 * Get packets from the connection input buffer, and process them as long as
1439 * there are packets available. 1154 * there are packets available.
@@ -1449,7 +1164,7 @@ client_process_output(fd_set *writeset)
1449static void 1164static void
1450client_process_buffered_input_packets(void) 1165client_process_buffered_input_packets(void)
1451{ 1166{
1452 dispatch_run(DISPATCH_NONBLOCK, &quit_pending, active_state); 1167 ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, &quit_pending);
1453} 1168}
1454 1169
1455/* scan buf[] for '~' before sending data to the peer */ 1170/* scan buf[] for '~' before sending data to the peer */
@@ -1468,25 +1183,25 @@ client_new_escape_filter_ctx(int escape_char)
1468 1183
1469/* Free the escape filter context on channel free */ 1184/* Free the escape filter context on channel free */
1470void 1185void
1471client_filter_cleanup(int cid, void *ctx) 1186client_filter_cleanup(struct ssh *ssh, int cid, void *ctx)
1472{ 1187{
1473 free(ctx); 1188 free(ctx);
1474} 1189}
1475 1190
1476int 1191int
1477client_simple_escape_filter(Channel *c, char *buf, int len) 1192client_simple_escape_filter(struct ssh *ssh, Channel *c, char *buf, int len)
1478{ 1193{
1479 if (c->extended_usage != CHAN_EXTENDED_WRITE) 1194 if (c->extended_usage != CHAN_EXTENDED_WRITE)
1480 return 0; 1195 return 0;
1481 1196
1482 return process_escapes(c, &c->input, &c->output, &c->extended, 1197 return process_escapes(ssh, c, c->input, c->output, c->extended,
1483 buf, len); 1198 buf, len);
1484} 1199}
1485 1200
1486static void 1201static void
1487client_channel_closed(int id, void *arg) 1202client_channel_closed(struct ssh *ssh, int id, void *arg)
1488{ 1203{
1489 channel_cancel_cleanup(id); 1204 channel_cancel_cleanup(ssh, id);
1490 session_closed = 1; 1205 session_closed = 1;
1491 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 1206 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1492} 1207}
@@ -1497,9 +1212,9 @@ client_channel_closed(int id, void *arg)
1497 * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character 1212 * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character
1498 * used as an escape character for terminating or suspending the session. 1213 * used as an escape character for terminating or suspending the session.
1499 */ 1214 */
1500
1501int 1215int
1502client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) 1216client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1217 int ssh2_chan_id)
1503{ 1218{
1504 fd_set *readset = NULL, *writeset = NULL; 1219 fd_set *readset = NULL, *writeset = NULL;
1505 double start_time, total_time; 1220 double start_time, total_time;
@@ -1537,40 +1252,22 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1537 1252
1538 } else { 1253 } else {
1539 debug("pledge: network"); 1254 debug("pledge: network");
1540 if (pledge("stdio unix inet dns tty", NULL) == -1) 1255 if (pledge("stdio unix inet dns proc tty", NULL) == -1)
1541 fatal("%s pledge(): %s", __func__, strerror(errno)); 1256 fatal("%s pledge(): %s", __func__, strerror(errno));
1542 } 1257 }
1543 1258
1544 start_time = get_current_time(); 1259 start_time = get_current_time();
1545 1260
1546 /* Initialize variables. */ 1261 /* Initialize variables. */
1547 escape_pending1 = 0;
1548 last_was_cr = 1; 1262 last_was_cr = 1;
1549 exit_status = -1; 1263 exit_status = -1;
1550 stdin_eof = 0;
1551 buffer_high = 64 * 1024;
1552 connection_in = packet_get_connection_in(); 1264 connection_in = packet_get_connection_in();
1553 connection_out = packet_get_connection_out(); 1265 connection_out = packet_get_connection_out();
1554 max_fd = MAXIMUM(connection_in, connection_out); 1266 max_fd = MAXIMUM(connection_in, connection_out);
1555 1267
1556 if (!compat20) {
1557 /* enable nonblocking unless tty */
1558 if (!isatty(fileno(stdin)))
1559 set_nonblock(fileno(stdin));
1560 if (!isatty(fileno(stdout)))
1561 set_nonblock(fileno(stdout));
1562 if (!isatty(fileno(stderr)))
1563 set_nonblock(fileno(stderr));
1564 max_fd = MAXIMUM(max_fd, fileno(stdin));
1565 max_fd = MAXIMUM(max_fd, fileno(stdout));
1566 max_fd = MAXIMUM(max_fd, fileno(stderr));
1567 }
1568 quit_pending = 0; 1268 quit_pending = 0;
1569 escape_char1 = escape_char_arg;
1570 1269
1571 /* Initialize buffers. */ 1270 /* Initialize buffers. */
1572 buffer_init(&stdin_buffer);
1573 buffer_init(&stdout_buffer);
1574 buffer_init(&stderr_buffer); 1271 buffer_init(&stderr_buffer);
1575 1272
1576 client_init_dispatch(); 1273 client_init_dispatch();
@@ -1592,22 +1289,17 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1592 if (have_pty) 1289 if (have_pty)
1593 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 1290 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1594 1291
1595 if (compat20) { 1292 session_ident = ssh2_chan_id;
1596 session_ident = ssh2_chan_id; 1293 if (session_ident != -1) {
1597 if (session_ident != -1) { 1294 if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
1598 if (escape_char_arg != SSH_ESCAPECHAR_NONE) { 1295 channel_register_filter(ssh, session_ident,
1599 channel_register_filter(session_ident, 1296 client_simple_escape_filter, NULL,
1600 client_simple_escape_filter, NULL, 1297 client_filter_cleanup,
1601 client_filter_cleanup, 1298 client_new_escape_filter_ctx(
1602 client_new_escape_filter_ctx( 1299 escape_char_arg));
1603 escape_char_arg));
1604 }
1605 channel_register_cleanup(session_ident,
1606 client_channel_closed, 0);
1607 } 1300 }
1608 } else { 1301 channel_register_cleanup(ssh, session_ident,
1609 /* Check if we should immediately send eof on stdin. */ 1302 client_channel_closed, 0);
1610 client_check_initial_eof_on_stdin();
1611 } 1303 }
1612 1304
1613 /* Main loop of the client for the interactive session mode. */ 1305 /* Main loop of the client for the interactive session mode. */
@@ -1616,38 +1308,31 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1616 /* Process buffered packets sent by the server. */ 1308 /* Process buffered packets sent by the server. */
1617 client_process_buffered_input_packets(); 1309 client_process_buffered_input_packets();
1618 1310
1619 if (compat20 && session_closed && !channel_still_open()) 1311 if (session_closed && !channel_still_open(ssh))
1620 break; 1312 break;
1621 1313
1622 if (ssh_packet_is_rekeying(active_state)) { 1314 if (ssh_packet_is_rekeying(ssh)) {
1623 debug("rekeying in progress"); 1315 debug("rekeying in progress");
1624 } else if (need_rekeying) { 1316 } else if (need_rekeying) {
1625 /* manual rekey request */ 1317 /* manual rekey request */
1626 debug("need rekeying"); 1318 debug("need rekeying");
1627 if ((r = kex_start_rekex(active_state)) != 0) 1319 if ((r = kex_start_rekex(ssh)) != 0)
1628 fatal("%s: kex_start_rekex: %s", __func__, 1320 fatal("%s: kex_start_rekex: %s", __func__,
1629 ssh_err(r)); 1321 ssh_err(r));
1630 need_rekeying = 0; 1322 need_rekeying = 0;
1631 } else { 1323 } else {
1632 /* 1324 /*
1633 * Make packets of buffered stdin data, and buffer
1634 * them for sending to the server.
1635 */
1636 if (!compat20)
1637 client_make_packets_from_stdin_data();
1638
1639 /*
1640 * Make packets from buffered channel data, and 1325 * Make packets from buffered channel data, and
1641 * enqueue them for sending to the server. 1326 * enqueue them for sending to the server.
1642 */ 1327 */
1643 if (packet_not_very_much_data_to_write()) 1328 if (packet_not_very_much_data_to_write())
1644 channel_output_poll(); 1329 channel_output_poll(ssh);
1645 1330
1646 /* 1331 /*
1647 * Check if the window size has changed, and buffer a 1332 * Check if the window size has changed, and buffer a
1648 * message about it to the server if so. 1333 * message about it to the server if so.
1649 */ 1334 */
1650 client_check_window_change(); 1335 client_check_window_change(ssh);
1651 1336
1652 if (quit_pending) 1337 if (quit_pending)
1653 break; 1338 break;
@@ -1657,15 +1342,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1657 * available on one of the descriptors). 1342 * available on one of the descriptors).
1658 */ 1343 */
1659 max_fd2 = max_fd; 1344 max_fd2 = max_fd;
1660 client_wait_until_can_do_something(&readset, &writeset, 1345 client_wait_until_can_do_something(ssh, &readset, &writeset,
1661 &max_fd2, &nalloc, ssh_packet_is_rekeying(active_state)); 1346 &max_fd2, &nalloc, ssh_packet_is_rekeying(ssh));
1662 1347
1663 if (quit_pending) 1348 if (quit_pending)
1664 break; 1349 break;
1665 1350
1666 /* Do channel operations unless rekeying in progress. */ 1351 /* Do channel operations unless rekeying in progress. */
1667 if (!ssh_packet_is_rekeying(active_state)) 1352 if (!ssh_packet_is_rekeying(ssh))
1668 channel_after_select(readset, writeset); 1353 channel_after_select(ssh, readset, writeset);
1669 1354
1670 /* Buffer input from the connection. */ 1355 /* Buffer input from the connection. */
1671 client_process_net_input(readset); 1356 client_process_net_input(readset);
@@ -1673,16 +1358,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1673 if (quit_pending) 1358 if (quit_pending)
1674 break; 1359 break;
1675 1360
1676 if (!compat20) {
1677 /* Buffer data from stdin */
1678 client_process_input(readset);
1679 /*
1680 * Process output to stdout and stderr. Output to
1681 * the connection is processed elsewhere (above).
1682 */
1683 client_process_output(writeset);
1684 }
1685
1686 /* 1361 /*
1687 * Send as much buffered packet data as possible to the 1362 * Send as much buffered packet data as possible to the
1688 * sender. 1363 * sender.
@@ -1710,16 +1385,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1710 /* Stop watching for window change. */ 1385 /* Stop watching for window change. */
1711 signal(SIGWINCH, SIG_DFL); 1386 signal(SIGWINCH, SIG_DFL);
1712 1387
1713 if (compat20) { 1388 packet_start(SSH2_MSG_DISCONNECT);
1714 packet_start(SSH2_MSG_DISCONNECT); 1389 packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
1715 packet_put_int(SSH2_DISCONNECT_BY_APPLICATION); 1390 packet_put_cstring("disconnected by user");
1716 packet_put_cstring("disconnected by user"); 1391 packet_put_cstring(""); /* language tag */
1717 packet_put_cstring(""); /* language tag */ 1392 packet_send();
1718 packet_send(); 1393 packet_write_wait();
1719 packet_write_wait();
1720 }
1721 1394
1722 channel_free_all(); 1395 channel_free_all(ssh);
1723 1396
1724 if (have_pty) 1397 if (have_pty)
1725 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 1398 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
@@ -1742,8 +1415,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1742 exit_status = 0; 1415 exit_status = 0;
1743 } 1416 }
1744 1417
1745 if (received_signal) 1418 if (received_signal) {
1746 fatal("Killed by signal %d.", (int) received_signal); 1419 verbose("Killed by signal %d.", (int) received_signal);
1420 cleanup_exit(0);
1421 }
1747 1422
1748 /* 1423 /*
1749 * In interactive mode (with pseudo tty) display a message indicating 1424 * In interactive mode (with pseudo tty) display a message indicating
@@ -1755,16 +1430,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1755 buffer_append(&stderr_buffer, buf, strlen(buf)); 1430 buffer_append(&stderr_buffer, buf, strlen(buf));
1756 } 1431 }
1757 1432
1758 /* Output any buffered data for stdout. */
1759 if (buffer_len(&stdout_buffer) > 0) {
1760 len = atomicio(vwrite, fileno(stdout),
1761 buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer));
1762 if (len < 0 || (u_int)len != buffer_len(&stdout_buffer))
1763 error("Write failed flushing stdout buffer.");
1764 else
1765 buffer_consume(&stdout_buffer, len);
1766 }
1767
1768 /* Output any buffered data for stderr. */ 1433 /* Output any buffered data for stderr. */
1769 if (buffer_len(&stderr_buffer) > 0) { 1434 if (buffer_len(&stderr_buffer) > 0) {
1770 len = atomicio(vwrite, fileno(stderr), 1435 len = atomicio(vwrite, fileno(stderr),
@@ -1777,8 +1442,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1777 1442
1778 /* Clear and free any buffers. */ 1443 /* Clear and free any buffers. */
1779 explicit_bzero(buf, sizeof(buf)); 1444 explicit_bzero(buf, sizeof(buf));
1780 buffer_free(&stdin_buffer);
1781 buffer_free(&stdout_buffer);
1782 buffer_free(&stderr_buffer); 1445 buffer_free(&stderr_buffer);
1783 1446
1784 /* Report bytes transferred, and transfer rates. */ 1447 /* Report bytes transferred, and transfer rates. */
@@ -1796,95 +1459,9 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
1796 1459
1797/*********/ 1460/*********/
1798 1461
1799static int
1800client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
1801{
1802 u_int data_len;
1803 char *data = packet_get_string(&data_len);
1804 packet_check_eom();
1805 buffer_append(&stdout_buffer, data, data_len);
1806 explicit_bzero(data, data_len);
1807 free(data);
1808 return 0;
1809}
1810static int
1811client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
1812{
1813 u_int data_len;
1814 char *data = packet_get_string(&data_len);
1815 packet_check_eom();
1816 buffer_append(&stderr_buffer, data, data_len);
1817 explicit_bzero(data, data_len);
1818 free(data);
1819 return 0;
1820}
1821static int
1822client_input_exit_status(int type, u_int32_t seq, void *ctxt)
1823{
1824 exit_status = packet_get_int();
1825 packet_check_eom();
1826 /* Acknowledge the exit. */
1827 packet_start(SSH_CMSG_EXIT_CONFIRMATION);
1828 packet_send();
1829 /*
1830 * Must wait for packet to be sent since we are
1831 * exiting the loop.
1832 */
1833 packet_write_wait();
1834 /* Flag that we want to exit. */
1835 quit_pending = 1;
1836 return 0;
1837}
1838
1839static int
1840client_input_agent_open(int type, u_int32_t seq, void *ctxt)
1841{
1842 Channel *c = NULL;
1843 int r, remote_id, sock;
1844
1845 /* Read the remote channel number from the message. */
1846 remote_id = packet_get_int();
1847 packet_check_eom();
1848
1849 /*
1850 * Get a connection to the local authentication agent (this may again
1851 * get forwarded).
1852 */
1853 if ((r = ssh_get_authentication_socket(&sock)) != 0 &&
1854 r != SSH_ERR_AGENT_NOT_PRESENT)
1855 debug("%s: ssh_get_authentication_socket: %s",
1856 __func__, ssh_err(r));
1857
1858
1859 /*
1860 * If we could not connect the agent, send an error message back to
1861 * the server. This should never happen unless the agent dies,
1862 * because authentication forwarding is only enabled if we have an
1863 * agent.
1864 */
1865 if (sock >= 0) {
1866 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
1867 -1, 0, 0, 0, "authentication agent connection", 1);
1868 c->remote_id = remote_id;
1869 c->force_drain = 1;
1870 }
1871 if (c == NULL) {
1872 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1873 packet_put_int(remote_id);
1874 } else {
1875 /* Send a confirmation to the remote host. */
1876 debug("Forwarding authentication connection.");
1877 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
1878 packet_put_int(remote_id);
1879 packet_put_int(c->self);
1880 }
1881 packet_send();
1882 return 0;
1883}
1884
1885static Channel * 1462static Channel *
1886client_request_forwarded_tcpip(const char *request_type, int rchan, 1463client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
1887 u_int rwindow, u_int rmaxpack) 1464 int rchan, u_int rwindow, u_int rmaxpack)
1888{ 1465{
1889 Channel *c = NULL; 1466 Channel *c = NULL;
1890 struct sshbuf *b = NULL; 1467 struct sshbuf *b = NULL;
@@ -1902,7 +1479,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan,
1902 debug("%s: listen %s port %d, originator %s port %d", __func__, 1479 debug("%s: listen %s port %d, originator %s port %d", __func__,
1903 listen_address, listen_port, originator_address, originator_port); 1480 listen_address, listen_port, originator_address, originator_port);
1904 1481
1905 c = channel_connect_by_listen_address(listen_address, listen_port, 1482 c = channel_connect_by_listen_address(ssh, listen_address, listen_port,
1906 "forwarded-tcpip", originator_address); 1483 "forwarded-tcpip", originator_address);
1907 1484
1908 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { 1485 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
@@ -1921,7 +1498,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan,
1921 (r = sshbuf_put_u32(b, listen_port)) != 0 || 1498 (r = sshbuf_put_u32(b, listen_port)) != 0 ||
1922 (r = sshbuf_put_cstring(b, originator_address)) != 0 || 1499 (r = sshbuf_put_cstring(b, originator_address)) != 0 ||
1923 (r = sshbuf_put_u32(b, originator_port)) != 0 || 1500 (r = sshbuf_put_u32(b, originator_port)) != 0 ||
1924 (r = sshbuf_put_stringb(&c->output, b)) != 0) { 1501 (r = sshbuf_put_stringb(c->output, b)) != 0) {
1925 error("%s: compose for muxclient %s", __func__, 1502 error("%s: compose for muxclient %s", __func__,
1926 ssh_err(r)); 1503 ssh_err(r));
1927 goto out; 1504 goto out;
@@ -1936,7 +1513,8 @@ client_request_forwarded_tcpip(const char *request_type, int rchan,
1936} 1513}
1937 1514
1938static Channel * 1515static Channel *
1939client_request_forwarded_streamlocal(const char *request_type, int rchan) 1516client_request_forwarded_streamlocal(struct ssh *ssh,
1517 const char *request_type, int rchan)
1940{ 1518{
1941 Channel *c = NULL; 1519 Channel *c = NULL;
1942 char *listen_path; 1520 char *listen_path;
@@ -1950,14 +1528,14 @@ client_request_forwarded_streamlocal(const char *request_type, int rchan)
1950 1528
1951 debug("%s: %s", __func__, listen_path); 1529 debug("%s: %s", __func__, listen_path);
1952 1530
1953 c = channel_connect_by_listen_path(listen_path, 1531 c = channel_connect_by_listen_path(ssh, listen_path,
1954 "forwarded-streamlocal@openssh.com", "forwarded-streamlocal"); 1532 "forwarded-streamlocal@openssh.com", "forwarded-streamlocal");
1955 free(listen_path); 1533 free(listen_path);
1956 return c; 1534 return c;
1957} 1535}
1958 1536
1959static Channel * 1537static Channel *
1960client_request_x11(const char *request_type, int rchan) 1538client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
1961{ 1539{
1962 Channel *c = NULL; 1540 Channel *c = NULL;
1963 char *originator; 1541 char *originator;
@@ -1987,10 +1565,10 @@ client_request_x11(const char *request_type, int rchan)
1987 debug("client_request_x11: request from %s %d", originator, 1565 debug("client_request_x11: request from %s %d", originator,
1988 originator_port); 1566 originator_port);
1989 free(originator); 1567 free(originator);
1990 sock = x11_connect_display(); 1568 sock = x11_connect_display(ssh);
1991 if (sock < 0) 1569 if (sock < 0)
1992 return NULL; 1570 return NULL;
1993 c = channel_new("x11", 1571 c = channel_new(ssh, "x11",
1994 SSH_CHANNEL_X11_OPEN, sock, sock, -1, 1572 SSH_CHANNEL_X11_OPEN, sock, sock, -1,
1995 CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); 1573 CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
1996 c->force_drain = 1; 1574 c->force_drain = 1;
@@ -1998,7 +1576,7 @@ client_request_x11(const char *request_type, int rchan)
1998} 1576}
1999 1577
2000static Channel * 1578static Channel *
2001client_request_agent(const char *request_type, int rchan) 1579client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
2002{ 1580{
2003 Channel *c = NULL; 1581 Channel *c = NULL;
2004 int r, sock; 1582 int r, sock;
@@ -2015,7 +1593,7 @@ client_request_agent(const char *request_type, int rchan)
2015 __func__, ssh_err(r)); 1593 __func__, ssh_err(r));
2016 return NULL; 1594 return NULL;
2017 } 1595 }
2018 c = channel_new("authentication agent connection", 1596 c = channel_new(ssh, "authentication agent connection",
2019 SSH_CHANNEL_OPEN, sock, sock, -1, 1597 SSH_CHANNEL_OPEN, sock, sock, -1,
2020 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, 1598 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
2021 "authentication agent connection", 1); 1599 "authentication agent connection", 1);
@@ -2024,7 +1602,8 @@ client_request_agent(const char *request_type, int rchan)
2024} 1602}
2025 1603
2026int 1604int
2027client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) 1605client_request_tun_fwd(struct ssh *ssh, int tun_mode,
1606 int local_tun, int remote_tun)
2028{ 1607{
2029 Channel *c; 1608 Channel *c;
2030 int fd; 1609 int fd;
@@ -2032,11 +1611,6 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
2032 if (tun_mode == SSH_TUNMODE_NO) 1611 if (tun_mode == SSH_TUNMODE_NO)
2033 return 0; 1612 return 0;
2034 1613
2035 if (!compat20) {
2036 error("Tunnel forwarding is not supported for protocol 1");
2037 return -1;
2038 }
2039
2040 debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); 1614 debug("Requesting tun unit %d in mode %d", local_tun, tun_mode);
2041 1615
2042 /* Open local tunnel device */ 1616 /* Open local tunnel device */
@@ -2045,13 +1619,13 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
2045 return -1; 1619 return -1;
2046 } 1620 }
2047 1621
2048 c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, 1622 c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1,
2049 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); 1623 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
2050 c->datagram = 1; 1624 c->datagram = 1;
2051 1625
2052#if defined(SSH_TUN_FILTER) 1626#if defined(SSH_TUN_FILTER)
2053 if (options.tun_open == SSH_TUNMODE_POINTOPOINT) 1627 if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
2054 channel_register_filter(c->self, sys_tun_infilter, 1628 channel_register_filter(ssh, c->self, sys_tun_infilter,
2055 sys_tun_outfilter, NULL, NULL); 1629 sys_tun_outfilter, NULL, NULL);
2056#endif 1630#endif
2057 1631
@@ -2069,7 +1643,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
2069 1643
2070/* XXXX move to generic input handler */ 1644/* XXXX move to generic input handler */
2071static int 1645static int
2072client_input_channel_open(int type, u_int32_t seq, void *ctxt) 1646client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
2073{ 1647{
2074 Channel *c = NULL; 1648 Channel *c = NULL;
2075 char *ctype; 1649 char *ctype;
@@ -2085,20 +1659,21 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt)
2085 ctype, rchan, rwindow, rmaxpack); 1659 ctype, rchan, rwindow, rmaxpack);
2086 1660
2087 if (strcmp(ctype, "forwarded-tcpip") == 0) { 1661 if (strcmp(ctype, "forwarded-tcpip") == 0) {
2088 c = client_request_forwarded_tcpip(ctype, rchan, rwindow, 1662 c = client_request_forwarded_tcpip(ssh, ctype, rchan, rwindow,
2089 rmaxpack); 1663 rmaxpack);
2090 } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) { 1664 } else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) {
2091 c = client_request_forwarded_streamlocal(ctype, rchan); 1665 c = client_request_forwarded_streamlocal(ssh, ctype, rchan);
2092 } else if (strcmp(ctype, "x11") == 0) { 1666 } else if (strcmp(ctype, "x11") == 0) {
2093 c = client_request_x11(ctype, rchan); 1667 c = client_request_x11(ssh, ctype, rchan);
2094 } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { 1668 } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {
2095 c = client_request_agent(ctype, rchan); 1669 c = client_request_agent(ssh, ctype, rchan);
2096 } 1670 }
2097 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { 1671 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
2098 debug3("proxied to downstream: %s", ctype); 1672 debug3("proxied to downstream: %s", ctype);
2099 } else if (c != NULL) { 1673 } else if (c != NULL) {
2100 debug("confirm %s", ctype); 1674 debug("confirm %s", ctype);
2101 c->remote_id = rchan; 1675 c->remote_id = rchan;
1676 c->have_remote_id = 1;
2102 c->remote_window = rwindow; 1677 c->remote_window = rwindow;
2103 c->remote_maxpacket = rmaxpack; 1678 c->remote_maxpacket = rmaxpack;
2104 if (c->type != SSH_CHANNEL_CONNECTING) { 1679 if (c->type != SSH_CHANNEL_CONNECTING) {
@@ -2125,15 +1700,15 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt)
2125} 1700}
2126 1701
2127static int 1702static int
2128client_input_channel_req(int type, u_int32_t seq, void *ctxt) 1703client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
2129{ 1704{
2130 Channel *c = NULL; 1705 Channel *c = NULL;
2131 int exitval, id, reply, success = 0; 1706 int exitval, id, reply, success = 0;
2132 char *rtype; 1707 char *rtype;
2133 1708
2134 id = packet_get_int(); 1709 id = packet_get_int();
2135 c = channel_lookup(id); 1710 c = channel_lookup(ssh, id);
2136 if (channel_proxy_upstream(c, type, seq, ctxt)) 1711 if (channel_proxy_upstream(c, type, seq, ssh))
2137 return 0; 1712 return 0;
2138 rtype = packet_get_string(NULL); 1713 rtype = packet_get_string(NULL);
2139 reply = packet_get_char(); 1714 reply = packet_get_char();
@@ -2148,11 +1723,11 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
2148 "unknown channel", id); 1723 "unknown channel", id);
2149 } else if (strcmp(rtype, "eow@openssh.com") == 0) { 1724 } else if (strcmp(rtype, "eow@openssh.com") == 0) {
2150 packet_check_eom(); 1725 packet_check_eom();
2151 chan_rcvd_eow(c); 1726 chan_rcvd_eow(ssh, c);
2152 } else if (strcmp(rtype, "exit-status") == 0) { 1727 } else if (strcmp(rtype, "exit-status") == 0) {
2153 exitval = packet_get_int(); 1728 exitval = packet_get_int();
2154 if (c->ctl_chan != -1) { 1729 if (c->ctl_chan != -1) {
2155 mux_exit_message(c, exitval); 1730 mux_exit_message(ssh, c, exitval);
2156 success = 1; 1731 success = 1;
2157 } else if (id == session_ident) { 1732 } else if (id == session_ident) {
2158 /* Record exit value of local session */ 1733 /* Record exit value of local session */
@@ -2166,6 +1741,9 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt)
2166 packet_check_eom(); 1741 packet_check_eom();
2167 } 1742 }
2168 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) { 1743 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) {
1744 if (!c->have_remote_id)
1745 fatal("%s: channel %d: no remote_id",
1746 __func__, c->self);
2169 packet_start(success ? 1747 packet_start(success ?
2170 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 1748 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
2171 packet_put_int(c->remote_id); 1749 packet_put_int(c->remote_id);
@@ -2187,9 +1765,7 @@ struct hostkeys_update_ctx {
2187 */ 1765 */
2188 struct sshkey **keys; 1766 struct sshkey **keys;
2189 int *keys_seen; 1767 int *keys_seen;
2190 size_t nkeys; 1768 size_t nkeys, nnew;
2191
2192 size_t nnew;
2193 1769
2194 /* 1770 /*
2195 * Keys that are in known_hosts, but were not present in the update 1771 * Keys that are in known_hosts, but were not present in the update
@@ -2226,8 +1802,7 @@ hostkeys_find(struct hostkey_foreach_line *l, void *_ctx)
2226 size_t i; 1802 size_t i;
2227 struct sshkey **tmp; 1803 struct sshkey **tmp;
2228 1804
2229 if (l->status != HKF_STATUS_MATCHED || l->key == NULL || 1805 if (l->status != HKF_STATUS_MATCHED || l->key == NULL)
2230 l->key->type == KEY_RSA1)
2231 return 0; 1806 return 0;
2232 1807
2233 /* Mark off keys we've already seen for this host */ 1808 /* Mark off keys we've already seen for this host */
@@ -2242,9 +1817,9 @@ hostkeys_find(struct hostkey_foreach_line *l, void *_ctx)
2242 /* This line contained a key that not offered by the server */ 1817 /* This line contained a key that not offered by the server */
2243 debug3("%s: deprecated %s key at %s:%ld", __func__, 1818 debug3("%s: deprecated %s key at %s:%ld", __func__,
2244 sshkey_ssh_name(l->key), l->path, l->linenum); 1819 sshkey_ssh_name(l->key), l->path, l->linenum);
2245 if ((tmp = reallocarray(ctx->old_keys, ctx->nold + 1, 1820 if ((tmp = recallocarray(ctx->old_keys, ctx->nold, ctx->nold + 1,
2246 sizeof(*ctx->old_keys))) == NULL) 1821 sizeof(*ctx->old_keys))) == NULL)
2247 fatal("%s: reallocarray failed nold = %zu", 1822 fatal("%s: recallocarray failed nold = %zu",
2248 __func__, ctx->nold); 1823 __func__, ctx->nold);
2249 ctx->old_keys = tmp; 1824 ctx->old_keys = tmp;
2250 ctx->old_keys[ctx->nold++] = l->key; 1825 ctx->old_keys[ctx->nold++] = l->key;
@@ -2323,9 +1898,9 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
2323} 1898}
2324 1899
2325static void 1900static void
2326client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx) 1901client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
1902 u_int32_t seq, void *_ctx)
2327{ 1903{
2328 struct ssh *ssh = active_state; /* XXX */
2329 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; 1904 struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
2330 size_t i, ndone; 1905 size_t i, ndone;
2331 struct sshbuf *signdata; 1906 struct sshbuf *signdata;
@@ -2476,9 +2051,9 @@ client_input_hostkeys(void)
2476 } 2051 }
2477 } 2052 }
2478 /* Key is good, record it */ 2053 /* Key is good, record it */
2479 if ((tmp = reallocarray(ctx->keys, ctx->nkeys + 1, 2054 if ((tmp = recallocarray(ctx->keys, ctx->nkeys, ctx->nkeys + 1,
2480 sizeof(*ctx->keys))) == NULL) 2055 sizeof(*ctx->keys))) == NULL)
2481 fatal("%s: reallocarray failed nkeys = %zu", 2056 fatal("%s: recallocarray failed nkeys = %zu",
2482 __func__, ctx->nkeys); 2057 __func__, ctx->nkeys);
2483 ctx->keys = tmp; 2058 ctx->keys = tmp;
2484 ctx->keys[ctx->nkeys++] = key; 2059 ctx->keys[ctx->nkeys++] = key;
@@ -2566,7 +2141,7 @@ client_input_hostkeys(void)
2566} 2141}
2567 2142
2568static int 2143static int
2569client_input_global_request(int type, u_int32_t seq, void *ctxt) 2144client_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
2570{ 2145{
2571 char *rtype; 2146 char *rtype;
2572 int want_reply; 2147 int want_reply;
@@ -2589,7 +2164,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt)
2589} 2164}
2590 2165
2591void 2166void
2592client_session2_setup(int id, int want_tty, int want_subsystem, 2167client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2593 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) 2168 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env)
2594{ 2169{
2595 int len; 2170 int len;
@@ -2597,8 +2172,8 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2597 2172
2598 debug2("%s: id %d", __func__, id); 2173 debug2("%s: id %d", __func__, id);
2599 2174
2600 if ((c = channel_lookup(id)) == NULL) 2175 if ((c = channel_lookup(ssh, id)) == NULL)
2601 fatal("client_session2_setup: channel %d: unknown channel", id); 2176 fatal("%s: channel %d: unknown channel", __func__, id);
2602 2177
2603 packet_set_interactive(want_tty, 2178 packet_set_interactive(want_tty,
2604 options.ip_qos_interactive, options.ip_qos_bulk); 2179 options.ip_qos_interactive, options.ip_qos_bulk);
@@ -2610,8 +2185,8 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2610 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) 2185 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0)
2611 memset(&ws, 0, sizeof(ws)); 2186 memset(&ws, 0, sizeof(ws));
2612 2187
2613 channel_request_start(id, "pty-req", 1); 2188 channel_request_start(ssh, id, "pty-req", 1);
2614 client_expect_confirm(id, "PTY allocation", CONFIRM_TTY); 2189 client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY);
2615 packet_put_cstring(term != NULL ? term : ""); 2190 packet_put_cstring(term != NULL ? term : "");
2616 packet_put_int((u_int)ws.ws_col); 2191 packet_put_int((u_int)ws.ws_col);
2617 packet_put_int((u_int)ws.ws_row); 2192 packet_put_int((u_int)ws.ws_row);
@@ -2654,7 +2229,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2654 } 2229 }
2655 2230
2656 debug("Sending env %s = %s", name, val); 2231 debug("Sending env %s = %s", name, val);
2657 channel_request_start(id, "env", 0); 2232 channel_request_start(ssh, id, "env", 0);
2658 packet_put_cstring(name); 2233 packet_put_cstring(name);
2659 packet_put_cstring(val); 2234 packet_put_cstring(val);
2660 packet_send(); 2235 packet_send();
@@ -2669,25 +2244,26 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2669 if (want_subsystem) { 2244 if (want_subsystem) {
2670 debug("Sending subsystem: %.*s", 2245 debug("Sending subsystem: %.*s",
2671 len, (u_char*)buffer_ptr(cmd)); 2246 len, (u_char*)buffer_ptr(cmd));
2672 channel_request_start(id, "subsystem", 1); 2247 channel_request_start(ssh, id, "subsystem", 1);
2673 client_expect_confirm(id, "subsystem", CONFIRM_CLOSE); 2248 client_expect_confirm(ssh, id, "subsystem",
2249 CONFIRM_CLOSE);
2674 } else { 2250 } else {
2675 debug("Sending command: %.*s", 2251 debug("Sending command: %.*s",
2676 len, (u_char*)buffer_ptr(cmd)); 2252 len, (u_char*)buffer_ptr(cmd));
2677 channel_request_start(id, "exec", 1); 2253 channel_request_start(ssh, id, "exec", 1);
2678 client_expect_confirm(id, "exec", CONFIRM_CLOSE); 2254 client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE);
2679 } 2255 }
2680 packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); 2256 packet_put_string(buffer_ptr(cmd), buffer_len(cmd));
2681 packet_send(); 2257 packet_send();
2682 } else { 2258 } else {
2683 channel_request_start(id, "shell", 1); 2259 channel_request_start(ssh, id, "shell", 1);
2684 client_expect_confirm(id, "shell", CONFIRM_CLOSE); 2260 client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE);
2685 packet_send(); 2261 packet_send();
2686 } 2262 }
2687} 2263}
2688 2264
2689static void 2265static void
2690client_init_dispatch_20(void) 2266client_init_dispatch(void)
2691{ 2267{
2692 dispatch_init(&dispatch_protocol_error); 2268 dispatch_init(&dispatch_protocol_error);
2693 2269
@@ -2712,45 +2288,6 @@ client_init_dispatch_20(void)
2712 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); 2288 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
2713} 2289}
2714 2290
2715static void
2716client_init_dispatch_13(void)
2717{
2718 dispatch_init(NULL);
2719 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
2720 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
2721 dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
2722 dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
2723 dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
2724 dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
2725 dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);
2726 dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);
2727 dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
2728
2729 dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?
2730 &client_input_agent_open : &deny_input_open);
2731 dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
2732 &x11_input_open : &deny_input_open);
2733}
2734
2735static void
2736client_init_dispatch_15(void)
2737{
2738 client_init_dispatch_13();
2739 dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
2740 dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
2741}
2742
2743static void
2744client_init_dispatch(void)
2745{
2746 if (compat20)
2747 client_init_dispatch_20();
2748 else if (compat13)
2749 client_init_dispatch_13();
2750 else
2751 client_init_dispatch_15();
2752}
2753
2754void 2291void
2755client_stop_mux(void) 2292client_stop_mux(void)
2756{ 2293{
diff --git a/clientloop.h b/clientloop.h
index ae83aa8cf..a1975ccc8 100644
--- a/clientloop.h
+++ b/clientloop.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.h,v 1.33 2016/09/30 09:19:13 markus Exp $ */ 1/* $OpenBSD: clientloop.h,v 1.34 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,28 +37,31 @@
37 37
38#include <termios.h> 38#include <termios.h>
39 39
40struct ssh;
41
40/* Client side main loop for the interactive session. */ 42/* Client side main loop for the interactive session. */
41int client_loop(int, int, int); 43int client_loop(struct ssh *, int, int, int);
42int client_x11_get_proto(const char *, const char *, u_int, u_int, 44int client_x11_get_proto(struct ssh *, const char *, const char *,
43 char **, char **); 45 u_int, u_int, char **, char **);
44void client_global_request_reply_fwd(int, u_int32_t, void *); 46void client_global_request_reply_fwd(int, u_int32_t, void *);
45void client_session2_setup(int, int, int, const char *, struct termios *, 47void client_session2_setup(struct ssh *, int, int, int,
46 int, Buffer *, char **); 48 const char *, struct termios *, int, Buffer *, char **);
47int client_request_tun_fwd(int, int, int); 49int client_request_tun_fwd(struct ssh *, int, int, int);
48void client_stop_mux(void); 50void client_stop_mux(void);
49 51
50/* Escape filter for protocol 2 sessions */ 52/* Escape filter for protocol 2 sessions */
51void *client_new_escape_filter_ctx(int); 53void *client_new_escape_filter_ctx(int);
52void client_filter_cleanup(int, void *); 54void client_filter_cleanup(struct ssh *, int, void *);
53int client_simple_escape_filter(Channel *, char *, int); 55int client_simple_escape_filter(struct ssh *, Channel *, char *, int);
54 56
55/* Global request confirmation callbacks */ 57/* Global request confirmation callbacks */
56typedef void global_confirm_cb(int, u_int32_t seq, void *); 58typedef void global_confirm_cb(struct ssh *, int, u_int32_t, void *);
57void client_register_global_confirm(global_confirm_cb *, void *); 59void client_register_global_confirm(global_confirm_cb *, void *);
58 60
59/* Channel request confirmation callbacks */ 61/* Channel request confirmation callbacks */
60enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY }; 62enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY };
61void client_expect_confirm(int, const char *, enum confirm_action); 63void client_expect_confirm(struct ssh *, int, const char *,
64 enum confirm_action);
62 65
63/* Multiplexing protocol version */ 66/* Multiplexing protocol version */
64#define SSHMUX_VER 4 67#define SSHMUX_VER 4
@@ -73,8 +76,8 @@ void client_expect_confirm(int, const char *, enum confirm_action);
73#define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */ 76#define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */
74#define SSHMUX_COMMAND_PROXY 8 /* Open new connection */ 77#define SSHMUX_COMMAND_PROXY 8 /* Open new connection */
75 78
76void muxserver_listen(void); 79void muxserver_listen(struct ssh *);
77int muxclient(const char *); 80int muxclient(const char *);
78void mux_exit_message(Channel *, int); 81void mux_exit_message(struct ssh *, Channel *, int);
79void mux_tty_alloc_failed(Channel *); 82void mux_tty_alloc_failed(struct ssh *ssh, Channel *);
80 83
diff --git a/compat.c b/compat.c
index 1e80cfa9a..d82135e2b 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.c,v 1.100 2017/02/03 23:01:19 djm Exp $ */ 1/* $OpenBSD: compat.c,v 1.104 2017/07/25 09:22:25 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -39,24 +39,8 @@
39#include "match.h" 39#include "match.h"
40#include "kex.h" 40#include "kex.h"
41 41
42int compat13 = 0;
43int compat20 = 0;
44int datafellows = 0; 42int datafellows = 0;
45 43
46void
47enable_compat20(void)
48{
49 if (compat20)
50 return;
51 debug("Enabling compatibility mode for protocol 2.0");
52 compat20 = 1;
53}
54void
55enable_compat13(void)
56{
57 debug("Enabling compatibility mode for protocol 1.3");
58 compat13 = 1;
59}
60/* datafellows bug compatibility */ 44/* datafellows bug compatibility */
61u_int 45u_int
62compat_datafellows(const char *version) 46compat_datafellows(const char *version)
@@ -193,9 +177,12 @@ compat_datafellows(const char *version)
193 "TTSSH/2.72*", SSH_BUG_HOSTKEYS }, 177 "TTSSH/2.72*", SSH_BUG_HOSTKEYS },
194 { "WinSCP_release_4*," 178 { "WinSCP_release_4*,"
195 "WinSCP_release_5.0*," 179 "WinSCP_release_5.0*,"
196 "WinSCP_release_5.1*," 180 "WinSCP_release_5.1,"
197 "WinSCP_release_5.5*," 181 "WinSCP_release_5.1.*,"
198 "WinSCP_release_5.6*," 182 "WinSCP_release_5.5,"
183 "WinSCP_release_5.5.*,"
184 "WinSCP_release_5.6,"
185 "WinSCP_release_5.6.*,"
199 "WinSCP_release_5.7," 186 "WinSCP_release_5.7,"
200 "WinSCP_release_5.7.1," 187 "WinSCP_release_5.7.1,"
201 "WinSCP_release_5.7.2," 188 "WinSCP_release_5.7.2,"
@@ -232,13 +219,6 @@ proto_spec(const char *spec)
232 return ret; 219 return ret;
233 for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { 220 for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) {
234 switch (atoi(p)) { 221 switch (atoi(p)) {
235 case 1:
236#ifdef WITH_SSH1
237 if (ret == SSH_PROTO_UNKNOWN)
238 ret |= SSH_PROTO_1_PREFERRED;
239 ret |= SSH_PROTO_1;
240#endif
241 break;
242 case 2: 222 case 2:
243 ret |= SSH_PROTO_2; 223 ret |= SSH_PROTO_2;
244 break; 224 break;
diff --git a/compat.h b/compat.h
index 2be290a8a..2e7830f1b 100644
--- a/compat.h
+++ b/compat.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: compat.h,v 1.48 2015/05/26 23:23:40 dtucker Exp $ */ 1/* $OpenBSD: compat.h,v 1.49 2017/04/30 23:13:25 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@@ -63,15 +63,11 @@
63#define SSH_BUG_HOSTKEYS 0x20000000 63#define SSH_BUG_HOSTKEYS 0x20000000
64#define SSH_BUG_DHGEX_LARGE 0x40000000 64#define SSH_BUG_DHGEX_LARGE 0x40000000
65 65
66void enable_compat13(void);
67void enable_compat20(void);
68u_int compat_datafellows(const char *); 66u_int compat_datafellows(const char *);
69int proto_spec(const char *); 67int proto_spec(const char *);
70char *compat_cipher_proposal(char *); 68char *compat_cipher_proposal(char *);
71char *compat_pkalg_proposal(char *); 69char *compat_pkalg_proposal(char *);
72char *compat_kex_proposal(char *); 70char *compat_kex_proposal(char *);
73 71
74extern int compat13;
75extern int compat20;
76extern int datafellows; 72extern int datafellows;
77#endif 73#endif
diff --git a/config.h.in b/config.h.in
index b65420e4a..63fc548b5 100644
--- a/config.h.in
+++ b/config.h.in
@@ -252,6 +252,9 @@
252/* Define to 1 if you have the <bstring.h> header file. */ 252/* Define to 1 if you have the <bstring.h> header file. */
253#undef HAVE_BSTRING_H 253#undef HAVE_BSTRING_H
254 254
255/* calloc(x, 0) returns NULL */
256#undef HAVE_CALLOC
257
255/* Define to 1 if you have the `cap_rights_limit' function. */ 258/* Define to 1 if you have the `cap_rights_limit' function. */
256#undef HAVE_CAP_RIGHTS_LIMIT 259#undef HAVE_CAP_RIGHTS_LIMIT
257 260
@@ -469,6 +472,9 @@
469/* Define to 1 if you have the `freeaddrinfo' function. */ 472/* Define to 1 if you have the `freeaddrinfo' function. */
470#undef HAVE_FREEADDRINFO 473#undef HAVE_FREEADDRINFO
471 474
475/* Define to 1 if you have the `freezero' function. */
476#undef HAVE_FREEZERO
477
472/* Define to 1 if the system has the type `fsblkcnt_t'. */ 478/* Define to 1 if the system has the type `fsblkcnt_t'. */
473#undef HAVE_FSBLKCNT_T 479#undef HAVE_FSBLKCNT_T
474 480
@@ -769,6 +775,10 @@
769/* Define to 1 if you have the <maillock.h> header file. */ 775/* Define to 1 if you have the <maillock.h> header file. */
770#undef HAVE_MAILLOCK_H 776#undef HAVE_MAILLOCK_H
771 777
778/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
779 to 0 otherwise. */
780#undef HAVE_MALLOC
781
772/* Define to 1 if you have the `mblen' function. */ 782/* Define to 1 if you have the `mblen' function. */
773#undef HAVE_MBLEN 783#undef HAVE_MBLEN
774 784
@@ -899,12 +909,19 @@
899/* Define to 1 if you have the <readpassphrase.h> header file. */ 909/* Define to 1 if you have the <readpassphrase.h> header file. */
900#undef HAVE_READPASSPHRASE_H 910#undef HAVE_READPASSPHRASE_H
901 911
912/* Define to 1 if your system has a GNU libc compatible `realloc' function,
913 and to 0 otherwise. */
914#undef HAVE_REALLOC
915
902/* Define to 1 if you have the `reallocarray' function. */ 916/* Define to 1 if you have the `reallocarray' function. */
903#undef HAVE_REALLOCARRAY 917#undef HAVE_REALLOCARRAY
904 918
905/* Define to 1 if you have the `realpath' function. */ 919/* Define to 1 if you have the `realpath' function. */
906#undef HAVE_REALPATH 920#undef HAVE_REALPATH
907 921
922/* Define to 1 if you have the `recallocarray' function. */
923#undef HAVE_RECALLOCARRAY
924
908/* Define to 1 if you have the `recvmsg' function. */ 925/* Define to 1 if you have the `recvmsg' function. */
909#undef HAVE_RECVMSG 926#undef HAVE_RECVMSG
910 927
@@ -1115,6 +1132,9 @@
1115/* Define to 1 if you have the `strsep' function. */ 1132/* Define to 1 if you have the `strsep' function. */
1116#undef HAVE_STRSEP 1133#undef HAVE_STRSEP
1117 1134
1135/* Define to 1 if you have the `strsignal' function. */
1136#undef HAVE_STRSIGNAL
1137
1118/* Define to 1 if you have the `strtoll' function. */ 1138/* Define to 1 if you have the `strtoll' function. */
1119#undef HAVE_STRTOLL 1139#undef HAVE_STRTOLL
1120 1140
@@ -1157,6 +1177,12 @@
1157/* Define to 1 if `st_blksize' is a member of `struct stat'. */ 1177/* Define to 1 if `st_blksize' is a member of `struct stat'. */
1158#undef HAVE_STRUCT_STAT_ST_BLKSIZE 1178#undef HAVE_STRUCT_STAT_ST_BLKSIZE
1159 1179
1180/* Define to 1 if `st_mtim' is a member of `struct stat'. */
1181#undef HAVE_STRUCT_STAT_ST_MTIM
1182
1183/* Define to 1 if `st_mtime' is a member of `struct stat'. */
1184#undef HAVE_STRUCT_STAT_ST_MTIME
1185
1160/* Define to 1 if the system has the type `struct timespec'. */ 1186/* Define to 1 if the system has the type `struct timespec'. */
1161#undef HAVE_STRUCT_TIMESPEC 1187#undef HAVE_STRUCT_TIMESPEC
1162 1188
@@ -1181,8 +1207,8 @@
1181/* Define to 1 if you have the <sys/bsdtty.h> header file. */ 1207/* Define to 1 if you have the <sys/bsdtty.h> header file. */
1182#undef HAVE_SYS_BSDTTY_H 1208#undef HAVE_SYS_BSDTTY_H
1183 1209
1184/* Define to 1 if you have the <sys/capability.h> header file. */ 1210/* Define to 1 if you have the <sys/capsicum.h> header file. */
1185#undef HAVE_SYS_CAPABILITY_H 1211#undef HAVE_SYS_CAPSICUM_H
1186 1212
1187/* Define to 1 if you have the <sys/cdefs.h> header file. */ 1213/* Define to 1 if you have the <sys/cdefs.h> header file. */
1188#undef HAVE_SYS_CDEFS_H 1214#undef HAVE_SYS_CDEFS_H
@@ -1719,9 +1745,6 @@
1719/* Define if you want SELinux support. */ 1745/* Define if you want SELinux support. */
1720#undef WITH_SELINUX 1746#undef WITH_SELINUX
1721 1747
1722/* include SSH protocol version 1 support */
1723#undef WITH_SSH1
1724
1725/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most 1748/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
1726 significant byte first (like Motorola and SPARC, unlike Intel). */ 1749 significant byte first (like Motorola and SPARC, unlike Intel). */
1727#if defined AC_APPLE_UNIVERSAL_BUILD 1750#if defined AC_APPLE_UNIVERSAL_BUILD
@@ -1760,11 +1783,20 @@
1760/* Define if we don't have struct __res_state in resolv.h */ 1783/* Define if we don't have struct __res_state in resolv.h */
1761#undef __res_state 1784#undef __res_state
1762 1785
1786/* Define to rpl_calloc if the replacement function should be used. */
1787#undef calloc
1788
1763/* Define to `__inline__' or `__inline' if that's what the C compiler 1789/* Define to `__inline__' or `__inline' if that's what the C compiler
1764 calls it, or to nothing if 'inline' is not supported under any name. */ 1790 calls it, or to nothing if 'inline' is not supported under any name. */
1765#ifndef __cplusplus 1791#ifndef __cplusplus
1766#undef inline 1792#undef inline
1767#endif 1793#endif
1768 1794
1795/* Define to rpl_malloc if the replacement function should be used. */
1796#undef malloc
1797
1798/* Define to rpl_realloc if the replacement function should be used. */
1799#undef realloc
1800
1769/* type to use in place of socklen_t if not defined */ 1801/* type to use in place of socklen_t if not defined */
1770#undef socklen_t 1802#undef socklen_t
diff --git a/configure b/configure
index 5eaaa392f..b2c2c3b91 100755
--- a/configure
+++ b/configure
@@ -624,7 +624,6 @@ ac_includes_default="\
624#endif" 624#endif"
625 625
626ac_subst_vars='LTLIBOBJS 626ac_subst_vars='LTLIBOBJS
627LIBOBJS
628UNSUPPORTED_ALGORITHMS 627UNSUPPORTED_ALGORITHMS
629TEST_MALLOC_OPTIONS 628TEST_MALLOC_OPTIONS
630TEST_SSH_UTF8 629TEST_SSH_UTF8
@@ -648,7 +647,7 @@ TEST_SSH_ECC
648LIBEDIT 647LIBEDIT
649PKGCONFIG 648PKGCONFIG
650LDNSCONFIG 649LDNSCONFIG
651COMMENT_OUT_RSA1 650LIBOBJS
652LD 651LD
653PATH_PASSWD_PROG 652PATH_PASSWD_PROG
654STARTUP_SCRIPT_SHELL 653STARTUP_SCRIPT_SHELL
@@ -735,13 +734,14 @@ ac_user_opts='
735enable_option_checking 734enable_option_checking
736enable_largefile 735enable_largefile
737with_openssl 736with_openssl
738with_ssh1
739with_stackprotect 737with_stackprotect
740with_hardening 738with_hardening
741with_rpath 739with_rpath
742with_cflags 740with_cflags
741with_cflags_after
743with_cppflags 742with_cppflags
744with_ldflags 743with_ldflags
744with_ldflags_after
745with_libs 745with_libs
746with_Werror 746with_Werror
747with_solaris_contracts 747with_solaris_contracts
@@ -1430,13 +1430,14 @@ Optional Packages:
1430 --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] 1430 --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
1431 --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) 1431 --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
1432 --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** 1432 --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL**
1433 --with-ssh1 Enable support for SSH protocol 1
1434 --without-stackprotect Don't use compiler's stack protection 1433 --without-stackprotect Don't use compiler's stack protection
1435 --without-hardening Don't use toolchain hardening flags 1434 --without-hardening Don't use toolchain hardening flags
1436 --without-rpath Disable auto-added -R linker paths 1435 --without-rpath Disable auto-added -R linker paths
1437 --with-cflags Specify additional flags to pass to compiler 1436 --with-cflags Specify additional flags to pass to compiler
1437 --with-cflags-after Specify additional flags to pass to compiler after configure
1438 --with-cppflags Specify additional flags to pass to preprocessor 1438 --with-cppflags Specify additional flags to pass to preprocessor
1439 --with-ldflags Specify additional flags to pass to linker 1439 --with-ldflags Specify additional flags to pass to linker
1440 --with-ldflags-after Specify additional flags to pass to linker after configure
1440 --with-libs Specify additional libraries to link with 1441 --with-libs Specify additional libraries to link with
1441 --with-Werror Build main code with -Werror 1442 --with-Werror Build main code with -Werror
1442 --with-solaris-contracts Enable Solaris process contracts (experimental) 1443 --with-solaris-contracts Enable Solaris process contracts (experimental)
@@ -5634,14 +5635,11 @@ fi
5634 5635
5635 5636
5636openssl=yes 5637openssl=yes
5637ssh1=no
5638COMMENT_OUT_RSA1="#no ssh1#"
5639 5638
5640# Check whether --with-openssl was given. 5639# Check whether --with-openssl was given.
5641if test "${with_openssl+set}" = set; then : 5640if test "${with_openssl+set}" = set; then :
5642 withval=$with_openssl; if test "x$withval" = "xno" ; then 5641 withval=$with_openssl; if test "x$withval" = "xno" ; then
5643 openssl=no 5642 openssl=no
5644 ssh1=no
5645 fi 5643 fi
5646 5644
5647 5645
@@ -5662,41 +5660,6 @@ else
5662$as_echo "no" >&6; } 5660$as_echo "no" >&6; }
5663fi 5661fi
5664 5662
5665
5666# Check whether --with-ssh1 was given.
5667if test "${with_ssh1+set}" = set; then :
5668 withval=$with_ssh1;
5669 if test "x$withval" = "xyes" ; then
5670 if test "x$openssl" = "xno" ; then
5671 as_fn_error $? "Cannot enable SSH protocol 1 with OpenSSL disabled" "$LINENO" 5
5672 fi
5673 ssh1=yes
5674 COMMENT_OUT_RSA1=""
5675 elif test "x$withval" = "xno" ; then
5676 ssh1=no
5677 else
5678 as_fn_error $? "unknown --with-ssh1 argument" "$LINENO" 5
5679 fi
5680
5681
5682fi
5683
5684{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether SSH protocol 1 support is enabled" >&5
5685$as_echo_n "checking whether SSH protocol 1 support is enabled... " >&6; }
5686if test "x$ssh1" = "xyes" ; then
5687 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
5688$as_echo "yes" >&6; }
5689
5690cat >>confdefs.h <<_ACEOF
5691#define WITH_SSH1 1
5692_ACEOF
5693
5694
5695else
5696 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
5697$as_echo "no" >&6; }
5698fi
5699
5700use_stack_protector=1 5663use_stack_protector=1
5701use_toolchain_hardening=1 5664use_toolchain_hardening=1
5702 5665
@@ -5743,6 +5706,49 @@ CFLAGS="$saved_CFLAGS"
5743 5706
5744if test "$GCC" = "yes" || test "$GCC" = "egcs"; then 5707if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
5745 { 5708 {
5709 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -pipe" >&5
5710$as_echo_n "checking if $CC supports compile flag -pipe... " >&6; }
5711 saved_CFLAGS="$CFLAGS"
5712 CFLAGS="$CFLAGS $WERROR -pipe"
5713 _define_flag=""
5714 test "x$_define_flag" = "x" && _define_flag="-pipe"
5715 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
5716/* end confdefs.h. */
5717
5718#include <stdlib.h>
5719#include <stdio.h>
5720int main(int argc, char **argv) {
5721 /* Some math to catch -ftrapv problems in the toolchain */
5722 int i = 123 * argc, j = 456 + argc, k = 789 - argc;
5723 float l = i * 2.1;
5724 double m = l / 0.5;
5725 long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
5726 printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
5727 exit(0);
5728}
5729
5730_ACEOF
5731if ac_fn_c_try_compile "$LINENO"; then :
5732
5733if `grep -i "unrecognized option" conftest.err >/dev/null`
5734then
5735 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
5736$as_echo "no" >&6; }
5737 CFLAGS="$saved_CFLAGS"
5738else
5739 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
5740$as_echo "yes" >&6; }
5741 CFLAGS="$saved_CFLAGS $_define_flag"
5742fi
5743else
5744 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
5745$as_echo "no" >&6; }
5746 CFLAGS="$saved_CFLAGS"
5747
5748fi
5749rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
5750}
5751 {
5746 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Qunused-arguments" >&5 5752 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Qunused-arguments" >&5
5747$as_echo_n "checking if $CC supports compile flag -Qunused-arguments... " >&6; } 5753$as_echo_n "checking if $CC supports compile flag -Qunused-arguments... " >&6; }
5748 saved_CFLAGS="$CFLAGS" 5754 saved_CFLAGS="$CFLAGS"
@@ -6215,6 +6221,7 @@ $as_echo "no" >&6; }
6215fi 6221fi
6216rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 6222rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
6217} 6223}
6224 if test "x$use_toolchain_hardening" = "x1"; then
6218 { 6225 {
6219 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -D_FORTIFY_SOURCE=2" >&5 6226 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -D_FORTIFY_SOURCE=2" >&5
6220$as_echo_n "checking if $CC supports compile flag -D_FORTIFY_SOURCE=2... " >&6; } 6227$as_echo_n "checking if $CC supports compile flag -D_FORTIFY_SOURCE=2... " >&6; }
@@ -6258,7 +6265,6 @@ $as_echo "no" >&6; }
6258fi 6265fi
6259rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext 6266rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
6260} 6267}
6261 if test "x$use_toolchain_hardening" = "x1"; then
6262 { 6268 {
6263 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,relro" >&5 6269 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,relro" >&5
6264$as_echo_n "checking if $LD supports link flag -Wl,-z,relro... " >&6; } 6270$as_echo_n "checking if $LD supports link flag -Wl,-z,relro... " >&6; }
@@ -6620,6 +6626,19 @@ if test "${with_cflags+set}" = set; then :
6620fi 6626fi
6621 6627
6622 6628
6629
6630# Check whether --with-cflags-after was given.
6631if test "${with_cflags_after+set}" = set; then :
6632 withval=$with_cflags_after;
6633 if test -n "$withval" && test "x$withval" != "xno" && \
6634 test "x${withval}" != "xyes"; then
6635 CFLAGS_AFTER="$withval"
6636 fi
6637
6638
6639fi
6640
6641
6623# Check whether --with-cppflags was given. 6642# Check whether --with-cppflags was given.
6624if test "${with_cppflags+set}" = set; then : 6643if test "${with_cppflags+set}" = set; then :
6625 withval=$with_cppflags; 6644 withval=$with_cppflags;
@@ -6644,6 +6663,18 @@ if test "${with_ldflags+set}" = set; then :
6644fi 6663fi
6645 6664
6646 6665
6666# Check whether --with-ldflags-after was given.
6667if test "${with_ldflags_after+set}" = set; then :
6668 withval=$with_ldflags_after;
6669 if test -n "$withval" && test "x$withval" != "xno" && \
6670 test "x${withval}" != "xyes"; then
6671 LDFLAGS_AFTER="$withval"
6672 fi
6673
6674
6675fi
6676
6677
6647# Check whether --with-libs was given. 6678# Check whether --with-libs was given.
6648if test "${with_libs+set}" = set; then : 6679if test "${with_libs+set}" = set; then :
6649 withval=$with_libs; 6680 withval=$with_libs;
@@ -6712,7 +6743,6 @@ for ac_header in \
6712 sys/audit.h \ 6743 sys/audit.h \
6713 sys/bitypes.h \ 6744 sys/bitypes.h \
6714 sys/bsdtty.h \ 6745 sys/bsdtty.h \
6715 sys/capability.h \
6716 sys/cdefs.h \ 6746 sys/cdefs.h \
6717 sys/dir.h \ 6747 sys/dir.h \
6718 sys/mman.h \ 6748 sys/mman.h \
@@ -6756,6 +6786,25 @@ fi
6756done 6786done
6757 6787
6758 6788
6789# sys/capsicum.h requires sys/types.h
6790for ac_header in sys/capsicum.h
6791do :
6792 ac_fn_c_check_header_compile "$LINENO" "sys/capsicum.h" "ac_cv_header_sys_capsicum_h" "
6793#ifdef HAVE_SYS_TYPES_H
6794# include <sys/types.h>
6795#endif
6796
6797"
6798if test "x$ac_cv_header_sys_capsicum_h" = xyes; then :
6799 cat >>confdefs.h <<_ACEOF
6800#define HAVE_SYS_CAPSICUM_H 1
6801_ACEOF
6802
6803fi
6804
6805done
6806
6807
6759# lastlog.h requires sys/time.h to be included first on Solaris 6808# lastlog.h requires sys/time.h to be included first on Solaris
6760for ac_header in lastlog.h 6809for ac_header in lastlog.h
6761do : 6810do :
@@ -8208,6 +8257,8 @@ $as_echo "#define UNIXWARE_LONG_PASSWORDS 1" >>confdefs.h
8208 8257
8209 $as_echo "#define PASSWD_NEEDS_USERNAME 1" >>confdefs.h 8258 $as_echo "#define PASSWD_NEEDS_USERNAME 1" >>confdefs.h
8210 8259
8260 $as_echo "#define BROKEN_TCGETATTR_ICANON 1" >>confdefs.h
8261
8211 TEST_SHELL=$SHELL # let configure find us a capable shell 8262 TEST_SHELL=$SHELL # let configure find us a capable shell
8212 case "$host" in 8263 case "$host" in
8213 *-*-sysv5SCO_SV*) # SCO OpenServer 6.x 8264 *-*-sysv5SCO_SV*) # SCO OpenServer 6.x
@@ -9631,6 +9682,8 @@ if test "$ac_res" != no; then :
9631fi 9682fi
9632 9683
9633 9684
9685# "Particular Function Checks"
9686# see https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Particular-Functions.html
9634for ac_func in strftime 9687for ac_func in strftime
9635do : 9688do :
9636 ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime" 9689 ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
@@ -9686,6 +9739,149 @@ fi
9686fi 9739fi
9687done 9740done
9688 9741
9742for ac_header in stdlib.h
9743do :
9744 ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
9745if test "x$ac_cv_header_stdlib_h" = xyes; then :
9746 cat >>confdefs.h <<_ACEOF
9747#define HAVE_STDLIB_H 1
9748_ACEOF
9749
9750fi
9751
9752done
9753
9754{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
9755$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
9756if ${ac_cv_func_malloc_0_nonnull+:} false; then :
9757 $as_echo_n "(cached) " >&6
9758else
9759 if test "$cross_compiling" = yes; then :
9760 ac_cv_func_malloc_0_nonnull=no
9761else
9762 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
9763/* end confdefs.h. */
9764#if defined STDC_HEADERS || defined HAVE_STDLIB_H
9765# include <stdlib.h>
9766#else
9767char *malloc ();
9768#endif
9769
9770int
9771main ()
9772{
9773return ! malloc (0);
9774 ;
9775 return 0;
9776}
9777_ACEOF
9778if ac_fn_c_try_run "$LINENO"; then :
9779 ac_cv_func_malloc_0_nonnull=yes
9780else
9781 ac_cv_func_malloc_0_nonnull=no
9782fi
9783rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
9784 conftest.$ac_objext conftest.beam conftest.$ac_ext
9785fi
9786
9787fi
9788{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
9789$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
9790if test $ac_cv_func_malloc_0_nonnull = yes; then :
9791
9792$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
9793
9794else
9795 $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
9796
9797 case " $LIBOBJS " in
9798 *" malloc.$ac_objext "* ) ;;
9799 *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
9800 ;;
9801esac
9802
9803
9804$as_echo "#define malloc rpl_malloc" >>confdefs.h
9805
9806fi
9807
9808
9809for ac_header in stdlib.h
9810do :
9811 ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
9812if test "x$ac_cv_header_stdlib_h" = xyes; then :
9813 cat >>confdefs.h <<_ACEOF
9814#define HAVE_STDLIB_H 1
9815_ACEOF
9816
9817fi
9818
9819done
9820
9821{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible realloc" >&5
9822$as_echo_n "checking for GNU libc compatible realloc... " >&6; }
9823if ${ac_cv_func_realloc_0_nonnull+:} false; then :
9824 $as_echo_n "(cached) " >&6
9825else
9826 if test "$cross_compiling" = yes; then :
9827 ac_cv_func_realloc_0_nonnull=no
9828else
9829 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
9830/* end confdefs.h. */
9831#if defined STDC_HEADERS || defined HAVE_STDLIB_H
9832# include <stdlib.h>
9833#else
9834char *realloc ();
9835#endif
9836
9837int
9838main ()
9839{
9840return ! realloc (0, 0);
9841 ;
9842 return 0;
9843}
9844_ACEOF
9845if ac_fn_c_try_run "$LINENO"; then :
9846 ac_cv_func_realloc_0_nonnull=yes
9847else
9848 ac_cv_func_realloc_0_nonnull=no
9849fi
9850rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
9851 conftest.$ac_objext conftest.beam conftest.$ac_ext
9852fi
9853
9854fi
9855{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_realloc_0_nonnull" >&5
9856$as_echo "$ac_cv_func_realloc_0_nonnull" >&6; }
9857if test $ac_cv_func_realloc_0_nonnull = yes; then :
9858
9859$as_echo "#define HAVE_REALLOC 1" >>confdefs.h
9860
9861else
9862 $as_echo "#define HAVE_REALLOC 0" >>confdefs.h
9863
9864 case " $LIBOBJS " in
9865 *" realloc.$ac_objext "* ) ;;
9866 *) LIBOBJS="$LIBOBJS realloc.$ac_objext"
9867 ;;
9868esac
9869
9870
9871$as_echo "#define realloc rpl_realloc" >>confdefs.h
9872
9873fi
9874
9875
9876# autoconf doesn't have AC_FUNC_CALLOC so fake it if malloc returns NULL;
9877if test "x$ac_cv_func_malloc_0_nonnull" != "xyes"; then
9878
9879$as_echo "#define HAVE_CALLOC 0" >>confdefs.h
9880
9881
9882$as_echo "#define calloc rpl_calloc" >>confdefs.h
9883
9884fi
9689 9885
9690# Check for ALTDIRFUNC glob() extension 9886# Check for ALTDIRFUNC glob() extension
9691{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_ALTDIRFUNC support" >&5 9887{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_ALTDIRFUNC support" >&5
@@ -10068,6 +10264,7 @@ fi
10068 else 10264 else
10069 LIBS="$LIBS `$LDNSCONFIG --libs`" 10265 LIBS="$LIBS `$LDNSCONFIG --libs`"
10070 CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`" 10266 CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`"
10267 ldns=yes
10071 fi 10268 fi
10072 elif test "x$withval" != "xno" ; then 10269 elif test "x$withval" != "xno" ; then
10073 CPPFLAGS="$CPPFLAGS -I${withval}/include" 10270 CPPFLAGS="$CPPFLAGS -I${withval}/include"
@@ -10647,6 +10844,7 @@ for ac_func in \
10647 fchmod \ 10844 fchmod \
10648 fchown \ 10845 fchown \
10649 freeaddrinfo \ 10846 freeaddrinfo \
10847 freezero \
10650 fstatfs \ 10848 fstatfs \
10651 fstatvfs \ 10849 fstatvfs \
10652 futimes \ 10850 futimes \
@@ -10655,6 +10853,7 @@ for ac_func in \
10655 getgrouplist \ 10853 getgrouplist \
10656 getnameinfo \ 10854 getnameinfo \
10657 getopt \ 10855 getopt \
10856 getpagesize \
10658 getpeereid \ 10857 getpeereid \
10659 getpeerucred \ 10858 getpeerucred \
10660 getpgid \ 10859 getpgid \
@@ -10685,6 +10884,7 @@ for ac_func in \
10685 readpassphrase \ 10884 readpassphrase \
10686 reallocarray \ 10885 reallocarray \
10687 recvmsg \ 10886 recvmsg \
10887 recallocarray \
10688 rresvport_af \ 10888 rresvport_af \
10689 sendmsg \ 10889 sendmsg \
10690 setdtablesize \ 10890 setdtablesize \
@@ -10718,6 +10918,7 @@ for ac_func in \
10718 strnlen \ 10918 strnlen \
10719 strnvis \ 10919 strnvis \
10720 strptime \ 10920 strptime \
10921 strsignal \
10721 strtonum \ 10922 strtonum \
10722 strtoll \ 10923 strtoll \
10723 strtoul \ 10924 strtoul \
@@ -12484,7 +12685,11 @@ if ac_fn_c_try_run "$LINENO"; then :
12484 10000*|0*) 12685 10000*|0*)
12485 as_fn_error $? "OpenSSL >= 1.0.1 required (have \"$ssl_library_ver\")" "$LINENO" 5 12686 as_fn_error $? "OpenSSL >= 1.0.1 required (have \"$ssl_library_ver\")" "$LINENO" 5
12486 ;; 12687 ;;
12487 *) ;; 12688 100*) ;; # 1.0.x
12689 200*) ;; # LibreSSL
12690 *)
12691 as_fn_error $? "OpenSSL >= 1.1.0 is not yet supported (have \"$ssl_library_ver\")" "$LINENO" 5
12692 ;;
12488 esac 12693 esac
12489 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_library_ver" >&5 12694 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_library_ver" >&5
12490$as_echo "$ssl_library_ver" >&6; } 12695$as_echo "$ssl_library_ver" >&6; }
@@ -13053,9 +13258,6 @@ $as_echo_n "checking whether OpenSSL has NID_X9_62_prime256v1... " >&6; }
13053 #include <openssl/evp.h> 13258 #include <openssl/evp.h>
13054 #include <openssl/objects.h> 13259 #include <openssl/objects.h>
13055 #include <openssl/opensslv.h> 13260 #include <openssl/opensslv.h>
13056 #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
13057 # error "OpenSSL < 0.9.8g has unreliable ECC code"
13058 #endif
13059 13261
13060int 13262int
13061main () 13263main ()
@@ -13091,9 +13293,6 @@ $as_echo_n "checking whether OpenSSL has NID_secp384r1... " >&6; }
13091 #include <openssl/evp.h> 13293 #include <openssl/evp.h>
13092 #include <openssl/objects.h> 13294 #include <openssl/objects.h>
13093 #include <openssl/opensslv.h> 13295 #include <openssl/opensslv.h>
13094 #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
13095 # error "OpenSSL < 0.9.8g has unreliable ECC code"
13096 #endif
13097 13296
13098int 13297int
13099main () 13298main ()
@@ -13129,9 +13328,6 @@ $as_echo_n "checking whether OpenSSL has NID_secp521r1... " >&6; }
13129 #include <openssl/evp.h> 13328 #include <openssl/evp.h>
13130 #include <openssl/objects.h> 13329 #include <openssl/objects.h>
13131 #include <openssl/opensslv.h> 13330 #include <openssl/opensslv.h>
13132 #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
13133 # error "OpenSSL < 0.9.8g has unreliable ECC code"
13134 #endif
13135 13331
13136int 13332int
13137main () 13333main ()
@@ -13858,6 +14054,7 @@ $as_echo_n "checking if select works with descriptor rlimit... " >&6; }
13858if test "$cross_compiling" = yes; then : 14054if test "$cross_compiling" = yes; then :
13859 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5 14055 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5
13860$as_echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} 14056$as_echo "$as_me: WARNING: cross compiling: assuming yes" >&2;}
14057 select_works_with_rlimit=yes
13861 14058
13862else 14059else
13863 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 14060 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13918,6 +14115,7 @@ $as_echo_n "checking if setrlimit(RLIMIT_NOFILE,{0,0}) works... " >&6; }
13918if test "$cross_compiling" = yes; then : 14115if test "$cross_compiling" = yes; then :
13919 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5 14116 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5
13920$as_echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} 14117$as_echo "$as_me: WARNING: cross compiling: assuming yes" >&2;}
14118 rlimit_nofile_zero_works=yes
13921 14119
13922else 14120else
13923 cat confdefs.h - <<_ACEOF >conftest.$ac_ext 14121 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -14052,10 +14250,10 @@ $as_echo "#define SANDBOX_SECCOMP_FILTER 1" >>confdefs.h
14052 14250
14053elif test "x$sandbox_arg" = "xcapsicum" || \ 14251elif test "x$sandbox_arg" = "xcapsicum" || \
14054 ( test -z "$sandbox_arg" && \ 14252 ( test -z "$sandbox_arg" && \
14055 test "x$ac_cv_header_sys_capability_h" = "xyes" && \ 14253 test "x$ac_cv_header_sys_capsicum_h" = "xyes" && \
14056 test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then 14254 test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then
14057 test "x$ac_cv_header_sys_capability_h" != "xyes" && \ 14255 test "x$ac_cv_header_sys_capsicum_h" != "xyes" && \
14058 as_fn_error $? "capsicum sandbox requires sys/capability.h header" "$LINENO" 5 14256 as_fn_error $? "capsicum sandbox requires sys/capsicum.h header" "$LINENO" 5
14059 test "x$ac_cv_func_cap_rights_limit" != "xyes" && \ 14257 test "x$ac_cv_func_cap_rights_limit" != "xyes" && \
14060 as_fn_error $? "capsicum sandbox requires cap_rights_limit function" "$LINENO" 5 14258 as_fn_error $? "capsicum sandbox requires cap_rights_limit function" "$LINENO" 5
14061 SANDBOX_STYLE="capsicum" 14259 SANDBOX_STYLE="capsicum"
@@ -16187,6 +16385,26 @@ _ACEOF
16187 16385
16188fi 16386fi
16189 16387
16388ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default"
16389if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then :
16390
16391cat >>confdefs.h <<_ACEOF
16392#define HAVE_STRUCT_STAT_ST_MTIM 1
16393_ACEOF
16394
16395
16396fi
16397
16398ac_fn_c_check_member "$LINENO" "struct stat" "st_mtime" "ac_cv_member_struct_stat_st_mtime" "$ac_includes_default"
16399if test "x$ac_cv_member_struct_stat_st_mtime" = xyes; then :
16400
16401cat >>confdefs.h <<_ACEOF
16402#define HAVE_STRUCT_STAT_ST_MTIME 1
16403_ACEOF
16404
16405
16406fi
16407
16190ac_fn_c_check_member "$LINENO" "struct passwd" "pw_gecos" "ac_cv_member_struct_passwd_pw_gecos" " 16408ac_fn_c_check_member "$LINENO" "struct passwd" "pw_gecos" "ac_cv_member_struct_passwd_pw_gecos" "
16191#include <sys/types.h> 16409#include <sys/types.h>
16192#include <pwd.h> 16410#include <pwd.h>
@@ -19055,6 +19273,9 @@ TEST_MALLOC_OPTIONS=$TEST_MALLOC_OPTIONS
19055UNSUPPORTED_ALGORITHMS=$unsupported_algorithms 19273UNSUPPORTED_ALGORITHMS=$unsupported_algorithms
19056 19274
19057 19275
19276CFLAGS="${CFLAGS} ${CFLAGS_AFTER}"
19277LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}"
19278
19058 19279
19059ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/regress/Makefile survey.sh" 19280ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/regress/Makefile survey.sh"
19060 19281
diff --git a/configure.ac b/configure.ac
index c2878e3d4..889f50637 100644
--- a/configure.ac
+++ b/configure.ac
@@ -109,13 +109,10 @@ AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [
109]) 109])
110 110
111openssl=yes 111openssl=yes
112ssh1=no
113COMMENT_OUT_RSA1="#no ssh1#"
114AC_ARG_WITH([openssl], 112AC_ARG_WITH([openssl],
115 [ --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ], 113 [ --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ],
116 [ if test "x$withval" = "xno" ; then 114 [ if test "x$withval" = "xno" ; then
117 openssl=no 115 openssl=no
118 ssh1=no
119 fi 116 fi
120 ] 117 ]
121) 118)
@@ -127,31 +124,6 @@ else
127 AC_MSG_RESULT([no]) 124 AC_MSG_RESULT([no])
128fi 125fi
129 126
130AC_ARG_WITH([ssh1],
131 [ --with-ssh1 Enable support for SSH protocol 1],
132 [
133 if test "x$withval" = "xyes" ; then
134 if test "x$openssl" = "xno" ; then
135 AC_MSG_ERROR([Cannot enable SSH protocol 1 with OpenSSL disabled])
136 fi
137 ssh1=yes
138 COMMENT_OUT_RSA1=""
139 elif test "x$withval" = "xno" ; then
140 ssh1=no
141 else
142 AC_MSG_ERROR([unknown --with-ssh1 argument])
143 fi
144 ]
145)
146AC_MSG_CHECKING([whether SSH protocol 1 support is enabled])
147if test "x$ssh1" = "xyes" ; then
148 AC_MSG_RESULT([yes])
149 AC_DEFINE_UNQUOTED([WITH_SSH1], [1], [include SSH protocol version 1 support])
150 AC_SUBST([COMMENT_OUT_RSA1])
151else
152 AC_MSG_RESULT([no])
153fi
154
155use_stack_protector=1 127use_stack_protector=1
156use_toolchain_hardening=1 128use_toolchain_hardening=1
157AC_ARG_WITH([stackprotect], 129AC_ARG_WITH([stackprotect],
@@ -179,6 +151,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])],
179CFLAGS="$saved_CFLAGS" 151CFLAGS="$saved_CFLAGS"
180 152
181if test "$GCC" = "yes" || test "$GCC" = "egcs"; then 153if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
154 OSSH_CHECK_CFLAG_COMPILE([-pipe])
182 OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments]) 155 OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments])
183 OSSH_CHECK_CFLAG_COMPILE([-Wunknown-warning-option]) 156 OSSH_CHECK_CFLAG_COMPILE([-Wunknown-warning-option])
184 OSSH_CHECK_CFLAG_COMPILE([-Wall]) 157 OSSH_CHECK_CFLAG_COMPILE([-Wall])
@@ -190,8 +163,8 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
190 OSSH_CHECK_CFLAG_COMPILE([-Wpointer-sign], [-Wno-pointer-sign]) 163 OSSH_CHECK_CFLAG_COMPILE([-Wpointer-sign], [-Wno-pointer-sign])
191 OSSH_CHECK_CFLAG_COMPILE([-Wunused-result], [-Wno-unused-result]) 164 OSSH_CHECK_CFLAG_COMPILE([-Wunused-result], [-Wno-unused-result])
192 OSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing]) 165 OSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing])
193 OSSH_CHECK_CFLAG_COMPILE([-D_FORTIFY_SOURCE=2])
194 if test "x$use_toolchain_hardening" = "x1"; then 166 if test "x$use_toolchain_hardening" = "x1"; then
167 OSSH_CHECK_CFLAG_COMPILE([-D_FORTIFY_SOURCE=2])
195 OSSH_CHECK_LDFLAG_LINK([-Wl,-z,relro]) 168 OSSH_CHECK_LDFLAG_LINK([-Wl,-z,relro])
196 OSSH_CHECK_LDFLAG_LINK([-Wl,-z,now]) 169 OSSH_CHECK_LDFLAG_LINK([-Wl,-z,now])
197 OSSH_CHECK_LDFLAG_LINK([-Wl,-z,noexecstack]) 170 OSSH_CHECK_LDFLAG_LINK([-Wl,-z,noexecstack])
@@ -316,6 +289,16 @@ AC_ARG_WITH([cflags],
316 fi 289 fi
317 ] 290 ]
318) 291)
292
293AC_ARG_WITH([cflags-after],
294 [ --with-cflags-after Specify additional flags to pass to compiler after configure],
295 [
296 if test -n "$withval" && test "x$withval" != "xno" && \
297 test "x${withval}" != "xyes"; then
298 CFLAGS_AFTER="$withval"
299 fi
300 ]
301)
319AC_ARG_WITH([cppflags], 302AC_ARG_WITH([cppflags],
320 [ --with-cppflags Specify additional flags to pass to preprocessor] , 303 [ --with-cppflags Specify additional flags to pass to preprocessor] ,
321 [ 304 [
@@ -334,6 +317,15 @@ AC_ARG_WITH([ldflags],
334 fi 317 fi
335 ] 318 ]
336) 319)
320AC_ARG_WITH([ldflags-after],
321 [ --with-ldflags-after Specify additional flags to pass to linker after configure],
322 [
323 if test -n "$withval" && test "x$withval" != "xno" && \
324 test "x${withval}" != "xyes"; then
325 LDFLAGS_AFTER="$withval"
326 fi
327 ]
328)
337AC_ARG_WITH([libs], 329AC_ARG_WITH([libs],
338 [ --with-libs Specify additional libraries to link with], 330 [ --with-libs Specify additional libraries to link with],
339 [ 331 [
@@ -397,7 +389,6 @@ AC_CHECK_HEADERS([ \
397 sys/audit.h \ 389 sys/audit.h \
398 sys/bitypes.h \ 390 sys/bitypes.h \
399 sys/bsdtty.h \ 391 sys/bsdtty.h \
400 sys/capability.h \
401 sys/cdefs.h \ 392 sys/cdefs.h \
402 sys/dir.h \ 393 sys/dir.h \
403 sys/mman.h \ 394 sys/mman.h \
@@ -429,6 +420,13 @@ AC_CHECK_HEADERS([ \
429 wchar.h \ 420 wchar.h \
430]) 421])
431 422
423# sys/capsicum.h requires sys/types.h
424AC_CHECK_HEADERS([sys/capsicum.h], [], [], [
425#ifdef HAVE_SYS_TYPES_H
426# include <sys/types.h>
427#endif
428])
429
432# lastlog.h requires sys/time.h to be included first on Solaris 430# lastlog.h requires sys/time.h to be included first on Solaris
433AC_CHECK_HEADERS([lastlog.h], [], [], [ 431AC_CHECK_HEADERS([lastlog.h], [], [], [
434#ifdef HAVE_SYS_TIME_H 432#ifdef HAVE_SYS_TIME_H
@@ -1007,6 +1005,7 @@ mips-sony-bsd|mips-sony-newsos4)
1007 AC_DEFINE([BROKEN_SETREUID]) 1005 AC_DEFINE([BROKEN_SETREUID])
1008 AC_DEFINE([BROKEN_SETREGID]) 1006 AC_DEFINE([BROKEN_SETREGID])
1009 AC_DEFINE([PASSWD_NEEDS_USERNAME]) 1007 AC_DEFINE([PASSWD_NEEDS_USERNAME])
1008 AC_DEFINE([BROKEN_TCGETATTR_ICANON])
1010 TEST_SHELL=$SHELL # let configure find us a capable shell 1009 TEST_SHELL=$SHELL # let configure find us a capable shell
1011 case "$host" in 1010 case "$host" in
1012 *-*-sysv5SCO_SV*) # SCO OpenServer 6.x 1011 *-*-sysv5SCO_SV*) # SCO OpenServer 6.x
@@ -1332,7 +1331,17 @@ AC_CHECK_FUNCS([fmt_scaled scan_scaled login logout openpty updwtmp logwtmp])
1332AC_SEARCH_LIBS([inet_ntop], [resolv nsl]) 1331AC_SEARCH_LIBS([inet_ntop], [resolv nsl])
1333AC_SEARCH_LIBS([gethostbyname], [resolv nsl]) 1332AC_SEARCH_LIBS([gethostbyname], [resolv nsl])
1334 1333
1334# "Particular Function Checks"
1335# see https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Particular-Functions.html
1335AC_FUNC_STRFTIME 1336AC_FUNC_STRFTIME
1337AC_FUNC_MALLOC
1338AC_FUNC_REALLOC
1339# autoconf doesn't have AC_FUNC_CALLOC so fake it if malloc returns NULL;
1340if test "x$ac_cv_func_malloc_0_nonnull" != "xyes"; then
1341 AC_DEFINE(HAVE_CALLOC, 0, [calloc(x, 0) returns NULL])
1342 AC_DEFINE(calloc, rpl_calloc,
1343 [Define to rpl_calloc if the replacement function should be used.])
1344fi
1336 1345
1337# Check for ALTDIRFUNC glob() extension 1346# Check for ALTDIRFUNC glob() extension
1338AC_MSG_CHECKING([for GLOB_ALTDIRFUNC support]) 1347AC_MSG_CHECKING([for GLOB_ALTDIRFUNC support])
@@ -1486,6 +1495,7 @@ AC_ARG_WITH(ldns,
1486 else 1495 else
1487 LIBS="$LIBS `$LDNSCONFIG --libs`" 1496 LIBS="$LIBS `$LDNSCONFIG --libs`"
1488 CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`" 1497 CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`"
1498 ldns=yes
1489 fi 1499 fi
1490 elif test "x$withval" != "xno" ; then 1500 elif test "x$withval" != "xno" ; then
1491 CPPFLAGS="$CPPFLAGS -I${withval}/include" 1501 CPPFLAGS="$CPPFLAGS -I${withval}/include"
@@ -1696,6 +1706,7 @@ AC_CHECK_FUNCS([ \
1696 fchmod \ 1706 fchmod \
1697 fchown \ 1707 fchown \
1698 freeaddrinfo \ 1708 freeaddrinfo \
1709 freezero \
1699 fstatfs \ 1710 fstatfs \
1700 fstatvfs \ 1711 fstatvfs \
1701 futimes \ 1712 futimes \
@@ -1704,6 +1715,7 @@ AC_CHECK_FUNCS([ \
1704 getgrouplist \ 1715 getgrouplist \
1705 getnameinfo \ 1716 getnameinfo \
1706 getopt \ 1717 getopt \
1718 getpagesize \
1707 getpeereid \ 1719 getpeereid \
1708 getpeerucred \ 1720 getpeerucred \
1709 getpgid \ 1721 getpgid \
@@ -1734,6 +1746,7 @@ AC_CHECK_FUNCS([ \
1734 readpassphrase \ 1746 readpassphrase \
1735 reallocarray \ 1747 reallocarray \
1736 recvmsg \ 1748 recvmsg \
1749 recallocarray \
1737 rresvport_af \ 1750 rresvport_af \
1738 sendmsg \ 1751 sendmsg \
1739 setdtablesize \ 1752 setdtablesize \
@@ -1767,6 +1780,7 @@ AC_CHECK_FUNCS([ \
1767 strnlen \ 1780 strnlen \
1768 strnvis \ 1781 strnvis \
1769 strptime \ 1782 strptime \
1783 strsignal \
1770 strtonum \ 1784 strtonum \
1771 strtoll \ 1785 strtoll \
1772 strtoul \ 1786 strtoul \
@@ -2535,7 +2549,11 @@ if test "x$openssl" = "xyes" ; then
2535 10000*|0*) 2549 10000*|0*)
2536 AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")]) 2550 AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
2537 ;; 2551 ;;
2538 *) ;; 2552 100*) ;; # 1.0.x
2553 200*) ;; # LibreSSL
2554 *)
2555 AC_MSG_ERROR([OpenSSL >= 1.1.0 is not yet supported (have "$ssl_library_ver")])
2556 ;;
2539 esac 2557 esac
2540 AC_MSG_RESULT([$ssl_library_ver]) 2558 AC_MSG_RESULT([$ssl_library_ver])
2541 ], 2559 ],
@@ -2768,9 +2786,6 @@ if test "x$openssl" = "xyes" ; then
2768 #include <openssl/evp.h> 2786 #include <openssl/evp.h>
2769 #include <openssl/objects.h> 2787 #include <openssl/objects.h>
2770 #include <openssl/opensslv.h> 2788 #include <openssl/opensslv.h>
2771 #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
2772 # error "OpenSSL < 0.9.8g has unreliable ECC code"
2773 #endif
2774 ]], [[ 2789 ]], [[
2775 EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 2790 EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
2776 const EVP_MD *m = EVP_sha256(); /* We need this too */ 2791 const EVP_MD *m = EVP_sha256(); /* We need this too */
@@ -2789,9 +2804,6 @@ if test "x$openssl" = "xyes" ; then
2789 #include <openssl/evp.h> 2804 #include <openssl/evp.h>
2790 #include <openssl/objects.h> 2805 #include <openssl/objects.h>
2791 #include <openssl/opensslv.h> 2806 #include <openssl/opensslv.h>
2792 #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
2793 # error "OpenSSL < 0.9.8g has unreliable ECC code"
2794 #endif
2795 ]], [[ 2807 ]], [[
2796 EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); 2808 EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1);
2797 const EVP_MD *m = EVP_sha384(); /* We need this too */ 2809 const EVP_MD *m = EVP_sha384(); /* We need this too */
@@ -2810,9 +2822,6 @@ if test "x$openssl" = "xyes" ; then
2810 #include <openssl/evp.h> 2822 #include <openssl/evp.h>
2811 #include <openssl/objects.h> 2823 #include <openssl/objects.h>
2812 #include <openssl/opensslv.h> 2824 #include <openssl/opensslv.h>
2813 #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */
2814 # error "OpenSSL < 0.9.8g has unreliable ECC code"
2815 #endif
2816 ]], [[ 2825 ]], [[
2817 EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); 2826 EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
2818 const EVP_MD *m = EVP_sha512(); /* We need this too */ 2827 const EVP_MD *m = EVP_sha512(); /* We need this too */
@@ -3197,7 +3206,8 @@ AC_RUN_IFELSE(
3197 select_works_with_rlimit=yes], 3206 select_works_with_rlimit=yes],
3198 [AC_MSG_RESULT([no]) 3207 [AC_MSG_RESULT([no])
3199 select_works_with_rlimit=no], 3208 select_works_with_rlimit=no],
3200 [AC_MSG_WARN([cross compiling: assuming yes])] 3209 [AC_MSG_WARN([cross compiling: assuming yes])
3210 select_works_with_rlimit=yes]
3201) 3211)
3202 3212
3203AC_MSG_CHECKING([if setrlimit(RLIMIT_NOFILE,{0,0}) works]) 3213AC_MSG_CHECKING([if setrlimit(RLIMIT_NOFILE,{0,0}) works])
@@ -3223,7 +3233,8 @@ AC_RUN_IFELSE(
3223 rlimit_nofile_zero_works=yes], 3233 rlimit_nofile_zero_works=yes],
3224 [AC_MSG_RESULT([no]) 3234 [AC_MSG_RESULT([no])
3225 rlimit_nofile_zero_works=no], 3235 rlimit_nofile_zero_works=no],
3226 [AC_MSG_WARN([cross compiling: assuming yes])] 3236 [AC_MSG_WARN([cross compiling: assuming yes])
3237 rlimit_nofile_zero_works=yes]
3227) 3238)
3228 3239
3229AC_MSG_CHECKING([if setrlimit RLIMIT_FSIZE works]) 3240AC_MSG_CHECKING([if setrlimit RLIMIT_FSIZE works])
@@ -3286,10 +3297,10 @@ elif test "x$sandbox_arg" = "xseccomp_filter" || \
3286 AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter]) 3297 AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter])
3287elif test "x$sandbox_arg" = "xcapsicum" || \ 3298elif test "x$sandbox_arg" = "xcapsicum" || \
3288 ( test -z "$sandbox_arg" && \ 3299 ( test -z "$sandbox_arg" && \
3289 test "x$ac_cv_header_sys_capability_h" = "xyes" && \ 3300 test "x$ac_cv_header_sys_capsicum_h" = "xyes" && \
3290 test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then 3301 test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then
3291 test "x$ac_cv_header_sys_capability_h" != "xyes" && \ 3302 test "x$ac_cv_header_sys_capsicum_h" != "xyes" && \
3292 AC_MSG_ERROR([capsicum sandbox requires sys/capability.h header]) 3303 AC_MSG_ERROR([capsicum sandbox requires sys/capsicum.h header])
3293 test "x$ac_cv_func_cap_rights_limit" != "xyes" && \ 3304 test "x$ac_cv_func_cap_rights_limit" != "xyes" && \
3294 AC_MSG_ERROR([capsicum sandbox requires cap_rights_limit function]) 3305 AC_MSG_ERROR([capsicum sandbox requires cap_rights_limit function])
3295 SANDBOX_STYLE="capsicum" 3306 SANDBOX_STYLE="capsicum"
@@ -3845,6 +3856,8 @@ OSSH_CHECK_HEADER_FOR_FIELD([ut_time], [utmpx.h], [HAVE_TIME_IN_UTMPX])
3845OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmpx.h], [HAVE_TV_IN_UTMPX]) 3856OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmpx.h], [HAVE_TV_IN_UTMPX])
3846 3857
3847AC_CHECK_MEMBERS([struct stat.st_blksize]) 3858AC_CHECK_MEMBERS([struct stat.st_blksize])
3859AC_CHECK_MEMBERS([struct stat.st_mtim])
3860AC_CHECK_MEMBERS([struct stat.st_mtime])
3848AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_class, 3861AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_class,
3849struct passwd.pw_change, struct passwd.pw_expire], 3862struct passwd.pw_change, struct passwd.pw_expire],
3850[], [], [[ 3863[], [], [[
@@ -5044,6 +5057,9 @@ AC_SUBST([TEST_SSH_UTF8], [$TEST_SSH_UTF8])
5044AC_SUBST([TEST_MALLOC_OPTIONS], [$TEST_MALLOC_OPTIONS]) 5057AC_SUBST([TEST_MALLOC_OPTIONS], [$TEST_MALLOC_OPTIONS])
5045AC_SUBST([UNSUPPORTED_ALGORITHMS], [$unsupported_algorithms]) 5058AC_SUBST([UNSUPPORTED_ALGORITHMS], [$unsupported_algorithms])
5046 5059
5060CFLAGS="${CFLAGS} ${CFLAGS_AFTER}"
5061LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}"
5062
5047AC_EXEEXT 5063AC_EXEEXT
5048AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ 5064AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
5049 openbsd-compat/Makefile openbsd-compat/regress/Makefile \ 5065 openbsd-compat/Makefile openbsd-compat/regress/Makefile \
diff --git a/contrib/aix/README b/contrib/aix/README
index 2a299350a..4a11ae703 100644
--- a/contrib/aix/README
+++ b/contrib/aix/README
@@ -35,7 +35,7 @@ The script treats all packages as USR packages (not ROOT+USR when
35appropriate). It seems to work, though...... 35appropriate). It seems to work, though......
36 36
37If there are any patches to this that have not yet been integrated they 37If there are any patches to this that have not yet been integrated they
38may be found at http://www.zip.com.au/~dtucker/openssh/. 38may be found at http://www.dtucker.net/openssh/.
39 39
40 40
41Disclaimer: 41Disclaimer:
diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec
index 7de45457a..a96a36e49 100644
--- a/contrib/redhat/openssh.spec
+++ b/contrib/redhat/openssh.spec
@@ -1,4 +1,4 @@
1%define ver 7.5p1 1%define ver 7.6p1
2%define rel 1 2%define rel 1
3 3
4# OpenSSH privilege separation requires a user & group ID 4# OpenSSH privilege separation requires a user & group ID
diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id
index bef5c95d9..b83b83619 100644
--- a/contrib/ssh-copy-id
+++ b/contrib/ssh-copy-id
@@ -1,6 +1,6 @@
1#!/bin/sh 1#!/bin/sh
2 2
3# Copyright (c) 1999-2013 Philip Hands <phil@hands.com> 3# Copyright (c) 1999-2016 Philip Hands <phil@hands.com>
4# 2013 Martin Kletzander <mkletzan@redhat.com> 4# 2013 Martin Kletzander <mkletzan@redhat.com>
5# 2010 Adeodato =?iso-8859-1?Q?Sim=F3?= <asp16@alu.ua.es> 5# 2010 Adeodato =?iso-8859-1?Q?Sim=F3?= <asp16@alu.ua.es>
6# 2010 Eric Moret <eric.moret@gmail.com> 6# 2010 Eric Moret <eric.moret@gmail.com>
@@ -56,7 +56,8 @@ then
56 fi 56 fi
57fi 57fi
58 58
59DEFAULT_PUB_ID_FILE="$HOME/$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)" 59most_recent_id="$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)"
60DEFAULT_PUB_ID_FILE="${most_recent_id:+$HOME/}$most_recent_id"
60 61
61usage () { 62usage () {
62 printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2 63 printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2
@@ -74,6 +75,11 @@ quote() {
74use_id_file() { 75use_id_file() {
75 local L_ID_FILE="$1" 76 local L_ID_FILE="$1"
76 77
78 if [ -z "$L_ID_FILE" ] ; then
79 printf "%s: ERROR: no ID file found\n" "$0"
80 exit 1
81 fi
82
77 if expr "$L_ID_FILE" : ".*\.pub$" >/dev/null ; then 83 if expr "$L_ID_FILE" : ".*\.pub$" >/dev/null ; then
78 PUB_ID_FILE="$L_ID_FILE" 84 PUB_ID_FILE="$L_ID_FILE"
79 else 85 else
@@ -287,9 +293,10 @@ case "$REMOTE_VERSION" in
287 *) 293 *)
288 # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect 294 # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect
289 populate_new_ids 0 295 populate_new_ids 0
290 # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; 'cd' to be at $HOME; and all on one line, because tcsh. 296 # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
297 # 'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh.
291 [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ 298 [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \
292 ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ 299 ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
293 || exit 1 300 || exit 1
294 ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) 301 ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l)
295 ;; 302 ;;
diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec
index e62be39d0..fdb3578cb 100644
--- a/contrib/suse/openssh.spec
+++ b/contrib/suse/openssh.spec
@@ -13,7 +13,7 @@
13 13
14Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation 14Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
15Name: openssh 15Name: openssh
16Version: 7.5p1 16Version: 7.6p1
17URL: https://www.openssh.com/ 17URL: https://www.openssh.com/
18Release: 1 18Release: 1
19Source0: openssh-%{version}.tar.gz 19Source0: openssh-%{version}.tar.gz
diff --git a/deattack.c b/deattack.c
deleted file mode 100644
index e76481a6d..000000000
--- a/deattack.c
+++ /dev/null
@@ -1,165 +0,0 @@
1/* $OpenBSD: deattack.c,v 1.32 2015/01/20 23:14:00 deraadt Exp $ */
2/*
3 * Cryptographic attack detector for ssh - source code
4 *
5 * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.
6 *
7 * All rights reserved. Redistribution and use in source and binary
8 * forms, with or without modification, are permitted provided that
9 * this copyright notice is retained.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE
13 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
14 * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS
15 * SOFTWARE.
16 *
17 * Ariel Futoransky <futo@core-sdi.com>
18 * <http://www.core-sdi.com>
19 */
20
21#include "includes.h"
22
23#include <string.h>
24#include <stdio.h>
25#include <stdlib.h>
26
27#include "deattack.h"
28#include "crc32.h"
29#include "sshbuf.h"
30#include "misc.h"
31
32/*
33 * CRC attack detection has a worst-case behaviour that is O(N^3) over
34 * the number of identical blocks in a packet. This behaviour can be
35 * exploited to create a limited denial of service attack.
36 *
37 * However, because we are dealing with encrypted data, identical
38 * blocks should only occur every 2^35 maximally-sized packets or so.
39 * Consequently, we can detect this DoS by looking for identical blocks
40 * in a packet.
41 *
42 * The parameter below determines how many identical blocks we will
43 * accept in a single packet, trading off between attack detection and
44 * likelihood of terminating a legitimate connection. A value of 32
45 * corresponds to an average of 2^40 messages before an attack is
46 * misdetected
47 */
48#define MAX_IDENTICAL 32
49
50/* SSH Constants */
51#define SSH_MAXBLOCKS (32 * 1024)
52#define SSH_BLOCKSIZE (8)
53
54/* Hashing constants */
55#define HASH_MINSIZE (8 * 1024)
56#define HASH_ENTRYSIZE (2)
57#define HASH_FACTOR(x) ((x)*3/2)
58#define HASH_UNUSEDCHAR (0xff)
59#define HASH_UNUSED (0xffff)
60#define HASH_IV (0xfffe)
61
62#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE)
63
64
65/* Hash function (Input keys are cipher results) */
66#define HASH(x) PEEK_U32(x)
67
68#define CMP(a, b) (memcmp(a, b, SSH_BLOCKSIZE))
69
70static void
71crc_update(u_int32_t *a, u_int32_t b)
72{
73 b ^= *a;
74 *a = ssh_crc32((u_char *)&b, sizeof(b));
75}
76
77/* detect if a block is used in a particular pattern */
78static int
79check_crc(const u_char *S, const u_char *buf, u_int32_t len)
80{
81 u_int32_t crc;
82 const u_char *c;
83
84 crc = 0;
85 for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
86 if (!CMP(S, c)) {
87 crc_update(&crc, 1);
88 crc_update(&crc, 0);
89 } else {
90 crc_update(&crc, 0);
91 crc_update(&crc, 0);
92 }
93 }
94 return crc == 0;
95}
96
97void
98deattack_init(struct deattack_ctx *dctx)
99{
100 bzero(dctx, sizeof(*dctx));
101 dctx->n = HASH_MINSIZE / HASH_ENTRYSIZE;
102}
103
104/* Detect a crc32 compensation attack on a packet */
105int
106detect_attack(struct deattack_ctx *dctx, const u_char *buf, u_int32_t len)
107{
108 u_int32_t i, j, l, same;
109 u_int16_t *tmp;
110 const u_char *c, *d;
111
112 if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||
113 len % SSH_BLOCKSIZE != 0)
114 return DEATTACK_ERROR;
115 for (l = dctx->n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)
116 ;
117
118 if (dctx->h == NULL) {
119 if ((dctx->h = calloc(l, HASH_ENTRYSIZE)) == NULL)
120 return DEATTACK_ERROR;
121 dctx->n = l;
122 } else {
123 if (l > dctx->n) {
124 if ((tmp = reallocarray(dctx->h, l, HASH_ENTRYSIZE))
125 == NULL) {
126 free(dctx->h);
127 dctx->h = NULL;
128 return DEATTACK_ERROR;
129 }
130 dctx->h = tmp;
131 dctx->n = l;
132 }
133 }
134
135 if (len <= HASH_MINBLOCKS) {
136 for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
137 for (d = buf; d < c; d += SSH_BLOCKSIZE) {
138 if (!CMP(c, d)) {
139 if ((check_crc(c, buf, len)))
140 return DEATTACK_DETECTED;
141 else
142 break;
143 }
144 }
145 }
146 return DEATTACK_OK;
147 }
148 memset(dctx->h, HASH_UNUSEDCHAR, dctx->n * HASH_ENTRYSIZE);
149
150 for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
151 for (i = HASH(c) & (dctx->n - 1); dctx->h[i] != HASH_UNUSED;
152 i = (i + 1) & (dctx->n - 1)) {
153 if (!CMP(c, buf + dctx->h[i] * SSH_BLOCKSIZE)) {
154 if (++same > MAX_IDENTICAL)
155 return DEATTACK_DOS_DETECTED;
156 if (check_crc(c, buf, len))
157 return DEATTACK_DETECTED;
158 else
159 break;
160 }
161 }
162 dctx->h[i] = j;
163 }
164 return DEATTACK_OK;
165}
diff --git a/deattack.h b/deattack.h
deleted file mode 100644
index ce67a30ff..000000000
--- a/deattack.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/* $OpenBSD: deattack.h,v 1.11 2015/01/19 19:52:16 markus Exp $ */
2
3/*
4 * Cryptographic attack detector for ssh - Header file
5 *
6 * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.
7 *
8 * All rights reserved. Redistribution and use in source and binary
9 * forms, with or without modification, are permitted provided that
10 * this copyright notice is retained.
11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE
14 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
15 * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS
16 * SOFTWARE.
17 *
18 * Ariel Futoransky <futo@core-sdi.com>
19 * <http://www.core-sdi.com>
20 */
21
22#ifndef _DEATTACK_H
23#define _DEATTACK_H
24
25/* Return codes */
26#define DEATTACK_OK 0
27#define DEATTACK_DETECTED 1
28#define DEATTACK_DOS_DETECTED 2
29#define DEATTACK_ERROR 3
30
31struct deattack_ctx {
32 u_int16_t *h;
33 u_int32_t n;
34};
35
36void deattack_init(struct deattack_ctx *);
37int detect_attack(struct deattack_ctx *, const u_char *, u_int32_t);
38#endif
diff --git a/defines.h b/defines.h
index c89f85a8d..f1662edcf 100644
--- a/defines.h
+++ b/defines.h
@@ -328,6 +328,28 @@ typedef unsigned int size_t;
328#define SIZE_MAX SIZE_T_MAX 328#define SIZE_MAX SIZE_T_MAX
329#endif 329#endif
330 330
331#ifndef INT32_MAX
332# if (SIZEOF_INT == 4)
333# define INT32_MAX INT_MAX
334# elif (SIZEOF_LONG == 4)
335# define INT32_MAX LONG_MAX
336# else
337# error "need INT32_MAX"
338# endif
339#endif
340
341#ifndef INT64_MAX
342# if (SIZEOF_INT == 8)
343# define INT64_MAX INT_MAX
344# elif (SIZEOF_LONG == 8)
345# define INT64_MAX LONG_MAX
346# elif (SIZEOF_LONG_LONG_INT == 8)
347# define INT64_MAX LLONG_MAX
348# else
349# error "need INT64_MAX"
350# endif
351#endif
352
331#ifndef HAVE_SSIZE_T 353#ifndef HAVE_SSIZE_T
332typedef int ssize_t; 354typedef int ssize_t;
333# define HAVE_SSIZE_T 355# define HAVE_SSIZE_T
@@ -497,6 +519,13 @@ struct winsize {
497} 519}
498#endif 520#endif
499 521
522#ifndef timespeccmp
523#define timespeccmp(tsp, usp, cmp) \
524 (((tsp)->tv_sec == (usp)->tv_sec) ? \
525 ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
526 ((tsp)->tv_sec cmp (usp)->tv_sec))
527#endif
528
500#ifndef __P 529#ifndef __P
501# define __P(x) x 530# define __P(x) x
502#endif 531#endif
diff --git a/digest-libc.c b/digest-libc.c
index 40db00274..c2b0b2403 100644
--- a/digest-libc.c
+++ b/digest-libc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: digest-libc.c,v 1.5 2015/05/05 02:48:17 jsg Exp $ */ 1/* $OpenBSD: digest-libc.c,v 1.6 2017/05/08 22:57:38 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 * Copyright (c) 2014 Markus Friedl. All rights reserved. 4 * Copyright (c) 2014 Markus Friedl. All rights reserved.
@@ -69,16 +69,6 @@ const struct ssh_digest digests[SSH_DIGEST_MAX] = {
69 (md_final_fn *) MD5Final 69 (md_final_fn *) MD5Final
70 }, 70 },
71 { 71 {
72 SSH_DIGEST_RIPEMD160,
73 "RIPEMD160",
74 RMD160_BLOCK_LENGTH,
75 RMD160_DIGEST_LENGTH,
76 sizeof(RMD160_CTX),
77 (md_init_fn *) RMD160Init,
78 (md_update_fn *) RMD160Update,
79 (md_final_fn *) RMD160Final
80 },
81 {
82 SSH_DIGEST_SHA1, 72 SSH_DIGEST_SHA1,
83 "SHA1", 73 "SHA1",
84 SHA1_BLOCK_LENGTH, 74 SHA1_BLOCK_LENGTH,
diff --git a/digest-openssl.c b/digest-openssl.c
index c55ceb93f..277099929 100644
--- a/digest-openssl.c
+++ b/digest-openssl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: digest-openssl.c,v 1.6 2017/03/10 02:59:51 dtucker Exp $ */ 1/* $OpenBSD: digest-openssl.c,v 1.7 2017/05/08 22:57:38 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -56,7 +56,6 @@ struct ssh_digest {
56/* NB. Indexed directly by algorithm number */ 56/* NB. Indexed directly by algorithm number */
57const struct ssh_digest digests[] = { 57const struct ssh_digest digests[] = {
58 { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 }, 58 { SSH_DIGEST_MD5, "MD5", 16, EVP_md5 },
59 { SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 },
60 { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 }, 59 { SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 },
61 { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 }, 60 { SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 },
62 { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 }, 61 { SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 },
diff --git a/digest.h b/digest.h
index 3fe073468..274574d0e 100644
--- a/digest.h
+++ b/digest.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: digest.h,v 1.7 2014/12/21 22:27:56 djm Exp $ */ 1/* $OpenBSD: digest.h,v 1.8 2017/05/08 22:57:38 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org> 3 * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
4 * 4 *
@@ -23,12 +23,11 @@
23 23
24/* Digest algorithms */ 24/* Digest algorithms */
25#define SSH_DIGEST_MD5 0 25#define SSH_DIGEST_MD5 0
26#define SSH_DIGEST_RIPEMD160 1 26#define SSH_DIGEST_SHA1 1
27#define SSH_DIGEST_SHA1 2 27#define SSH_DIGEST_SHA256 2
28#define SSH_DIGEST_SHA256 3 28#define SSH_DIGEST_SHA384 3
29#define SSH_DIGEST_SHA384 4 29#define SSH_DIGEST_SHA512 4
30#define SSH_DIGEST_SHA512 5 30#define SSH_DIGEST_MAX 5
31#define SSH_DIGEST_MAX 6
32 31
33struct sshbuf; 32struct sshbuf;
34struct ssh_digest_ctx; 33struct ssh_digest_ctx;
diff --git a/dispatch.c b/dispatch.c
index aac933e0a..0b3ea614e 100644
--- a/dispatch.c
+++ b/dispatch.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dispatch.c,v 1.27 2015/05/01 07:10:01 djm Exp $ */ 1/* $OpenBSD: dispatch.c,v 1.31 2017/05/31 07:00:13 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -30,7 +30,6 @@
30#include <signal.h> 30#include <signal.h>
31#include <stdarg.h> 31#include <stdarg.h>
32 32
33#include "ssh1.h"
34#include "ssh2.h" 33#include "ssh2.h"
35#include "log.h" 34#include "log.h"
36#include "dispatch.h" 35#include "dispatch.h"
@@ -39,14 +38,11 @@
39#include "ssherr.h" 38#include "ssherr.h"
40 39
41int 40int
42dispatch_protocol_error(int type, u_int32_t seq, void *ctx) 41dispatch_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
43{ 42{
44 struct ssh *ssh = active_state; /* XXX */
45 int r; 43 int r;
46 44
47 logit("dispatch_protocol_error: type %d seq %u", type, seq); 45 logit("dispatch_protocol_error: type %d seq %u", type, seq);
48 if (!compat20)
49 fatal("protocol error");
50 if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || 46 if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
51 (r = sshpkt_put_u32(ssh, seq)) != 0 || 47 (r = sshpkt_put_u32(ssh, seq)) != 0 ||
52 (r = sshpkt_send(ssh)) != 0 || 48 (r = sshpkt_send(ssh)) != 0 ||
@@ -56,7 +52,7 @@ dispatch_protocol_error(int type, u_int32_t seq, void *ctx)
56} 52}
57 53
58int 54int
59dispatch_protocol_ignore(int type, u_int32_t seq, void *ssh) 55dispatch_protocol_ignore(int type, u_int32_t seq, struct ssh *ssh)
60{ 56{
61 logit("dispatch_protocol_ignore: type %d seq %u", type, seq); 57 logit("dispatch_protocol_ignore: type %d seq %u", type, seq);
62 return 0; 58 return 0;
@@ -89,8 +85,7 @@ ssh_dispatch_set(struct ssh *ssh, int type, dispatch_fn *fn)
89} 85}
90 86
91int 87int
92ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done, 88ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done)
93 void *ctxt)
94{ 89{
95 int r; 90 int r;
96 u_char type; 91 u_char type;
@@ -115,8 +110,7 @@ ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done,
115 ssh->dispatch_skip_packets--; 110 ssh->dispatch_skip_packets--;
116 continue; 111 continue;
117 } 112 }
118 /* XXX 'ssh' will replace 'ctxt' later */ 113 r = (*ssh->dispatch[type])(type, seqnr, ssh);
119 r = (*ssh->dispatch[type])(type, seqnr, ctxt);
120 if (r != 0) 114 if (r != 0)
121 return r; 115 return r;
122 } else { 116 } else {
@@ -132,11 +126,10 @@ ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done,
132} 126}
133 127
134void 128void
135ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done, 129ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done)
136 void *ctxt)
137{ 130{
138 int r; 131 int r;
139 132
140 if ((r = ssh_dispatch_run(ssh, mode, done, ctxt)) != 0) 133 if ((r = ssh_dispatch_run(ssh, mode, done)) != 0)
141 sshpkt_fatal(ssh, __func__, r); 134 sshpkt_fatal(ssh, __func__, r);
142} 135}
diff --git a/dispatch.h b/dispatch.h
index cd51dbc0b..17a6f3db6 100644
--- a/dispatch.h
+++ b/dispatch.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: dispatch.h,v 1.12 2015/01/19 20:07:45 markus Exp $ */ 1/* $OpenBSD: dispatch.h,v 1.14 2017/05/31 07:00:13 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -36,15 +36,15 @@ enum {
36 36
37struct ssh; 37struct ssh;
38 38
39typedef int dispatch_fn(int, u_int32_t, void *); 39typedef int dispatch_fn(int, u_int32_t, struct ssh *);
40 40
41int dispatch_protocol_error(int, u_int32_t, void *); 41int dispatch_protocol_error(int, u_int32_t, struct ssh *);
42int dispatch_protocol_ignore(int, u_int32_t, void *); 42int dispatch_protocol_ignore(int, u_int32_t, struct ssh *);
43void ssh_dispatch_init(struct ssh *, dispatch_fn *); 43void ssh_dispatch_init(struct ssh *, dispatch_fn *);
44void ssh_dispatch_set(struct ssh *, int, dispatch_fn *); 44void ssh_dispatch_set(struct ssh *, int, dispatch_fn *);
45void ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *); 45void ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *);
46int ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *, void *); 46int ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *);
47void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *, void *); 47void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *);
48 48
49#define dispatch_init(dflt) \ 49#define dispatch_init(dflt) \
50 ssh_dispatch_init(active_state, (dflt)) 50 ssh_dispatch_init(active_state, (dflt))
@@ -52,7 +52,5 @@ void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *, void *);
52 ssh_dispatch_range(active_state, (from), (to), (fn)) 52 ssh_dispatch_range(active_state, (from), (to), (fn))
53#define dispatch_set(type, fn) \ 53#define dispatch_set(type, fn) \
54 ssh_dispatch_set(active_state, (type), (fn)) 54 ssh_dispatch_set(active_state, (type), (fn))
55#define dispatch_run(mode, done, ctxt) \
56 ssh_dispatch_run_fatal(active_state, (mode), (done), (ctxt))
57 55
58#endif 56#endif
diff --git a/dns.c b/dns.c
index e813afeae..6e1abb530 100644
--- a/dns.c
+++ b/dns.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dns.c,v 1.35 2015/08/20 22:32:42 deraadt Exp $ */ 1/* $OpenBSD: dns.c,v 1.37 2017/09/14 04:32:21 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2003 Wesley Griffin. All rights reserved. 4 * Copyright (c) 2003 Wesley Griffin. All rights reserved.
diff --git a/dns.h b/dns.h
index 30e2b19b3..68443f7cb 100644
--- a/dns.h
+++ b/dns.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: dns.h,v 1.15 2015/05/08 06:45:13 djm Exp $ */ 1/* $OpenBSD: dns.h,v 1.17 2017/09/14 04:32:21 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2003 Wesley Griffin. All rights reserved. 4 * Copyright (c) 2003 Wesley Griffin. All rights reserved.
diff --git a/gss-serv.c b/gss-serv.c
index 53993d674..6cae720e5 100644
--- a/gss-serv.c
+++ b/gss-serv.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: gss-serv.c,v 1.29 2015/05/22 03:50:02 djm Exp $ */ 1/* $OpenBSD: gss-serv.c,v 1.30 2017/06/24 06:34:38 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 4 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -393,4 +393,13 @@ ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
393 return (ctx->major); 393 return (ctx->major);
394} 394}
395 395
396/* Privileged */
397const char *ssh_gssapi_displayname(void)
398{
399 if (gssapi_client.displayname.length == 0 ||
400 gssapi_client.displayname.value == NULL)
401 return NULL;
402 return (char *)gssapi_client.displayname.value;
403}
404
396#endif 405#endif
diff --git a/hostfile.c b/hostfile.c
index e23faa969..12f174ff9 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: hostfile.c,v 1.68 2017/03/10 04:26:06 djm Exp $ */ 1/* $OpenBSD: hostfile.c,v 1.71 2017/05/31 09:15:42 deraadt Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -251,7 +251,7 @@ record_hostkey(struct hostkey_foreach_line *l, void *_ctx)
251 l->marker == MRK_NONE ? "" : 251 l->marker == MRK_NONE ? "" :
252 (l->marker == MRK_CA ? "ca " : "revoked "), 252 (l->marker == MRK_CA ? "ca " : "revoked "),
253 sshkey_type(l->key), l->path, l->linenum); 253 sshkey_type(l->key), l->path, l->linenum);
254 if ((tmp = reallocarray(hostkeys->entries, 254 if ((tmp = recallocarray(hostkeys->entries, hostkeys->num_entries,
255 hostkeys->num_entries + 1, sizeof(*hostkeys->entries))) == NULL) 255 hostkeys->num_entries + 1, sizeof(*hostkeys->entries))) == NULL)
256 return SSH_ERR_ALLOC_FAIL; 256 return SSH_ERR_ALLOC_FAIL;
257 hostkeys->entries = tmp; 257 hostkeys->entries = tmp;
@@ -346,16 +346,11 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys,
346 HostStatus end_return = HOST_NEW; 346 HostStatus end_return = HOST_NEW;
347 int want_cert = sshkey_is_cert(k); 347 int want_cert = sshkey_is_cert(k);
348 HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE; 348 HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE;
349 int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2;
350 349
351 if (found != NULL) 350 if (found != NULL)
352 *found = NULL; 351 *found = NULL;
353 352
354 for (i = 0; i < hostkeys->num_entries; i++) { 353 for (i = 0; i < hostkeys->num_entries; i++) {
355 if (proto == 1 && hostkeys->entries[i].key->type != KEY_RSA1)
356 continue;
357 if (proto == 2 && hostkeys->entries[i].key->type == KEY_RSA1)
358 continue;
359 if (hostkeys->entries[i].marker != want_marker) 354 if (hostkeys->entries[i].marker != want_marker)
360 continue; 355 continue;
361 if (k == NULL) { 356 if (k == NULL) {
@@ -490,13 +485,6 @@ host_delete(struct hostkey_foreach_line *l, void *_ctx)
490 return 0; 485 return 0;
491 } 486 }
492 487
493 /* XXX might need a knob for this later */
494 /* Don't remove RSA1 keys */
495 if (l->key->type == KEY_RSA1) {
496 fprintf(ctx->out, "%s\n", l->line);
497 return 0;
498 }
499
500 /* 488 /*
501 * If this line contains one of the keys that we will be 489 * If this line contains one of the keys that we will be
502 * adding later, then don't change it and mark the key for 490 * adding later, then don't change it and mark the key for
@@ -789,20 +777,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
789 break; 777 break;
790 } 778 }
791 if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) { 779 if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) {
792#ifdef WITH_SSH1
793 sshkey_free(lineinfo.key);
794 lineinfo.key = sshkey_new(KEY_RSA1);
795 if (lineinfo.key == NULL) {
796 error("%s: sshkey_new fail", __func__);
797 r = SSH_ERR_ALLOC_FAIL;
798 break;
799 }
800 if (!hostfile_read_key(&cp, &kbits,
801 lineinfo.key))
802 goto bad;
803#else
804 goto bad; 780 goto bad;
805#endif
806 } 781 }
807 lineinfo.keytype = lineinfo.key->type; 782 lineinfo.keytype = lineinfo.key->type;
808 lineinfo.comment = cp; 783 lineinfo.comment = cp;
@@ -817,12 +792,12 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
817 lineinfo.keytype = sshkey_type_from_name(ktype); 792 lineinfo.keytype = sshkey_type_from_name(ktype);
818 793
819 /* 794 /*
820 * Assume RSA1 if the first component is a short 795 * Assume legacy RSA1 if the first component is a short
821 * decimal number. 796 * decimal number.
822 */ 797 */
823 if (lineinfo.keytype == KEY_UNSPEC && l < 8 && 798 if (lineinfo.keytype == KEY_UNSPEC && l < 8 &&
824 strspn(ktype, "0123456789") == l) 799 strspn(ktype, "0123456789") == l)
825 lineinfo.keytype = KEY_RSA1; 800 goto bad;
826 801
827 /* 802 /*
828 * Check that something other than whitespace follows 803 * Check that something other than whitespace follows
diff --git a/includes.h b/includes.h
index 497a038b2..0fd71792e 100644
--- a/includes.h
+++ b/includes.h
@@ -93,6 +93,9 @@
93#ifdef HAVE_SYS_SYSMACROS_H 93#ifdef HAVE_SYS_SYSMACROS_H
94# include <sys/sysmacros.h> /* For MIN, MAX, etc */ 94# include <sys/sysmacros.h> /* For MIN, MAX, etc */
95#endif 95#endif
96#ifdef HAVE_SYS_TIME_H
97# include <sys/time.h> /* for timespeccmp if present */
98#endif
96#ifdef HAVE_SYS_MMAN_H 99#ifdef HAVE_SYS_MMAN_H
97#include <sys/mman.h> /* for MAP_ANONYMOUS */ 100#include <sys/mman.h> /* for MAP_ANONYMOUS */
98#endif 101#endif
diff --git a/kex.c b/kex.c
index cf4ac0dc5..d5d5a9dae 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.131 2017/03/15 07:07:39 markus Exp $ */ 1/* $OpenBSD: kex.c,v 1.134 2017/06/13 12:13:59 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -54,17 +54,9 @@
54#include "sshbuf.h" 54#include "sshbuf.h"
55#include "digest.h" 55#include "digest.h"
56 56
57#if OPENSSL_VERSION_NUMBER >= 0x00907000L
58# if defined(HAVE_EVP_SHA256)
59# define evp_ssh_sha256 EVP_sha256
60# else
61extern const EVP_MD *evp_ssh_sha256(void);
62# endif
63#endif
64
65/* prototype */ 57/* prototype */
66static int kex_choose_conf(struct ssh *); 58static int kex_choose_conf(struct ssh *);
67static int kex_input_newkeys(int, u_int32_t, void *); 59static int kex_input_newkeys(int, u_int32_t, struct ssh *);
68 60
69static const char *proposal_names[PROPOSAL_MAX] = { 61static const char *proposal_names[PROPOSAL_MAX] = {
70 "KEX algorithms", 62 "KEX algorithms",
@@ -323,9 +315,8 @@ kex_prop_free(char **proposal)
323 315
324/* ARGSUSED */ 316/* ARGSUSED */
325static int 317static int
326kex_protocol_error(int type, u_int32_t seq, void *ctxt) 318kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
327{ 319{
328 struct ssh *ssh = active_state; /* XXX */
329 int r; 320 int r;
330 321
331 error("kex protocol error: type %d seq %u", type, seq); 322 error("kex protocol error: type %d seq %u", type, seq);
@@ -383,12 +374,13 @@ kex_send_newkeys(struct ssh *ssh)
383} 374}
384 375
385int 376int
386kex_input_ext_info(int type, u_int32_t seq, void *ctxt) 377kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
387{ 378{
388 struct ssh *ssh = ctxt;
389 struct kex *kex = ssh->kex; 379 struct kex *kex = ssh->kex;
390 u_int32_t i, ninfo; 380 u_int32_t i, ninfo;
391 char *name, *val, *found; 381 char *name, *found;
382 u_char *val;
383 size_t vlen;
392 int r; 384 int r;
393 385
394 debug("SSH2_MSG_EXT_INFO received"); 386 debug("SSH2_MSG_EXT_INFO received");
@@ -398,12 +390,17 @@ kex_input_ext_info(int type, u_int32_t seq, void *ctxt)
398 for (i = 0; i < ninfo; i++) { 390 for (i = 0; i < ninfo; i++) {
399 if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) 391 if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
400 return r; 392 return r;
401 if ((r = sshpkt_get_cstring(ssh, &val, NULL)) != 0) { 393 if ((r = sshpkt_get_string(ssh, &val, &vlen)) != 0) {
402 free(name); 394 free(name);
403 return r; 395 return r;
404 } 396 }
405 debug("%s: %s=<%s>", __func__, name, val);
406 if (strcmp(name, "server-sig-algs") == 0) { 397 if (strcmp(name, "server-sig-algs") == 0) {
398 /* Ensure no \0 lurking in value */
399 if (memchr(val, '\0', vlen) != NULL) {
400 error("%s: nul byte in %s", __func__, name);
401 return SSH_ERR_INVALID_FORMAT;
402 }
403 debug("%s: %s=<%s>", __func__, name, val);
407 found = match_list("rsa-sha2-256", val, NULL); 404 found = match_list("rsa-sha2-256", val, NULL);
408 if (found) { 405 if (found) {
409 kex->rsa_sha2 = 256; 406 kex->rsa_sha2 = 256;
@@ -414,7 +411,8 @@ kex_input_ext_info(int type, u_int32_t seq, void *ctxt)
414 kex->rsa_sha2 = 512; 411 kex->rsa_sha2 = 512;
415 free(found); 412 free(found);
416 } 413 }
417 } 414 } else
415 debug("%s: %s (unrecognised)", __func__, name);
418 free(name); 416 free(name);
419 free(val); 417 free(val);
420 } 418 }
@@ -422,9 +420,8 @@ kex_input_ext_info(int type, u_int32_t seq, void *ctxt)
422} 420}
423 421
424static int 422static int
425kex_input_newkeys(int type, u_int32_t seq, void *ctxt) 423kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh)
426{ 424{
427 struct ssh *ssh = ctxt;
428 struct kex *kex = ssh->kex; 425 struct kex *kex = ssh->kex;
429 int r; 426 int r;
430 427
@@ -475,9 +472,8 @@ kex_send_kexinit(struct ssh *ssh)
475 472
476/* ARGSUSED */ 473/* ARGSUSED */
477int 474int
478kex_input_kexinit(int type, u_int32_t seq, void *ctxt) 475kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
479{ 476{
480 struct ssh *ssh = ctxt;
481 struct kex *kex = ssh->kex; 477 struct kex *kex = ssh->kex;
482 const u_char *ptr; 478 const u_char *ptr;
483 u_int i; 479 u_int i;
@@ -988,47 +984,6 @@ kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,
988} 984}
989#endif 985#endif
990 986
991#ifdef WITH_SSH1
992int
993derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
994 u_int8_t cookie[8], u_int8_t id[16])
995{
996 u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
997 struct ssh_digest_ctx *hashctx = NULL;
998 size_t hlen, slen;
999 int r;
1000
1001 hlen = BN_num_bytes(host_modulus);
1002 slen = BN_num_bytes(server_modulus);
1003 if (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) ||
1004 slen < (512 / 8) || (u_int)slen > sizeof(sbuf))
1005 return SSH_ERR_KEY_BITS_MISMATCH;
1006 if (BN_bn2bin(host_modulus, hbuf) <= 0 ||
1007 BN_bn2bin(server_modulus, sbuf) <= 0) {
1008 r = SSH_ERR_LIBCRYPTO_ERROR;
1009 goto out;
1010 }
1011 if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) {
1012 r = SSH_ERR_ALLOC_FAIL;
1013 goto out;
1014 }
1015 if (ssh_digest_update(hashctx, hbuf, hlen) != 0 ||
1016 ssh_digest_update(hashctx, sbuf, slen) != 0 ||
1017 ssh_digest_update(hashctx, cookie, 8) != 0 ||
1018 ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) {
1019 r = SSH_ERR_LIBCRYPTO_ERROR;
1020 goto out;
1021 }
1022 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
1023 r = 0;
1024 out:
1025 ssh_digest_free(hashctx);
1026 explicit_bzero(hbuf, sizeof(hbuf));
1027 explicit_bzero(sbuf, sizeof(sbuf));
1028 explicit_bzero(obuf, sizeof(obuf));
1029 return r;
1030}
1031#endif
1032 987
1033#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 988#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
1034void 989void
diff --git a/kex.h b/kex.h
index 3794f2127..01bb3986a 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.h,v 1.81 2016/09/28 21:44:52 djm Exp $ */ 1/* $OpenBSD: kex.h,v 1.83 2017/05/30 14:23:52 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -181,8 +181,8 @@ int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]);
181void kex_prop_free(char **); 181void kex_prop_free(char **);
182 182
183int kex_send_kexinit(struct ssh *); 183int kex_send_kexinit(struct ssh *);
184int kex_input_kexinit(int, u_int32_t, void *); 184int kex_input_kexinit(int, u_int32_t, struct ssh *);
185int kex_input_ext_info(int, u_int32_t, void *); 185int kex_input_ext_info(int, u_int32_t, struct ssh *);
186int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); 186int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *);
187int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *); 187int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *);
188int kex_send_newkeys(struct ssh *); 188int kex_send_newkeys(struct ssh *);
@@ -225,9 +225,6 @@ int kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
225 __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 225 __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
226 __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 226 __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
227 227
228int
229derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
230
231#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 228#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
232void dump_digest(char *, u_char *, int); 229void dump_digest(char *, u_char *, int);
233#endif 230#endif
diff --git a/kexc25519c.c b/kexc25519c.c
index b7ef65dc3..e488013e9 100644
--- a/kexc25519c.c
+++ b/kexc25519c.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexc25519c.c,v 1.7 2015/01/26 06:10:03 djm Exp $ */ 1/* $OpenBSD: kexc25519c.c,v 1.8 2017/05/31 04:17:12 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -44,7 +44,7 @@
44#include "ssherr.h" 44#include "ssherr.h"
45 45
46static int 46static int
47input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt); 47input_kex_c25519_reply(int type, u_int32_t seq, struct ssh *ssh);
48 48
49int 49int
50kexc25519_client(struct ssh *ssh) 50kexc25519_client(struct ssh *ssh)
@@ -69,9 +69,8 @@ kexc25519_client(struct ssh *ssh)
69} 69}
70 70
71static int 71static int
72input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt) 72input_kex_c25519_reply(int type, u_int32_t seq, struct ssh *ssh)
73{ 73{
74 struct ssh *ssh = ctxt;
75 struct kex *kex = ssh->kex; 74 struct kex *kex = ssh->kex;
76 struct sshkey *server_host_key = NULL; 75 struct sshkey *server_host_key = NULL;
77 struct sshbuf *shared_secret = NULL; 76 struct sshbuf *shared_secret = NULL;
diff --git a/kexc25519s.c b/kexc25519s.c
index 4e77622b0..0a008d447 100644
--- a/kexc25519s.c
+++ b/kexc25519s.c
@@ -41,7 +41,7 @@
41#include "sshbuf.h" 41#include "sshbuf.h"
42#include "ssherr.h" 42#include "ssherr.h"
43 43
44static int input_kex_c25519_init(int, u_int32_t, void *); 44static int input_kex_c25519_init(int, u_int32_t, struct ssh *);
45 45
46int 46int
47kexc25519_server(struct ssh *ssh) 47kexc25519_server(struct ssh *ssh)
@@ -52,9 +52,8 @@ kexc25519_server(struct ssh *ssh)
52} 52}
53 53
54static int 54static int
55input_kex_c25519_init(int type, u_int32_t seq, void *ctxt) 55input_kex_c25519_init(int type, u_int32_t seq, struct ssh *ssh)
56{ 56{
57 struct ssh *ssh = ctxt;
58 struct kex *kex = ssh->kex; 57 struct kex *kex = ssh->kex;
59 struct sshkey *server_host_private, *server_host_public; 58 struct sshkey *server_host_private, *server_host_public;
60 struct sshbuf *shared_secret = NULL; 59 struct sshbuf *shared_secret = NULL;
diff --git a/kexdhc.c b/kexdhc.c
index ad3975f09..9864ee2ec 100644
--- a/kexdhc.c
+++ b/kexdhc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexdhc.c,v 1.19 2016/05/02 10:26:04 djm Exp $ */ 1/* $OpenBSD: kexdhc.c,v 1.20 2017/05/30 14:23:52 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -49,7 +49,7 @@
49#include "ssherr.h" 49#include "ssherr.h"
50#include "sshbuf.h" 50#include "sshbuf.h"
51 51
52static int input_kex_dh(int, u_int32_t, void *); 52static int input_kex_dh(int, u_int32_t, struct ssh *);
53 53
54int 54int
55kexdh_client(struct ssh *ssh) 55kexdh_client(struct ssh *ssh)
@@ -100,9 +100,8 @@ kexdh_client(struct ssh *ssh)
100} 100}
101 101
102static int 102static int
103input_kex_dh(int type, u_int32_t seq, void *ctxt) 103input_kex_dh(int type, u_int32_t seq, struct ssh *ssh)
104{ 104{
105 struct ssh *ssh = ctxt;
106 struct kex *kex = ssh->kex; 105 struct kex *kex = ssh->kex;
107 BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; 106 BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
108 struct sshkey *server_host_key = NULL; 107 struct sshkey *server_host_key = NULL;
diff --git a/kexdhs.c b/kexdhs.c
index 108f66427..81ce56d7a 100644
--- a/kexdhs.c
+++ b/kexdhs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexdhs.c,v 1.24 2016/05/02 10:26:04 djm Exp $ */ 1/* $OpenBSD: kexdhs.c,v 1.25 2017/05/30 14:23:52 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -49,7 +49,7 @@
49#include "ssherr.h" 49#include "ssherr.h"
50#include "sshbuf.h" 50#include "sshbuf.h"
51 51
52static int input_kex_dh_init(int, u_int32_t, void *); 52static int input_kex_dh_init(int, u_int32_t, struct ssh *);
53 53
54int 54int
55kexdh_server(struct ssh *ssh) 55kexdh_server(struct ssh *ssh)
@@ -91,9 +91,8 @@ kexdh_server(struct ssh *ssh)
91} 91}
92 92
93int 93int
94input_kex_dh_init(int type, u_int32_t seq, void *ctxt) 94input_kex_dh_init(int type, u_int32_t seq, struct ssh *ssh)
95{ 95{
96 struct ssh *ssh = ctxt;
97 struct kex *kex = ssh->kex; 96 struct kex *kex = ssh->kex;
98 BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; 97 BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
99 struct sshkey *server_host_public, *server_host_private; 98 struct sshkey *server_host_public, *server_host_private;
diff --git a/kexecdhc.c b/kexecdhc.c
index 90220ce82..d8a8b660f 100644
--- a/kexecdhc.c
+++ b/kexecdhc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexecdhc.c,v 1.10 2015/01/26 06:10:03 djm Exp $ */ 1/* $OpenBSD: kexecdhc.c,v 1.11 2017/05/30 14:23:52 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -49,7 +49,7 @@
49#include "ssherr.h" 49#include "ssherr.h"
50#include "sshbuf.h" 50#include "sshbuf.h"
51 51
52static int input_kex_ecdh_reply(int, u_int32_t, void *); 52static int input_kex_ecdh_reply(int, u_int32_t, struct ssh *);
53 53
54int 54int
55kexecdh_client(struct ssh *ssh) 55kexecdh_client(struct ssh *ssh)
@@ -95,9 +95,8 @@ kexecdh_client(struct ssh *ssh)
95} 95}
96 96
97static int 97static int
98input_kex_ecdh_reply(int type, u_int32_t seq, void *ctxt) 98input_kex_ecdh_reply(int type, u_int32_t seq, struct ssh *ssh)
99{ 99{
100 struct ssh *ssh = ctxt;
101 struct kex *kex = ssh->kex; 100 struct kex *kex = ssh->kex;
102 const EC_GROUP *group; 101 const EC_GROUP *group;
103 EC_POINT *server_public = NULL; 102 EC_POINT *server_public = NULL;
diff --git a/kexecdhs.c b/kexecdhs.c
index ccdbf70b1..dc24a3af6 100644
--- a/kexecdhs.c
+++ b/kexecdhs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexecdhs.c,v 1.15 2015/12/04 16:41:28 markus Exp $ */ 1/* $OpenBSD: kexecdhs.c,v 1.16 2017/05/30 14:23:52 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -47,7 +47,7 @@
47#include "ssherr.h" 47#include "ssherr.h"
48#include "sshbuf.h" 48#include "sshbuf.h"
49 49
50static int input_kex_ecdh_init(int, u_int32_t, void *); 50static int input_kex_ecdh_init(int, u_int32_t, struct ssh *);
51 51
52int 52int
53kexecdh_server(struct ssh *ssh) 53kexecdh_server(struct ssh *ssh)
@@ -58,9 +58,8 @@ kexecdh_server(struct ssh *ssh)
58} 58}
59 59
60static int 60static int
61input_kex_ecdh_init(int type, u_int32_t seq, void *ctxt) 61input_kex_ecdh_init(int type, u_int32_t seq, struct ssh *ssh)
62{ 62{
63 struct ssh *ssh = ctxt;
64 struct kex *kex = ssh->kex; 63 struct kex *kex = ssh->kex;
65 EC_POINT *client_public; 64 EC_POINT *client_public;
66 EC_KEY *server_key = NULL; 65 EC_KEY *server_key = NULL;
diff --git a/kexgexc.c b/kexgexc.c
index ad0d1c8c0..cd1128752 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexgexc.c,v 1.23 2016/09/12 01:22:38 deraadt Exp $ */ 1/* $OpenBSD: kexgexc.c,v 1.25 2017/05/30 14:23:52 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Niels Provos. All rights reserved. 3 * Copyright (c) 2000 Niels Provos. All rights reserved.
4 * Copyright (c) 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -51,8 +51,8 @@
51#include "sshbuf.h" 51#include "sshbuf.h"
52#include "misc.h" 52#include "misc.h"
53 53
54static int input_kex_dh_gex_group(int, u_int32_t, void *); 54static int input_kex_dh_gex_group(int, u_int32_t, struct ssh *);
55static int input_kex_dh_gex_reply(int, u_int32_t, void *); 55static int input_kex_dh_gex_reply(int, u_int32_t, struct ssh *);
56 56
57int 57int
58kexgex_client(struct ssh *ssh) 58kexgex_client(struct ssh *ssh)
@@ -89,9 +89,8 @@ kexgex_client(struct ssh *ssh)
89} 89}
90 90
91static int 91static int
92input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt) 92input_kex_dh_gex_group(int type, u_int32_t seq, struct ssh *ssh)
93{ 93{
94 struct ssh *ssh = ctxt;
95 struct kex *kex = ssh->kex; 94 struct kex *kex = ssh->kex;
96 BIGNUM *p = NULL, *g = NULL; 95 BIGNUM *p = NULL, *g = NULL;
97 int r, bits; 96 int r, bits;
@@ -143,9 +142,8 @@ out:
143} 142}
144 143
145static int 144static int
146input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt) 145input_kex_dh_gex_reply(int type, u_int32_t seq, struct ssh *ssh)
147{ 146{
148 struct ssh *ssh = ctxt;
149 struct kex *kex = ssh->kex; 147 struct kex *kex = ssh->kex;
150 BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; 148 BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
151 struct sshkey *server_host_key = NULL; 149 struct sshkey *server_host_key = NULL;
@@ -165,10 +163,6 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt)
165 (r = sshkey_from_blob(server_host_key_blob, sbloblen, 163 (r = sshkey_from_blob(server_host_key_blob, sbloblen,
166 &server_host_key)) != 0) 164 &server_host_key)) != 0)
167 goto out; 165 goto out;
168 if (server_host_key->type != kex->hostkey_type) {
169 r = SSH_ERR_KEY_TYPE_MISMATCH;
170 goto out;
171 }
172 if (server_host_key->type != kex->hostkey_type || 166 if (server_host_key->type != kex->hostkey_type ||
173 (kex->hostkey_type == KEY_ECDSA && 167 (kex->hostkey_type == KEY_ECDSA &&
174 server_host_key->ecdsa_nid != kex->hostkey_nid)) { 168 server_host_key->ecdsa_nid != kex->hostkey_nid)) {
diff --git a/kexgexs.c b/kexgexs.c
index 449603592..c5dd00578 100644
--- a/kexgexs.c
+++ b/kexgexs.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexgexs.c,v 1.30 2016/09/12 01:22:38 deraadt Exp $ */ 1/* $OpenBSD: kexgexs.c,v 1.31 2017/05/30 14:23:52 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Niels Provos. All rights reserved. 3 * Copyright (c) 2000 Niels Provos. All rights reserved.
4 * Copyright (c) 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -54,8 +54,8 @@
54#include "sshbuf.h" 54#include "sshbuf.h"
55#include "misc.h" 55#include "misc.h"
56 56
57static int input_kex_dh_gex_request(int, u_int32_t, void *); 57static int input_kex_dh_gex_request(int, u_int32_t, struct ssh *);
58static int input_kex_dh_gex_init(int, u_int32_t, void *); 58static int input_kex_dh_gex_init(int, u_int32_t, struct ssh *);
59 59
60int 60int
61kexgex_server(struct ssh *ssh) 61kexgex_server(struct ssh *ssh)
@@ -67,9 +67,8 @@ kexgex_server(struct ssh *ssh)
67} 67}
68 68
69static int 69static int
70input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt) 70input_kex_dh_gex_request(int type, u_int32_t seq, struct ssh *ssh)
71{ 71{
72 struct ssh *ssh = ctxt;
73 struct kex *kex = ssh->kex; 72 struct kex *kex = ssh->kex;
74 int r; 73 int r;
75 u_int min = 0, max = 0, nbits = 0; 74 u_int min = 0, max = 0, nbits = 0;
@@ -120,9 +119,8 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
120} 119}
121 120
122static int 121static int
123input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt) 122input_kex_dh_gex_init(int type, u_int32_t seq, struct ssh *ssh)
124{ 123{
125 struct ssh *ssh = ctxt;
126 struct kex *kex = ssh->kex; 124 struct kex *kex = ssh->kex;
127 BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; 125 BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
128 struct sshkey *server_host_public, *server_host_private; 126 struct sshkey *server_host_public, *server_host_private;
diff --git a/key.c b/key.c
index 93f4ccb24..6e338c495 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.c,v 1.130 2016/05/02 09:36:42 djm Exp $ */ 1/* $OpenBSD: key.c,v 1.131 2017/05/30 14:16:41 markus Exp $ */
2/* 2/*
3 * placed in the public domain 3 * placed in the public domain
4 */ 4 */
@@ -20,68 +20,6 @@
20#include "log.h" 20#include "log.h"
21#include "authfile.h" 21#include "authfile.h"
22 22
23void
24key_add_private(Key *k)
25{
26 int r;
27
28 if ((r = sshkey_add_private(k)) != 0)
29 fatal("%s: %s", __func__, ssh_err(r));
30}
31
32Key *
33key_new_private(int type)
34{
35 Key *ret = NULL;
36
37 if ((ret = sshkey_new_private(type)) == NULL)
38 fatal("%s: failed", __func__);
39 return ret;
40}
41
42int
43key_read(Key *ret, char **cpp)
44{
45 return sshkey_read(ret, cpp) == 0 ? 1 : -1;
46}
47
48int
49key_write(const Key *key, FILE *f)
50{
51 return sshkey_write(key, f) == 0 ? 1 : 0;
52}
53
54Key *
55key_generate(int type, u_int bits)
56{
57 int r;
58 Key *ret = NULL;
59
60 if ((r = sshkey_generate(type, bits, &ret)) != 0)
61 fatal("%s: %s", __func__, ssh_err(r));
62 return ret;
63}
64
65void
66key_cert_copy(const Key *from_key, Key *to_key)
67{
68 int r;
69
70 if ((r = sshkey_cert_copy(from_key, to_key)) != 0)
71 fatal("%s: %s", __func__, ssh_err(r));
72}
73
74Key *
75key_from_private(const Key *k)
76{
77 int r;
78 Key *ret = NULL;
79
80 if ((r = sshkey_from_private(k, &ret)) != 0)
81 fatal("%s: %s", __func__, ssh_err(r));
82 return ret;
83}
84
85static void 23static void
86fatal_on_fatal_errors(int r, const char *func, int extra_fatal) 24fatal_on_fatal_errors(int r, const char *func, int extra_fatal)
87{ 25{
@@ -184,19 +122,6 @@ key_demote(const Key *k)
184} 122}
185 123
186int 124int
187key_to_certified(Key *k)
188{
189 int r;
190
191 if ((r = sshkey_to_certified(k)) != 0) {
192 fatal_on_fatal_errors(r, __func__, 0);
193 error("%s: %s", __func__, ssh_err(r));
194 return -1;
195 }
196 return 0;
197}
198
199int
200key_drop_cert(Key *k) 125key_drop_cert(Key *k)
201{ 126{
202 int r; 127 int r;
@@ -210,19 +135,6 @@ key_drop_cert(Key *k)
210} 135}
211 136
212int 137int
213key_certify(Key *k, Key *ca)
214{
215 int r;
216
217 if ((r = sshkey_certify(k, ca, NULL)) != 0) {
218 fatal_on_fatal_errors(r, __func__, 0);
219 error("%s: %s", __func__, ssh_err(r));
220 return -1;
221 }
222 return 0;
223}
224
225int
226key_cert_check_authority(const Key *k, int want_host, int require_principal, 138key_cert_check_authority(const Key *k, int want_host, int require_principal,
227 const char *name, const char **reason) 139 const char *name, const char **reason)
228{ 140{
@@ -237,88 +149,8 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal,
237 return 0; 149 return 0;
238} 150}
239 151
240#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
241int
242key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
243{
244 int r;
245
246 if ((r = sshkey_ec_validate_public(group, public)) != 0) {
247 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
248 error("%s: %s", __func__, ssh_err(r));
249 return -1;
250 }
251 return 0;
252}
253
254int
255key_ec_validate_private(const EC_KEY *key)
256{
257 int r;
258
259 if ((r = sshkey_ec_validate_private(key)) != 0) {
260 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
261 error("%s: %s", __func__, ssh_err(r));
262 return -1;
263 }
264 return 0;
265}
266#endif /* WITH_OPENSSL */
267
268void
269key_private_serialize(const Key *key, struct sshbuf *b)
270{
271 int r;
272
273 if ((r = sshkey_private_serialize(key, b)) != 0)
274 fatal("%s: %s", __func__, ssh_err(r));
275}
276
277Key *
278key_private_deserialize(struct sshbuf *blob)
279{
280 int r;
281 Key *ret = NULL;
282
283 if ((r = sshkey_private_deserialize(blob, &ret)) != 0) {
284 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
285 error("%s: %s", __func__, ssh_err(r));
286 return NULL;
287 }
288 return ret;
289}
290
291/* authfile.c */ 152/* authfile.c */
292 153
293int
294key_save_private(Key *key, const char *filename, const char *passphrase,
295 const char *comment, int force_new_format, const char *new_format_cipher,
296 int new_format_rounds)
297{
298 int r;
299
300 if ((r = sshkey_save_private(key, filename, passphrase, comment,
301 force_new_format, new_format_cipher, new_format_rounds)) != 0) {
302 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
303 error("%s: %s", __func__, ssh_err(r));
304 return 0;
305 }
306 return 1;
307}
308
309int
310key_load_file(int fd, const char *filename, struct sshbuf *blob)
311{
312 int r;
313
314 if ((r = sshkey_load_file(fd, blob)) != 0) {
315 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
316 error("%s: %s", __func__, ssh_err(r));
317 return 0;
318 }
319 return 1;
320}
321
322Key * 154Key *
323key_load_cert(const char *filename) 155key_load_cert(const char *filename)
324{ 156{
@@ -417,10 +249,3 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
417 } 249 }
418 return ret; 250 return ret;
419} 251}
420
421int
422key_perm_ok(int fd, const char *filename)
423{
424 return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;
425}
426
diff --git a/key.h b/key.h
index 2e501a9f4..a14f37037 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.h,v 1.50 2016/09/12 23:31:27 djm Exp $ */ 1/* $OpenBSD: key.h,v 1.51 2017/05/30 14:16:41 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -35,51 +35,24 @@ typedef struct sshkey Key;
35#define fp_rep sshkey_fp_rep 35#define fp_rep sshkey_fp_rep
36 36
37#ifndef SSH_KEY_NO_DEFINE 37#ifndef SSH_KEY_NO_DEFINE
38#define key_new sshkey_new
39#define key_free sshkey_free 38#define key_free sshkey_free
40#define key_equal_public sshkey_equal_public 39#define key_equal_public sshkey_equal_public
41#define key_equal sshkey_equal 40#define key_equal sshkey_equal
42#define key_type sshkey_type 41#define key_type sshkey_type
43#define key_cert_type sshkey_cert_type
44#define key_ssh_name sshkey_ssh_name 42#define key_ssh_name sshkey_ssh_name
45#define key_ssh_name_plain sshkey_ssh_name_plain 43#define key_ssh_name_plain sshkey_ssh_name_plain
46#define key_type_from_name sshkey_type_from_name 44#define key_type_from_name sshkey_type_from_name
47#define key_ecdsa_nid_from_name sshkey_ecdsa_nid_from_name
48#define key_type_is_cert sshkey_type_is_cert
49#define key_size sshkey_size
50#define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid
51#define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid
52#define key_is_cert sshkey_is_cert 45#define key_is_cert sshkey_is_cert
53#define key_type_plain sshkey_type_plain 46#define key_type_plain sshkey_type_plain
54#define key_curve_name_to_nid sshkey_curve_name_to_nid
55#define key_curve_nid_to_bits sshkey_curve_nid_to_bits
56#define key_curve_nid_to_name sshkey_curve_nid_to_name
57#define key_ec_nid_to_hash_alg sshkey_ec_nid_to_hash_alg
58#define key_dump_ec_point sshkey_dump_ec_point
59#define key_dump_ec_key sshkey_dump_ec_key
60#endif 47#endif
61 48
62void key_add_private(Key *);
63Key *key_new_private(int);
64void key_free(Key *); 49void key_free(Key *);
65Key *key_demote(const Key *); 50Key *key_demote(const Key *);
66int key_write(const Key *, FILE *);
67int key_read(Key *, char **);
68 51
69Key *key_generate(int, u_int);
70Key *key_from_private(const Key *);
71int key_to_certified(Key *);
72int key_drop_cert(Key *); 52int key_drop_cert(Key *);
73int key_certify(Key *, Key *);
74void key_cert_copy(const Key *, Key *);
75int key_cert_check_authority(const Key *, int, int, const char *, 53int key_cert_check_authority(const Key *, int, int, const char *,
76 const char **); 54 const char **);
77 55
78#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
79int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
80int key_ec_validate_private(const EC_KEY *);
81#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */
82
83Key *key_from_blob(const u_char *, u_int); 56Key *key_from_blob(const u_char *, u_int);
84int key_to_blob(const Key *, u_char **, u_int *); 57int key_to_blob(const Key *, u_char **, u_int *);
85 58
@@ -87,18 +60,11 @@ int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int,
87 const char *); 60 const char *);
88int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); 61int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int);
89 62
90void key_private_serialize(const Key *, struct sshbuf *);
91Key *key_private_deserialize(struct sshbuf *);
92
93/* authfile.c */ 63/* authfile.c */
94int key_save_private(Key *, const char *, const char *, const char *,
95 int, const char *, int);
96int key_load_file(int, const char *, struct sshbuf *);
97Key *key_load_cert(const char *); 64Key *key_load_cert(const char *);
98Key *key_load_public(const char *, char **); 65Key *key_load_public(const char *, char **);
99Key *key_load_private(const char *, const char *, char **); 66Key *key_load_private(const char *, const char *, char **);
100Key *key_load_private_cert(int, const char *, const char *, int *); 67Key *key_load_private_cert(int, const char *, const char *, int *);
101Key *key_load_private_type(int, const char *, const char *, char **, int *); 68Key *key_load_private_type(int, const char *, const char *, char **, int *);
102int key_perm_ok(int, const char *);
103 69
104#endif 70#endif
diff --git a/krl.c b/krl.c
index 3f28178b7..086fc20e5 100644
--- a/krl.c
+++ b/krl.c
@@ -14,7 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17/* $OpenBSD: krl.c,v 1.39 2017/03/10 07:18:32 dtucker Exp $ */ 17/* $OpenBSD: krl.c,v 1.40 2017/05/31 09:15:42 deraadt Exp $ */
18 18
19#include "includes.h" 19#include "includes.h"
20 20
@@ -1026,7 +1026,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
1026 } 1026 }
1027 } 1027 }
1028 /* Record keys used to sign the KRL */ 1028 /* Record keys used to sign the KRL */
1029 tmp_ca_used = reallocarray(ca_used, nca_used + 1, 1029 tmp_ca_used = recallocarray(ca_used, nca_used, nca_used + 1,
1030 sizeof(*ca_used)); 1030 sizeof(*ca_used));
1031 if (tmp_ca_used == NULL) { 1031 if (tmp_ca_used == NULL) {
1032 r = SSH_ERR_ALLOC_FAIL; 1032 r = SSH_ERR_ALLOC_FAIL;
diff --git a/log.c b/log.c
index d0f86cf6f..99450dd12 100644
--- a/log.c
+++ b/log.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: log.c,v 1.49 2017/03/10 03:15:58 djm Exp $ */ 1/* $OpenBSD: log.c,v 1.50 2017/05/17 01:24:17 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -256,18 +256,7 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
256 256
257 argv0 = av0; 257 argv0 = av0;
258 258
259 switch (level) { 259 if (log_change_level(level) != 0) {
260 case SYSLOG_LEVEL_QUIET:
261 case SYSLOG_LEVEL_FATAL:
262 case SYSLOG_LEVEL_ERROR:
263 case SYSLOG_LEVEL_INFO:
264 case SYSLOG_LEVEL_VERBOSE:
265 case SYSLOG_LEVEL_DEBUG1:
266 case SYSLOG_LEVEL_DEBUG2:
267 case SYSLOG_LEVEL_DEBUG3:
268 log_level = level;
269 break;
270 default:
271 fprintf(stderr, "Unrecognized internal syslog level code %d\n", 260 fprintf(stderr, "Unrecognized internal syslog level code %d\n",
272 (int) level); 261 (int) level);
273 exit(1); 262 exit(1);
@@ -340,13 +329,27 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
340#endif 329#endif
341} 330}
342 331
343void 332int
344log_change_level(LogLevel new_log_level) 333log_change_level(LogLevel new_log_level)
345{ 334{
346 /* no-op if log_init has not been called */ 335 /* no-op if log_init has not been called */
347 if (argv0 == NULL) 336 if (argv0 == NULL)
348 return; 337 return 0;
349 log_init(argv0, new_log_level, log_facility, log_on_stderr); 338
339 switch (new_log_level) {
340 case SYSLOG_LEVEL_QUIET:
341 case SYSLOG_LEVEL_FATAL:
342 case SYSLOG_LEVEL_ERROR:
343 case SYSLOG_LEVEL_INFO:
344 case SYSLOG_LEVEL_VERBOSE:
345 case SYSLOG_LEVEL_DEBUG1:
346 case SYSLOG_LEVEL_DEBUG2:
347 case SYSLOG_LEVEL_DEBUG3:
348 log_level = new_log_level;
349 return 0;
350 default:
351 return -1;
352 }
350} 353}
351 354
352int 355int
diff --git a/log.h b/log.h
index 434b7c81a..78221046c 100644
--- a/log.h
+++ b/log.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: log.h,v 1.21 2016/07/15 05:01:58 dtucker Exp $ */ 1/* $OpenBSD: log.h,v 1.22 2017/05/17 01:24:17 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -49,7 +49,7 @@ typedef enum {
49typedef void (log_handler_fn)(LogLevel, const char *, void *); 49typedef void (log_handler_fn)(LogLevel, const char *, void *);
50 50
51void log_init(char *, LogLevel, SyslogFacility, int); 51void log_init(char *, LogLevel, SyslogFacility, int);
52void log_change_level(LogLevel); 52int log_change_level(LogLevel);
53int log_is_on_stderr(void); 53int log_is_on_stderr(void);
54void log_redirect_stderr_to(const char *); 54void log_redirect_stderr_to(const char *);
55 55
diff --git a/mac.c b/mac.c
index 5ba7fae19..51dc11d76 100644
--- a/mac.c
+++ b/mac.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mac.c,v 1.33 2016/07/08 03:44:42 djm Exp $ */ 1/* $OpenBSD: mac.c,v 1.34 2017/05/08 22:57:38 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -64,10 +64,6 @@ static const struct macalg macs[] = {
64#endif 64#endif
65 { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, 65 { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 },
66 { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 }, 66 { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 },
67#ifdef HAVE_EVP_RIPEMD160
68 { "hmac-ripemd160", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
69 { "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
70#endif
71 { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, 67 { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 },
72 { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, 68 { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 },
73 69
@@ -80,9 +76,6 @@ static const struct macalg macs[] = {
80#endif 76#endif
81 { "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 }, 77 { "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 },
82 { "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 }, 78 { "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 },
83#ifdef HAVE_EVP_RIPEMD160
84 { "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 },
85#endif
86 { "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 }, 79 { "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 },
87 { "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 }, 80 { "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 },
88 81
diff --git a/md-sha256.c b/md-sha256.c
deleted file mode 100644
index 8c1b3b92d..000000000
--- a/md-sha256.c
+++ /dev/null
@@ -1,86 +0,0 @@
1/* $OpenBSD: md-sha256.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */
2/*
3 * Copyright (c) 2005 Damien Miller <djm@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* EVP wrapper for SHA256 */
19
20#include "includes.h"
21
22#include <sys/types.h>
23#include <openssl/opensslv.h>
24
25#if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L)
26
27#include <string.h>
28#include <openssl/evp.h>
29#ifdef HAVE_SHA256_UPDATE
30# ifdef HAVE_SHA2_H
31# include <sha2.h>
32# elif defined(HAVE_CRYPTO_SHA2_H)
33# include <crypto/sha2.h>
34# endif
35#endif
36
37const EVP_MD *evp_ssh_sha256(void);
38
39static int
40ssh_sha256_init(EVP_MD_CTX *ctxt)
41{
42 SHA256_Init(ctxt->md_data);
43 return (1);
44}
45
46static int
47ssh_sha256_update(EVP_MD_CTX *ctxt, const void *data, unsigned long len)
48{
49 SHA256_Update(ctxt->md_data, data, len);
50 return (1);
51}
52
53static int
54ssh_sha256_final(EVP_MD_CTX *ctxt, unsigned char *digest)
55{
56 SHA256_Final(digest, ctxt->md_data);
57 return (1);
58}
59
60static int
61ssh_sha256_cleanup(EVP_MD_CTX *ctxt)
62{
63 memset(ctxt->md_data, 0, sizeof(SHA256_CTX));
64 return (1);
65}
66
67const EVP_MD *
68evp_ssh_sha256(void)
69{
70 static EVP_MD ssh_sha256;
71
72 memset(&ssh_sha256, 0, sizeof(ssh_sha256));
73 ssh_sha256.type = NID_undef;
74 ssh_sha256.md_size = SHA256_DIGEST_LENGTH;
75 ssh_sha256.init = ssh_sha256_init;
76 ssh_sha256.update = ssh_sha256_update;
77 ssh_sha256.final = ssh_sha256_final;
78 ssh_sha256.cleanup = ssh_sha256_cleanup;
79 ssh_sha256.block_size = SHA256_BLOCK_LENGTH;
80 ssh_sha256.ctx_size = sizeof(SHA256_CTX);
81
82 return (&ssh_sha256);
83}
84
85#endif /* !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) */
86
diff --git a/misc.c b/misc.c
index cfd32729a..05950a471 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.c,v 1.109 2017/03/14 00:55:37 dtucker Exp $ */ 1/* $OpenBSD: misc.c,v 1.113 2017/08/18 05:48:04 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -29,10 +29,16 @@
29#include <sys/types.h> 29#include <sys/types.h>
30#include <sys/ioctl.h> 30#include <sys/ioctl.h>
31#include <sys/socket.h> 31#include <sys/socket.h>
32#include <sys/stat.h>
32#include <sys/time.h> 33#include <sys/time.h>
34#include <sys/wait.h>
33#include <sys/un.h> 35#include <sys/un.h>
34 36
35#include <limits.h> 37#include <limits.h>
38#ifdef HAVE_LIBGEN_H
39# include <libgen.h>
40#endif
41#include <signal.h>
36#include <stdarg.h> 42#include <stdarg.h>
37#include <stdio.h> 43#include <stdio.h>
38#include <stdlib.h> 44#include <stdlib.h>
@@ -61,6 +67,10 @@
61#include "misc.h" 67#include "misc.h"
62#include "log.h" 68#include "log.h"
63#include "ssh.h" 69#include "ssh.h"
70#include "sshbuf.h"
71#include "ssherr.h"
72#include "uidswap.h"
73#include "platform.h"
64 74
65/* remove newline at end of string */ 75/* remove newline at end of string */
66char * 76char *
@@ -539,7 +549,7 @@ addargs(arglist *args, char *fmt, ...)
539 } else if (args->num+2 >= nalloc) 549 } else if (args->num+2 >= nalloc)
540 nalloc *= 2; 550 nalloc *= 2;
541 551
542 args->list = xreallocarray(args->list, nalloc, sizeof(char *)); 552 args->list = xrecallocarray(args->list, args->nalloc, nalloc, sizeof(char *));
543 args->nalloc = nalloc; 553 args->nalloc = nalloc;
544 args->list[args->num++] = cp; 554 args->list[args->num++] = cp;
545 args->list[args->num] = NULL; 555 args->list[args->num] = NULL;
@@ -1085,6 +1095,7 @@ static const struct {
1085 const char *name; 1095 const char *name;
1086 int value; 1096 int value;
1087} ipqos[] = { 1097} ipqos[] = {
1098 { "none", INT_MAX }, /* can't use 0 here; that's CS0 */
1088 { "af11", IPTOS_DSCP_AF11 }, 1099 { "af11", IPTOS_DSCP_AF11 },
1089 { "af12", IPTOS_DSCP_AF12 }, 1100 { "af12", IPTOS_DSCP_AF12 },
1090 { "af13", IPTOS_DSCP_AF13 }, 1101 { "af13", IPTOS_DSCP_AF13 },
@@ -1274,3 +1285,461 @@ daemonized(void)
1274 debug3("already daemonized"); 1285 debug3("already daemonized");
1275 return 1; 1286 return 1;
1276} 1287}
1288
1289
1290/*
1291 * Splits 's' into an argument vector. Handles quoted string and basic
1292 * escape characters (\\, \", \'). Caller must free the argument vector
1293 * and its members.
1294 */
1295int
1296argv_split(const char *s, int *argcp, char ***argvp)
1297{
1298 int r = SSH_ERR_INTERNAL_ERROR;
1299 int argc = 0, quote, i, j;
1300 char *arg, **argv = xcalloc(1, sizeof(*argv));
1301
1302 *argvp = NULL;
1303 *argcp = 0;
1304
1305 for (i = 0; s[i] != '\0'; i++) {
1306 /* Skip leading whitespace */
1307 if (s[i] == ' ' || s[i] == '\t')
1308 continue;
1309
1310 /* Start of a token */
1311 quote = 0;
1312 if (s[i] == '\\' &&
1313 (s[i + 1] == '\'' || s[i + 1] == '\"' || s[i + 1] == '\\'))
1314 i++;
1315 else if (s[i] == '\'' || s[i] == '"')
1316 quote = s[i++];
1317
1318 argv = xreallocarray(argv, (argc + 2), sizeof(*argv));
1319 arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1);
1320 argv[argc] = NULL;
1321
1322 /* Copy the token in, removing escapes */
1323 for (j = 0; s[i] != '\0'; i++) {
1324 if (s[i] == '\\') {
1325 if (s[i + 1] == '\'' ||
1326 s[i + 1] == '\"' ||
1327 s[i + 1] == '\\') {
1328 i++; /* Skip '\' */
1329 arg[j++] = s[i];
1330 } else {
1331 /* Unrecognised escape */
1332 arg[j++] = s[i];
1333 }
1334 } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t'))
1335 break; /* done */
1336 else if (quote != 0 && s[i] == quote)
1337 break; /* done */
1338 else
1339 arg[j++] = s[i];
1340 }
1341 if (s[i] == '\0') {
1342 if (quote != 0) {
1343 /* Ran out of string looking for close quote */
1344 r = SSH_ERR_INVALID_FORMAT;
1345 goto out;
1346 }
1347 break;
1348 }
1349 }
1350 /* Success */
1351 *argcp = argc;
1352 *argvp = argv;
1353 argc = 0;
1354 argv = NULL;
1355 r = 0;
1356 out:
1357 if (argc != 0 && argv != NULL) {
1358 for (i = 0; i < argc; i++)
1359 free(argv[i]);
1360 free(argv);
1361 }
1362 return r;
1363}
1364
1365/*
1366 * Reassemble an argument vector into a string, quoting and escaping as
1367 * necessary. Caller must free returned string.
1368 */
1369char *
1370argv_assemble(int argc, char **argv)
1371{
1372 int i, j, ws, r;
1373 char c, *ret;
1374 struct sshbuf *buf, *arg;
1375
1376 if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL)
1377 fatal("%s: sshbuf_new failed", __func__);
1378
1379 for (i = 0; i < argc; i++) {
1380 ws = 0;
1381 sshbuf_reset(arg);
1382 for (j = 0; argv[i][j] != '\0'; j++) {
1383 r = 0;
1384 c = argv[i][j];
1385 switch (c) {
1386 case ' ':
1387 case '\t':
1388 ws = 1;
1389 r = sshbuf_put_u8(arg, c);
1390 break;
1391 case '\\':
1392 case '\'':
1393 case '"':
1394 if ((r = sshbuf_put_u8(arg, '\\')) != 0)
1395 break;
1396 /* FALLTHROUGH */
1397 default:
1398 r = sshbuf_put_u8(arg, c);
1399 break;
1400 }
1401 if (r != 0)
1402 fatal("%s: sshbuf_put_u8: %s",
1403 __func__, ssh_err(r));
1404 }
1405 if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) ||
1406 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) ||
1407 (r = sshbuf_putb(buf, arg)) != 0 ||
1408 (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0))
1409 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1410 }
1411 if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL)
1412 fatal("%s: malloc failed", __func__);
1413 memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf));
1414 ret[sshbuf_len(buf)] = '\0';
1415 sshbuf_free(buf);
1416 sshbuf_free(arg);
1417 return ret;
1418}
1419
1420/*
1421 * Runs command in a subprocess wuth a minimal environment.
1422 * Returns pid on success, 0 on failure.
1423 * The child stdout and stderr maybe captured, left attached or sent to
1424 * /dev/null depending on the contents of flags.
1425 * "tag" is prepended to log messages.
1426 * NB. "command" is only used for logging; the actual command executed is
1427 * av[0].
1428 */
1429pid_t
1430subprocess(const char *tag, struct passwd *pw, const char *command,
1431 int ac, char **av, FILE **child, u_int flags)
1432{
1433 FILE *f = NULL;
1434 struct stat st;
1435 int fd, devnull, p[2], i;
1436 pid_t pid;
1437 char *cp, errmsg[512];
1438 u_int envsize;
1439 char **child_env;
1440
1441 if (child != NULL)
1442 *child = NULL;
1443
1444 debug3("%s: %s command \"%s\" running as %s (flags 0x%x)", __func__,
1445 tag, command, pw->pw_name, flags);
1446
1447 /* Check consistency */
1448 if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 &&
1449 (flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) {
1450 error("%s: inconsistent flags", __func__);
1451 return 0;
1452 }
1453 if (((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) != (child == NULL)) {
1454 error("%s: inconsistent flags/output", __func__);
1455 return 0;
1456 }
1457
1458 /*
1459 * If executing an explicit binary, then verify the it exists
1460 * and appears safe-ish to execute
1461 */
1462 if (*av[0] != '/') {
1463 error("%s path is not absolute", tag);
1464 return 0;
1465 }
1466 temporarily_use_uid(pw);
1467 if (stat(av[0], &st) < 0) {
1468 error("Could not stat %s \"%s\": %s", tag,
1469 av[0], strerror(errno));
1470 restore_uid();
1471 return 0;
1472 }
1473 if (safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) {
1474 error("Unsafe %s \"%s\": %s", tag, av[0], errmsg);
1475 restore_uid();
1476 return 0;
1477 }
1478 /* Prepare to keep the child's stdout if requested */
1479 if (pipe(p) != 0) {
1480 error("%s: pipe: %s", tag, strerror(errno));
1481 restore_uid();
1482 return 0;
1483 }
1484 restore_uid();
1485
1486 switch ((pid = fork())) {
1487 case -1: /* error */
1488 error("%s: fork: %s", tag, strerror(errno));
1489 close(p[0]);
1490 close(p[1]);
1491 return 0;
1492 case 0: /* child */
1493 /* Prepare a minimal environment for the child. */
1494 envsize = 5;
1495 child_env = xcalloc(sizeof(*child_env), envsize);
1496 child_set_env(&child_env, &envsize, "PATH", _PATH_STDPATH);
1497 child_set_env(&child_env, &envsize, "USER", pw->pw_name);
1498 child_set_env(&child_env, &envsize, "LOGNAME", pw->pw_name);
1499 child_set_env(&child_env, &envsize, "HOME", pw->pw_dir);
1500 if ((cp = getenv("LANG")) != NULL)
1501 child_set_env(&child_env, &envsize, "LANG", cp);
1502
1503 for (i = 0; i < NSIG; i++)
1504 signal(i, SIG_DFL);
1505
1506 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
1507 error("%s: open %s: %s", tag, _PATH_DEVNULL,
1508 strerror(errno));
1509 _exit(1);
1510 }
1511 if (dup2(devnull, STDIN_FILENO) == -1) {
1512 error("%s: dup2: %s", tag, strerror(errno));
1513 _exit(1);
1514 }
1515
1516 /* Set up stdout as requested; leave stderr in place for now. */
1517 fd = -1;
1518 if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0)
1519 fd = p[1];
1520 else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0)
1521 fd = devnull;
1522 if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) {
1523 error("%s: dup2: %s", tag, strerror(errno));
1524 _exit(1);
1525 }
1526 closefrom(STDERR_FILENO + 1);
1527
1528 /* Don't use permanently_set_uid() here to avoid fatal() */
1529 if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
1530 error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid,
1531 strerror(errno));
1532 _exit(1);
1533 }
1534 if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
1535 error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid,
1536 strerror(errno));
1537 _exit(1);
1538 }
1539 /* stdin is pointed to /dev/null at this point */
1540 if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 &&
1541 dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
1542 error("%s: dup2: %s", tag, strerror(errno));
1543 _exit(1);
1544 }
1545
1546 execve(av[0], av, child_env);
1547 error("%s exec \"%s\": %s", tag, command, strerror(errno));
1548 _exit(127);
1549 default: /* parent */
1550 break;
1551 }
1552
1553 close(p[1]);
1554 if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0)
1555 close(p[0]);
1556 else if ((f = fdopen(p[0], "r")) == NULL) {
1557 error("%s: fdopen: %s", tag, strerror(errno));
1558 close(p[0]);
1559 /* Don't leave zombie child */
1560 kill(pid, SIGTERM);
1561 while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
1562 ;
1563 return 0;
1564 }
1565 /* Success */
1566 debug3("%s: %s pid %ld", __func__, tag, (long)pid);
1567 if (child != NULL)
1568 *child = f;
1569 return pid;
1570}
1571
1572/* Returns 0 if pid exited cleanly, non-zero otherwise */
1573int
1574exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet)
1575{
1576 int status;
1577
1578 while (waitpid(pid, &status, 0) == -1) {
1579 if (errno != EINTR) {
1580 error("%s: waitpid: %s", tag, strerror(errno));
1581 return -1;
1582 }
1583 }
1584 if (WIFSIGNALED(status)) {
1585 error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status));
1586 return -1;
1587 } else if (WEXITSTATUS(status) != 0) {
1588 do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO,
1589 "%s %s failed, status %d", tag, cmd, WEXITSTATUS(status));
1590 return -1;
1591 }
1592 return 0;
1593}
1594
1595/*
1596 * Check a given path for security. This is defined as all components
1597 * of the path to the file must be owned by either the owner of
1598 * of the file or root and no directories must be group or world writable.
1599 *
1600 * XXX Should any specific check be done for sym links ?
1601 *
1602 * Takes a file name, its stat information (preferably from fstat() to
1603 * avoid races), the uid of the expected owner, their home directory and an
1604 * error buffer plus max size as arguments.
1605 *
1606 * Returns 0 on success and -1 on failure
1607 */
1608int
1609safe_path(const char *name, struct stat *stp, const char *pw_dir,
1610 uid_t uid, char *err, size_t errlen)
1611{
1612 char buf[PATH_MAX], homedir[PATH_MAX];
1613 char *cp;
1614 int comparehome = 0;
1615 struct stat st;
1616
1617 if (realpath(name, buf) == NULL) {
1618 snprintf(err, errlen, "realpath %s failed: %s", name,
1619 strerror(errno));
1620 return -1;
1621 }
1622 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
1623 comparehome = 1;
1624
1625 if (!S_ISREG(stp->st_mode)) {
1626 snprintf(err, errlen, "%s is not a regular file", buf);
1627 return -1;
1628 }
1629 if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
1630 (stp->st_mode & 022) != 0) {
1631 snprintf(err, errlen, "bad ownership or modes for file %s",
1632 buf);
1633 return -1;
1634 }
1635
1636 /* for each component of the canonical path, walking upwards */
1637 for (;;) {
1638 if ((cp = dirname(buf)) == NULL) {
1639 snprintf(err, errlen, "dirname() failed");
1640 return -1;
1641 }
1642 strlcpy(buf, cp, sizeof(buf));
1643
1644 if (stat(buf, &st) < 0 ||
1645 (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
1646 (st.st_mode & 022) != 0) {
1647 snprintf(err, errlen,
1648 "bad ownership or modes for directory %s", buf);
1649 return -1;
1650 }
1651
1652 /* If are past the homedir then we can stop */
1653 if (comparehome && strcmp(homedir, buf) == 0)
1654 break;
1655
1656 /*
1657 * dirname should always complete with a "/" path,
1658 * but we can be paranoid and check for "." too
1659 */
1660 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
1661 break;
1662 }
1663 return 0;
1664}
1665
1666/*
1667 * Version of safe_path() that accepts an open file descriptor to
1668 * avoid races.
1669 *
1670 * Returns 0 on success and -1 on failure
1671 */
1672int
1673safe_path_fd(int fd, const char *file, struct passwd *pw,
1674 char *err, size_t errlen)
1675{
1676 struct stat st;
1677
1678 /* check the open file to avoid races */
1679 if (fstat(fd, &st) < 0) {
1680 snprintf(err, errlen, "cannot stat file %s: %s",
1681 file, strerror(errno));
1682 return -1;
1683 }
1684 return safe_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
1685}
1686
1687/*
1688 * Sets the value of the given variable in the environment. If the variable
1689 * already exists, its value is overridden.
1690 */
1691void
1692child_set_env(char ***envp, u_int *envsizep, const char *name,
1693 const char *value)
1694{
1695 char **env;
1696 u_int envsize;
1697 u_int i, namelen;
1698
1699 if (strchr(name, '=') != NULL) {
1700 error("Invalid environment variable \"%.100s\"", name);
1701 return;
1702 }
1703
1704 /*
1705 * If we're passed an uninitialized list, allocate a single null
1706 * entry before continuing.
1707 */
1708 if (*envp == NULL && *envsizep == 0) {
1709 *envp = xmalloc(sizeof(char *));
1710 *envp[0] = NULL;
1711 *envsizep = 1;
1712 }
1713
1714 /*
1715 * Find the slot where the value should be stored. If the variable
1716 * already exists, we reuse the slot; otherwise we append a new slot
1717 * at the end of the array, expanding if necessary.
1718 */
1719 env = *envp;
1720 namelen = strlen(name);
1721 for (i = 0; env[i]; i++)
1722 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
1723 break;
1724 if (env[i]) {
1725 /* Reuse the slot. */
1726 free(env[i]);
1727 } else {
1728 /* New variable. Expand if necessary. */
1729 envsize = *envsizep;
1730 if (i >= envsize - 1) {
1731 if (envsize >= 1000)
1732 fatal("child_set_env: too many env vars");
1733 envsize += 50;
1734 env = (*envp) = xreallocarray(env, envsize, sizeof(char *));
1735 *envsizep = envsize;
1736 }
1737 /* Need to set the NULL pointer at end of array beyond the new slot. */
1738 env[i + 1] = NULL;
1739 }
1740
1741 /* Allocate space and format the variable in the appropriate slot. */
1742 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
1743 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
1744}
1745
diff --git a/misc.h b/misc.h
index c242f9011..153d11375 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.h,v 1.61 2016/11/30 00:28:31 dtucker Exp $ */ 1/* $OpenBSD: misc.h,v 1.63 2017/08/18 05:48:04 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,6 +16,7 @@
16#define _MISC_H 16#define _MISC_H
17 17
18#include <sys/time.h> 18#include <sys/time.h>
19#include <sys/types.h>
19 20
20/* Data structure for representing a forwarding request. */ 21/* Data structure for representing a forwarding request. */
21struct Forward { 22struct Forward {
@@ -132,6 +133,25 @@ int parse_ipqos(const char *);
132const char *iptos2str(int); 133const char *iptos2str(int);
133void mktemp_proto(char *, size_t); 134void mktemp_proto(char *, size_t);
134 135
136void child_set_env(char ***envp, u_int *envsizep, const char *name,
137 const char *value);
138
139int argv_split(const char *, int *, char ***);
140char *argv_assemble(int, char **argv);
141int exited_cleanly(pid_t, const char *, const char *, int);
142
143#define SSH_SUBPROCESS_STDOUT_DISCARD (1) /* Discard stdout */
144#define SSH_SUBPROCESS_STDOUT_CAPTURE (1<<1) /* Redirect stdout */
145#define SSH_SUBPROCESS_STDERR_DISCARD (1<<2) /* Discard stderr */
146pid_t subprocess(const char *, struct passwd *,
147 const char *, int, char **, FILE **, u_int flags);
148
149struct stat;
150int safe_path(const char *, struct stat *, const char *, uid_t,
151 char *, size_t);
152int safe_path_fd(int, const char *, struct passwd *,
153 char *err, size_t errlen);
154
135/* readpass.c */ 155/* readpass.c */
136 156
137#define RP_ECHO 0x0001 157#define RP_ECHO 0x0001
diff --git a/moduli.0 b/moduli.0
index dd762af85..e319015b2 100644
--- a/moduli.0
+++ b/moduli.0
@@ -71,4 +71,4 @@ STANDARDS
71 the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006, 71 the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006,
72 2006. 72 2006.
73 73
74OpenBSD 6.0 September 26, 2012 OpenBSD 6.0 74OpenBSD 6.2 September 26, 2012 OpenBSD 6.2
diff --git a/monitor.c b/monitor.c
index 96d22b7e4..f517da482 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.167 2017/02/03 23:05:57 djm Exp $ */ 1/* $OpenBSD: monitor.c,v 1.174 2017/10/02 19:33:20 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -308,6 +308,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
308 partial = 0; 308 partial = 0;
309 auth_method = "unknown"; 309 auth_method = "unknown";
310 auth_submethod = NULL; 310 auth_submethod = NULL;
311 auth2_authctxt_reset_info(authctxt);
312
311 authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); 313 authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
312 314
313 /* Special handling for multiple required authentications */ 315 /* Special handling for multiple required authentications */
@@ -347,6 +349,10 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
347 auth_method, auth_submethod); 349 auth_method, auth_submethod);
348 if (!partial && !authenticated) 350 if (!partial && !authenticated)
349 authctxt->failures++; 351 authctxt->failures++;
352 if (authenticated || partial) {
353 auth2_update_session_info(authctxt,
354 auth_method, auth_submethod);
355 }
350 } 356 }
351 } 357 }
352 358
@@ -754,10 +760,12 @@ mm_answer_pwnamallow(int sock, Buffer *m)
754 for (i = 0; i < options.nx; i++) \ 760 for (i = 0; i < options.nx; i++) \
755 buffer_put_cstring(m, options.x[i]); \ 761 buffer_put_cstring(m, options.x[i]); \
756 } while (0) 762 } while (0)
763#define M_CP_STRARRAYOPT_ALLOC(x, nx) M_CP_STRARRAYOPT(x, nx)
757 /* See comment in servconf.h */ 764 /* See comment in servconf.h */
758 COPY_MATCH_STRING_OPTS(); 765 COPY_MATCH_STRING_OPTS();
759#undef M_CP_STROPT 766#undef M_CP_STROPT
760#undef M_CP_STRARRAYOPT 767#undef M_CP_STRARRAYOPT
768#undef M_CP_STRARRAYOPT_ALLOC
761 769
762 /* Create valid auth method lists */ 770 /* Create valid auth method lists */
763 if (auth2_setup_methods_lists(authctxt) != 0) { 771 if (auth2_setup_methods_lists(authctxt) != 0) {
@@ -1119,7 +1127,7 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
1119int 1127int
1120mm_answer_keyallowed(int sock, Buffer *m) 1128mm_answer_keyallowed(int sock, Buffer *m)
1121{ 1129{
1122 Key *key; 1130 struct sshkey *key;
1123 char *cuser, *chost; 1131 char *cuser, *chost;
1124 u_char *blob; 1132 u_char *blob;
1125 u_int bloblen, pubkey_auth_attempt; 1133 u_int bloblen, pubkey_auth_attempt;
@@ -1147,12 +1155,11 @@ mm_answer_keyallowed(int sock, Buffer *m)
1147 switch (type) { 1155 switch (type) {
1148 case MM_USERKEY: 1156 case MM_USERKEY:
1149 allowed = options.pubkey_authentication && 1157 allowed = options.pubkey_authentication &&
1150 !auth2_userkey_already_used(authctxt, key) && 1158 !auth2_key_already_used(authctxt, key) &&
1151 match_pattern_list(sshkey_ssh_name(key), 1159 match_pattern_list(sshkey_ssh_name(key),
1152 options.pubkey_key_types, 0) == 1 && 1160 options.pubkey_key_types, 0) == 1 &&
1153 user_key_allowed(authctxt->pw, key, 1161 user_key_allowed(authctxt->pw, key,
1154 pubkey_auth_attempt); 1162 pubkey_auth_attempt);
1155 pubkey_auth_info(authctxt, key, NULL);
1156 auth_method = "publickey"; 1163 auth_method = "publickey";
1157 if (options.pubkey_authentication && 1164 if (options.pubkey_authentication &&
1158 (!pubkey_auth_attempt || allowed != 1)) 1165 (!pubkey_auth_attempt || allowed != 1))
@@ -1160,11 +1167,12 @@ mm_answer_keyallowed(int sock, Buffer *m)
1160 break; 1167 break;
1161 case MM_HOSTKEY: 1168 case MM_HOSTKEY:
1162 allowed = options.hostbased_authentication && 1169 allowed = options.hostbased_authentication &&
1170 !auth2_key_already_used(authctxt, key) &&
1163 match_pattern_list(sshkey_ssh_name(key), 1171 match_pattern_list(sshkey_ssh_name(key),
1164 options.hostbased_key_types, 0) == 1 && 1172 options.hostbased_key_types, 0) == 1 &&
1165 hostbased_key_allowed(authctxt->pw, 1173 hostbased_key_allowed(authctxt->pw,
1166 cuser, chost, key); 1174 cuser, chost, key);
1167 pubkey_auth_info(authctxt, key, 1175 auth2_record_info(authctxt,
1168 "client user \"%.100s\", client host \"%.100s\"", 1176 "client user \"%.100s\", client host \"%.100s\"",
1169 cuser, chost); 1177 cuser, chost);
1170 auth_method = "hostbased"; 1178 auth_method = "hostbased";
@@ -1175,11 +1183,10 @@ mm_answer_keyallowed(int sock, Buffer *m)
1175 } 1183 }
1176 } 1184 }
1177 1185
1178 debug3("%s: key %p is %s", 1186 debug3("%s: key is %s", __func__, allowed ? "allowed" : "not allowed");
1179 __func__, key, allowed ? "allowed" : "not allowed");
1180 1187
1181 if (key != NULL) 1188 auth2_record_key(authctxt, 0, key);
1182 key_free(key); 1189 sshkey_free(key);
1183 1190
1184 /* clear temporarily storage (used by verify) */ 1191 /* clear temporarily storage (used by verify) */
1185 monitor_reset_key_state(); 1192 monitor_reset_key_state();
@@ -1330,33 +1337,35 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser,
1330} 1337}
1331 1338
1332int 1339int
1333mm_answer_keyverify(int sock, Buffer *m) 1340mm_answer_keyverify(int sock, struct sshbuf *m)
1334{ 1341{
1335 Key *key; 1342 struct sshkey *key;
1336 u_char *signature, *data, *blob; 1343 u_char *signature, *data, *blob;
1337 u_int signaturelen, datalen, bloblen; 1344 size_t signaturelen, datalen, bloblen;
1338 int verified = 0; 1345 int r, ret, valid_data = 0, encoded_ret;
1339 int valid_data = 0;
1340 1346
1341 blob = buffer_get_string(m, &bloblen); 1347 if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 ||
1342 signature = buffer_get_string(m, &signaturelen); 1348 (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 ||
1343 data = buffer_get_string(m, &datalen); 1349 (r = sshbuf_get_string(m, &data, &datalen)) != 0)
1350 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1344 1351
1345 if (hostbased_cuser == NULL || hostbased_chost == NULL || 1352 if (hostbased_cuser == NULL || hostbased_chost == NULL ||
1346 !monitor_allowed_key(blob, bloblen)) 1353 !monitor_allowed_key(blob, bloblen))
1347 fatal("%s: bad key, not previously allowed", __func__); 1354 fatal("%s: bad key, not previously allowed", __func__);
1348 1355
1349 key = key_from_blob(blob, bloblen); 1356 /* XXX use sshkey_froms here; need to change key_blob, etc. */
1350 if (key == NULL) 1357 if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0)
1351 fatal("%s: bad public key blob", __func__); 1358 fatal("%s: bad public key blob: %s", __func__, ssh_err(r));
1352 1359
1353 switch (key_blobtype) { 1360 switch (key_blobtype) {
1354 case MM_USERKEY: 1361 case MM_USERKEY:
1355 valid_data = monitor_valid_userblob(data, datalen); 1362 valid_data = monitor_valid_userblob(data, datalen);
1363 auth_method = "publickey";
1356 break; 1364 break;
1357 case MM_HOSTKEY: 1365 case MM_HOSTKEY:
1358 valid_data = monitor_valid_hostbasedblob(data, datalen, 1366 valid_data = monitor_valid_hostbasedblob(data, datalen,
1359 hostbased_cuser, hostbased_chost); 1367 hostbased_cuser, hostbased_chost);
1368 auth_method = "hostbased";
1360 break; 1369 break;
1361 default: 1370 default:
1362 valid_data = 0; 1371 valid_data = 0;
@@ -1365,29 +1374,28 @@ mm_answer_keyverify(int sock, Buffer *m)
1365 if (!valid_data) 1374 if (!valid_data)
1366 fatal("%s: bad signature data blob", __func__); 1375 fatal("%s: bad signature data blob", __func__);
1367 1376
1368 verified = key_verify(key, signature, signaturelen, data, datalen); 1377 ret = sshkey_verify(key, signature, signaturelen, data, datalen,
1369 debug3("%s: key %p signature %s", 1378 active_state->compat);
1370 __func__, key, (verified == 1) ? "verified" : "unverified"); 1379 debug3("%s: %s %p signature %s", __func__, auth_method, key,
1371 1380 (ret == 0) ? "verified" : "unverified");
1372 /* If auth was successful then record key to ensure it isn't reused */ 1381 auth2_record_key(authctxt, ret == 0, key);
1373 if (verified == 1 && key_blobtype == MM_USERKEY)
1374 auth2_record_userkey(authctxt, key);
1375 else
1376 key_free(key);
1377 1382
1378 free(blob); 1383 free(blob);
1379 free(signature); 1384 free(signature);
1380 free(data); 1385 free(data);
1381 1386
1382 auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
1383
1384 monitor_reset_key_state(); 1387 monitor_reset_key_state();
1385 1388
1386 buffer_clear(m); 1389 sshkey_free(key);
1387 buffer_put_int(m, verified); 1390 sshbuf_reset(m);
1391
1392 /* encode ret != 0 as positive integer, since we're sending u32 */
1393 encoded_ret = (ret != 0);
1394 if ((r = sshbuf_put_u32(m, encoded_ret)) != 0)
1395 fatal("%s: buffer error: %s", __func__, ssh_err(r));
1388 mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); 1396 mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m);
1389 1397
1390 return (verified == 1); 1398 return ret == 0;
1391} 1399}
1392 1400
1393static void 1401static void
@@ -1513,13 +1521,14 @@ mm_answer_pty_cleanup(int sock, Buffer *m)
1513int 1521int
1514mm_answer_term(int sock, Buffer *req) 1522mm_answer_term(int sock, Buffer *req)
1515{ 1523{
1524 struct ssh *ssh = active_state; /* XXX */
1516 extern struct monitor *pmonitor; 1525 extern struct monitor *pmonitor;
1517 int res, status; 1526 int res, status;
1518 1527
1519 debug3("%s: tearing down sessions", __func__); 1528 debug3("%s: tearing down sessions", __func__);
1520 1529
1521 /* The child is terminating */ 1530 /* The child is terminating */
1522 session_destroy_all(&mm_session_close); 1531 session_destroy_all(ssh, &mm_session_close);
1523 1532
1524#ifdef USE_PAM 1533#ifdef USE_PAM
1525 if (options.use_pam) 1534 if (options.use_pam)
@@ -1579,6 +1588,17 @@ mm_answer_audit_command(int socket, Buffer *m)
1579#endif /* SSH_AUDIT_EVENTS */ 1588#endif /* SSH_AUDIT_EVENTS */
1580 1589
1581void 1590void
1591monitor_clear_keystate(struct monitor *pmonitor)
1592{
1593 struct ssh *ssh = active_state; /* XXX */
1594
1595 ssh_clear_newkeys(ssh, MODE_IN);
1596 ssh_clear_newkeys(ssh, MODE_OUT);
1597 sshbuf_free(child_state);
1598 child_state = NULL;
1599}
1600
1601void
1582monitor_apply_keystate(struct monitor *pmonitor) 1602monitor_apply_keystate(struct monitor *pmonitor)
1583{ 1603{
1584 struct ssh *ssh = active_state; /* XXX */ 1604 struct ssh *ssh = active_state; /* XXX */
@@ -1639,9 +1659,18 @@ static void
1639monitor_openfds(struct monitor *mon, int do_logfds) 1659monitor_openfds(struct monitor *mon, int do_logfds)
1640{ 1660{
1641 int pair[2]; 1661 int pair[2];
1662#ifdef SO_ZEROIZE
1663 int on = 1;
1664#endif
1642 1665
1643 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) 1666 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
1644 fatal("%s: socketpair: %s", __func__, strerror(errno)); 1667 fatal("%s: socketpair: %s", __func__, strerror(errno));
1668#ifdef SO_ZEROIZE
1669 if (setsockopt(pair[0], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
1670 error("setsockopt SO_ZEROIZE(0): %.100s", strerror(errno));
1671 if (setsockopt(pair[1], SOL_SOCKET, SO_ZEROIZE, &on, sizeof(on)) < 0)
1672 error("setsockopt SO_ZEROIZE(1): %.100s", strerror(errno));
1673#endif
1645 FD_CLOSEONEXEC(pair[0]); 1674 FD_CLOSEONEXEC(pair[0]);
1646 FD_CLOSEONEXEC(pair[1]); 1675 FD_CLOSEONEXEC(pair[1]);
1647 mon->m_recvfd = pair[0]; 1676 mon->m_recvfd = pair[0];
@@ -1774,6 +1803,7 @@ int
1774mm_answer_gss_userok(int sock, Buffer *m) 1803mm_answer_gss_userok(int sock, Buffer *m)
1775{ 1804{
1776 int authenticated; 1805 int authenticated;
1806 const char *displayname;
1777 1807
1778 if (!options.gss_authentication) 1808 if (!options.gss_authentication)
1779 fatal("%s: GSSAPI authentication not enabled", __func__); 1809 fatal("%s: GSSAPI authentication not enabled", __func__);
@@ -1788,6 +1818,9 @@ mm_answer_gss_userok(int sock, Buffer *m)
1788 1818
1789 auth_method = "gssapi-with-mic"; 1819 auth_method = "gssapi-with-mic";
1790 1820
1821 if ((displayname = ssh_gssapi_displayname()) != NULL)
1822 auth2_record_info(authctxt, "%s", displayname);
1823
1791 /* Monitor loop will terminate if authenticated */ 1824 /* Monitor loop will terminate if authenticated */
1792 return (authenticated); 1825 return (authenticated);
1793} 1826}
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 64ff92885..69212aaf3 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.c,v 1.89 2016/08/13 17:47:41 markus Exp $ */ 1/* $OpenBSD: monitor_wrap.c,v 1.94 2017/10/02 19:33:20 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -216,7 +216,7 @@ mm_choose_dh(int min, int nbits, int max)
216#endif 216#endif
217 217
218int 218int
219mm_key_sign(Key *key, u_char **sigp, u_int *lenp, 219mm_key_sign(struct sshkey *key, u_char **sigp, u_int *lenp,
220 const u_char *data, u_int datalen, const char *hostkey_alg) 220 const u_char *data, u_int datalen, const char *hostkey_alg)
221{ 221{
222 struct kex *kex = *pmonitor->m_pkex; 222 struct kex *kex = *pmonitor->m_pkex;
@@ -242,6 +242,7 @@ mm_key_sign(Key *key, u_char **sigp, u_int *lenp,
242struct passwd * 242struct passwd *
243mm_getpwnamallow(const char *username) 243mm_getpwnamallow(const char *username)
244{ 244{
245 struct ssh *ssh = active_state; /* XXX */
245 Buffer m; 246 Buffer m;
246 struct passwd *pw; 247 struct passwd *pw;
247 u_int len, i; 248 u_int len, i;
@@ -289,12 +290,20 @@ out:
289 for (i = 0; i < newopts->nx; i++) \ 290 for (i = 0; i < newopts->nx; i++) \
290 newopts->x[i] = buffer_get_string(&m, NULL); \ 291 newopts->x[i] = buffer_get_string(&m, NULL); \
291 } while (0) 292 } while (0)
293#define M_CP_STRARRAYOPT_ALLOC(x, nx) do { \
294 newopts->x = newopts->nx == 0 ? \
295 NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
296 M_CP_STRARRAYOPT(x, nx); \
297 } while (0)
292 /* See comment in servconf.h */ 298 /* See comment in servconf.h */
293 COPY_MATCH_STRING_OPTS(); 299 COPY_MATCH_STRING_OPTS();
294#undef M_CP_STROPT 300#undef M_CP_STROPT
295#undef M_CP_STRARRAYOPT 301#undef M_CP_STRARRAYOPT
302#undef M_CP_STRARRAYOPT_ALLOC
296 303
297 copy_set_server_options(&options, newopts, 1); 304 copy_set_server_options(&options, newopts, 1);
305 log_change_level(options.log_level);
306 process_permitopen(ssh, &options);
298 free(newopts); 307 free(newopts);
299 308
300 buffer_free(&m); 309 buffer_free(&m);
@@ -374,7 +383,8 @@ mm_auth_password(Authctxt *authctxt, char *password)
374} 383}
375 384
376int 385int
377mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt) 386mm_user_key_allowed(struct passwd *pw, struct sshkey *key,
387 int pubkey_auth_attempt)
378{ 388{
379 return (mm_key_allowed(MM_USERKEY, NULL, NULL, key, 389 return (mm_key_allowed(MM_USERKEY, NULL, NULL, key,
380 pubkey_auth_attempt)); 390 pubkey_auth_attempt));
@@ -382,14 +392,14 @@ mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt)
382 392
383int 393int
384mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host, 394mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host,
385 Key *key) 395 struct sshkey *key)
386{ 396{
387 return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0)); 397 return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0));
388} 398}
389 399
390int 400int
391mm_key_allowed(enum mm_keytype type, const char *user, const char *host, 401mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
392 Key *key, int pubkey_auth_attempt) 402 struct sshkey *key, int pubkey_auth_attempt)
393{ 403{
394 Buffer m; 404 Buffer m;
395 u_char *blob; 405 u_char *blob;
@@ -434,12 +444,13 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host,
434 */ 444 */
435 445
436int 446int
437mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) 447mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen,
448 const u_char *data, size_t datalen, u_int compat)
438{ 449{
439 Buffer m; 450 Buffer m;
440 u_char *blob; 451 u_char *blob;
441 u_int len; 452 u_int len;
442 int verified = 0; 453 u_int encoded_ret = 0;
443 454
444 debug3("%s entering", __func__); 455 debug3("%s entering", __func__);
445 456
@@ -458,11 +469,13 @@ mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
458 debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); 469 debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
459 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); 470 mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
460 471
461 verified = buffer_get_int(&m); 472 encoded_ret = buffer_get_int(&m);
462 473
463 buffer_free(&m); 474 buffer_free(&m);
464 475
465 return (verified); 476 if (encoded_ret != 0)
477 return SSH_ERR_SIGNATURE_INVALID;
478 return 0;
466} 479}
467 480
468void 481void
diff --git a/monitor_wrap.h b/monitor_wrap.h
index db5902f55..9e032d204 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.h,v 1.32 2016/09/28 16:33:07 djm Exp $ */ 1/* $OpenBSD: monitor_wrap.h,v 1.35 2017/05/31 08:09:45 markus Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -34,22 +34,24 @@ extern int use_privsep;
34enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY }; 34enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY };
35 35
36struct monitor; 36struct monitor;
37struct mm_master;
38struct Authctxt; 37struct Authctxt;
39 38
40void mm_log_handler(LogLevel, const char *, void *); 39void mm_log_handler(LogLevel, const char *, void *);
41int mm_is_monitor(void); 40int mm_is_monitor(void);
42DH *mm_choose_dh(int, int, int); 41DH *mm_choose_dh(int, int, int);
43int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); 42int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int,
43 const char *);
44void mm_inform_authserv(char *, char *); 44void mm_inform_authserv(char *, char *);
45struct passwd *mm_getpwnamallow(const char *); 45struct passwd *mm_getpwnamallow(const char *);
46char *mm_auth2_read_banner(void); 46char *mm_auth2_read_banner(void);
47int mm_auth_password(struct Authctxt *, char *); 47int mm_auth_password(struct Authctxt *, char *);
48int mm_key_allowed(enum mm_keytype, const char *, const char *, Key *, int); 48int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *,
49int mm_user_key_allowed(struct passwd *, Key *, int); 49 int);
50int mm_user_key_allowed(struct passwd *, struct sshkey *, int);
50int mm_hostbased_key_allowed(struct passwd *, const char *, 51int mm_hostbased_key_allowed(struct passwd *, const char *,
51 const char *, Key *); 52 const char *, struct sshkey *);
52int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); 53int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t,
54 const u_char *, size_t, u_int);
53 55
54#ifdef GSSAPI 56#ifdef GSSAPI
55OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); 57OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
@@ -83,6 +85,7 @@ void mm_session_pty_cleanup2(struct Session *);
83struct newkeys *mm_newkeys_from_blob(u_char *, int); 85struct newkeys *mm_newkeys_from_blob(u_char *, int);
84int mm_newkeys_to_blob(int, u_char **, u_int *); 86int mm_newkeys_to_blob(int, u_char **, u_int *);
85 87
88void monitor_clear_keystate(struct monitor *);
86void monitor_apply_keystate(struct monitor *); 89void monitor_apply_keystate(struct monitor *);
87void mm_get_keystate(struct monitor *); 90void mm_get_keystate(struct monitor *);
88void mm_send_keystate(struct monitor*); 91void mm_send_keystate(struct monitor*);
diff --git a/mux.c b/mux.c
index 2d6639c5c..5ae454410 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.64 2017/01/21 11:32:04 guenther Exp $ */ 1/* $OpenBSD: mux.c,v 1.69 2017/09/20 05:19:00 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -161,22 +161,32 @@ struct mux_master_state {
161#define MUX_FWD_REMOTE 2 161#define MUX_FWD_REMOTE 2
162#define MUX_FWD_DYNAMIC 3 162#define MUX_FWD_DYNAMIC 3
163 163
164static void mux_session_confirm(int, int, void *); 164static void mux_session_confirm(struct ssh *, int, int, void *);
165static void mux_stdio_confirm(int, int, void *); 165static void mux_stdio_confirm(struct ssh *, int, int, void *);
166 166
167static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); 167static int process_mux_master_hello(struct ssh *, u_int,
168static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); 168 Channel *, struct sshbuf *, struct sshbuf *);
169static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *); 169static int process_mux_new_session(struct ssh *, u_int,
170static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *); 170 Channel *, struct sshbuf *, struct sshbuf *);
171static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *); 171static int process_mux_alive_check(struct ssh *, u_int,
172static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); 172 Channel *, struct sshbuf *, struct sshbuf *);
173static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); 173static int process_mux_terminate(struct ssh *, u_int,
174static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *); 174 Channel *, struct sshbuf *, struct sshbuf *);
175static int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *); 175static int process_mux_open_fwd(struct ssh *, u_int,
176 Channel *, struct sshbuf *, struct sshbuf *);
177static int process_mux_close_fwd(struct ssh *, u_int,
178 Channel *, struct sshbuf *, struct sshbuf *);
179static int process_mux_stdio_fwd(struct ssh *, u_int,
180 Channel *, struct sshbuf *, struct sshbuf *);
181static int process_mux_stop_listening(struct ssh *, u_int,
182 Channel *, struct sshbuf *, struct sshbuf *);
183static int process_mux_proxy(struct ssh *, u_int,
184 Channel *, struct sshbuf *, struct sshbuf *);
176 185
177static const struct { 186static const struct {
178 u_int type; 187 u_int type;
179 int (*handler)(u_int, Channel *, Buffer *, Buffer *); 188 int (*handler)(struct ssh *, u_int, Channel *,
189 struct sshbuf *, struct sshbuf *);
180} mux_master_handlers[] = { 190} mux_master_handlers[] = {
181 { MUX_MSG_HELLO, process_mux_master_hello }, 191 { MUX_MSG_HELLO, process_mux_master_hello },
182 { MUX_C_NEW_SESSION, process_mux_new_session }, 192 { MUX_C_NEW_SESSION, process_mux_new_session },
@@ -193,52 +203,54 @@ static const struct {
193/* Cleanup callback fired on closure of mux slave _session_ channel */ 203/* Cleanup callback fired on closure of mux slave _session_ channel */
194/* ARGSUSED */ 204/* ARGSUSED */
195static void 205static void
196mux_master_session_cleanup_cb(int cid, void *unused) 206mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused)
197{ 207{
198 Channel *cc, *c = channel_by_id(cid); 208 Channel *cc, *c = channel_by_id(ssh, cid);
199 209
200 debug3("%s: entering for channel %d", __func__, cid); 210 debug3("%s: entering for channel %d", __func__, cid);
201 if (c == NULL) 211 if (c == NULL)
202 fatal("%s: channel_by_id(%i) == NULL", __func__, cid); 212 fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
203 if (c->ctl_chan != -1) { 213 if (c->ctl_chan != -1) {
204 if ((cc = channel_by_id(c->ctl_chan)) == NULL) 214 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
205 fatal("%s: channel %d missing control channel %d", 215 fatal("%s: channel %d missing control channel %d",
206 __func__, c->self, c->ctl_chan); 216 __func__, c->self, c->ctl_chan);
207 c->ctl_chan = -1; 217 c->ctl_chan = -1;
208 cc->remote_id = -1; 218 cc->remote_id = 0;
209 chan_rcvd_oclose(cc); 219 cc->have_remote_id = 0;
220 chan_rcvd_oclose(ssh, cc);
210 } 221 }
211 channel_cancel_cleanup(c->self); 222 channel_cancel_cleanup(ssh, c->self);
212} 223}
213 224
214/* Cleanup callback fired on closure of mux slave _control_ channel */ 225/* Cleanup callback fired on closure of mux slave _control_ channel */
215/* ARGSUSED */ 226/* ARGSUSED */
216static void 227static void
217mux_master_control_cleanup_cb(int cid, void *unused) 228mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused)
218{ 229{
219 Channel *sc, *c = channel_by_id(cid); 230 Channel *sc, *c = channel_by_id(ssh, cid);
220 231
221 debug3("%s: entering for channel %d", __func__, cid); 232 debug3("%s: entering for channel %d", __func__, cid);
222 if (c == NULL) 233 if (c == NULL)
223 fatal("%s: channel_by_id(%i) == NULL", __func__, cid); 234 fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
224 if (c->remote_id != -1) { 235 if (c->have_remote_id) {
225 if ((sc = channel_by_id(c->remote_id)) == NULL) 236 if ((sc = channel_by_id(ssh, c->remote_id)) == NULL)
226 fatal("%s: channel %d missing session channel %d", 237 fatal("%s: channel %d missing session channel %u",
227 __func__, c->self, c->remote_id); 238 __func__, c->self, c->remote_id);
228 c->remote_id = -1; 239 c->remote_id = 0;
240 c->have_remote_id = 0;
229 sc->ctl_chan = -1; 241 sc->ctl_chan = -1;
230 if (sc->type != SSH_CHANNEL_OPEN && 242 if (sc->type != SSH_CHANNEL_OPEN &&
231 sc->type != SSH_CHANNEL_OPENING) { 243 sc->type != SSH_CHANNEL_OPENING) {
232 debug2("%s: channel %d: not open", __func__, sc->self); 244 debug2("%s: channel %d: not open", __func__, sc->self);
233 chan_mark_dead(sc); 245 chan_mark_dead(ssh, sc);
234 } else { 246 } else {
235 if (sc->istate == CHAN_INPUT_OPEN) 247 if (sc->istate == CHAN_INPUT_OPEN)
236 chan_read_failed(sc); 248 chan_read_failed(ssh, sc);
237 if (sc->ostate == CHAN_OUTPUT_OPEN) 249 if (sc->ostate == CHAN_OUTPUT_OPEN)
238 chan_write_failed(sc); 250 chan_write_failed(ssh, sc);
239 } 251 }
240 } 252 }
241 channel_cancel_cleanup(c->self); 253 channel_cancel_cleanup(ssh, c->self);
242} 254}
243 255
244/* Check mux client environment variables before passing them to mux master. */ 256/* Check mux client environment variables before passing them to mux master. */
@@ -266,7 +278,8 @@ env_permitted(char *env)
266/* Mux master protocol message handlers */ 278/* Mux master protocol message handlers */
267 279
268static int 280static int
269process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r) 281process_mux_master_hello(struct ssh *ssh, u_int rid,
282 Channel *c, Buffer *m, Buffer *r)
270{ 283{
271 u_int ver; 284 u_int ver;
272 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; 285 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
@@ -308,7 +321,8 @@ process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r)
308} 321}
309 322
310static int 323static int
311process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) 324process_mux_new_session(struct ssh *ssh, u_int rid,
325 Channel *c, Buffer *m, Buffer *r)
312{ 326{
313 Channel *nc; 327 Channel *nc;
314 struct mux_session_confirm_ctx *cctx; 328 struct mux_session_confirm_ctx *cctx;
@@ -401,7 +415,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
401 new_fd[0], new_fd[1], new_fd[2]); 415 new_fd[0], new_fd[1], new_fd[2]);
402 416
403 /* XXX support multiple child sessions in future */ 417 /* XXX support multiple child sessions in future */
404 if (c->remote_id != -1) { 418 if (c->have_remote_id) {
405 debug2("%s: session already open", __func__); 419 debug2("%s: session already open", __func__);
406 /* prepare reply */ 420 /* prepare reply */
407 buffer_put_int(r, MUX_S_FAILURE); 421 buffer_put_int(r, MUX_S_FAILURE);
@@ -453,15 +467,16 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
453 packetmax >>= 1; 467 packetmax >>= 1;
454 } 468 }
455 469
456 nc = channel_new("session", SSH_CHANNEL_OPENING, 470 nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING,
457 new_fd[0], new_fd[1], new_fd[2], window, packetmax, 471 new_fd[0], new_fd[1], new_fd[2], window, packetmax,
458 CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); 472 CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
459 473
460 nc->ctl_chan = c->self; /* link session -> control channel */ 474 nc->ctl_chan = c->self; /* link session -> control channel */
461 c->remote_id = nc->self; /* link control -> session channel */ 475 c->remote_id = nc->self; /* link control -> session channel */
476 c->have_remote_id = 1;
462 477
463 if (cctx->want_tty && escape_char != 0xffffffff) { 478 if (cctx->want_tty && escape_char != 0xffffffff) {
464 channel_register_filter(nc->self, 479 channel_register_filter(ssh, nc->self,
465 client_simple_escape_filter, NULL, 480 client_simple_escape_filter, NULL,
466 client_filter_cleanup, 481 client_filter_cleanup,
467 client_new_escape_filter_ctx((int)escape_char)); 482 client_new_escape_filter_ctx((int)escape_char));
@@ -470,17 +485,19 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
470 debug2("%s: channel_new: %d linked to control channel %d", 485 debug2("%s: channel_new: %d linked to control channel %d",
471 __func__, nc->self, nc->ctl_chan); 486 __func__, nc->self, nc->ctl_chan);
472 487
473 channel_send_open(nc->self); 488 channel_send_open(ssh, nc->self);
474 channel_register_open_confirm(nc->self, mux_session_confirm, cctx); 489 channel_register_open_confirm(ssh, nc->self, mux_session_confirm, cctx);
475 c->mux_pause = 1; /* stop handling messages until open_confirm done */ 490 c->mux_pause = 1; /* stop handling messages until open_confirm done */
476 channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); 491 channel_register_cleanup(ssh, nc->self,
492 mux_master_session_cleanup_cb, 1);
477 493
478 /* reply is deferred, sent by mux_session_confirm */ 494 /* reply is deferred, sent by mux_session_confirm */
479 return 0; 495 return 0;
480} 496}
481 497
482static int 498static int
483process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r) 499process_mux_alive_check(struct ssh *ssh, u_int rid,
500 Channel *c, Buffer *m, Buffer *r)
484{ 501{
485 debug2("%s: channel %d: alive check", __func__, c->self); 502 debug2("%s: channel %d: alive check", __func__, c->self);
486 503
@@ -493,7 +510,8 @@ process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r)
493} 510}
494 511
495static int 512static int
496process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r) 513process_mux_terminate(struct ssh *ssh, u_int rid,
514 Channel *c, Buffer *m, Buffer *r)
497{ 515{
498 debug2("%s: channel %d: terminate request", __func__, c->self); 516 debug2("%s: channel %d: terminate request", __func__, c->self);
499 517
@@ -582,7 +600,7 @@ compare_forward(struct Forward *a, struct Forward *b)
582} 600}
583 601
584static void 602static void
585mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) 603mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
586{ 604{
587 struct mux_channel_confirm_ctx *fctx = ctxt; 605 struct mux_channel_confirm_ctx *fctx = ctxt;
588 char *failmsg = NULL; 606 char *failmsg = NULL;
@@ -590,7 +608,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
590 Channel *c; 608 Channel *c;
591 Buffer out; 609 Buffer out;
592 610
593 if ((c = channel_by_id(fctx->cid)) == NULL) { 611 if ((c = channel_by_id(ssh, fctx->cid)) == NULL) {
594 /* no channel for reply */ 612 /* no channel for reply */
595 error("%s: unknown channel", __func__); 613 error("%s: unknown channel", __func__);
596 return; 614 return;
@@ -616,7 +634,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
616 buffer_put_int(&out, MUX_S_REMOTE_PORT); 634 buffer_put_int(&out, MUX_S_REMOTE_PORT);
617 buffer_put_int(&out, fctx->rid); 635 buffer_put_int(&out, fctx->rid);
618 buffer_put_int(&out, rfwd->allocated_port); 636 buffer_put_int(&out, rfwd->allocated_port);
619 channel_update_permitted_opens(rfwd->handle, 637 channel_update_permitted_opens(ssh, rfwd->handle,
620 rfwd->allocated_port); 638 rfwd->allocated_port);
621 } else { 639 } else {
622 buffer_put_int(&out, MUX_S_OK); 640 buffer_put_int(&out, MUX_S_OK);
@@ -625,7 +643,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
625 goto out; 643 goto out;
626 } else { 644 } else {
627 if (rfwd->listen_port == 0) 645 if (rfwd->listen_port == 0)
628 channel_update_permitted_opens(rfwd->handle, -1); 646 channel_update_permitted_opens(ssh, rfwd->handle, -1);
629 if (rfwd->listen_path != NULL) 647 if (rfwd->listen_path != NULL)
630 xasprintf(&failmsg, "remote port forwarding failed for " 648 xasprintf(&failmsg, "remote port forwarding failed for "
631 "listen path %s", rfwd->listen_path); 649 "listen path %s", rfwd->listen_path);
@@ -651,7 +669,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
651 buffer_put_cstring(&out, failmsg); 669 buffer_put_cstring(&out, failmsg);
652 free(failmsg); 670 free(failmsg);
653 out: 671 out:
654 buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out)); 672 buffer_put_string(c->output, buffer_ptr(&out), buffer_len(&out));
655 buffer_free(&out); 673 buffer_free(&out);
656 if (c->mux_pause <= 0) 674 if (c->mux_pause <= 0)
657 fatal("%s: mux_pause %d", __func__, c->mux_pause); 675 fatal("%s: mux_pause %d", __func__, c->mux_pause);
@@ -659,7 +677,8 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
659} 677}
660 678
661static int 679static int
662process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 680process_mux_open_fwd(struct ssh *ssh, u_int rid,
681 Channel *c, Buffer *m, Buffer *r)
663{ 682{
664 struct Forward fwd; 683 struct Forward fwd;
665 char *fwd_desc = NULL; 684 char *fwd_desc = NULL;
@@ -727,13 +746,16 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
727 fwd.listen_port); 746 fwd.listen_port);
728 goto invalid; 747 goto invalid;
729 } 748 }
730 if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536) 749 if ((fwd.connect_port != PORT_STREAMLOCAL &&
731 || (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) { 750 fwd.connect_port >= 65536) ||
751 (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE &&
752 fwd.connect_port == 0)) {
732 logit("%s: invalid connect port %u", __func__, 753 logit("%s: invalid connect port %u", __func__,
733 fwd.connect_port); 754 fwd.connect_port);
734 goto invalid; 755 goto invalid;
735 } 756 }
736 if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) { 757 if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL &&
758 fwd.connect_path == NULL) {
737 logit("%s: missing connect host", __func__); 759 logit("%s: missing connect host", __func__);
738 goto invalid; 760 goto invalid;
739 } 761 }
@@ -784,7 +806,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
784 } 806 }
785 807
786 if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) { 808 if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
787 if (!channel_setup_local_fwd_listener(&fwd, 809 if (!channel_setup_local_fwd_listener(ssh, &fwd,
788 &options.fwd_opts)) { 810 &options.fwd_opts)) {
789 fail: 811 fail:
790 logit("slave-requested %s failed", fwd_desc); 812 logit("slave-requested %s failed", fwd_desc);
@@ -798,7 +820,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
798 } else { 820 } else {
799 struct mux_channel_confirm_ctx *fctx; 821 struct mux_channel_confirm_ctx *fctx;
800 822
801 fwd.handle = channel_request_remote_forwarding(&fwd); 823 fwd.handle = channel_request_remote_forwarding(ssh, &fwd);
802 if (fwd.handle < 0) 824 if (fwd.handle < 0)
803 goto fail; 825 goto fail;
804 add_remote_forward(&options, &fwd); 826 add_remote_forward(&options, &fwd);
@@ -827,7 +849,8 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
827} 849}
828 850
829static int 851static int
830process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 852process_mux_close_fwd(struct ssh *ssh, u_int rid,
853 Channel *c, Buffer *m, Buffer *r)
831{ 854{
832 struct Forward fwd, *found_fwd; 855 struct Forward fwd, *found_fwd;
833 char *fwd_desc = NULL; 856 char *fwd_desc = NULL;
@@ -908,11 +931,11 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
908 * However, for dynamic allocated listen ports we need 931 * However, for dynamic allocated listen ports we need
909 * to use the actual listen port. 932 * to use the actual listen port.
910 */ 933 */
911 if (channel_request_rforward_cancel(found_fwd) == -1) 934 if (channel_request_rforward_cancel(ssh, found_fwd) == -1)
912 error_reason = "port not in permitted opens"; 935 error_reason = "port not in permitted opens";
913 } else { /* local and dynamic forwards */ 936 } else { /* local and dynamic forwards */
914 /* Ditto */ 937 /* Ditto */
915 if (channel_cancel_lport_listener(&fwd, fwd.connect_port, 938 if (channel_cancel_lport_listener(ssh, &fwd, fwd.connect_port,
916 &options.fwd_opts) == -1) 939 &options.fwd_opts) == -1)
917 error_reason = "port not found"; 940 error_reason = "port not found";
918 } 941 }
@@ -942,7 +965,8 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
942} 965}
943 966
944static int 967static int
945process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) 968process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
969 Channel *c, Buffer *m, Buffer *r)
946{ 970{
947 Channel *nc; 971 Channel *nc;
948 char *reserved, *chost; 972 char *reserved, *chost;
@@ -986,7 +1010,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
986 new_fd[0], new_fd[1]); 1010 new_fd[0], new_fd[1]);
987 1011
988 /* XXX support multiple child sessions in future */ 1012 /* XXX support multiple child sessions in future */
989 if (c->remote_id != -1) { 1013 if (c->have_remote_id) {
990 debug2("%s: session already open", __func__); 1014 debug2("%s: session already open", __func__);
991 /* prepare reply */ 1015 /* prepare reply */
992 buffer_put_int(r, MUX_S_FAILURE); 1016 buffer_put_int(r, MUX_S_FAILURE);
@@ -1018,19 +1042,21 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
1018 if (!isatty(new_fd[1])) 1042 if (!isatty(new_fd[1]))
1019 set_nonblock(new_fd[1]); 1043 set_nonblock(new_fd[1]);
1020 1044
1021 nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]); 1045 nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]);
1022 1046
1023 nc->ctl_chan = c->self; /* link session -> control channel */ 1047 nc->ctl_chan = c->self; /* link session -> control channel */
1024 c->remote_id = nc->self; /* link control -> session channel */ 1048 c->remote_id = nc->self; /* link control -> session channel */
1049 c->have_remote_id = 1;
1025 1050
1026 debug2("%s: channel_new: %d linked to control channel %d", 1051 debug2("%s: channel_new: %d linked to control channel %d",
1027 __func__, nc->self, nc->ctl_chan); 1052 __func__, nc->self, nc->ctl_chan);
1028 1053
1029 channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1); 1054 channel_register_cleanup(ssh, nc->self,
1055 mux_master_session_cleanup_cb, 1);
1030 1056
1031 cctx = xcalloc(1, sizeof(*cctx)); 1057 cctx = xcalloc(1, sizeof(*cctx));
1032 cctx->rid = rid; 1058 cctx->rid = rid;
1033 channel_register_open_confirm(nc->self, mux_stdio_confirm, cctx); 1059 channel_register_open_confirm(ssh, nc->self, mux_stdio_confirm, cctx);
1034 c->mux_pause = 1; /* stop handling messages until open_confirm done */ 1060 c->mux_pause = 1; /* stop handling messages until open_confirm done */
1035 1061
1036 /* reply is deferred, sent by mux_session_confirm */ 1062 /* reply is deferred, sent by mux_session_confirm */
@@ -1039,7 +1065,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
1039 1065
1040/* Callback on open confirmation in mux master for a mux stdio fwd session. */ 1066/* Callback on open confirmation in mux master for a mux stdio fwd session. */
1041static void 1067static void
1042mux_stdio_confirm(int id, int success, void *arg) 1068mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1043{ 1069{
1044 struct mux_stdio_confirm_ctx *cctx = arg; 1070 struct mux_stdio_confirm_ctx *cctx = arg;
1045 Channel *c, *cc; 1071 Channel *c, *cc;
@@ -1047,9 +1073,9 @@ mux_stdio_confirm(int id, int success, void *arg)
1047 1073
1048 if (cctx == NULL) 1074 if (cctx == NULL)
1049 fatal("%s: cctx == NULL", __func__); 1075 fatal("%s: cctx == NULL", __func__);
1050 if ((c = channel_by_id(id)) == NULL) 1076 if ((c = channel_by_id(ssh, id)) == NULL)
1051 fatal("%s: no channel for id %d", __func__, id); 1077 fatal("%s: no channel for id %d", __func__, id);
1052 if ((cc = channel_by_id(c->ctl_chan)) == NULL) 1078 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
1053 fatal("%s: channel %d lacks control channel %d", __func__, 1079 fatal("%s: channel %d lacks control channel %d", __func__,
1054 id, c->ctl_chan); 1080 id, c->ctl_chan);
1055 1081
@@ -1072,7 +1098,7 @@ mux_stdio_confirm(int id, int success, void *arg)
1072 1098
1073 done: 1099 done:
1074 /* Send reply */ 1100 /* Send reply */
1075 buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); 1101 buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply));
1076 buffer_free(&reply); 1102 buffer_free(&reply);
1077 1103
1078 if (cc->mux_pause <= 0) 1104 if (cc->mux_pause <= 0)
@@ -1083,7 +1109,8 @@ mux_stdio_confirm(int id, int success, void *arg)
1083} 1109}
1084 1110
1085static int 1111static int
1086process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) 1112process_mux_stop_listening(struct ssh *ssh, u_int rid,
1113 Channel *c, Buffer *m, Buffer *r)
1087{ 1114{
1088 debug("%s: channel %d: stop listening", __func__, c->self); 1115 debug("%s: channel %d: stop listening", __func__, c->self);
1089 1116
@@ -1100,7 +1127,7 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
1100 } 1127 }
1101 1128
1102 if (mux_listener_channel != NULL) { 1129 if (mux_listener_channel != NULL) {
1103 channel_free(mux_listener_channel); 1130 channel_free(ssh, mux_listener_channel);
1104 client_stop_mux(); 1131 client_stop_mux();
1105 free(options.control_path); 1132 free(options.control_path);
1106 options.control_path = NULL; 1133 options.control_path = NULL;
@@ -1116,7 +1143,8 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
1116} 1143}
1117 1144
1118static int 1145static int
1119process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) 1146process_mux_proxy(struct ssh *ssh, u_int rid,
1147 Channel *c, Buffer *m, Buffer *r)
1120{ 1148{
1121 debug("%s: channel %d: proxy request", __func__, c->self); 1149 debug("%s: channel %d: proxy request", __func__, c->self);
1122 1150
@@ -1129,7 +1157,7 @@ process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r)
1129 1157
1130/* Channel callbacks fired on read/write from mux slave fd */ 1158/* Channel callbacks fired on read/write from mux slave fd */
1131static int 1159static int
1132mux_master_read_cb(Channel *c) 1160mux_master_read_cb(struct ssh *ssh, Channel *c)
1133{ 1161{
1134 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx; 1162 struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
1135 Buffer in, out; 1163 Buffer in, out;
@@ -1141,7 +1169,7 @@ mux_master_read_cb(Channel *c)
1141 if (c->mux_ctx == NULL) { 1169 if (c->mux_ctx == NULL) {
1142 state = xcalloc(1, sizeof(*state)); 1170 state = xcalloc(1, sizeof(*state));
1143 c->mux_ctx = state; 1171 c->mux_ctx = state;
1144 channel_register_cleanup(c->self, 1172 channel_register_cleanup(ssh, c->self,
1145 mux_master_control_cleanup_cb, 0); 1173 mux_master_control_cleanup_cb, 0);
1146 1174
1147 /* Send hello */ 1175 /* Send hello */
@@ -1149,7 +1177,7 @@ mux_master_read_cb(Channel *c)
1149 buffer_put_int(&out, MUX_MSG_HELLO); 1177 buffer_put_int(&out, MUX_MSG_HELLO);
1150 buffer_put_int(&out, SSHMUX_VER); 1178 buffer_put_int(&out, SSHMUX_VER);
1151 /* no extensions */ 1179 /* no extensions */
1152 buffer_put_string(&c->output, buffer_ptr(&out), 1180 buffer_put_string(c->output, buffer_ptr(&out),
1153 buffer_len(&out)); 1181 buffer_len(&out));
1154 buffer_free(&out); 1182 buffer_free(&out);
1155 debug3("%s: channel %d: hello sent", __func__, c->self); 1183 debug3("%s: channel %d: hello sent", __func__, c->self);
@@ -1160,7 +1188,7 @@ mux_master_read_cb(Channel *c)
1160 buffer_init(&out); 1188 buffer_init(&out);
1161 1189
1162 /* Channel code ensures that we receive whole packets */ 1190 /* Channel code ensures that we receive whole packets */
1163 if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) { 1191 if ((ptr = buffer_get_string_ptr_ret(c->input, &have)) == NULL) {
1164 malf: 1192 malf:
1165 error("%s: malformed message", __func__); 1193 error("%s: malformed message", __func__);
1166 goto out; 1194 goto out;
@@ -1186,7 +1214,8 @@ mux_master_read_cb(Channel *c)
1186 1214
1187 for (i = 0; mux_master_handlers[i].handler != NULL; i++) { 1215 for (i = 0; mux_master_handlers[i].handler != NULL; i++) {
1188 if (type == mux_master_handlers[i].type) { 1216 if (type == mux_master_handlers[i].type) {
1189 ret = mux_master_handlers[i].handler(rid, c, &in, &out); 1217 ret = mux_master_handlers[i].handler(ssh, rid,
1218 c, &in, &out);
1190 break; 1219 break;
1191 } 1220 }
1192 } 1221 }
@@ -1199,7 +1228,7 @@ mux_master_read_cb(Channel *c)
1199 } 1228 }
1200 /* Enqueue reply packet */ 1229 /* Enqueue reply packet */
1201 if (buffer_len(&out) != 0) { 1230 if (buffer_len(&out) != 0) {
1202 buffer_put_string(&c->output, buffer_ptr(&out), 1231 buffer_put_string(c->output, buffer_ptr(&out),
1203 buffer_len(&out)); 1232 buffer_len(&out));
1204 } 1233 }
1205 out: 1234 out:
@@ -1209,7 +1238,7 @@ mux_master_read_cb(Channel *c)
1209} 1238}
1210 1239
1211void 1240void
1212mux_exit_message(Channel *c, int exitval) 1241mux_exit_message(struct ssh *ssh, Channel *c, int exitval)
1213{ 1242{
1214 Buffer m; 1243 Buffer m;
1215 Channel *mux_chan; 1244 Channel *mux_chan;
@@ -1217,7 +1246,7 @@ mux_exit_message(Channel *c, int exitval)
1217 debug3("%s: channel %d: exit message, exitval %d", __func__, c->self, 1246 debug3("%s: channel %d: exit message, exitval %d", __func__, c->self,
1218 exitval); 1247 exitval);
1219 1248
1220 if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) 1249 if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
1221 fatal("%s: channel %d missing mux channel %d", 1250 fatal("%s: channel %d missing mux channel %d",
1222 __func__, c->self, c->ctl_chan); 1251 __func__, c->self, c->ctl_chan);
1223 1252
@@ -1227,19 +1256,19 @@ mux_exit_message(Channel *c, int exitval)
1227 buffer_put_int(&m, c->self); 1256 buffer_put_int(&m, c->self);
1228 buffer_put_int(&m, exitval); 1257 buffer_put_int(&m, exitval);
1229 1258
1230 buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); 1259 buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m));
1231 buffer_free(&m); 1260 buffer_free(&m);
1232} 1261}
1233 1262
1234void 1263void
1235mux_tty_alloc_failed(Channel *c) 1264mux_tty_alloc_failed(struct ssh *ssh, Channel *c)
1236{ 1265{
1237 Buffer m; 1266 Buffer m;
1238 Channel *mux_chan; 1267 Channel *mux_chan;
1239 1268
1240 debug3("%s: channel %d: TTY alloc failed", __func__, c->self); 1269 debug3("%s: channel %d: TTY alloc failed", __func__, c->self);
1241 1270
1242 if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) 1271 if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
1243 fatal("%s: channel %d missing mux channel %d", 1272 fatal("%s: channel %d missing mux channel %d",
1244 __func__, c->self, c->ctl_chan); 1273 __func__, c->self, c->ctl_chan);
1245 1274
@@ -1248,13 +1277,13 @@ mux_tty_alloc_failed(Channel *c)
1248 buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL); 1277 buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL);
1249 buffer_put_int(&m, c->self); 1278 buffer_put_int(&m, c->self);
1250 1279
1251 buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); 1280 buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m));
1252 buffer_free(&m); 1281 buffer_free(&m);
1253} 1282}
1254 1283
1255/* Prepare a mux master to listen on a Unix domain socket. */ 1284/* Prepare a mux master to listen on a Unix domain socket. */
1256void 1285void
1257muxserver_listen(void) 1286muxserver_listen(struct ssh *ssh)
1258{ 1287{
1259 mode_t old_umask; 1288 mode_t old_umask;
1260 char *orig_control_path = options.control_path; 1289 char *orig_control_path = options.control_path;
@@ -1327,7 +1356,7 @@ muxserver_listen(void)
1327 1356
1328 set_nonblock(muxserver_sock); 1357 set_nonblock(muxserver_sock);
1329 1358
1330 mux_listener_channel = channel_new("mux listener", 1359 mux_listener_channel = channel_new(ssh, "mux listener",
1331 SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1, 1360 SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
1332 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 1361 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1333 0, options.control_path, 1); 1362 0, options.control_path, 1);
@@ -1338,7 +1367,7 @@ muxserver_listen(void)
1338 1367
1339/* Callback on open confirmation in mux master for a mux client session. */ 1368/* Callback on open confirmation in mux master for a mux client session. */
1340static void 1369static void
1341mux_session_confirm(int id, int success, void *arg) 1370mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
1342{ 1371{
1343 struct mux_session_confirm_ctx *cctx = arg; 1372 struct mux_session_confirm_ctx *cctx = arg;
1344 const char *display; 1373 const char *display;
@@ -1348,9 +1377,9 @@ mux_session_confirm(int id, int success, void *arg)
1348 1377
1349 if (cctx == NULL) 1378 if (cctx == NULL)
1350 fatal("%s: cctx == NULL", __func__); 1379 fatal("%s: cctx == NULL", __func__);
1351 if ((c = channel_by_id(id)) == NULL) 1380 if ((c = channel_by_id(ssh, id)) == NULL)
1352 fatal("%s: no channel for id %d", __func__, id); 1381 fatal("%s: no channel for id %d", __func__, id);
1353 if ((cc = channel_by_id(c->ctl_chan)) == NULL) 1382 if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
1354 fatal("%s: channel %d lacks control channel %d", __func__, 1383 fatal("%s: channel %d lacks control channel %d", __func__,
1355 id, c->ctl_chan); 1384 id, c->ctl_chan);
1356 1385
@@ -1369,27 +1398,27 @@ mux_session_confirm(int id, int success, void *arg)
1369 char *proto, *data; 1398 char *proto, *data;
1370 1399
1371 /* Get reasonable local authentication information. */ 1400 /* Get reasonable local authentication information. */
1372 if (client_x11_get_proto(display, options.xauth_location, 1401 if (client_x11_get_proto(ssh, display, options.xauth_location,
1373 options.forward_x11_trusted, options.forward_x11_timeout, 1402 options.forward_x11_trusted, options.forward_x11_timeout,
1374 &proto, &data) == 0) { 1403 &proto, &data) == 0) {
1375 /* Request forwarding with authentication spoofing. */ 1404 /* Request forwarding with authentication spoofing. */
1376 debug("Requesting X11 forwarding with authentication " 1405 debug("Requesting X11 forwarding with authentication "
1377 "spoofing."); 1406 "spoofing.");
1378 x11_request_forwarding_with_spoofing(id, display, proto, 1407 x11_request_forwarding_with_spoofing(ssh, id,
1379 data, 1); 1408 display, proto, data, 1);
1380 /* XXX exit_on_forward_failure */ 1409 /* XXX exit_on_forward_failure */
1381 client_expect_confirm(id, "X11 forwarding", 1410 client_expect_confirm(ssh, id, "X11 forwarding",
1382 CONFIRM_WARN); 1411 CONFIRM_WARN);
1383 } 1412 }
1384 } 1413 }
1385 1414
1386 if (cctx->want_agent_fwd && options.forward_agent) { 1415 if (cctx->want_agent_fwd && options.forward_agent) {
1387 debug("Requesting authentication agent forwarding."); 1416 debug("Requesting authentication agent forwarding.");
1388 channel_request_start(id, "auth-agent-req@openssh.com", 0); 1417 channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
1389 packet_send(); 1418 packet_send();
1390 } 1419 }
1391 1420
1392 client_session2_setup(id, cctx->want_tty, cctx->want_subsys, 1421 client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys,
1393 cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); 1422 cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env);
1394 1423
1395 debug3("%s: sending success reply", __func__); 1424 debug3("%s: sending success reply", __func__);
@@ -1401,7 +1430,7 @@ mux_session_confirm(int id, int success, void *arg)
1401 1430
1402 done: 1431 done:
1403 /* Send reply */ 1432 /* Send reply */
1404 buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply)); 1433 buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply));
1405 buffer_free(&reply); 1434 buffer_free(&reply);
1406 1435
1407 if (cc->mux_pause <= 0) 1436 if (cc->mux_pause <= 0)
@@ -1570,31 +1599,38 @@ mux_client_hello_exchange(int fd)
1570{ 1599{
1571 Buffer m; 1600 Buffer m;
1572 u_int type, ver; 1601 u_int type, ver;
1602 int ret = -1;
1573 1603
1574 buffer_init(&m); 1604 buffer_init(&m);
1575 buffer_put_int(&m, MUX_MSG_HELLO); 1605 buffer_put_int(&m, MUX_MSG_HELLO);
1576 buffer_put_int(&m, SSHMUX_VER); 1606 buffer_put_int(&m, SSHMUX_VER);
1577 /* no extensions */ 1607 /* no extensions */
1578 1608
1579 if (mux_client_write_packet(fd, &m) != 0) 1609 if (mux_client_write_packet(fd, &m) != 0) {
1580 fatal("%s: write packet: %s", __func__, strerror(errno)); 1610 debug("%s: write packet: %s", __func__, strerror(errno));
1611 goto out;
1612 }
1581 1613
1582 buffer_clear(&m); 1614 buffer_clear(&m);
1583 1615
1584 /* Read their HELLO */ 1616 /* Read their HELLO */
1585 if (mux_client_read_packet(fd, &m) != 0) { 1617 if (mux_client_read_packet(fd, &m) != 0) {
1586 buffer_free(&m); 1618 debug("%s: read packet failed", __func__);
1587 return -1; 1619 goto out;
1588 } 1620 }
1589 1621
1590 type = buffer_get_int(&m); 1622 type = buffer_get_int(&m);
1591 if (type != MUX_MSG_HELLO) 1623 if (type != MUX_MSG_HELLO) {
1592 fatal("%s: expected HELLO (%u) received %u", 1624 error("%s: expected HELLO (%u) received %u",
1593 __func__, MUX_MSG_HELLO, type); 1625 __func__, MUX_MSG_HELLO, type);
1626 goto out;
1627 }
1594 ver = buffer_get_int(&m); 1628 ver = buffer_get_int(&m);
1595 if (ver != SSHMUX_VER) 1629 if (ver != SSHMUX_VER) {
1596 fatal("Unsupported multiplexing protocol version %d " 1630 error("Unsupported multiplexing protocol version %d "
1597 "(expected %d)", ver, SSHMUX_VER); 1631 "(expected %d)", ver, SSHMUX_VER);
1632 goto out;
1633 }
1598 debug2("%s: master version %u", __func__, ver); 1634 debug2("%s: master version %u", __func__, ver);
1599 /* No extensions are presently defined */ 1635 /* No extensions are presently defined */
1600 while (buffer_len(&m) > 0) { 1636 while (buffer_len(&m) > 0) {
@@ -1605,8 +1641,11 @@ mux_client_hello_exchange(int fd)
1605 free(name); 1641 free(name);
1606 free(value); 1642 free(value);
1607 } 1643 }
1644 /* success */
1645 ret = 0;
1646 out:
1608 buffer_free(&m); 1647 buffer_free(&m);
1609 return 0; 1648 return ret;
1610} 1649}
1611 1650
1612static u_int 1651static u_int
@@ -1962,7 +2001,7 @@ mux_client_request_session(int fd)
1962 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 2001 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1963 2002
1964 if (muxclient_terminate) { 2003 if (muxclient_terminate) {
1965 debug2("Exiting on signal %d", muxclient_terminate); 2004 debug2("Exiting on signal: %s", strsignal(muxclient_terminate));
1966 exitval = 255; 2005 exitval = 255;
1967 } else if (!exitval_seen) { 2006 } else if (!exitval_seen) {
1968 debug2("Control master terminated unexpectedly"); 2007 debug2("Control master terminated unexpectedly");
diff --git a/myproposal.h b/myproposal.h
index 072e36ec7..c255147aa 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: myproposal.h,v 1.54 2016/09/28 16:33:07 djm Exp $ */ 1/* $OpenBSD: myproposal.h,v 1.55 2017/05/07 23:13:42 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -121,8 +121,7 @@
121 "aes128-ctr,aes192-ctr,aes256-ctr" \ 121 "aes128-ctr,aes192-ctr,aes256-ctr" \
122 AESGCM_CIPHER_MODES 122 AESGCM_CIPHER_MODES
123 123
124#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT "," \ 124#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT
125 "aes128-cbc,aes192-cbc,aes256-cbc"
126 125
127#define KEX_SERVER_MAC \ 126#define KEX_SERVER_MAC \
128 "umac-64-etm@openssh.com," \ 127 "umac-64-etm@openssh.com," \
diff --git a/nchan.c b/nchan.c
index 20f6a2f49..24929556d 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */ 1/* $OpenBSD: nchan.c,v 1.67 2017/09/12 06:35:32 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -33,9 +33,9 @@
33#include <stdarg.h> 33#include <stdarg.h>
34 34
35#include "openbsd-compat/sys-queue.h" 35#include "openbsd-compat/sys-queue.h"
36#include "ssh1.h"
37#include "ssh2.h" 36#include "ssh2.h"
38#include "buffer.h" 37#include "sshbuf.h"
38#include "ssherr.h"
39#include "packet.h" 39#include "packet.h"
40#include "channels.h" 40#include "channels.h"
41#include "compat.h" 41#include "compat.h"
@@ -74,18 +74,15 @@
74/* 74/*
75 * ACTIONS: should never update the channel states 75 * ACTIONS: should never update the channel states
76 */ 76 */
77static void chan_send_ieof1(Channel *); 77static void chan_send_eof2(struct ssh *, Channel *);
78static void chan_send_oclose1(Channel *); 78static void chan_send_eow2(struct ssh *, Channel *);
79static void chan_send_close2(Channel *);
80static void chan_send_eof2(Channel *);
81static void chan_send_eow2(Channel *);
82 79
83/* helper */ 80/* helper */
84static void chan_shutdown_write(Channel *); 81static void chan_shutdown_write(struct ssh *, Channel *);
85static void chan_shutdown_read(Channel *); 82static void chan_shutdown_read(struct ssh *, Channel *);
86 83
87static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; 84static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
88static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; 85static const char *istates[] = { "open", "drain", "wait_oclose", "closed" };
89 86
90static void 87static void
91chan_set_istate(Channel *c, u_int next) 88chan_set_istate(Channel *c, u_int next)
@@ -96,6 +93,7 @@ chan_set_istate(Channel *c, u_int next)
96 istates[next]); 93 istates[next]);
97 c->istate = next; 94 c->istate = next;
98} 95}
96
99static void 97static void
100chan_set_ostate(Channel *c, u_int next) 98chan_set_ostate(Channel *c, u_int next)
101{ 99{
@@ -106,41 +104,13 @@ chan_set_ostate(Channel *c, u_int next)
106 c->ostate = next; 104 c->ostate = next;
107} 105}
108 106
109/*
110 * SSH1 specific implementation of event functions
111 */
112
113static void
114chan_rcvd_oclose1(Channel *c)
115{
116 debug2("channel %d: rcvd oclose", c->self);
117 switch (c->istate) {
118 case CHAN_INPUT_WAIT_OCLOSE:
119 chan_set_istate(c, CHAN_INPUT_CLOSED);
120 break;
121 case CHAN_INPUT_OPEN:
122 chan_shutdown_read(c);
123 chan_send_ieof1(c);
124 chan_set_istate(c, CHAN_INPUT_CLOSED);
125 break;
126 case CHAN_INPUT_WAIT_DRAIN:
127 /* both local read_failed and remote write_failed */
128 chan_send_ieof1(c);
129 chan_set_istate(c, CHAN_INPUT_CLOSED);
130 break;
131 default:
132 error("channel %d: protocol error: rcvd_oclose for istate %d",
133 c->self, c->istate);
134 return;
135 }
136}
137void 107void
138chan_read_failed(Channel *c) 108chan_read_failed(struct ssh *ssh, Channel *c)
139{ 109{
140 debug2("channel %d: read failed", c->self); 110 debug2("channel %d: read failed", c->self);
141 switch (c->istate) { 111 switch (c->istate) {
142 case CHAN_INPUT_OPEN: 112 case CHAN_INPUT_OPEN:
143 chan_shutdown_read(c); 113 chan_shutdown_read(ssh, c);
144 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN); 114 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
145 break; 115 break;
146 default: 116 default:
@@ -149,25 +119,21 @@ chan_read_failed(Channel *c)
149 break; 119 break;
150 } 120 }
151} 121}
122
152void 123void
153chan_ibuf_empty(Channel *c) 124chan_ibuf_empty(struct ssh *ssh, Channel *c)
154{ 125{
155 debug2("channel %d: ibuf empty", c->self); 126 debug2("channel %d: ibuf empty", c->self);
156 if (buffer_len(&c->input)) { 127 if (sshbuf_len(c->input)) {
157 error("channel %d: chan_ibuf_empty for non empty buffer", 128 error("channel %d: chan_ibuf_empty for non empty buffer",
158 c->self); 129 c->self);
159 return; 130 return;
160 } 131 }
161 switch (c->istate) { 132 switch (c->istate) {
162 case CHAN_INPUT_WAIT_DRAIN: 133 case CHAN_INPUT_WAIT_DRAIN:
163 if (compat20) { 134 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
164 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL))) 135 chan_send_eof2(ssh, c);
165 chan_send_eof2(c); 136 chan_set_istate(c, CHAN_INPUT_CLOSED);
166 chan_set_istate(c, CHAN_INPUT_CLOSED);
167 } else {
168 chan_send_ieof1(c);
169 chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
170 }
171 break; 137 break;
172 default: 138 default:
173 error("channel %d: chan_ibuf_empty for istate %d", 139 error("channel %d: chan_ibuf_empty for istate %d",
@@ -175,58 +141,19 @@ chan_ibuf_empty(Channel *c)
175 break; 141 break;
176 } 142 }
177} 143}
178static void 144
179chan_rcvd_ieof1(Channel *c)
180{
181 debug2("channel %d: rcvd ieof", c->self);
182 switch (c->ostate) {
183 case CHAN_OUTPUT_OPEN:
184 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
185 break;
186 case CHAN_OUTPUT_WAIT_IEOF:
187 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
188 break;
189 default:
190 error("channel %d: protocol error: rcvd_ieof for ostate %d",
191 c->self, c->ostate);
192 break;
193 }
194}
195static void
196chan_write_failed1(Channel *c)
197{
198 debug2("channel %d: write failed", c->self);
199 switch (c->ostate) {
200 case CHAN_OUTPUT_OPEN:
201 chan_shutdown_write(c);
202 chan_send_oclose1(c);
203 chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
204 break;
205 case CHAN_OUTPUT_WAIT_DRAIN:
206 chan_shutdown_write(c);
207 chan_send_oclose1(c);
208 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
209 break;
210 default:
211 error("channel %d: chan_write_failed for ostate %d",
212 c->self, c->ostate);
213 break;
214 }
215}
216void 145void
217chan_obuf_empty(Channel *c) 146chan_obuf_empty(struct ssh *ssh, Channel *c)
218{ 147{
219 debug2("channel %d: obuf empty", c->self); 148 debug2("channel %d: obuf empty", c->self);
220 if (buffer_len(&c->output)) { 149 if (sshbuf_len(c->output)) {
221 error("channel %d: chan_obuf_empty for non empty buffer", 150 error("channel %d: chan_obuf_empty for non empty buffer",
222 c->self); 151 c->self);
223 return; 152 return;
224 } 153 }
225 switch (c->ostate) { 154 switch (c->ostate) {
226 case CHAN_OUTPUT_WAIT_DRAIN: 155 case CHAN_OUTPUT_WAIT_DRAIN:
227 chan_shutdown_write(c); 156 chan_shutdown_write(ssh, c);
228 if (!compat20)
229 chan_send_oclose1(c);
230 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 157 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
231 break; 158 break;
232 default: 159 default:
@@ -235,47 +162,107 @@ chan_obuf_empty(Channel *c)
235 break; 162 break;
236 } 163 }
237} 164}
238static void 165
239chan_send_ieof1(Channel *c) 166void
167chan_rcvd_eow(struct ssh *ssh, Channel *c)
240{ 168{
241 debug2("channel %d: send ieof", c->self); 169 debug2("channel %d: rcvd eow", c->self);
242 switch (c->istate) { 170 switch (c->istate) {
243 case CHAN_INPUT_OPEN: 171 case CHAN_INPUT_OPEN:
172 chan_shutdown_read(ssh, c);
173 chan_set_istate(c, CHAN_INPUT_CLOSED);
174 break;
175 }
176}
177
178static void
179chan_send_eof2(struct ssh *ssh, Channel *c)
180{
181 int r;
182
183 debug2("channel %d: send eof", c->self);
184 switch (c->istate) {
244 case CHAN_INPUT_WAIT_DRAIN: 185 case CHAN_INPUT_WAIT_DRAIN:
245 packet_start(SSH_MSG_CHANNEL_INPUT_EOF); 186 if (!c->have_remote_id)
246 packet_put_int(c->remote_id); 187 fatal("%s: channel %d: no remote_id",
247 packet_send(); 188 __func__, c->self);
189 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 ||
190 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
191 (r = sshpkt_send(ssh)) != 0)
192 fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
193 c->flags |= CHAN_EOF_SENT;
248 break; 194 break;
249 default: 195 default:
250 error("channel %d: cannot send ieof for istate %d", 196 error("channel %d: cannot send eof for istate %d",
251 c->self, c->istate); 197 c->self, c->istate);
252 break; 198 break;
253 } 199 }
254} 200}
201
255static void 202static void
256chan_send_oclose1(Channel *c) 203chan_send_close2(struct ssh *ssh, Channel *c)
257{ 204{
258 debug2("channel %d: send oclose", c->self); 205 int r;
259 switch (c->ostate) { 206
260 case CHAN_OUTPUT_OPEN: 207 debug2("channel %d: send close", c->self);
261 case CHAN_OUTPUT_WAIT_DRAIN: 208 if (c->ostate != CHAN_OUTPUT_CLOSED ||
262 buffer_clear(&c->output); 209 c->istate != CHAN_INPUT_CLOSED) {
263 packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE); 210 error("channel %d: cannot send close for istate/ostate %d/%d",
264 packet_put_int(c->remote_id); 211 c->self, c->istate, c->ostate);
265 packet_send(); 212 } else if (c->flags & CHAN_CLOSE_SENT) {
266 break; 213 error("channel %d: already sent close", c->self);
267 default: 214 } else {
268 error("channel %d: cannot send oclose for ostate %d", 215 if (!c->have_remote_id)
269 c->self, c->ostate); 216 fatal("%s: channel %d: no remote_id",
270 break; 217 __func__, c->self);
218 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 ||
219 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
220 (r = sshpkt_send(ssh)) != 0)
221 fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
222 c->flags |= CHAN_CLOSE_SENT;
271 } 223 }
272} 224}
273 225
274/*
275 * the same for SSH2
276 */
277static void 226static void
278chan_rcvd_close2(Channel *c) 227chan_send_eow2(struct ssh *ssh, Channel *c)
228{
229 int r;
230
231 debug2("channel %d: send eow", c->self);
232 if (c->ostate == CHAN_OUTPUT_CLOSED) {
233 error("channel %d: must not sent eow on closed output",
234 c->self);
235 return;
236 }
237 if (!(datafellows & SSH_NEW_OPENSSH))
238 return;
239 if (!c->have_remote_id)
240 fatal("%s: channel %d: no remote_id", __func__, c->self);
241 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
242 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
243 (r = sshpkt_put_cstring(ssh, "eow@openssh.com")) != 0 ||
244 (r = sshpkt_put_u8(ssh, 0)) != 0 ||
245 (r = sshpkt_send(ssh)) != 0)
246 fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
247}
248
249/* shared */
250
251void
252chan_rcvd_ieof(struct ssh *ssh, Channel *c)
253{
254 debug2("channel %d: rcvd eof", c->self);
255 c->flags |= CHAN_EOF_RCVD;
256 if (c->ostate == CHAN_OUTPUT_OPEN)
257 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
258 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
259 sshbuf_len(c->output) == 0 &&
260 !CHANNEL_EFD_OUTPUT_ACTIVE(c))
261 chan_obuf_empty(ssh, c);
262}
263
264void
265chan_rcvd_oclose(struct ssh *ssh, Channel *c)
279{ 266{
280 debug2("channel %d: rcvd close", c->self); 267 debug2("channel %d: rcvd close", c->self);
281 if (!(c->flags & CHAN_LOCAL)) { 268 if (!(c->flags & CHAN_LOCAL)) {
@@ -301,46 +288,27 @@ chan_rcvd_close2(Channel *c)
301 } 288 }
302 switch (c->istate) { 289 switch (c->istate) {
303 case CHAN_INPUT_OPEN: 290 case CHAN_INPUT_OPEN:
304 chan_shutdown_read(c); 291 chan_shutdown_read(ssh, c);
305 chan_set_istate(c, CHAN_INPUT_CLOSED); 292 chan_set_istate(c, CHAN_INPUT_CLOSED);
306 break; 293 break;
307 case CHAN_INPUT_WAIT_DRAIN: 294 case CHAN_INPUT_WAIT_DRAIN:
308 if (!(c->flags & CHAN_LOCAL)) 295 if (!(c->flags & CHAN_LOCAL))
309 chan_send_eof2(c); 296 chan_send_eof2(ssh, c);
310 chan_set_istate(c, CHAN_INPUT_CLOSED); 297 chan_set_istate(c, CHAN_INPUT_CLOSED);
311 break; 298 break;
312 } 299 }
313} 300}
314 301
315void 302void
316chan_rcvd_eow(Channel *c) 303chan_write_failed(struct ssh *ssh, Channel *c)
317{
318 debug2("channel %d: rcvd eow", c->self);
319 switch (c->istate) {
320 case CHAN_INPUT_OPEN:
321 chan_shutdown_read(c);
322 chan_set_istate(c, CHAN_INPUT_CLOSED);
323 break;
324 }
325}
326static void
327chan_rcvd_eof2(Channel *c)
328{
329 debug2("channel %d: rcvd eof", c->self);
330 c->flags |= CHAN_EOF_RCVD;
331 if (c->ostate == CHAN_OUTPUT_OPEN)
332 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
333}
334static void
335chan_write_failed2(Channel *c)
336{ 304{
337 debug2("channel %d: write failed", c->self); 305 debug2("channel %d: write failed", c->self);
338 switch (c->ostate) { 306 switch (c->ostate) {
339 case CHAN_OUTPUT_OPEN: 307 case CHAN_OUTPUT_OPEN:
340 case CHAN_OUTPUT_WAIT_DRAIN: 308 case CHAN_OUTPUT_WAIT_DRAIN:
341 chan_shutdown_write(c); 309 chan_shutdown_write(ssh, c);
342 if (strcmp(c->ctype, "session") == 0) 310 if (strcmp(c->ctype, "session") == 0)
343 chan_send_eow2(c); 311 chan_send_eow2(ssh, c);
344 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 312 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
345 break; 313 break;
346 default: 314 default:
@@ -349,97 +317,15 @@ chan_write_failed2(Channel *c)
349 break; 317 break;
350 } 318 }
351} 319}
352static void
353chan_send_eof2(Channel *c)
354{
355 debug2("channel %d: send eof", c->self);
356 switch (c->istate) {
357 case CHAN_INPUT_WAIT_DRAIN:
358 packet_start(SSH2_MSG_CHANNEL_EOF);
359 packet_put_int(c->remote_id);
360 packet_send();
361 c->flags |= CHAN_EOF_SENT;
362 break;
363 default:
364 error("channel %d: cannot send eof for istate %d",
365 c->self, c->istate);
366 break;
367 }
368}
369static void
370chan_send_close2(Channel *c)
371{
372 debug2("channel %d: send close", c->self);
373 if (c->ostate != CHAN_OUTPUT_CLOSED ||
374 c->istate != CHAN_INPUT_CLOSED) {
375 error("channel %d: cannot send close for istate/ostate %d/%d",
376 c->self, c->istate, c->ostate);
377 } else if (c->flags & CHAN_CLOSE_SENT) {
378 error("channel %d: already sent close", c->self);
379 } else {
380 packet_start(SSH2_MSG_CHANNEL_CLOSE);
381 packet_put_int(c->remote_id);
382 packet_send();
383 c->flags |= CHAN_CLOSE_SENT;
384 }
385}
386static void
387chan_send_eow2(Channel *c)
388{
389 debug2("channel %d: send eow", c->self);
390 if (c->ostate == CHAN_OUTPUT_CLOSED) {
391 error("channel %d: must not sent eow on closed output",
392 c->self);
393 return;
394 }
395 if (!(datafellows & SSH_NEW_OPENSSH))
396 return;
397 packet_start(SSH2_MSG_CHANNEL_REQUEST);
398 packet_put_int(c->remote_id);
399 packet_put_cstring("eow@openssh.com");
400 packet_put_char(0);
401 packet_send();
402}
403
404/* shared */
405 320
406void 321void
407chan_rcvd_ieof(Channel *c) 322chan_mark_dead(struct ssh *ssh, Channel *c)
408{
409 if (compat20)
410 chan_rcvd_eof2(c);
411 else
412 chan_rcvd_ieof1(c);
413 if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
414 buffer_len(&c->output) == 0 &&
415 !CHANNEL_EFD_OUTPUT_ACTIVE(c))
416 chan_obuf_empty(c);
417}
418void
419chan_rcvd_oclose(Channel *c)
420{
421 if (compat20)
422 chan_rcvd_close2(c);
423 else
424 chan_rcvd_oclose1(c);
425}
426void
427chan_write_failed(Channel *c)
428{
429 if (compat20)
430 chan_write_failed2(c);
431 else
432 chan_write_failed1(c);
433}
434
435void
436chan_mark_dead(Channel *c)
437{ 323{
438 c->type = SSH_CHANNEL_ZOMBIE; 324 c->type = SSH_CHANNEL_ZOMBIE;
439} 325}
440 326
441int 327int
442chan_is_dead(Channel *c, int do_send) 328chan_is_dead(struct ssh *ssh, Channel *c, int do_send)
443{ 329{
444 if (c->type == SSH_CHANNEL_ZOMBIE) { 330 if (c->type == SSH_CHANNEL_ZOMBIE) {
445 debug2("channel %d: zombie", c->self); 331 debug2("channel %d: zombie", c->self);
@@ -447,16 +333,12 @@ chan_is_dead(Channel *c, int do_send)
447 } 333 }
448 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) 334 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
449 return 0; 335 return 0;
450 if (!compat20) {
451 debug2("channel %d: is dead", c->self);
452 return 1;
453 }
454 if ((datafellows & SSH_BUG_EXTEOF) && 336 if ((datafellows & SSH_BUG_EXTEOF) &&
455 c->extended_usage == CHAN_EXTENDED_WRITE && 337 c->extended_usage == CHAN_EXTENDED_WRITE &&
456 c->efd != -1 && 338 c->efd != -1 &&
457 buffer_len(&c->extended) > 0) { 339 sshbuf_len(c->extended) > 0) {
458 debug2("channel %d: active efd: %d len %d", 340 debug2("channel %d: active efd: %d len %zu",
459 c->self, c->efd, buffer_len(&c->extended)); 341 c->self, c->efd, sshbuf_len(c->extended));
460 return 0; 342 return 0;
461 } 343 }
462 if (c->flags & CHAN_LOCAL) { 344 if (c->flags & CHAN_LOCAL) {
@@ -465,7 +347,7 @@ chan_is_dead(Channel *c, int do_send)
465 } 347 }
466 if (!(c->flags & CHAN_CLOSE_SENT)) { 348 if (!(c->flags & CHAN_CLOSE_SENT)) {
467 if (do_send) { 349 if (do_send) {
468 chan_send_close2(c); 350 chan_send_close2(ssh, c);
469 } else { 351 } else {
470 /* channel would be dead if we sent a close */ 352 /* channel would be dead if we sent a close */
471 if (c->flags & CHAN_CLOSE_RCVD) { 353 if (c->flags & CHAN_CLOSE_RCVD) {
@@ -485,10 +367,10 @@ chan_is_dead(Channel *c, int do_send)
485 367
486/* helper */ 368/* helper */
487static void 369static void
488chan_shutdown_write(Channel *c) 370chan_shutdown_write(struct ssh *ssh, Channel *c)
489{ 371{
490 buffer_clear(&c->output); 372 sshbuf_reset(c->output);
491 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 373 if (c->type == SSH_CHANNEL_LARVAL)
492 return; 374 return;
493 /* shutdown failure is allowed if write failed already */ 375 /* shutdown failure is allowed if write failed already */
494 debug2("channel %d: close_write", c->self); 376 debug2("channel %d: close_write", c->self);
@@ -498,16 +380,17 @@ chan_shutdown_write(Channel *c)
498 "shutdown() failed for fd %d: %.100s", 380 "shutdown() failed for fd %d: %.100s",
499 c->self, c->sock, strerror(errno)); 381 c->self, c->sock, strerror(errno));
500 } else { 382 } else {
501 if (channel_close_fd(&c->wfd) < 0) 383 if (channel_close_fd(ssh, &c->wfd) < 0)
502 logit("channel %d: chan_shutdown_write: " 384 logit("channel %d: chan_shutdown_write: "
503 "close() failed for fd %d: %.100s", 385 "close() failed for fd %d: %.100s",
504 c->self, c->wfd, strerror(errno)); 386 c->self, c->wfd, strerror(errno));
505 } 387 }
506} 388}
389
507static void 390static void
508chan_shutdown_read(Channel *c) 391chan_shutdown_read(struct ssh *ssh, Channel *c)
509{ 392{
510 if (compat20 && c->type == SSH_CHANNEL_LARVAL) 393 if (c->type == SSH_CHANNEL_LARVAL)
511 return; 394 return;
512 debug2("channel %d: close_read", c->self); 395 debug2("channel %d: close_read", c->self);
513 if (c->sock != -1) { 396 if (c->sock != -1) {
@@ -523,7 +406,7 @@ chan_shutdown_read(Channel *c)
523 c->self, c->sock, c->istate, c->ostate, 406 c->self, c->sock, c->istate, c->ostate,
524 strerror(errno)); 407 strerror(errno));
525 } else { 408 } else {
526 if (channel_close_fd(&c->rfd) < 0) 409 if (channel_close_fd(ssh, &c->rfd) < 0)
527 logit("channel %d: chan_shutdown_read: " 410 logit("channel %d: chan_shutdown_read: "
528 "close() failed for fd %d: %.100s", 411 "close() failed for fd %d: %.100s",
529 c->self, c->rfd, strerror(errno)); 412 c->self, c->rfd, strerror(errno));
diff --git a/opacket.c b/opacket.c
index 5970dd377..ad244b452 100644
--- a/opacket.c
+++ b/opacket.c
@@ -74,16 +74,6 @@ ssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len)
74 fatal("%s: %s", __func__, ssh_err(r)); 74 fatal("%s: %s", __func__, ssh_err(r));
75} 75}
76 76
77#ifdef WITH_SSH1
78void
79ssh_packet_put_bignum(struct ssh *ssh, BIGNUM * value)
80{
81 int r;
82
83 if ((r = sshpkt_put_bignum1(ssh, value)) != 0)
84 fatal("%s: %s", __func__, ssh_err(r));
85}
86#endif
87 77
88#ifdef WITH_OPENSSL 78#ifdef WITH_OPENSSL
89void 79void
@@ -150,16 +140,6 @@ ssh_packet_get_int64(struct ssh *ssh)
150 return val; 140 return val;
151} 141}
152 142
153#ifdef WITH_SSH1
154void
155ssh_packet_get_bignum(struct ssh *ssh, BIGNUM * value)
156{
157 int r;
158
159 if ((r = sshpkt_get_bignum1(ssh, value)) != 0)
160 fatal("%s: %s", __func__, ssh_err(r));
161}
162#endif
163 143
164#ifdef WITH_OPENSSL 144#ifdef WITH_OPENSSL
165void 145void
diff --git a/opacket.h b/opacket.h
index c487f4f40..c49d0c04a 100644
--- a/opacket.h
+++ b/opacket.h
@@ -6,7 +6,6 @@ void ssh_packet_start(struct ssh *, u_char);
6void ssh_packet_put_char(struct ssh *, int ch); 6void ssh_packet_put_char(struct ssh *, int ch);
7void ssh_packet_put_int(struct ssh *, u_int value); 7void ssh_packet_put_int(struct ssh *, u_int value);
8void ssh_packet_put_int64(struct ssh *, u_int64_t value); 8void ssh_packet_put_int64(struct ssh *, u_int64_t value);
9void ssh_packet_put_bignum(struct ssh *, BIGNUM * value);
10void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value); 9void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value);
11void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *); 10void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *);
12void ssh_packet_put_string(struct ssh *, const void *buf, u_int len); 11void ssh_packet_put_string(struct ssh *, const void *buf, u_int len);
@@ -17,7 +16,6 @@ void ssh_packet_send(struct ssh *);
17u_int ssh_packet_get_char(struct ssh *); 16u_int ssh_packet_get_char(struct ssh *);
18u_int ssh_packet_get_int(struct ssh *); 17u_int ssh_packet_get_int(struct ssh *);
19u_int64_t ssh_packet_get_int64(struct ssh *); 18u_int64_t ssh_packet_get_int64(struct ssh *);
20void ssh_packet_get_bignum(struct ssh *, BIGNUM * value);
21void ssh_packet_get_bignum2(struct ssh *, BIGNUM * value); 19void ssh_packet_get_bignum2(struct ssh *, BIGNUM * value);
22void ssh_packet_get_ecpoint(struct ssh *, const EC_GROUP *, EC_POINT *); 20void ssh_packet_get_ecpoint(struct ssh *, const EC_GROUP *, EC_POINT *);
23void *ssh_packet_get_string(struct ssh *, u_int *length_ptr); 21void *ssh_packet_get_string(struct ssh *, u_int *length_ptr);
@@ -62,8 +60,6 @@ void packet_read_expect(int expected_type);
62 ssh_packet_get_protocol_flags(active_state) 60 ssh_packet_get_protocol_flags(active_state)
63#define packet_start_compression(level) \ 61#define packet_start_compression(level) \
64 ssh_packet_start_compression(active_state, (level)) 62 ssh_packet_start_compression(active_state, (level))
65#define packet_set_encryption_key(key, keylen, number) \
66 ssh_packet_set_encryption_key(active_state, (key), (keylen), (number))
67#define packet_start(type) \ 63#define packet_start(type) \
68 ssh_packet_start(active_state, (type)) 64 ssh_packet_start(active_state, (type))
69#define packet_put_char(value) \ 65#define packet_put_char(value) \
@@ -78,8 +74,6 @@ void packet_read_expect(int expected_type);
78 ssh_packet_put_cstring(active_state, (str)) 74 ssh_packet_put_cstring(active_state, (str))
79#define packet_put_raw(buf, len) \ 75#define packet_put_raw(buf, len) \
80 ssh_packet_put_raw(active_state, (buf), (len)) 76 ssh_packet_put_raw(active_state, (buf), (len))
81#define packet_put_bignum(value) \
82 ssh_packet_put_bignum(active_state, (value))
83#define packet_put_bignum2(value) \ 77#define packet_put_bignum2(value) \
84 ssh_packet_put_bignum2(active_state, (value)) 78 ssh_packet_put_bignum2(active_state, (value))
85#define packet_send() \ 79#define packet_send() \
@@ -88,8 +82,6 @@ void packet_read_expect(int expected_type);
88 ssh_packet_read(active_state) 82 ssh_packet_read(active_state)
89#define packet_get_int64() \ 83#define packet_get_int64() \
90 ssh_packet_get_int64(active_state) 84 ssh_packet_get_int64(active_state)
91#define packet_get_bignum(value) \
92 ssh_packet_get_bignum(active_state, (value))
93#define packet_get_bignum2(value) \ 85#define packet_get_bignum2(value) \
94 ssh_packet_get_bignum2(active_state, (value)) 86 ssh_packet_get_bignum2(active_state, (value))
95#define packet_remaining() \ 87#define packet_remaining() \
@@ -157,5 +149,7 @@ void packet_disconnect(const char *, ...)
157 ssh_packet_set_mux(active_state) 149 ssh_packet_set_mux(active_state)
158#define packet_get_mux() \ 150#define packet_get_mux() \
159 ssh_packet_get_mux(active_state) 151 ssh_packet_get_mux(active_state)
152#define packet_clear_keys() \
153 ssh_packet_clear_keys(active_state)
160 154
161#endif /* _OPACKET_H */ 155#endif /* _OPACKET_H */
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index d51eacf65..ac8ae4305 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -16,9 +16,9 @@ RANLIB=@RANLIB@
16INSTALL=@INSTALL@ 16INSTALL=@INSTALL@
17LDFLAGS=-L. @LDFLAGS@ 17LDFLAGS=-L. @LDFLAGS@
18 18
19OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strcasestr.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o 19OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o recallocarray.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strcasestr.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o freezero.o
20 20
21COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o 21COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-malloc.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
22 22
23PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o 23PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
24 24
diff --git a/openbsd-compat/bsd-err.c b/openbsd-compat/bsd-err.c
index ab10646f0..e4ed22b86 100644
--- a/openbsd-compat/bsd-err.c
+++ b/openbsd-compat/bsd-err.c
@@ -27,6 +27,12 @@
27 27
28#include "includes.h" 28#include "includes.h"
29 29
30#include <errno.h>
31#include <stdarg.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35
30#ifndef HAVE_ERR 36#ifndef HAVE_ERR
31void 37void
32err(int r, const char *fmt, ...) 38err(int r, const char *fmt, ...)
diff --git a/openbsd-compat/bsd-getpagesize.c b/openbsd-compat/bsd-getpagesize.c
new file mode 100644
index 000000000..9daddfbd3
--- /dev/null
+++ b/openbsd-compat/bsd-getpagesize.c
@@ -0,0 +1,23 @@
1/* Placed in the public domain */
2
3#ifndef HAVE_GETPAGESIZE
4
5#include <unistd.h>
6#include <limits.h>
7
8int
9getpagesize(void)
10{
11#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
12 long r = sysconf(_SC_PAGESIZE);
13 if (r > 0 && r < INT_MAX)
14 return (int)r;
15#endif
16 /*
17 * This is at the lower end of common values and appropriate for
18 * our current use of getpagesize() in recallocarray().
19 */
20 return 4096;
21}
22
23#endif /* HAVE_GETPAGESIZE */
diff --git a/openbsd-compat/bsd-malloc.c b/openbsd-compat/bsd-malloc.c
new file mode 100644
index 000000000..6402ab588
--- /dev/null
+++ b/openbsd-compat/bsd-malloc.c
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 2017 Darren Tucker (dtucker at zip com au).
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "config.h"
18#undef malloc
19#undef calloc
20#undef realloc
21
22#include <sys/types.h>
23#include <stdlib.h>
24
25#if defined(HAVE_MALLOC) && HAVE_MALLOC == 0
26void *
27rpl_malloc(size_t size)
28{
29 if (size == 0)
30 size = 1;
31 return malloc(size);
32}
33#endif
34
35#if defined(HAVE_CALLOC) && HAVE_CALLOC == 0
36void *
37rpl_calloc(size_t nmemb, size_t size)
38{
39 if (nmemb == 0)
40 nmemb = 1;
41 if (size == 0)
42 size = 1;
43 return calloc(nmemb, size);
44}
45#endif
46
47#if defined (HAVE_REALLOC) && HAVE_REALLOC == 0
48void *
49rpl_realloc(void *ptr, size_t size)
50{
51 if (size == 0)
52 size = 1;
53 return realloc(ptr, size);
54}
55#endif
diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c
index cfd73260a..29f6ad38c 100644
--- a/openbsd-compat/bsd-misc.c
+++ b/openbsd-compat/bsd-misc.c
@@ -104,6 +104,16 @@ const char *strerror(int e)
104} 104}
105#endif 105#endif
106 106
107#if !defined(HAVE_STRSIGNAL)
108char *strsignal(int sig)
109{
110 static char buf[16];
111
112 (void)snprintf(buf, sizeof(buf), "%d", sig);
113 return buf;
114}
115#endif
116
107#ifndef HAVE_UTIMES 117#ifndef HAVE_UTIMES
108int utimes(char *filename, struct timeval *tvp) 118int utimes(char *filename, struct timeval *tvp)
109{ 119{
diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h
index 70a538f04..0b1a3504f 100644
--- a/openbsd-compat/bsd-misc.h
+++ b/openbsd-compat/bsd-misc.h
@@ -49,6 +49,10 @@ int setegid(uid_t);
49const char *strerror(int); 49const char *strerror(int);
50#endif 50#endif
51 51
52#if !defined(HAVE_STRSIGNAL)
53char *strsignal(int);
54#endif
55
52#if !defined(HAVE_SETLINEBUF) 56#if !defined(HAVE_SETLINEBUF)
53#define setlinebuf(a) (setvbuf((a), NULL, _IOLBF, 0)) 57#define setlinebuf(a) (setvbuf((a), NULL, _IOLBF, 0))
54#endif 58#endif
diff --git a/openbsd-compat/explicit_bzero.c b/openbsd-compat/explicit_bzero.c
index 5078134d1..53a003472 100644
--- a/openbsd-compat/explicit_bzero.c
+++ b/openbsd-compat/explicit_bzero.c
@@ -20,6 +20,8 @@
20void 20void
21explicit_bzero(void *p, size_t n) 21explicit_bzero(void *p, size_t n)
22{ 22{
23 if (n == 0)
24 return;
23 (void)memset_s(p, n, 0, n); 25 (void)memset_s(p, n, 0, n);
24} 26}
25 27
@@ -34,6 +36,8 @@ static void (* volatile ssh_bzero)(void *, size_t) = bzero;
34void 36void
35explicit_bzero(void *p, size_t n) 37explicit_bzero(void *p, size_t n)
36{ 38{
39 if (n == 0)
40 return;
37 /* 41 /*
38 * clang -fsanitize=memory needs to intercept memset-like functions 42 * clang -fsanitize=memory needs to intercept memset-like functions
39 * to correctly detect memory initialisation. Make sure one is called 43 * to correctly detect memory initialisation. Make sure one is called
diff --git a/openbsd-compat/fmt_scaled.c b/openbsd-compat/fmt_scaled.c
index e5533b2de..7c5193e26 100644
--- a/openbsd-compat/fmt_scaled.c
+++ b/openbsd-compat/fmt_scaled.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: fmt_scaled.c,v 1.13 2017/03/11 23:37:23 djm Exp $ */ 1/* $OpenBSD: fmt_scaled.c,v 1.16 2017/03/16 02:40:46 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved. 4 * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved.
@@ -125,22 +125,30 @@ scan_scaled(char *scaled, long long *result)
125 /* ignore extra fractional digits */ 125 /* ignore extra fractional digits */
126 continue; 126 continue;
127 fract_digits++; /* for later scaling */ 127 fract_digits++; /* for later scaling */
128 if (fpart >= LLONG_MAX / 10) { 128 if (fpart > LLONG_MAX / 10) {
129 errno = ERANGE; 129 errno = ERANGE;
130 return -1; 130 return -1;
131 } 131 }
132 fpart *= 10; 132 fpart *= 10;
133 if (i > LLONG_MAX - fpart) {
134 errno = ERANGE;
135 return -1;
136 }
133 fpart += i; 137 fpart += i;
134 } else { /* normal digit */ 138 } else { /* normal digit */
135 if (++ndigits >= MAX_DIGITS) { 139 if (++ndigits >= MAX_DIGITS) {
136 errno = ERANGE; 140 errno = ERANGE;
137 return -1; 141 return -1;
138 } 142 }
139 if (whole >= LLONG_MAX / 10) { 143 if (whole > LLONG_MAX / 10) {
140 errno = ERANGE; 144 errno = ERANGE;
141 return -1; 145 return -1;
142 } 146 }
143 whole *= 10; 147 whole *= 10;
148 if (i > LLONG_MAX - whole) {
149 errno = ERANGE;
150 return -1;
151 }
144 whole += i; 152 whole += i;
145 } 153 }
146 } 154 }
@@ -170,7 +178,9 @@ scan_scaled(char *scaled, long long *result)
170 } 178 }
171 scale_fact = scale_factors[i]; 179 scale_fact = scale_factors[i];
172 180
173 if (whole >= LLONG_MAX / scale_fact) { 181 /* check for overflow and underflow after scaling */
182 if (whole > LLONG_MAX / scale_fact ||
183 whole < LLONG_MIN / scale_fact) {
174 errno = ERANGE; 184 errno = ERANGE;
175 return -1; 185 return -1;
176 } 186 }
diff --git a/openbsd-compat/freezero.c b/openbsd-compat/freezero.c
new file mode 100644
index 000000000..3af8f4a73
--- /dev/null
+++ b/openbsd-compat/freezero.c
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "includes.h"
18
19#ifndef HAVE_FREEZERO
20
21void
22freezero(void *ptr, size_t sz)
23{
24 explicit_bzero(ptr, sz);
25 free(ptr);
26}
27
28#endif /* HAVE_FREEZERO */
29
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index cff547745..cac799e84 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -60,6 +60,10 @@ int bindresvport_sa(int sd, struct sockaddr *sa);
60void closefrom(int); 60void closefrom(int);
61#endif 61#endif
62 62
63#ifndef HAVE_GETPAGESIZE
64int getpagesize(void);
65#endif
66
63#ifndef HAVE_GETCWD 67#ifndef HAVE_GETCWD
64char *getcwd(char *pt, size_t size); 68char *getcwd(char *pt, size_t size);
65#endif 69#endif
@@ -68,6 +72,10 @@ char *getcwd(char *pt, size_t size);
68void *reallocarray(void *, size_t, size_t); 72void *reallocarray(void *, size_t, size_t);
69#endif 73#endif
70 74
75#ifndef HAVE_RECALLOCARRAY
76void *recallocarray(void *, size_t, size_t, size_t);
77#endif
78
71#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) 79#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
72/* 80/*
73 * glibc's FORTIFY_SOURCE can redefine this and prevent us picking up the 81 * glibc's FORTIFY_SOURCE can redefine this and prevent us picking up the
@@ -296,6 +304,10 @@ int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t,
296void explicit_bzero(void *p, size_t n); 304void explicit_bzero(void *p, size_t n);
297#endif 305#endif
298 306
307#ifndef HAVE_FREEZERO
308void freezero(void *, size_t);
309#endif
310
299char *xcrypt(const char *password, const char *salt); 311char *xcrypt(const char *password, const char *salt);
300char *shadow_pw(struct passwd *pw); 312char *shadow_pw(struct passwd *pw);
301 313
diff --git a/openbsd-compat/port-tun.c b/openbsd-compat/port-tun.c
index a444adf1d..7579c6084 100644
--- a/openbsd-compat/port-tun.c
+++ b/openbsd-compat/port-tun.c
@@ -199,84 +199,81 @@ sys_tun_open(int tun, int mode)
199 */ 199 */
200 200
201#if defined(SSH_TUN_FILTER) 201#if defined(SSH_TUN_FILTER)
202/*
203 * The tunnel forwarding protocol prepends the address family of forwarded
204 * IP packets using OpenBSD's numbers.
205 */
202#define OPENBSD_AF_INET 2 206#define OPENBSD_AF_INET 2
203#define OPENBSD_AF_INET6 24 207#define OPENBSD_AF_INET6 24
204 208
205int 209int
206sys_tun_infilter(struct Channel *c, char *buf, int len) 210sys_tun_infilter(struct ssh *ssh, struct Channel *c, char *buf, int _len)
207{ 211{
212 int r;
213 size_t len;
214 char *ptr = buf;
208#if defined(SSH_TUN_PREPEND_AF) 215#if defined(SSH_TUN_PREPEND_AF)
209 char rbuf[CHAN_RBUF]; 216 char rbuf[CHAN_RBUF];
210 struct ip *iph; 217 struct ip iph;
211#endif 218#endif
212 u_int32_t *af; 219#if defined(SSH_TUN_PREPEND_AF) || defined(SSH_TUN_COMPAT_AF)
213 char *ptr = buf; 220 u_int32_t af;
214 int r;
215
216#if defined(SSH_TUN_PREPEND_AF)
217 if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af)))
218 return (-1);
219 ptr = (char *)&rbuf[0];
220 bcopy(buf, ptr + sizeof(u_int32_t), len);
221 len += sizeof(u_int32_t);
222 af = (u_int32_t *)ptr;
223
224 iph = (struct ip *)(ptr + sizeof(u_int32_t));
225 switch (iph->ip_v) {
226 case 6:
227 *af = AF_INET6;
228 break;
229 case 4:
230 default:
231 *af = AF_INET;
232 break;
233 }
234#endif 221#endif
235 222
236#if defined(SSH_TUN_COMPAT_AF) 223 /* XXX update channel input filter API to use unsigned length */
237 if (len < (int)sizeof(u_int32_t)) 224 if (_len < 0)
238 return (-1); 225 return -1;
226 len = _len;
239 227
240 af = (u_int32_t *)ptr; 228#if defined(SSH_TUN_PREPEND_AF)
241 if (*af == htonl(AF_INET6)) 229 if (len <= sizeof(iph) || len > sizeof(rbuf) - 4)
242 *af = htonl(OPENBSD_AF_INET6); 230 return -1;
243 else 231 /* Determine address family from packet IP header. */
244 *af = htonl(OPENBSD_AF_INET); 232 memcpy(&iph, buf, sizeof(iph));
233 af = iph.ip_v == 6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET;
234 /* Prepend address family to packet using OpenBSD constants */
235 memcpy(rbuf + 4, buf, len);
236 len += 4;
237 POKE_U32(rbuf, af);
238 ptr = rbuf;
239#elif defined(SSH_TUN_COMPAT_AF)
240 /* Convert existing address family header to OpenBSD value */
241 if (len <= 4)
242 return -1;
243 af = PEEK_U32(buf);
244 /* Put it back */
245 POKE_U32(buf, af == AF_INET6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET);
245#endif 246#endif
246 247
247 if ((r = sshbuf_put_string(&c->input, ptr, len)) != 0) 248 if ((r = sshbuf_put_string(c->input, ptr, len)) != 0)
248 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 249 fatal("%s: buffer error: %s", __func__, ssh_err(r));
249 return (0); 250 return (0);
250} 251}
251 252
252u_char * 253u_char *
253sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen) 254sys_tun_outfilter(struct ssh *ssh, struct Channel *c,
255 u_char **data, size_t *dlen)
254{ 256{
255 u_char *buf; 257 u_char *buf;
256 u_int32_t *af; 258 u_int32_t af;
257 int r; 259 int r;
258 size_t xxx_dlen;
259 260
260 /* XXX new API is incompatible with this signature. */ 261 /* XXX new API is incompatible with this signature. */
261 if ((r = sshbuf_get_string(&c->output, data, &xxx_dlen)) != 0) 262 if ((r = sshbuf_get_string(c->output, data, dlen)) != 0)
262 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 263 fatal("%s: buffer error: %s", __func__, ssh_err(r));
263 if (dlen != NULL) 264 if (*dlen < sizeof(af))
264 *dlen = xxx_dlen;
265 if (*dlen < sizeof(*af))
266 return (NULL); 265 return (NULL);
267 buf = *data; 266 buf = *data;
268 267
269#if defined(SSH_TUN_PREPEND_AF) 268#if defined(SSH_TUN_PREPEND_AF)
270 *dlen -= sizeof(u_int32_t); 269 /* skip address family */
271 buf = *data + sizeof(u_int32_t); 270 *dlen -= sizeof(af);
271 buf = *data + sizeof(af);
272#elif defined(SSH_TUN_COMPAT_AF) 272#elif defined(SSH_TUN_COMPAT_AF)
273 af = ntohl(*(u_int32_t *)buf); 273 /* translate address family */
274 if (*af == OPENBSD_AF_INET6) 274 af = (PEEK_U32(buf) == OPENBSD_AF_INET6) ? AF_INET6 : AF_INET;
275 *af = htonl(AF_INET6); 275 POKE_U32(buf, af);
276 else
277 *af = htonl(AF_INET);
278#endif 276#endif
279
280 return (buf); 277 return (buf);
281} 278}
282#endif /* SSH_TUN_FILTER */ 279#endif /* SSH_TUN_FILTER */
diff --git a/openbsd-compat/port-tun.h b/openbsd-compat/port-tun.h
index c53df01fc..103514370 100644
--- a/openbsd-compat/port-tun.h
+++ b/openbsd-compat/port-tun.h
@@ -18,6 +18,7 @@
18#define _PORT_TUN_H 18#define _PORT_TUN_H
19 19
20struct Channel; 20struct Channel;
21struct ssh;
21 22
22#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) 23#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD)
23# define CUSTOM_SYS_TUN_OPEN 24# define CUSTOM_SYS_TUN_OPEN
@@ -26,8 +27,8 @@ int sys_tun_open(int, int);
26 27
27#if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF) 28#if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF)
28# define SSH_TUN_FILTER 29# define SSH_TUN_FILTER
29int sys_tun_infilter(struct Channel *, char *, int); 30int sys_tun_infilter(struct ssh *, struct Channel *, char *, int);
30u_char *sys_tun_outfilter(struct Channel *, u_char **, u_int *); 31u_char *sys_tun_outfilter(struct ssh *, struct Channel *, u_char **, size_t *);
31#endif 32#endif
32 33
33#endif 34#endif
diff --git a/openbsd-compat/recallocarray.c b/openbsd-compat/recallocarray.c
new file mode 100644
index 000000000..3e1156ce2
--- /dev/null
+++ b/openbsd-compat/recallocarray.c
@@ -0,0 +1,90 @@
1/* $OpenBSD: recallocarray.c,v 1.1 2017/03/06 18:44:21 otto Exp $ */
2/*
3 * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* OPENBSD ORIGINAL: lib/libc/stdlib/recallocarray.c */
19
20#include "includes.h"
21#ifndef HAVE_RECALLOCARRAY
22
23#include <errno.h>
24#include <stdlib.h>
25#ifdef HAVE_STDINT_H
26#include <stdint.h>
27#endif
28#include <string.h>
29#include <unistd.h>
30
31/*
32 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
33 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
34 */
35#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
36
37void *
38recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
39{
40 size_t oldsize, newsize;
41 void *newptr;
42
43 if (ptr == NULL)
44 return calloc(newnmemb, size);
45
46 if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
47 newnmemb > 0 && SIZE_MAX / newnmemb < size) {
48 errno = ENOMEM;
49 return NULL;
50 }
51 newsize = newnmemb * size;
52
53 if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
54 oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
55 errno = EINVAL;
56 return NULL;
57 }
58 oldsize = oldnmemb * size;
59
60 /*
61 * Don't bother too much if we're shrinking just a bit,
62 * we do not shrink for series of small steps, oh well.
63 */
64 if (newsize <= oldsize) {
65 size_t d = oldsize - newsize;
66
67 if (d < oldsize / 2 && d < (size_t)getpagesize()) {
68 memset((char *)ptr + newsize, 0, d);
69 return ptr;
70 }
71 }
72
73 newptr = malloc(newsize);
74 if (newptr == NULL)
75 return NULL;
76
77 if (newsize > oldsize) {
78 memcpy(newptr, ptr, oldsize);
79 memset((char *)newptr + oldsize, 0, newsize - oldsize);
80 } else
81 memcpy(newptr, ptr, newsize);
82
83 explicit_bzero(ptr, oldsize);
84 free(ptr);
85
86 return newptr;
87}
88/* DEF_WEAK(recallocarray); */
89
90#endif /* HAVE_RECALLOCARRAY */
diff --git a/packet.c b/packet.c
index 2f3a2ec70..f114ea52c 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.247 2017/03/11 13:07:35 markus Exp $ */ 1/* $OpenBSD: packet.c,v 1.264 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -68,9 +68,7 @@
68 68
69#include "xmalloc.h" 69#include "xmalloc.h"
70#include "crc32.h" 70#include "crc32.h"
71#include "deattack.h"
72#include "compat.h" 71#include "compat.h"
73#include "ssh1.h"
74#include "ssh2.h" 72#include "ssh2.h"
75#include "cipher.h" 73#include "cipher.h"
76#include "sshkey.h" 74#include "sshkey.h"
@@ -186,10 +184,6 @@ struct session_state {
186 u_int32_t rekey_interval; /* how often in seconds */ 184 u_int32_t rekey_interval; /* how often in seconds */
187 time_t rekey_time; /* time of last rekeying */ 185 time_t rekey_time; /* time of last rekeying */
188 186
189 /* Session key for protocol v1 */
190 u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
191 u_int ssh1_keylen;
192
193 /* roundup current message to extra_pad bytes */ 187 /* roundup current message to extra_pad bytes */
194 u_char extra_pad; 188 u_char extra_pad;
195 189
@@ -216,9 +210,6 @@ struct session_state {
216 /* One-off warning about weak ciphers */ 210 /* One-off warning about weak ciphers */
217 int cipher_warning_done; 211 int cipher_warning_done;
218 212
219 /* SSH1 CRC compensation attack detector */
220 struct deattack_ctx deattack;
221
222 /* Hook for fuzzing inbound packets */ 213 /* Hook for fuzzing inbound packets */
223 ssh_packet_hook_fn *hook_in; 214 ssh_packet_hook_fn *hook_in;
224 void *hook_in_ctx; 215 void *hook_in_ctx;
@@ -278,13 +269,12 @@ ssh_packet_set_input_hook(struct ssh *ssh, ssh_packet_hook_fn *hook, void *ctx)
278int 269int
279ssh_packet_is_rekeying(struct ssh *ssh) 270ssh_packet_is_rekeying(struct ssh *ssh)
280{ 271{
281 return compat20 && 272 return ssh->state->rekeying ||
282 (ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0)); 273 (ssh->kex != NULL && ssh->kex->done == 0);
283} 274}
284 275
285/* 276/*
286 * Sets the descriptors used for communication. Disables encryption until 277 * Sets the descriptors used for communication.
287 * packet_set_encryption_key is called.
288 */ 278 */
289struct ssh * 279struct ssh *
290ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) 280ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out)
@@ -315,7 +305,6 @@ ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out)
315 return NULL; 305 return NULL;
316 } 306 }
317 state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL; 307 state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL;
318 deattack_init(&state->deattack);
319 /* 308 /*
320 * Cache the IP address of the remote connection for use in error 309 * Cache the IP address of the remote connection for use in error
321 * messages that might be generated after the connection has closed. 310 * messages that might be generated after the connection has closed.
@@ -570,8 +559,8 @@ ssh_local_port(struct ssh *ssh)
570 559
571/* Closes the connection and clears and frees internal data structures. */ 560/* Closes the connection and clears and frees internal data structures. */
572 561
573void 562static void
574ssh_packet_close(struct ssh *ssh) 563ssh_packet_close_internal(struct ssh *ssh, int do_close)
575{ 564{
576 struct session_state *state = ssh->state; 565 struct session_state *state = ssh->state;
577 u_int mode; 566 u_int mode;
@@ -579,20 +568,25 @@ ssh_packet_close(struct ssh *ssh)
579 if (!state->initialized) 568 if (!state->initialized)
580 return; 569 return;
581 state->initialized = 0; 570 state->initialized = 0;
582 if (state->connection_in == state->connection_out) { 571 if (do_close) {
583 shutdown(state->connection_out, SHUT_RDWR); 572 if (state->connection_in == state->connection_out) {
584 close(state->connection_out); 573 close(state->connection_out);
585 } else { 574 } else {
586 close(state->connection_in); 575 close(state->connection_in);
587 close(state->connection_out); 576 close(state->connection_out);
577 }
588 } 578 }
589 sshbuf_free(state->input); 579 sshbuf_free(state->input);
590 sshbuf_free(state->output); 580 sshbuf_free(state->output);
591 sshbuf_free(state->outgoing_packet); 581 sshbuf_free(state->outgoing_packet);
592 sshbuf_free(state->incoming_packet); 582 sshbuf_free(state->incoming_packet);
593 for (mode = 0; mode < MODE_MAX; mode++) 583 for (mode = 0; mode < MODE_MAX; mode++) {
594 kex_free_newkeys(state->newkeys[mode]); 584 kex_free_newkeys(state->newkeys[mode]); /* current keys */
595 if (state->compression_buffer) { 585 state->newkeys[mode] = NULL;
586 ssh_clear_newkeys(ssh, mode); /* next keys */
587 }
588 /* comression state is in shared mem, so we can only release it once */
589 if (do_close && state->compression_buffer) {
596 sshbuf_free(state->compression_buffer); 590 sshbuf_free(state->compression_buffer);
597 if (state->compression_out_started) { 591 if (state->compression_out_started) {
598 z_streamp stream = &state->compression_out_stream; 592 z_streamp stream = &state->compression_out_stream;
@@ -606,7 +600,7 @@ ssh_packet_close(struct ssh *ssh)
606 deflateEnd(stream); 600 deflateEnd(stream);
607 } 601 }
608 if (state->compression_in_started) { 602 if (state->compression_in_started) {
609 z_streamp stream = &state->compression_out_stream; 603 z_streamp stream = &state->compression_in_stream;
610 debug("compress incoming: " 604 debug("compress incoming: "
611 "raw data %llu, compressed %llu, factor %.2f", 605 "raw data %llu, compressed %llu, factor %.2f",
612 (unsigned long long)stream->total_out, 606 (unsigned long long)stream->total_out,
@@ -620,10 +614,24 @@ ssh_packet_close(struct ssh *ssh)
620 cipher_free(state->send_context); 614 cipher_free(state->send_context);
621 cipher_free(state->receive_context); 615 cipher_free(state->receive_context);
622 state->send_context = state->receive_context = NULL; 616 state->send_context = state->receive_context = NULL;
623 free(ssh->remote_ipaddr); 617 if (do_close) {
624 ssh->remote_ipaddr = NULL; 618 free(ssh->remote_ipaddr);
625 free(ssh->state); 619 ssh->remote_ipaddr = NULL;
626 ssh->state = NULL; 620 free(ssh->state);
621 ssh->state = NULL;
622 }
623}
624
625void
626ssh_packet_close(struct ssh *ssh)
627{
628 ssh_packet_close_internal(ssh, 1);
629}
630
631void
632ssh_packet_clear_keys(struct ssh *ssh)
633{
634 ssh_packet_close_internal(ssh, 0);
627} 635}
628 636
629/* Sets remote side protocol flags. */ 637/* Sets remote side protocol flags. */
@@ -698,7 +706,7 @@ ssh_packet_start_compression(struct ssh *ssh, int level)
698{ 706{
699 int r; 707 int r;
700 708
701 if (ssh->state->packet_compression && !compat20) 709 if (ssh->state->packet_compression)
702 return SSH_ERR_INTERNAL_ERROR; 710 return SSH_ERR_INTERNAL_ERROR;
703 ssh->state->packet_compression = 1; 711 ssh->state->packet_compression = 1;
704 if ((r = ssh_packet_init_compression(ssh)) != 0 || 712 if ((r = ssh_packet_init_compression(ssh)) != 0 ||
@@ -802,136 +810,13 @@ uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out)
802 /* NOTREACHED */ 810 /* NOTREACHED */
803} 811}
804 812
805/*
806 * Causes any further packets to be encrypted using the given key. The same
807 * key is used for both sending and reception. However, both directions are
808 * encrypted independently of each other.
809 */
810
811void 813void
812ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number) 814ssh_clear_newkeys(struct ssh *ssh, int mode)
813{ 815{
814#ifndef WITH_SSH1 816 if (ssh->kex && ssh->kex->newkeys[mode]) {
815 fatal("no SSH protocol 1 support"); 817 kex_free_newkeys(ssh->kex->newkeys[mode]);
816#else /* WITH_SSH1 */ 818 ssh->kex->newkeys[mode] = NULL;
817 struct session_state *state = ssh->state;
818 const struct sshcipher *cipher = cipher_by_number(number);
819 int r;
820 const char *wmsg;
821
822 if (cipher == NULL)
823 fatal("%s: unknown cipher number %d", __func__, number);
824 if (keylen < 20)
825 fatal("%s: keylen too small: %d", __func__, keylen);
826 if (keylen > SSH_SESSION_KEY_LENGTH)
827 fatal("%s: keylen too big: %d", __func__, keylen);
828 memcpy(state->ssh1_key, key, keylen);
829 state->ssh1_keylen = keylen;
830 if ((r = cipher_init(&state->send_context, cipher, key, keylen,
831 NULL, 0, CIPHER_ENCRYPT)) != 0 ||
832 (r = cipher_init(&state->receive_context, cipher, key, keylen,
833 NULL, 0, CIPHER_DECRYPT) != 0))
834 fatal("%s: cipher_init failed: %s", __func__, ssh_err(r));
835 if (!state->cipher_warning_done &&
836 ((wmsg = cipher_warning_message(state->send_context)) != NULL ||
837 (wmsg = cipher_warning_message(state->send_context)) != NULL)) {
838 error("Warning: %s", wmsg);
839 state->cipher_warning_done = 1;
840 } 819 }
841#endif /* WITH_SSH1 */
842}
843
844/*
845 * Finalizes and sends the packet. If the encryption key has been set,
846 * encrypts the packet before sending.
847 */
848
849int
850ssh_packet_send1(struct ssh *ssh)
851{
852 struct session_state *state = ssh->state;
853 u_char buf[8], *cp;
854 int r, padding, len;
855 u_int checksum;
856
857 /*
858 * If using packet compression, compress the payload of the outgoing
859 * packet.
860 */
861 if (state->packet_compression) {
862 sshbuf_reset(state->compression_buffer);
863 /* Skip padding. */
864 if ((r = sshbuf_consume(state->outgoing_packet, 8)) != 0)
865 goto out;
866 /* padding */
867 if ((r = sshbuf_put(state->compression_buffer,
868 "\0\0\0\0\0\0\0\0", 8)) != 0)
869 goto out;
870 if ((r = compress_buffer(ssh, state->outgoing_packet,
871 state->compression_buffer)) != 0)
872 goto out;
873 sshbuf_reset(state->outgoing_packet);
874 if ((r = sshbuf_putb(state->outgoing_packet,
875 state->compression_buffer)) != 0)
876 goto out;
877 }
878 /* Compute packet length without padding (add checksum, remove padding). */
879 len = sshbuf_len(state->outgoing_packet) + 4 - 8;
880
881 /* Insert padding. Initialized to zero in packet_start1() */
882 padding = 8 - len % 8;
883 if (!cipher_ctx_is_plaintext(state->send_context)) {
884 cp = sshbuf_mutable_ptr(state->outgoing_packet);
885 if (cp == NULL) {
886 r = SSH_ERR_INTERNAL_ERROR;
887 goto out;
888 }
889 arc4random_buf(cp + 8 - padding, padding);
890 }
891 if ((r = sshbuf_consume(state->outgoing_packet, 8 - padding)) != 0)
892 goto out;
893
894 /* Add check bytes. */
895 checksum = ssh_crc32(sshbuf_ptr(state->outgoing_packet),
896 sshbuf_len(state->outgoing_packet));
897 POKE_U32(buf, checksum);
898 if ((r = sshbuf_put(state->outgoing_packet, buf, 4)) != 0)
899 goto out;
900
901#ifdef PACKET_DEBUG
902 fprintf(stderr, "packet_send plain: ");
903 sshbuf_dump(state->outgoing_packet, stderr);
904#endif
905
906 /* Append to output. */
907 POKE_U32(buf, len);
908 if ((r = sshbuf_put(state->output, buf, 4)) != 0)
909 goto out;
910 if ((r = sshbuf_reserve(state->output,
911 sshbuf_len(state->outgoing_packet), &cp)) != 0)
912 goto out;
913 if ((r = cipher_crypt(state->send_context, 0, cp,
914 sshbuf_ptr(state->outgoing_packet),
915 sshbuf_len(state->outgoing_packet), 0, 0)) != 0)
916 goto out;
917
918#ifdef PACKET_DEBUG
919 fprintf(stderr, "encrypted: ");
920 sshbuf_dump(state->output, stderr);
921#endif
922 state->p_send.packets++;
923 state->p_send.bytes += len +
924 sshbuf_len(state->outgoing_packet);
925 sshbuf_reset(state->outgoing_packet);
926
927 /*
928 * Note that the packet is now only buffered in output. It won't be
929 * actually sent until ssh_packet_write_wait or ssh_packet_write_poll
930 * is called.
931 */
932 r = 0;
933 out:
934 return r;
935} 820}
936 821
937int 822int
@@ -944,45 +829,33 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
944 struct sshcipher_ctx **ccp; 829 struct sshcipher_ctx **ccp;
945 struct packet_state *ps; 830 struct packet_state *ps;
946 u_int64_t *max_blocks; 831 u_int64_t *max_blocks;
947 const char *wmsg, *dir; 832 const char *wmsg;
948 int r, crypt_type; 833 int r, crypt_type;
949 834
950 debug2("set_newkeys: mode %d", mode); 835 debug2("set_newkeys: mode %d", mode);
951 836
952 if (mode == MODE_OUT) { 837 if (mode == MODE_OUT) {
953 dir = "output";
954 ccp = &state->send_context; 838 ccp = &state->send_context;
955 crypt_type = CIPHER_ENCRYPT; 839 crypt_type = CIPHER_ENCRYPT;
956 ps = &state->p_send; 840 ps = &state->p_send;
957 max_blocks = &state->max_blocks_out; 841 max_blocks = &state->max_blocks_out;
958 } else { 842 } else {
959 dir = "input";
960 ccp = &state->receive_context; 843 ccp = &state->receive_context;
961 crypt_type = CIPHER_DECRYPT; 844 crypt_type = CIPHER_DECRYPT;
962 ps = &state->p_read; 845 ps = &state->p_read;
963 max_blocks = &state->max_blocks_in; 846 max_blocks = &state->max_blocks_in;
964 } 847 }
965 if (state->newkeys[mode] != NULL) { 848 if (state->newkeys[mode] != NULL) {
966 debug("%s: rekeying after %llu %s blocks" 849 debug("set_newkeys: rekeying, input %llu bytes %llu blocks, "
967 " (%llu bytes total)", __func__, 850 "output %llu bytes %llu blocks",
968 (unsigned long long)ps->blocks, dir, 851 (unsigned long long)state->p_read.bytes,
969 (unsigned long long)ps->bytes); 852 (unsigned long long)state->p_read.blocks,
853 (unsigned long long)state->p_send.bytes,
854 (unsigned long long)state->p_send.blocks);
970 cipher_free(*ccp); 855 cipher_free(*ccp);
971 *ccp = NULL; 856 *ccp = NULL;
972 enc = &state->newkeys[mode]->enc; 857 kex_free_newkeys(state->newkeys[mode]);
973 mac = &state->newkeys[mode]->mac; 858 state->newkeys[mode] = NULL;
974 comp = &state->newkeys[mode]->comp;
975 mac_clear(mac);
976 explicit_bzero(enc->iv, enc->iv_len);
977 explicit_bzero(enc->key, enc->key_len);
978 explicit_bzero(mac->key, mac->key_len);
979 free(enc->name);
980 free(enc->iv);
981 free(enc->key);
982 free(mac->name);
983 free(mac->key);
984 free(comp->name);
985 free(state->newkeys[mode]);
986 } 859 }
987 /* note that both bytes and the seqnr are not reset */ 860 /* note that both bytes and the seqnr are not reset */
988 ps->packets = ps->blocks = 0; 861 ps->packets = ps->blocks = 0;
@@ -1027,7 +900,8 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
1027 } 900 }
1028 /* 901 /*
1029 * The 2^(blocksize*2) limit is too expensive for 3DES, 902 * The 2^(blocksize*2) limit is too expensive for 3DES,
1030 * blowfish, etc, so enforce a 1GB limit for small blocksizes. 903 * so enforce a 1GB limit for small blocksizes.
904 * See RFC4344 section 3.2.
1031 */ 905 */
1032 if (enc->block_size >= 16) 906 if (enc->block_size >= 16)
1033 *max_blocks = (u_int64_t)1 << (enc->block_size*2); 907 *max_blocks = (u_int64_t)1 << (enc->block_size*2);
@@ -1071,7 +945,10 @@ ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len)
1071 (int64_t)state->rekey_time + state->rekey_interval <= monotime()) 945 (int64_t)state->rekey_time + state->rekey_interval <= monotime())
1072 return 1; 946 return 1;
1073 947
1074 /* Always rekey when MAX_PACKETS sent in either direction */ 948 /*
949 * Always rekey when MAX_PACKETS sent in either direction
950 * As per RFC4344 section 3.1 we do this after 2^31 packets.
951 */
1075 if (state->p_send.packets > MAX_PACKETS || 952 if (state->p_send.packets > MAX_PACKETS ||
1076 state->p_read.packets > MAX_PACKETS) 953 state->p_read.packets > MAX_PACKETS)
1077 return 1; 954 return 1;
@@ -1424,13 +1301,6 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1424 r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p); 1301 r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p);
1425 if (r != 0) 1302 if (r != 0)
1426 break; 1303 break;
1427 if (!compat20 && (
1428 *typep == SSH_SMSG_SUCCESS
1429 || *typep == SSH_SMSG_FAILURE
1430 || *typep == SSH_CMSG_EOF
1431 || *typep == SSH_CMSG_EXIT_CONFIRMATION))
1432 if ((r = sshpkt_get_end(ssh)) != 0)
1433 break;
1434 /* If we got a packet, return it. */ 1304 /* If we got a packet, return it. */
1435 if (*typep != SSH_MSG_NONE) 1305 if (*typep != SSH_MSG_NONE)
1436 break; 1306 break;
@@ -1524,153 +1394,6 @@ ssh_packet_read_expect(struct ssh *ssh, u_int expected_type)
1524 return 0; 1394 return 0;
1525} 1395}
1526 1396
1527/* Checks if a full packet is available in the data received so far via
1528 * packet_process_incoming. If so, reads the packet; otherwise returns
1529 * SSH_MSG_NONE. This does not wait for data from the connection.
1530 *
1531 * SSH_MSG_DISCONNECT is handled specially here. Also,
1532 * SSH_MSG_IGNORE messages are skipped by this function and are never returned
1533 * to higher levels.
1534 */
1535
1536int
1537ssh_packet_read_poll1(struct ssh *ssh, u_char *typep)
1538{
1539 struct session_state *state = ssh->state;
1540 u_int len, padded_len;
1541 const char *emsg;
1542 const u_char *cp;
1543 u_char *p;
1544 u_int checksum, stored_checksum;
1545 int r;
1546
1547 *typep = SSH_MSG_NONE;
1548
1549 /* Check if input size is less than minimum packet size. */
1550 if (sshbuf_len(state->input) < 4 + 8)
1551 return 0;
1552 /* Get length of incoming packet. */
1553 len = PEEK_U32(sshbuf_ptr(state->input));
1554 if (len < 1 + 2 + 2 || len > 256 * 1024) {
1555 if ((r = sshpkt_disconnect(ssh, "Bad packet length %u",
1556 len)) != 0)
1557 return r;
1558 return SSH_ERR_CONN_CORRUPT;
1559 }
1560 padded_len = (len + 8) & ~7;
1561
1562 /* Check if the packet has been entirely received. */
1563 if (sshbuf_len(state->input) < 4 + padded_len)
1564 return 0;
1565
1566 /* The entire packet is in buffer. */
1567
1568 /* Consume packet length. */
1569 if ((r = sshbuf_consume(state->input, 4)) != 0)
1570 goto out;
1571
1572 /*
1573 * Cryptographic attack detector for ssh
1574 * (C)1998 CORE-SDI, Buenos Aires Argentina
1575 * Ariel Futoransky(futo@core-sdi.com)
1576 */
1577 if (!cipher_ctx_is_plaintext(state->receive_context)) {
1578 emsg = NULL;
1579 switch (detect_attack(&state->deattack,
1580 sshbuf_ptr(state->input), padded_len)) {
1581 case DEATTACK_OK:
1582 break;
1583 case DEATTACK_DETECTED:
1584 emsg = "crc32 compensation attack detected";
1585 break;
1586 case DEATTACK_DOS_DETECTED:
1587 emsg = "deattack denial of service detected";
1588 break;
1589 default:
1590 emsg = "deattack error";
1591 break;
1592 }
1593 if (emsg != NULL) {
1594 error("%s", emsg);
1595 if ((r = sshpkt_disconnect(ssh, "%s", emsg)) != 0 ||
1596 (r = ssh_packet_write_wait(ssh)) != 0)
1597 return r;
1598 return SSH_ERR_CONN_CORRUPT;
1599 }
1600 }
1601
1602 /* Decrypt data to incoming_packet. */
1603 sshbuf_reset(state->incoming_packet);
1604 if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0)
1605 goto out;
1606 if ((r = cipher_crypt(state->receive_context, 0, p,
1607 sshbuf_ptr(state->input), padded_len, 0, 0)) != 0)
1608 goto out;
1609
1610 if ((r = sshbuf_consume(state->input, padded_len)) != 0)
1611 goto out;
1612
1613#ifdef PACKET_DEBUG
1614 fprintf(stderr, "read_poll plain: ");
1615 sshbuf_dump(state->incoming_packet, stderr);
1616#endif
1617
1618 /* Compute packet checksum. */
1619 checksum = ssh_crc32(sshbuf_ptr(state->incoming_packet),
1620 sshbuf_len(state->incoming_packet) - 4);
1621
1622 /* Skip padding. */
1623 if ((r = sshbuf_consume(state->incoming_packet, 8 - len % 8)) != 0)
1624 goto out;
1625
1626 /* Test check bytes. */
1627 if (len != sshbuf_len(state->incoming_packet)) {
1628 error("%s: len %d != sshbuf_len %zd", __func__,
1629 len, sshbuf_len(state->incoming_packet));
1630 if ((r = sshpkt_disconnect(ssh, "invalid packet length")) != 0 ||
1631 (r = ssh_packet_write_wait(ssh)) != 0)
1632 return r;
1633 return SSH_ERR_CONN_CORRUPT;
1634 }
1635
1636 cp = sshbuf_ptr(state->incoming_packet) + len - 4;
1637 stored_checksum = PEEK_U32(cp);
1638 if (checksum != stored_checksum) {
1639 error("Corrupted check bytes on input");
1640 if ((r = sshpkt_disconnect(ssh, "connection corrupted")) != 0 ||
1641 (r = ssh_packet_write_wait(ssh)) != 0)
1642 return r;
1643 return SSH_ERR_CONN_CORRUPT;
1644 }
1645 if ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0)
1646 goto out;
1647
1648 if (state->packet_compression) {
1649 sshbuf_reset(state->compression_buffer);
1650 if ((r = uncompress_buffer(ssh, state->incoming_packet,
1651 state->compression_buffer)) != 0)
1652 goto out;
1653 sshbuf_reset(state->incoming_packet);
1654 if ((r = sshbuf_putb(state->incoming_packet,
1655 state->compression_buffer)) != 0)
1656 goto out;
1657 }
1658 state->p_read.packets++;
1659 state->p_read.bytes += padded_len + 4;
1660 if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0)
1661 goto out;
1662 if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) {
1663 error("Invalid ssh1 packet type: %d", *typep);
1664 if ((r = sshpkt_disconnect(ssh, "invalid packet type")) != 0 ||
1665 (r = ssh_packet_write_wait(ssh)) != 0)
1666 return r;
1667 return SSH_ERR_PROTOCOL_ERROR;
1668 }
1669 r = 0;
1670 out:
1671 return r;
1672}
1673
1674static int 1397static int
1675ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) 1398ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1676{ 1399{
@@ -1951,75 +1674,48 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1951 1674
1952 for (;;) { 1675 for (;;) {
1953 msg = NULL; 1676 msg = NULL;
1954 if (compat20) { 1677 r = ssh_packet_read_poll2(ssh, typep, seqnr_p);
1955 r = ssh_packet_read_poll2(ssh, typep, seqnr_p); 1678 if (r != 0)
1956 if (r != 0) 1679 return r;
1957 return r; 1680 if (*typep) {
1958 if (*typep) { 1681 state->keep_alive_timeouts = 0;
1959 state->keep_alive_timeouts = 0; 1682 DBG(debug("received packet type %d", *typep));
1960 DBG(debug("received packet type %d", *typep)); 1683 }
1961 } 1684 switch (*typep) {
1962 switch (*typep) { 1685 case SSH2_MSG_IGNORE:
1963 case SSH2_MSG_IGNORE: 1686 debug3("Received SSH2_MSG_IGNORE");
1964 debug3("Received SSH2_MSG_IGNORE"); 1687 break;
1965 break; 1688 case SSH2_MSG_DEBUG:
1966 case SSH2_MSG_DEBUG: 1689 if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||
1967 if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || 1690 (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||
1968 (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || 1691 (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
1969 (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
1970 free(msg);
1971 return r;
1972 }
1973 debug("Remote: %.900s", msg);
1974 free(msg);
1975 break;
1976 case SSH2_MSG_DISCONNECT:
1977 if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
1978 (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
1979 return r;
1980 /* Ignore normal client exit notifications */
1981 do_log2(ssh->state->server_side &&
1982 reason == SSH2_DISCONNECT_BY_APPLICATION ?
1983 SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
1984 "Received disconnect from %s port %d:"
1985 "%u: %.400s", ssh_remote_ipaddr(ssh),
1986 ssh_remote_port(ssh), reason, msg);
1987 free(msg);
1988 return SSH_ERR_DISCONNECTED;
1989 case SSH2_MSG_UNIMPLEMENTED:
1990 if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
1991 return r;
1992 debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
1993 seqnr);
1994 break;
1995 default:
1996 return 0;
1997 }
1998 } else {
1999 r = ssh_packet_read_poll1(ssh, typep);
2000 switch (*typep) {
2001 case SSH_MSG_NONE:
2002 return SSH_MSG_NONE;
2003 case SSH_MSG_IGNORE:
2004 break;
2005 case SSH_MSG_DEBUG:
2006 if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
2007 return r;
2008 debug("Remote: %.900s", msg);
2009 free(msg);
2010 break;
2011 case SSH_MSG_DISCONNECT:
2012 if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
2013 return r;
2014 error("Received disconnect from %s port %d: "
2015 "%.400s", ssh_remote_ipaddr(ssh),
2016 ssh_remote_port(ssh), msg);
2017 free(msg); 1692 free(msg);
2018 return SSH_ERR_DISCONNECTED; 1693 return r;
2019 default:
2020 DBG(debug("received packet type %d", *typep));
2021 return 0;
2022 } 1694 }
1695 debug("Remote: %.900s", msg);
1696 free(msg);
1697 break;
1698 case SSH2_MSG_DISCONNECT:
1699 if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
1700 (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
1701 return r;
1702 /* Ignore normal client exit notifications */
1703 do_log2(ssh->state->server_side &&
1704 reason == SSH2_DISCONNECT_BY_APPLICATION ?
1705 SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
1706 "Received disconnect from %s port %d:"
1707 "%u: %.400s", ssh_remote_ipaddr(ssh),
1708 ssh_remote_port(ssh), reason, msg);
1709 free(msg);
1710 return SSH_ERR_DISCONNECTED;
1711 case SSH2_MSG_UNIMPLEMENTED:
1712 if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
1713 return r;
1714 debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
1715 seqnr);
1716 break;
1717 default:
1718 return 0;
2023 } 1719 }
2024 } 1720 }
2025} 1721}
@@ -2071,27 +1767,19 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...)
2071 va_list args; 1767 va_list args;
2072 int r; 1768 int r;
2073 1769
2074 if (compat20 && (ssh->compat & SSH_BUG_DEBUG)) 1770 if ((ssh->compat & SSH_BUG_DEBUG))
2075 return; 1771 return;
2076 1772
2077 va_start(args, fmt); 1773 va_start(args, fmt);
2078 vsnprintf(buf, sizeof(buf), fmt, args); 1774 vsnprintf(buf, sizeof(buf), fmt, args);
2079 va_end(args); 1775 va_end(args);
2080 1776
2081 if (compat20) { 1777 if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 ||
2082 if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 || 1778 (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */
2083 (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */ 1779 (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
2084 (r = sshpkt_put_cstring(ssh, buf)) != 0 || 1780 (r = sshpkt_put_cstring(ssh, "")) != 0 ||
2085 (r = sshpkt_put_cstring(ssh, "")) != 0 || 1781 (r = sshpkt_send(ssh)) != 0 ||
2086 (r = sshpkt_send(ssh)) != 0) 1782 (r = ssh_packet_write_wait(ssh)) != 0)
2087 fatal("%s: %s", __func__, ssh_err(r));
2088 } else {
2089 if ((r = sshpkt_start(ssh, SSH_MSG_DEBUG)) != 0 ||
2090 (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
2091 (r = sshpkt_send(ssh)) != 0)
2092 fatal("%s: %s", __func__, ssh_err(r));
2093 }
2094 if ((r = ssh_packet_write_wait(ssh)) != 0)
2095 fatal("%s: %s", __func__, ssh_err(r)); 1783 fatal("%s: %s", __func__, ssh_err(r));
2096} 1784}
2097 1785
@@ -2116,15 +1804,20 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
2116 1804
2117 switch (r) { 1805 switch (r) {
2118 case SSH_ERR_CONN_CLOSED: 1806 case SSH_ERR_CONN_CLOSED:
1807 ssh_packet_clear_keys(ssh);
2119 logdie("Connection closed by %s", remote_id); 1808 logdie("Connection closed by %s", remote_id);
2120 case SSH_ERR_CONN_TIMEOUT: 1809 case SSH_ERR_CONN_TIMEOUT:
1810 ssh_packet_clear_keys(ssh);
2121 logdie("Connection %s %s timed out", 1811 logdie("Connection %s %s timed out",
2122 ssh->state->server_side ? "from" : "to", remote_id); 1812 ssh->state->server_side ? "from" : "to", remote_id);
2123 case SSH_ERR_DISCONNECTED: 1813 case SSH_ERR_DISCONNECTED:
1814 ssh_packet_clear_keys(ssh);
2124 logdie("Disconnected from %s", remote_id); 1815 logdie("Disconnected from %s", remote_id);
2125 case SSH_ERR_SYSTEM_ERROR: 1816 case SSH_ERR_SYSTEM_ERROR:
2126 if (errno == ECONNRESET) 1817 if (errno == ECONNRESET) {
1818 ssh_packet_clear_keys(ssh);
2127 logdie("Connection reset by %s", remote_id); 1819 logdie("Connection reset by %s", remote_id);
1820 }
2128 /* FALLTHROUGH */ 1821 /* FALLTHROUGH */
2129 case SSH_ERR_NO_CIPHER_ALG_MATCH: 1822 case SSH_ERR_NO_CIPHER_ALG_MATCH:
2130 case SSH_ERR_NO_MAC_ALG_MATCH: 1823 case SSH_ERR_NO_MAC_ALG_MATCH:
@@ -2132,12 +1825,14 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
2132 case SSH_ERR_NO_KEX_ALG_MATCH: 1825 case SSH_ERR_NO_KEX_ALG_MATCH:
2133 case SSH_ERR_NO_HOSTKEY_ALG_MATCH: 1826 case SSH_ERR_NO_HOSTKEY_ALG_MATCH:
2134 if (ssh && ssh->kex && ssh->kex->failed_choice) { 1827 if (ssh && ssh->kex && ssh->kex->failed_choice) {
1828 ssh_packet_clear_keys(ssh);
2135 logdie("Unable to negotiate with %s: %s. " 1829 logdie("Unable to negotiate with %s: %s. "
2136 "Their offer: %s", remote_id, ssh_err(r), 1830 "Their offer: %s", remote_id, ssh_err(r),
2137 ssh->kex->failed_choice); 1831 ssh->kex->failed_choice);
2138 } 1832 }
2139 /* FALLTHROUGH */ 1833 /* FALLTHROUGH */
2140 default: 1834 default:
1835 ssh_packet_clear_keys(ssh);
2141 logdie("%s%sConnection %s %s: %s", 1836 logdie("%s%sConnection %s %s: %s",
2142 tag != NULL ? tag : "", tag != NULL ? ": " : "", 1837 tag != NULL ? tag : "", tag != NULL ? ": " : "",
2143 ssh->state->server_side ? "from" : "to", 1838 ssh->state->server_side ? "from" : "to",
@@ -2302,7 +1997,7 @@ void
2302ssh_packet_set_tos(struct ssh *ssh, int tos) 1997ssh_packet_set_tos(struct ssh *ssh, int tos)
2303{ 1998{
2304#ifndef IP_TOS_IS_BROKEN 1999#ifndef IP_TOS_IS_BROKEN
2305 if (!ssh_packet_connection_is_on_socket(ssh)) 2000 if (!ssh_packet_connection_is_on_socket(ssh) || tos == INT_MAX)
2306 return; 2001 return;
2307 switch (ssh_packet_connection_af(ssh)) { 2002 switch (ssh_packet_connection_af(ssh)) {
2308# ifdef IP_TOS 2003# ifdef IP_TOS
@@ -2395,36 +2090,6 @@ ssh_packet_get_maxsize(struct ssh *ssh)
2395 return ssh->state->max_packet_size; 2090 return ssh->state->max_packet_size;
2396} 2091}
2397 2092
2398/*
2399 * 9.2. Ignored Data Message
2400 *
2401 * byte SSH_MSG_IGNORE
2402 * string data
2403 *
2404 * All implementations MUST understand (and ignore) this message at any
2405 * time (after receiving the protocol version). No implementation is
2406 * required to send them. This message can be used as an additional
2407 * protection measure against advanced traffic analysis techniques.
2408 */
2409void
2410ssh_packet_send_ignore(struct ssh *ssh, int nbytes)
2411{
2412 u_int32_t rnd = 0;
2413 int r, i;
2414
2415 if ((r = sshpkt_start(ssh, compat20 ?
2416 SSH2_MSG_IGNORE : SSH_MSG_IGNORE)) != 0 ||
2417 (r = sshpkt_put_u32(ssh, nbytes)) != 0)
2418 fatal("%s: %s", __func__, ssh_err(r));
2419 for (i = 0; i < nbytes; i++) {
2420 if (i % 4 == 0)
2421 rnd = arc4random();
2422 if ((r = sshpkt_put_u8(ssh, (u_char)rnd & 0xff)) != 0)
2423 fatal("%s: %s", __func__, ssh_err(r));
2424 rnd >>= 8;
2425 }
2426}
2427
2428void 2093void
2429ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, u_int32_t seconds) 2094ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, u_int32_t seconds)
2430{ 2095{
@@ -2528,9 +2193,7 @@ newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode)
2528 return r; 2193 return r;
2529 if ((b = sshbuf_new()) == NULL) 2194 if ((b = sshbuf_new()) == NULL)
2530 return SSH_ERR_ALLOC_FAIL; 2195 return SSH_ERR_ALLOC_FAIL;
2531 /* The cipher struct is constant and shared, you export pointer */
2532 if ((r = sshbuf_put_cstring(b, enc->name)) != 0 || 2196 if ((r = sshbuf_put_cstring(b, enc->name)) != 0 ||
2533 (r = sshbuf_put(b, &enc->cipher, sizeof(enc->cipher))) != 0 ||
2534 (r = sshbuf_put_u32(b, enc->enabled)) != 0 || 2197 (r = sshbuf_put_u32(b, enc->enabled)) != 0 ||
2535 (r = sshbuf_put_u32(b, enc->block_size)) != 0 || 2198 (r = sshbuf_put_u32(b, enc->block_size)) != 0 ||
2536 (r = sshbuf_put_string(b, enc->key, enc->key_len)) != 0 || 2199 (r = sshbuf_put_string(b, enc->key, enc->key_len)) != 0 ||
@@ -2556,54 +2219,22 @@ int
2556ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) 2219ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m)
2557{ 2220{
2558 struct session_state *state = ssh->state; 2221 struct session_state *state = ssh->state;
2559 u_char *p; 2222 int r;
2560 size_t slen, rlen;
2561 int r, ssh1cipher;
2562
2563 if (!compat20) {
2564 ssh1cipher = cipher_ctx_get_number(state->receive_context);
2565 slen = cipher_get_keyiv_len(state->send_context);
2566 rlen = cipher_get_keyiv_len(state->receive_context);
2567 if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 ||
2568 (r = sshbuf_put_u32(m, ssh1cipher)) != 0 ||
2569 (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 ||
2570 (r = sshbuf_put_u32(m, slen)) != 0 ||
2571 (r = sshbuf_reserve(m, slen, &p)) != 0 ||
2572 (r = cipher_get_keyiv(state->send_context, p, slen)) != 0 ||
2573 (r = sshbuf_put_u32(m, rlen)) != 0 ||
2574 (r = sshbuf_reserve(m, rlen, &p)) != 0 ||
2575 (r = cipher_get_keyiv(state->receive_context, p, rlen)) != 0)
2576 return r;
2577 } else {
2578 if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
2579 (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||
2580 (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||
2581 (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||
2582 (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||
2583 (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||
2584 (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||
2585 (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 ||
2586 (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 ||
2587 (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 ||
2588 (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 ||
2589 (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 ||
2590 (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0)
2591 return r;
2592 }
2593 2223
2594 slen = cipher_get_keycontext(state->send_context, NULL); 2224 if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
2595 rlen = cipher_get_keycontext(state->receive_context, NULL); 2225 (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||
2596 if ((r = sshbuf_put_u32(m, slen)) != 0 || 2226 (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||
2597 (r = sshbuf_reserve(m, slen, &p)) != 0) 2227 (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||
2598 return r; 2228 (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||
2599 if (cipher_get_keycontext(state->send_context, p) != (int)slen) 2229 (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||
2600 return SSH_ERR_INTERNAL_ERROR; 2230 (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||
2601 if ((r = sshbuf_put_u32(m, rlen)) != 0 || 2231 (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 ||
2602 (r = sshbuf_reserve(m, rlen, &p)) != 0) 2232 (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 ||
2603 return r; 2233 (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 ||
2604 if (cipher_get_keycontext(state->receive_context, p) != (int)rlen) 2234 (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 ||
2605 return SSH_ERR_INTERNAL_ERROR; 2235 (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 ||
2606 if ((r = sshbuf_put_stringb(m, state->input)) != 0 || 2236 (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0 ||
2237 (r = sshbuf_put_stringb(m, state->input)) != 0 ||
2607 (r = sshbuf_put_stringb(m, state->output)) != 0) 2238 (r = sshbuf_put_stringb(m, state->output)) != 0)
2608 return r; 2239 return r;
2609 2240
@@ -2636,12 +2267,15 @@ newkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode)
2636 comp = &newkey->comp; 2267 comp = &newkey->comp;
2637 2268
2638 if ((r = sshbuf_get_cstring(b, &enc->name, NULL)) != 0 || 2269 if ((r = sshbuf_get_cstring(b, &enc->name, NULL)) != 0 ||
2639 (r = sshbuf_get(b, &enc->cipher, sizeof(enc->cipher))) != 0 ||
2640 (r = sshbuf_get_u32(b, (u_int *)&enc->enabled)) != 0 || 2270 (r = sshbuf_get_u32(b, (u_int *)&enc->enabled)) != 0 ||
2641 (r = sshbuf_get_u32(b, &enc->block_size)) != 0 || 2271 (r = sshbuf_get_u32(b, &enc->block_size)) != 0 ||
2642 (r = sshbuf_get_string(b, &enc->key, &keylen)) != 0 || 2272 (r = sshbuf_get_string(b, &enc->key, &keylen)) != 0 ||
2643 (r = sshbuf_get_string(b, &enc->iv, &ivlen)) != 0) 2273 (r = sshbuf_get_string(b, &enc->iv, &ivlen)) != 0)
2644 goto out; 2274 goto out;
2275 if ((enc->cipher = cipher_by_name(enc->name)) == NULL) {
2276 r = SSH_ERR_INVALID_FORMAT;
2277 goto out;
2278 }
2645 if (cipher_authlen(enc->cipher) == 0) { 2279 if (cipher_authlen(enc->cipher) == 0) {
2646 if ((r = sshbuf_get_cstring(b, &mac->name, NULL)) != 0) 2280 if ((r = sshbuf_get_cstring(b, &mac->name, NULL)) != 0)
2647 goto out; 2281 goto out;
@@ -2659,11 +2293,6 @@ newkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode)
2659 if ((r = sshbuf_get_u32(b, &comp->type)) != 0 || 2293 if ((r = sshbuf_get_u32(b, &comp->type)) != 0 ||
2660 (r = sshbuf_get_cstring(b, &comp->name, NULL)) != 0) 2294 (r = sshbuf_get_cstring(b, &comp->name, NULL)) != 0)
2661 goto out; 2295 goto out;
2662 if (enc->name == NULL ||
2663 cipher_by_name(enc->name) != enc->cipher) {
2664 r = SSH_ERR_INVALID_FORMAT;
2665 goto out;
2666 }
2667 if (sshbuf_len(b) != 0) { 2296 if (sshbuf_len(b) != 0) {
2668 r = SSH_ERR_INVALID_FORMAT; 2297 r = SSH_ERR_INVALID_FORMAT;
2669 goto out; 2298 goto out;
@@ -2728,61 +2357,33 @@ int
2728ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) 2357ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
2729{ 2358{
2730 struct session_state *state = ssh->state; 2359 struct session_state *state = ssh->state;
2731 const u_char *ssh1key, *ivin, *ivout, *keyin, *keyout, *input, *output; 2360 const u_char *input, *output;
2732 size_t ssh1keylen, rlen, slen, ilen, olen; 2361 size_t ilen, olen;
2733 int r; 2362 int r;
2734 u_int ssh1cipher = 0; 2363
2735 2364 if ((r = kex_from_blob(m, &ssh->kex)) != 0 ||
2736 if (!compat20) { 2365 (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 ||
2737 if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 || 2366 (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 ||
2738 (r = sshbuf_get_u32(m, &ssh1cipher)) != 0 || 2367 (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 ||
2739 (r = sshbuf_get_string_direct(m, &ssh1key, &ssh1keylen)) != 0 || 2368 (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 ||
2740 (r = sshbuf_get_string_direct(m, &ivout, &slen)) != 0 || 2369 (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||
2741 (r = sshbuf_get_string_direct(m, &ivin, &rlen)) != 0) 2370 (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||
2742 return r; 2371 (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 ||
2743 if (ssh1cipher > INT_MAX) 2372 (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 ||
2744 return SSH_ERR_KEY_UNKNOWN_CIPHER; 2373 (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 ||
2745 ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen, 2374 (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 ||
2746 (int)ssh1cipher); 2375 (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 ||
2747 if (cipher_get_keyiv_len(state->send_context) != (int)slen || 2376 (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)
2748 cipher_get_keyiv_len(state->receive_context) != (int)rlen) 2377 return r;
2749 return SSH_ERR_INVALID_FORMAT; 2378 /*
2750 if ((r = cipher_set_keyiv(state->send_context, ivout)) != 0 || 2379 * We set the time here so that in post-auth privsep slave we
2751 (r = cipher_set_keyiv(state->receive_context, ivin)) != 0) 2380 * count from the completion of the authentication.
2752 return r; 2381 */
2753 } else { 2382 state->rekey_time = monotime();
2754 if ((r = kex_from_blob(m, &ssh->kex)) != 0 || 2383 /* XXX ssh_set_newkeys overrides p_read.packets? XXX */
2755 (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || 2384 if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 ||
2756 (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 || 2385 (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0)
2757 (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 ||
2758 (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 ||
2759 (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||
2760 (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||
2761 (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 ||
2762 (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 ||
2763 (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 ||
2764 (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 ||
2765 (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 ||
2766 (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)
2767 return r;
2768 /*
2769 * We set the time here so that in post-auth privsep slave we
2770 * count from the completion of the authentication.
2771 */
2772 state->rekey_time = monotime();
2773 /* XXX ssh_set_newkeys overrides p_read.packets? XXX */
2774 if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 ||
2775 (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0)
2776 return r;
2777 }
2778 if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 ||
2779 (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0)
2780 return r; 2386 return r;
2781 if (cipher_get_keycontext(state->send_context, NULL) != (int)slen ||
2782 cipher_get_keycontext(state->receive_context, NULL) != (int)rlen)
2783 return SSH_ERR_INVALID_FORMAT;
2784 cipher_set_keycontext(state->send_context, keyout);
2785 cipher_set_keycontext(state->receive_context, keyin);
2786 2387
2787 if ((r = ssh_packet_set_postauth(ssh)) != 0) 2388 if ((r = ssh_packet_set_postauth(ssh)) != 0)
2788 return r; 2389 return r;
@@ -2862,13 +2463,6 @@ sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g)
2862} 2463}
2863#endif /* OPENSSL_HAS_ECC */ 2464#endif /* OPENSSL_HAS_ECC */
2864 2465
2865#ifdef WITH_SSH1
2866int
2867sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v)
2868{
2869 return sshbuf_put_bignum1(ssh->state->outgoing_packet, v);
2870}
2871#endif /* WITH_SSH1 */
2872 2466
2873int 2467int
2874sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) 2468sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v)
@@ -2916,6 +2510,12 @@ sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp)
2916} 2510}
2917 2511
2918int 2512int
2513sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp)
2514{
2515 return sshbuf_peek_string_direct(ssh->state->incoming_packet, valp, lenp);
2516}
2517
2518int
2919sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp) 2519sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp)
2920{ 2520{
2921 return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp); 2521 return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp);
@@ -2930,13 +2530,6 @@ sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g)
2930} 2530}
2931#endif /* OPENSSL_HAS_ECC */ 2531#endif /* OPENSSL_HAS_ECC */
2932 2532
2933#ifdef WITH_SSH1
2934int
2935sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v)
2936{
2937 return sshbuf_get_bignum1(ssh->state->incoming_packet, v);
2938}
2939#endif /* WITH_SSH1 */
2940 2533
2941int 2534int
2942sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v) 2535sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v)
@@ -2966,15 +2559,13 @@ sshpkt_ptr(struct ssh *ssh, size_t *lenp)
2966int 2559int
2967sshpkt_start(struct ssh *ssh, u_char type) 2560sshpkt_start(struct ssh *ssh, u_char type)
2968{ 2561{
2969 u_char buf[9]; 2562 u_char buf[6]; /* u32 packet length, u8 pad len, u8 type */
2970 int len;
2971 2563
2972 DBG(debug("packet_start[%d]", type)); 2564 DBG(debug("packet_start[%d]", type));
2973 len = compat20 ? 6 : 9; 2565 memset(buf, 0, sizeof(buf));
2974 memset(buf, 0, len - 1); 2566 buf[sizeof(buf) - 1] = type;
2975 buf[len - 1] = type;
2976 sshbuf_reset(ssh->state->outgoing_packet); 2567 sshbuf_reset(ssh->state->outgoing_packet);
2977 return sshbuf_put(ssh->state->outgoing_packet, buf, len); 2568 return sshbuf_put(ssh->state->outgoing_packet, buf, sizeof(buf));
2978} 2569}
2979 2570
2980static int 2571static int
@@ -3007,6 +2598,37 @@ ssh_packet_send_mux(struct ssh *ssh)
3007 return 0; 2598 return 0;
3008} 2599}
3009 2600
2601/*
2602 * 9.2. Ignored Data Message
2603 *
2604 * byte SSH_MSG_IGNORE
2605 * string data
2606 *
2607 * All implementations MUST understand (and ignore) this message at any
2608 * time (after receiving the protocol version). No implementation is
2609 * required to send them. This message can be used as an additional
2610 * protection measure against advanced traffic analysis techniques.
2611 */
2612int
2613sshpkt_msg_ignore(struct ssh *ssh, u_int nbytes)
2614{
2615 u_int32_t rnd = 0;
2616 int r;
2617 u_int i;
2618
2619 if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
2620 (r = sshpkt_put_u32(ssh, nbytes)) != 0)
2621 return r;
2622 for (i = 0; i < nbytes; i++) {
2623 if (i % 4 == 0)
2624 rnd = arc4random();
2625 if ((r = sshpkt_put_u8(ssh, (u_char)rnd & 0xff)) != 0)
2626 return r;
2627 rnd >>= 8;
2628 }
2629 return 0;
2630}
2631
3010/* send it */ 2632/* send it */
3011 2633
3012int 2634int
@@ -3014,10 +2636,7 @@ sshpkt_send(struct ssh *ssh)
3014{ 2636{
3015 if (ssh->state && ssh->state->mux) 2637 if (ssh->state && ssh->state->mux)
3016 return ssh_packet_send_mux(ssh); 2638 return ssh_packet_send_mux(ssh);
3017 if (compat20) 2639 return ssh_packet_send2(ssh);
3018 return ssh_packet_send2(ssh);
3019 else
3020 return ssh_packet_send1(ssh);
3021} 2640}
3022 2641
3023int 2642int
@@ -3031,19 +2650,12 @@ sshpkt_disconnect(struct ssh *ssh, const char *fmt,...)
3031 vsnprintf(buf, sizeof(buf), fmt, args); 2650 vsnprintf(buf, sizeof(buf), fmt, args);
3032 va_end(args); 2651 va_end(args);
3033 2652
3034 if (compat20) { 2653 if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
3035 if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || 2654 (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||
3036 (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || 2655 (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
3037 (r = sshpkt_put_cstring(ssh, buf)) != 0 || 2656 (r = sshpkt_put_cstring(ssh, "")) != 0 ||
3038 (r = sshpkt_put_cstring(ssh, "")) != 0 || 2657 (r = sshpkt_send(ssh)) != 0)
3039 (r = sshpkt_send(ssh)) != 0) 2658 return r;
3040 return r;
3041 } else {
3042 if ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 ||
3043 (r = sshpkt_put_cstring(ssh, buf)) != 0 ||
3044 (r = sshpkt_send(ssh)) != 0)
3045 return r;
3046 }
3047 return 0; 2659 return 0;
3048} 2660}
3049 2661
diff --git a/packet.h b/packet.h
index 0d25b352c..40837e9db 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.h,v 1.76 2017/02/03 23:03:33 djm Exp $ */ 1/* $OpenBSD: packet.h,v 1.82 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -77,6 +77,12 @@ struct ssh {
77 TAILQ_HEAD(, key_entry) private_keys; 77 TAILQ_HEAD(, key_entry) private_keys;
78 TAILQ_HEAD(, key_entry) public_keys; 78 TAILQ_HEAD(, key_entry) public_keys;
79 79
80 /* Client/Server authentication context */
81 void *authctxt;
82
83 /* Channels context */
84 struct ssh_channels *chanctxt;
85
80 /* APP data */ 86 /* APP data */
81 void *app_data; 87 void *app_data;
82}; 88};
@@ -93,8 +99,9 @@ void ssh_packet_set_nonblocking(struct ssh *);
93int ssh_packet_get_connection_in(struct ssh *); 99int ssh_packet_get_connection_in(struct ssh *);
94int ssh_packet_get_connection_out(struct ssh *); 100int ssh_packet_get_connection_out(struct ssh *);
95void ssh_packet_close(struct ssh *); 101void ssh_packet_close(struct ssh *);
96void ssh_packet_set_encryption_key(struct ssh *, const u_char *, u_int, int);
97void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *); 102void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *);
103void ssh_packet_clear_keys(struct ssh *);
104void ssh_clear_newkeys(struct ssh *, int);
98 105
99int ssh_packet_is_rekeying(struct ssh *); 106int ssh_packet_is_rekeying(struct ssh *);
100void ssh_packet_set_protocol_flags(struct ssh *, u_int); 107void ssh_packet_set_protocol_flags(struct ssh *, u_int);
@@ -112,14 +119,12 @@ int ssh_packet_set_log_preamble(struct ssh *, const char *, ...)
112 119
113int ssh_packet_log_type(u_char); 120int ssh_packet_log_type(u_char);
114 121
115int ssh_packet_send1(struct ssh *);
116int ssh_packet_send2_wrapped(struct ssh *); 122int ssh_packet_send2_wrapped(struct ssh *);
117int ssh_packet_send2(struct ssh *); 123int ssh_packet_send2(struct ssh *);
118 124
119int ssh_packet_read(struct ssh *); 125int ssh_packet_read(struct ssh *);
120int ssh_packet_read_expect(struct ssh *, u_int type); 126int ssh_packet_read_expect(struct ssh *, u_int type);
121int ssh_packet_read_poll(struct ssh *); 127int ssh_packet_read_poll(struct ssh *);
122int ssh_packet_read_poll1(struct ssh *, u_char *);
123int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); 128int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p);
124int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); 129int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len);
125int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); 130int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p);
@@ -141,7 +146,6 @@ int ssh_packet_not_very_much_data_to_write(struct ssh *);
141 146
142int ssh_packet_connection_is_on_socket(struct ssh *); 147int ssh_packet_connection_is_on_socket(struct ssh *);
143int ssh_packet_remaining(struct ssh *); 148int ssh_packet_remaining(struct ssh *);
144void ssh_packet_send_ignore(struct ssh *, int);
145 149
146void tty_make_modes(int, struct termios *); 150void tty_make_modes(int, struct termios *);
147void tty_parse_modes(int, int *); 151void tty_parse_modes(int, int *);
@@ -172,6 +176,7 @@ int sshpkt_disconnect(struct ssh *, const char *fmt, ...)
172 __attribute__((format(printf, 2, 3))); 176 __attribute__((format(printf, 2, 3)));
173int sshpkt_add_padding(struct ssh *, u_char); 177int sshpkt_add_padding(struct ssh *, u_char);
174void sshpkt_fatal(struct ssh *ssh, const char *tag, int r); 178void sshpkt_fatal(struct ssh *ssh, const char *tag, int r);
179int sshpkt_msg_ignore(struct ssh *, u_int);
175 180
176int sshpkt_put(struct ssh *ssh, const void *v, size_t len); 181int sshpkt_put(struct ssh *ssh, const void *v, size_t len);
177int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b); 182int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b);
@@ -182,7 +187,6 @@ int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len);
182int sshpkt_put_cstring(struct ssh *ssh, const void *v); 187int sshpkt_put_cstring(struct ssh *ssh, const void *v);
183int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); 188int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v);
184int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); 189int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g);
185int sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v);
186int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); 190int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v);
187 191
188int sshpkt_get(struct ssh *ssh, void *valp, size_t len); 192int sshpkt_get(struct ssh *ssh, void *valp, size_t len);
@@ -191,9 +195,9 @@ int sshpkt_get_u32(struct ssh *ssh, u_int32_t *valp);
191int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp); 195int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp);
192int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp); 196int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp);
193int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); 197int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
198int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
194int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); 199int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp);
195int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); 200int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g);
196int sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v);
197int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v); 201int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v);
198int sshpkt_get_end(struct ssh *ssh); 202int sshpkt_get_end(struct ssh *ssh);
199const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); 203const u_char *sshpkt_ptr(struct ssh *, size_t *lenp);
diff --git a/pathnames.h b/pathnames.h
index a8deb9fc6..1c221b01b 100644
--- a/pathnames.h
+++ b/pathnames.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: pathnames.h,v 1.25 2016/03/31 05:24:06 dtucker Exp $ */ 1/* $OpenBSD: pathnames.h,v 1.27 2017/05/05 10:42:49 naddy Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -36,7 +36,6 @@
36 */ 36 */
37#define _PATH_SERVER_CONFIG_FILE SSHDIR "/sshd_config" 37#define _PATH_SERVER_CONFIG_FILE SSHDIR "/sshd_config"
38#define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config" 38#define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config"
39#define _PATH_HOST_KEY_FILE SSHDIR "/ssh_host_key"
40#define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key" 39#define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key"
41#define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key" 40#define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key"
42#define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key" 41#define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key"
@@ -72,7 +71,6 @@
72 * Name of the default file containing client-side authentication key. This 71 * Name of the default file containing client-side authentication key. This
73 * file should only be readable by the user him/herself. 72 * file should only be readable by the user him/herself.
74 */ 73 */
75#define _PATH_SSH_CLIENT_IDENTITY _PATH_SSH_USER_DIR "/identity"
76#define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR "/id_dsa" 74#define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR "/id_dsa"
77#define _PATH_SSH_CLIENT_ID_ECDSA _PATH_SSH_USER_DIR "/id_ecdsa" 75#define _PATH_SSH_CLIENT_ID_ECDSA _PATH_SSH_USER_DIR "/id_ecdsa"
78#define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa" 76#define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa"
diff --git a/platform-misc.c b/platform-misc.c
new file mode 100644
index 000000000..3f3967049
--- /dev/null
+++ b/platform-misc.c
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2006 Darren Tucker. All rights reserved.
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "includes.h"
18
19#include "openbsd-compat/openbsd-compat.h"
20
21/*
22 * return 1 if the specified uid is a uid that may own a system directory
23 * otherwise 0.
24 */
25int
26platform_sys_dir_uid(uid_t uid)
27{
28 if (uid == 0)
29 return 1;
30#ifdef PLATFORM_SYS_DIR_UID
31 if (uid == PLATFORM_SYS_DIR_UID)
32 return 1;
33#endif
34 return 0;
35}
diff --git a/platform.c b/platform.c
index 973a63e40..18c7751de 100644
--- a/platform.c
+++ b/platform.c
@@ -197,19 +197,3 @@ platform_krb5_get_principal_name(const char *pw_name)
197 return NULL; 197 return NULL;
198#endif 198#endif
199} 199}
200
201/*
202 * return 1 if the specified uid is a uid that may own a system directory
203 * otherwise 0.
204 */
205int
206platform_sys_dir_uid(uid_t uid)
207{
208 if (uid == 0)
209 return 1;
210#ifdef PLATFORM_SYS_DIR_UID
211 if (uid == PLATFORM_SYS_DIR_UID)
212 return 1;
213#endif
214 return 0;
215}
diff --git a/readconf.c b/readconf.c
index 9d59493f0..f63894f9c 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.270 2017/03/10 04:27:32 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.279 2017/09/21 19:16:53 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -152,7 +152,7 @@ typedef enum {
152 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 152 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
153 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 153 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
154 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, 154 oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
155 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 155 oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,
156 oPubkeyAuthentication, 156 oPubkeyAuthentication,
157 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 157 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
158 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 158 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
@@ -163,7 +163,8 @@ typedef enum {
163 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 163 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
164 oSendEnv, oControlPath, oControlMaster, oControlPersist, 164 oSendEnv, oControlPath, oControlMaster, oControlPersist,
165 oHashKnownHosts, 165 oHashKnownHosts,
166 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 166 oTunnel, oTunnelDevice,
167 oLocalCommand, oPermitLocalCommand, oRemoteCommand,
167 oVisualHostKey, 168 oVisualHostKey,
168 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 169 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
169 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, 170 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
@@ -171,7 +172,7 @@ typedef enum {
171 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, 172 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
172 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, 173 oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
173 oPubkeyAcceptedKeyTypes, oProxyJump, 174 oPubkeyAcceptedKeyTypes, oProxyJump,
174 oIgnoredUnknownOption, oDeprecated, oUnsupported 175 oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
175} OpCodes; 176} OpCodes;
176 177
177/* Textual representations of the tokens. */ 178/* Textual representations of the tokens. */
@@ -181,6 +182,8 @@ static struct {
181 OpCodes opcode; 182 OpCodes opcode;
182} keywords[] = { 183} keywords[] = {
183 /* Deprecated options */ 184 /* Deprecated options */
185 { "protocol", oIgnore }, /* NB. silently ignored */
186 { "cipher", oDeprecated },
184 { "fallbacktorsh", oDeprecated }, 187 { "fallbacktorsh", oDeprecated },
185 { "globalknownhostsfile2", oDeprecated }, 188 { "globalknownhostsfile2", oDeprecated },
186 { "rhostsauthentication", oDeprecated }, 189 { "rhostsauthentication", oDeprecated },
@@ -208,15 +211,9 @@ static struct {
208 { "smartcarddevice", oUnsupported }, 211 { "smartcarddevice", oUnsupported },
209 { "pkcs11provider", oUnsupported }, 212 { "pkcs11provider", oUnsupported },
210#endif 213#endif
211#ifdef WITH_SSH1
212 { "rsaauthentication", oRSAAuthentication },
213 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
214 { "compressionlevel", oCompressionLevel },
215# else
216 { "rsaauthentication", oUnsupported }, 214 { "rsaauthentication", oUnsupported },
217 { "rhostsrsaauthentication", oUnsupported }, 215 { "rhostsrsaauthentication", oUnsupported },
218 { "compressionlevel", oUnsupported }, 216 { "compressionlevel", oUnsupported },
219#endif
220 217
221 { "forwardagent", oForwardAgent }, 218 { "forwardagent", oForwardAgent },
222 { "forwardx11", oForwardX11 }, 219 { "forwardx11", oForwardX11 },
@@ -245,10 +242,8 @@ static struct {
245 { "hostkeyalias", oHostKeyAlias }, 242 { "hostkeyalias", oHostKeyAlias },
246 { "proxycommand", oProxyCommand }, 243 { "proxycommand", oProxyCommand },
247 { "port", oPort }, 244 { "port", oPort },
248 { "cipher", oCipher },
249 { "ciphers", oCiphers }, 245 { "ciphers", oCiphers },
250 { "macs", oMacs }, 246 { "macs", oMacs },
251 { "protocol", oProtocol },
252 { "remoteforward", oRemoteForward }, 247 { "remoteforward", oRemoteForward },
253 { "localforward", oLocalForward }, 248 { "localforward", oLocalForward },
254 { "user", oUser }, 249 { "user", oUser },
@@ -265,6 +260,7 @@ static struct {
265 { "tcpkeepalive", oTCPKeepAlive }, 260 { "tcpkeepalive", oTCPKeepAlive },
266 { "keepalive", oTCPKeepAlive }, /* obsolete */ 261 { "keepalive", oTCPKeepAlive }, /* obsolete */
267 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 262 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
263 { "syslogfacility", oLogFacility },
268 { "loglevel", oLogLevel }, 264 { "loglevel", oLogLevel },
269 { "dynamicforward", oDynamicForward }, 265 { "dynamicforward", oDynamicForward },
270 { "preferredauthentications", oPreferredAuthentications }, 266 { "preferredauthentications", oPreferredAuthentications },
@@ -289,6 +285,7 @@ static struct {
289 { "tunneldevice", oTunnelDevice }, 285 { "tunneldevice", oTunnelDevice },
290 { "localcommand", oLocalCommand }, 286 { "localcommand", oLocalCommand },
291 { "permitlocalcommand", oPermitLocalCommand }, 287 { "permitlocalcommand", oPermitLocalCommand },
288 { "remotecommand", oRemoteCommand },
292 { "visualhostkey", oVisualHostKey }, 289 { "visualhostkey", oVisualHostKey },
293 { "kexalgorithms", oKexAlgorithms }, 290 { "kexalgorithms", oKexAlgorithms },
294 { "ipqos", oIPQoS }, 291 { "ipqos", oIPQoS },
@@ -443,8 +440,8 @@ add_identity_file(Options *options, const char *dir, const char *filename,
443 440
444 if (dir == NULL) /* no dir, filename is absolute */ 441 if (dir == NULL) /* no dir, filename is absolute */
445 path = xstrdup(filename); 442 path = xstrdup(filename);
446 else 443 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX)
447 (void)xasprintf(&path, "%.100s%.100s", dir, filename); 444 fatal("Identity file path %s too long", path);
448 445
449 /* Avoid registering duplicates */ 446 /* Avoid registering duplicates */
450 for (i = 0; i < options->num_identity_files; i++) { 447 for (i = 0; i < options->num_identity_files; i++) {
@@ -754,6 +751,16 @@ static const struct multistate multistate_yesnoask[] = {
754 { "ask", 2 }, 751 { "ask", 2 },
755 { NULL, -1 } 752 { NULL, -1 }
756}; 753};
754static const struct multistate multistate_strict_hostkey[] = {
755 { "true", SSH_STRICT_HOSTKEY_YES },
756 { "false", SSH_STRICT_HOSTKEY_OFF },
757 { "yes", SSH_STRICT_HOSTKEY_YES },
758 { "no", SSH_STRICT_HOSTKEY_OFF },
759 { "ask", SSH_STRICT_HOSTKEY_ASK },
760 { "off", SSH_STRICT_HOSTKEY_OFF },
761 { "accept-new", SSH_STRICT_HOSTKEY_NEW },
762 { NULL, -1 }
763};
757static const struct multistate multistate_yesnoaskconfirm[] = { 764static const struct multistate multistate_yesnoaskconfirm[] = {
758 { "true", 1 }, 765 { "true", 1 },
759 { "false", 0 }, 766 { "false", 0 },
@@ -829,7 +836,9 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
829 char **cpptr, fwdarg[256]; 836 char **cpptr, fwdarg[256];
830 u_int i, *uintptr, max_entries = 0; 837 u_int i, *uintptr, max_entries = 0;
831 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0; 838 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
839 int remotefwd, dynamicfwd;
832 LogLevel *log_level_ptr; 840 LogLevel *log_level_ptr;
841 SyslogFacility *log_facility_ptr;
833 long long val64; 842 long long val64;
834 size_t len; 843 size_t len;
835 struct Forward fwd; 844 struct Forward fwd;
@@ -870,6 +879,8 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
870 case oBadOption: 879 case oBadOption:
871 /* don't panic, but count bad options */ 880 /* don't panic, but count bad options */
872 return -1; 881 return -1;
882 case oIgnore:
883 return 0;
873 case oIgnoredUnknownOption: 884 case oIgnoredUnknownOption:
874 debug("%s line %d: Ignored unknown option \"%s\"", 885 debug("%s line %d: Ignored unknown option \"%s\"",
875 filename, linenum, keyword); 886 filename, linenum, keyword);
@@ -953,14 +964,6 @@ parse_time:
953 intptr = &options->pubkey_authentication; 964 intptr = &options->pubkey_authentication;
954 goto parse_flag; 965 goto parse_flag;
955 966
956 case oRSAAuthentication:
957 intptr = &options->rsa_authentication;
958 goto parse_flag;
959
960 case oRhostsRSAAuthentication:
961 intptr = &options->rhosts_rsa_authentication;
962 goto parse_flag;
963
964 case oHostbasedAuthentication: 967 case oHostbasedAuthentication:
965 intptr = &options->hostbased_authentication; 968 intptr = &options->hostbased_authentication;
966 goto parse_flag; 969 goto parse_flag;
@@ -992,7 +995,7 @@ parse_time:
992 995
993 case oStrictHostKeyChecking: 996 case oStrictHostKeyChecking:
994 intptr = &options->strict_host_key_checking; 997 intptr = &options->strict_host_key_checking;
995 multistate_ptr = multistate_yesnoask; 998 multistate_ptr = multistate_strict_hostkey;
996 goto parse_multistate; 999 goto parse_multistate;
997 1000
998 case oCompression: 1001 case oCompression:
@@ -1011,10 +1014,6 @@ parse_time:
1011 intptr = &options->number_of_password_prompts; 1014 intptr = &options->number_of_password_prompts;
1012 goto parse_int; 1015 goto parse_int;
1013 1016
1014 case oCompressionLevel:
1015 intptr = &options->compression_level;
1016 goto parse_int;
1017
1018 case oRekeyLimit: 1017 case oRekeyLimit:
1019 arg = strdelim(&s); 1018 arg = strdelim(&s);
1020 if (!arg || *arg == '\0') 1019 if (!arg || *arg == '\0')
@@ -1177,19 +1176,6 @@ parse_int:
1177 intptr = &options->connection_attempts; 1176 intptr = &options->connection_attempts;
1178 goto parse_int; 1177 goto parse_int;
1179 1178
1180 case oCipher:
1181 intptr = &options->cipher;
1182 arg = strdelim(&s);
1183 if (!arg || *arg == '\0')
1184 fatal("%.200s line %d: Missing argument.", filename, linenum);
1185 value = cipher_number(arg);
1186 if (value == -1)
1187 fatal("%.200s line %d: Bad cipher '%s'.",
1188 filename, linenum, arg ? arg : "<NONE>");
1189 if (*activep && *intptr == -1)
1190 *intptr = value;
1191 break;
1192
1193 case oCiphers: 1179 case oCiphers:
1194 arg = strdelim(&s); 1180 arg = strdelim(&s);
1195 if (!arg || *arg == '\0') 1181 if (!arg || *arg == '\0')
@@ -1240,19 +1226,6 @@ parse_keytypes:
1240 *charptr = xstrdup(arg); 1226 *charptr = xstrdup(arg);
1241 break; 1227 break;
1242 1228
1243 case oProtocol:
1244 intptr = &options->protocol;
1245 arg = strdelim(&s);
1246 if (!arg || *arg == '\0')
1247 fatal("%.200s line %d: Missing argument.", filename, linenum);
1248 value = proto_spec(arg);
1249 if (value == SSH_PROTO_UNKNOWN)
1250 fatal("%.200s line %d: Bad protocol spec '%s'.",
1251 filename, linenum, arg ? arg : "<NONE>");
1252 if (*activep && *intptr == SSH_PROTO_UNKNOWN)
1253 *intptr = value;
1254 break;
1255
1256 case oLogLevel: 1229 case oLogLevel:
1257 log_level_ptr = &options->log_level; 1230 log_level_ptr = &options->log_level;
1258 arg = strdelim(&s); 1231 arg = strdelim(&s);
@@ -1264,6 +1237,17 @@ parse_keytypes:
1264 *log_level_ptr = (LogLevel) value; 1237 *log_level_ptr = (LogLevel) value;
1265 break; 1238 break;
1266 1239
1240 case oLogFacility:
1241 log_facility_ptr = &options->log_facility;
1242 arg = strdelim(&s);
1243 value = log_facility_number(arg);
1244 if (value == SYSLOG_FACILITY_NOT_SET)
1245 fatal("%.200s line %d: unsupported log facility '%s'",
1246 filename, linenum, arg ? arg : "<NONE>");
1247 if (*log_facility_ptr == -1)
1248 *log_facility_ptr = (SyslogFacility) value;
1249 break;
1250
1267 case oLocalForward: 1251 case oLocalForward:
1268 case oRemoteForward: 1252 case oRemoteForward:
1269 case oDynamicForward: 1253 case oDynamicForward:
@@ -1272,31 +1256,36 @@ parse_keytypes:
1272 fatal("%.200s line %d: Missing port argument.", 1256 fatal("%.200s line %d: Missing port argument.",
1273 filename, linenum); 1257 filename, linenum);
1274 1258
1275 if (opcode == oLocalForward || 1259 remotefwd = (opcode == oRemoteForward);
1276 opcode == oRemoteForward) { 1260 dynamicfwd = (opcode == oDynamicForward);
1277 arg2 = strdelim(&s);
1278 if (arg2 == NULL || *arg2 == '\0')
1279 fatal("%.200s line %d: Missing target argument.",
1280 filename, linenum);
1281 1261
1282 /* construct a string for parse_forward */ 1262 if (!dynamicfwd) {
1283 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); 1263 arg2 = strdelim(&s);
1284 } else if (opcode == oDynamicForward) { 1264 if (arg2 == NULL || *arg2 == '\0') {
1285 strlcpy(fwdarg, arg, sizeof(fwdarg)); 1265 if (remotefwd)
1266 dynamicfwd = 1;
1267 else
1268 fatal("%.200s line %d: Missing target "
1269 "argument.", filename, linenum);
1270 } else {
1271 /* construct a string for parse_forward */
1272 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1273 arg2);
1274 }
1286 } 1275 }
1276 if (dynamicfwd)
1277 strlcpy(fwdarg, arg, sizeof(fwdarg));
1287 1278
1288 if (parse_forward(&fwd, fwdarg, 1279 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
1289 opcode == oDynamicForward ? 1 : 0,
1290 opcode == oRemoteForward ? 1 : 0) == 0)
1291 fatal("%.200s line %d: Bad forwarding specification.", 1280 fatal("%.200s line %d: Bad forwarding specification.",
1292 filename, linenum); 1281 filename, linenum);
1293 1282
1294 if (*activep) { 1283 if (*activep) {
1295 if (opcode == oLocalForward || 1284 if (remotefwd) {
1296 opcode == oDynamicForward)
1297 add_local_forward(options, &fwd);
1298 else if (opcode == oRemoteForward)
1299 add_remote_forward(options, &fwd); 1285 add_remote_forward(options, &fwd);
1286 } else {
1287 add_local_forward(options, &fwd);
1288 }
1300 } 1289 }
1301 break; 1290 break;
1302 1291
@@ -1469,6 +1458,10 @@ parse_keytypes:
1469 intptr = &options->permit_local_command; 1458 intptr = &options->permit_local_command;
1470 goto parse_flag; 1459 goto parse_flag;
1471 1460
1461 case oRemoteCommand:
1462 charptr = &options->remote_command;
1463 goto parse_command;
1464
1472 case oVisualHostKey: 1465 case oVisualHostKey:
1473 intptr = &options->visual_host_key; 1466 intptr = &options->visual_host_key;
1474 goto parse_flag; 1467 goto parse_flag;
@@ -1794,7 +1787,6 @@ initialize_options(Options * options)
1794 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; 1787 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1795 options->fwd_opts.streamlocal_bind_unlink = -1; 1788 options->fwd_opts.streamlocal_bind_unlink = -1;
1796 options->use_privileged_port = -1; 1789 options->use_privileged_port = -1;
1797 options->rsa_authentication = -1;
1798 options->pubkey_authentication = -1; 1790 options->pubkey_authentication = -1;
1799 options->challenge_response_authentication = -1; 1791 options->challenge_response_authentication = -1;
1800 options->gss_authentication = -1; 1792 options->gss_authentication = -1;
@@ -1802,25 +1794,21 @@ initialize_options(Options * options)
1802 options->password_authentication = -1; 1794 options->password_authentication = -1;
1803 options->kbd_interactive_authentication = -1; 1795 options->kbd_interactive_authentication = -1;
1804 options->kbd_interactive_devices = NULL; 1796 options->kbd_interactive_devices = NULL;
1805 options->rhosts_rsa_authentication = -1;
1806 options->hostbased_authentication = -1; 1797 options->hostbased_authentication = -1;
1807 options->batch_mode = -1; 1798 options->batch_mode = -1;
1808 options->check_host_ip = -1; 1799 options->check_host_ip = -1;
1809 options->strict_host_key_checking = -1; 1800 options->strict_host_key_checking = -1;
1810 options->compression = -1; 1801 options->compression = -1;
1811 options->tcp_keep_alive = -1; 1802 options->tcp_keep_alive = -1;
1812 options->compression_level = -1;
1813 options->port = -1; 1803 options->port = -1;
1814 options->address_family = -1; 1804 options->address_family = -1;
1815 options->connection_attempts = -1; 1805 options->connection_attempts = -1;
1816 options->connection_timeout = -1; 1806 options->connection_timeout = -1;
1817 options->number_of_password_prompts = -1; 1807 options->number_of_password_prompts = -1;
1818 options->cipher = -1;
1819 options->ciphers = NULL; 1808 options->ciphers = NULL;
1820 options->macs = NULL; 1809 options->macs = NULL;
1821 options->kex_algorithms = NULL; 1810 options->kex_algorithms = NULL;
1822 options->hostkeyalgorithms = NULL; 1811 options->hostkeyalgorithms = NULL;
1823 options->protocol = SSH_PROTO_UNKNOWN;
1824 options->num_identity_files = 0; 1812 options->num_identity_files = 0;
1825 options->num_certificate_files = 0; 1813 options->num_certificate_files = 0;
1826 options->hostname = NULL; 1814 options->hostname = NULL;
@@ -1838,6 +1826,7 @@ initialize_options(Options * options)
1838 options->num_local_forwards = 0; 1826 options->num_local_forwards = 0;
1839 options->remote_forwards = NULL; 1827 options->remote_forwards = NULL;
1840 options->num_remote_forwards = 0; 1828 options->num_remote_forwards = 0;
1829 options->log_facility = SYSLOG_FACILITY_NOT_SET;
1841 options->log_level = SYSLOG_LEVEL_NOT_SET; 1830 options->log_level = SYSLOG_LEVEL_NOT_SET;
1842 options->preferred_authentications = NULL; 1831 options->preferred_authentications = NULL;
1843 options->bind_address = NULL; 1832 options->bind_address = NULL;
@@ -1861,6 +1850,7 @@ initialize_options(Options * options)
1861 options->tun_remote = -1; 1850 options->tun_remote = -1;
1862 options->local_command = NULL; 1851 options->local_command = NULL;
1863 options->permit_local_command = -1; 1852 options->permit_local_command = -1;
1853 options->remote_command = NULL;
1864 options->add_keys_to_agent = -1; 1854 options->add_keys_to_agent = -1;
1865 options->identity_agent = NULL; 1855 options->identity_agent = NULL;
1866 options->visual_host_key = -1; 1856 options->visual_host_key = -1;
@@ -1934,8 +1924,6 @@ fill_default_options(Options * options)
1934 options->fwd_opts.streamlocal_bind_unlink = 0; 1924 options->fwd_opts.streamlocal_bind_unlink = 0;
1935 if (options->use_privileged_port == -1) 1925 if (options->use_privileged_port == -1)
1936 options->use_privileged_port = 0; 1926 options->use_privileged_port = 0;
1937 if (options->rsa_authentication == -1)
1938 options->rsa_authentication = 1;
1939 if (options->pubkey_authentication == -1) 1927 if (options->pubkey_authentication == -1)
1940 options->pubkey_authentication = 1; 1928 options->pubkey_authentication = 1;
1941 if (options->challenge_response_authentication == -1) 1929 if (options->challenge_response_authentication == -1)
@@ -1948,8 +1936,6 @@ fill_default_options(Options * options)
1948 options->password_authentication = 1; 1936 options->password_authentication = 1;
1949 if (options->kbd_interactive_authentication == -1) 1937 if (options->kbd_interactive_authentication == -1)
1950 options->kbd_interactive_authentication = 1; 1938 options->kbd_interactive_authentication = 1;
1951 if (options->rhosts_rsa_authentication == -1)
1952 options->rhosts_rsa_authentication = 0;
1953 if (options->hostbased_authentication == -1) 1939 if (options->hostbased_authentication == -1)
1954 options->hostbased_authentication = 0; 1940 options->hostbased_authentication = 0;
1955 if (options->batch_mode == -1) 1941 if (options->batch_mode == -1)
@@ -1957,13 +1943,11 @@ fill_default_options(Options * options)
1957 if (options->check_host_ip == -1) 1943 if (options->check_host_ip == -1)
1958 options->check_host_ip = 1; 1944 options->check_host_ip = 1;
1959 if (options->strict_host_key_checking == -1) 1945 if (options->strict_host_key_checking == -1)
1960 options->strict_host_key_checking = 2; /* 2 is default */ 1946 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
1961 if (options->compression == -1) 1947 if (options->compression == -1)
1962 options->compression = 0; 1948 options->compression = 0;
1963 if (options->tcp_keep_alive == -1) 1949 if (options->tcp_keep_alive == -1)
1964 options->tcp_keep_alive = 1; 1950 options->tcp_keep_alive = 1;
1965 if (options->compression_level == -1)
1966 options->compression_level = 6;
1967 if (options->port == -1) 1951 if (options->port == -1)
1968 options->port = 0; /* Filled in ssh_connect. */ 1952 options->port = 0; /* Filled in ssh_connect. */
1969 if (options->address_family == -1) 1953 if (options->address_family == -1)
@@ -1972,31 +1956,17 @@ fill_default_options(Options * options)
1972 options->connection_attempts = 1; 1956 options->connection_attempts = 1;
1973 if (options->number_of_password_prompts == -1) 1957 if (options->number_of_password_prompts == -1)
1974 options->number_of_password_prompts = 3; 1958 options->number_of_password_prompts = 3;
1975 /* Selected in ssh_login(). */
1976 if (options->cipher == -1)
1977 options->cipher = SSH_CIPHER_NOT_SET;
1978 /* options->hostkeyalgorithms, default set in myproposals.h */ 1959 /* options->hostkeyalgorithms, default set in myproposals.h */
1979 if (options->protocol == SSH_PROTO_UNKNOWN)
1980 options->protocol = SSH_PROTO_2;
1981 if (options->add_keys_to_agent == -1) 1960 if (options->add_keys_to_agent == -1)
1982 options->add_keys_to_agent = 0; 1961 options->add_keys_to_agent = 0;
1983 if (options->num_identity_files == 0) { 1962 if (options->num_identity_files == 0) {
1984 if (options->protocol & SSH_PROTO_1) { 1963 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
1985 add_identity_file(options, "~/", 1964 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
1986 _PATH_SSH_CLIENT_IDENTITY, 0);
1987 }
1988 if (options->protocol & SSH_PROTO_2) {
1989 add_identity_file(options, "~/",
1990 _PATH_SSH_CLIENT_ID_RSA, 0);
1991 add_identity_file(options, "~/",
1992 _PATH_SSH_CLIENT_ID_DSA, 0);
1993#ifdef OPENSSL_HAS_ECC 1965#ifdef OPENSSL_HAS_ECC
1994 add_identity_file(options, "~/", 1966 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
1995 _PATH_SSH_CLIENT_ID_ECDSA, 0);
1996#endif 1967#endif
1997 add_identity_file(options, "~/", 1968 add_identity_file(options, "~/",
1998 _PATH_SSH_CLIENT_ID_ED25519, 0); 1969 _PATH_SSH_CLIENT_ID_ED25519, 0);
1999 }
2000 } 1970 }
2001 if (options->escape_char == -1) 1971 if (options->escape_char == -1)
2002 options->escape_char = '~'; 1972 options->escape_char = '~';
@@ -2014,6 +1984,8 @@ fill_default_options(Options * options)
2014 } 1984 }
2015 if (options->log_level == SYSLOG_LEVEL_NOT_SET) 1985 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2016 options->log_level = SYSLOG_LEVEL_INFO; 1986 options->log_level = SYSLOG_LEVEL_INFO;
1987 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
1988 options->log_facility = SYSLOG_FACILITY_USER;
2017 if (options->no_host_authentication_for_localhost == - 1) 1989 if (options->no_host_authentication_for_localhost == - 1)
2018 options->no_host_authentication_for_localhost = 0; 1990 options->no_host_authentication_for_localhost = 0;
2019 if (options->identities_only == -1) 1991 if (options->identities_only == -1)
@@ -2083,6 +2055,7 @@ fill_default_options(Options * options)
2083 } \ 2055 } \
2084 } while(0) 2056 } while(0)
2085 CLEAR_ON_NONE(options->local_command); 2057 CLEAR_ON_NONE(options->local_command);
2058 CLEAR_ON_NONE(options->remote_command);
2086 CLEAR_ON_NONE(options->proxy_command); 2059 CLEAR_ON_NONE(options->proxy_command);
2087 CLEAR_ON_NONE(options->control_path); 2060 CLEAR_ON_NONE(options->control_path);
2088 CLEAR_ON_NONE(options->revoked_host_keys); 2061 CLEAR_ON_NONE(options->revoked_host_keys);
@@ -2372,9 +2345,10 @@ fmt_intarg(OpCodes code, int val)
2372 case oAddressFamily: 2345 case oAddressFamily:
2373 return fmt_multistate_int(val, multistate_addressfamily); 2346 return fmt_multistate_int(val, multistate_addressfamily);
2374 case oVerifyHostKeyDNS: 2347 case oVerifyHostKeyDNS:
2375 case oStrictHostKeyChecking:
2376 case oUpdateHostkeys: 2348 case oUpdateHostkeys:
2377 return fmt_multistate_int(val, multistate_yesnoask); 2349 return fmt_multistate_int(val, multistate_yesnoask);
2350 case oStrictHostKeyChecking:
2351 return fmt_multistate_int(val, multistate_strict_hostkey);
2378 case oControlMaster: 2352 case oControlMaster:
2379 return fmt_multistate_int(val, multistate_controlmaster); 2353 return fmt_multistate_int(val, multistate_controlmaster);
2380 case oTunnel: 2354 case oTunnel:
@@ -2385,17 +2359,6 @@ fmt_intarg(OpCodes code, int val)
2385 return fmt_multistate_int(val, multistate_canonicalizehostname); 2359 return fmt_multistate_int(val, multistate_canonicalizehostname);
2386 case oFingerprintHash: 2360 case oFingerprintHash:
2387 return ssh_digest_alg_name(val); 2361 return ssh_digest_alg_name(val);
2388 case oProtocol:
2389 switch (val) {
2390 case SSH_PROTO_1:
2391 return "1";
2392 case SSH_PROTO_2:
2393 return "2";
2394 case (SSH_PROTO_1|SSH_PROTO_2):
2395 return "2,1";
2396 default:
2397 return "UNKNOWN";
2398 }
2399 default: 2362 default:
2400 switch (val) { 2363 switch (val) {
2401 case 0: 2364 case 0:
@@ -2540,14 +2503,9 @@ dump_client_config(Options *o, const char *host)
2540 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); 2503 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
2541 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication); 2504 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
2542 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command); 2505 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
2543 dump_cfg_fmtint(oProtocol, o->protocol);
2544 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass); 2506 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
2545 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication); 2507 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
2546 dump_cfg_fmtint(oRequestTTY, o->request_tty); 2508 dump_cfg_fmtint(oRequestTTY, o->request_tty);
2547#ifdef WITH_RSA1
2548 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
2549 dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
2550#endif
2551 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 2509 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2552 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); 2510 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
2553 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); 2511 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
@@ -2559,9 +2517,6 @@ dump_client_config(Options *o, const char *host)
2559 2517
2560 /* Integer options */ 2518 /* Integer options */
2561 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); 2519 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
2562#ifdef WITH_SSH1
2563 dump_cfg_int(oCompressionLevel, o->compression_level);
2564#endif
2565 dump_cfg_int(oConnectionAttempts, o->connection_attempts); 2520 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
2566 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); 2521 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
2567 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); 2522 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
@@ -2579,6 +2534,7 @@ dump_client_config(Options *o, const char *host)
2579 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); 2534 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
2580 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); 2535 dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX);
2581 dump_cfg_string(oLocalCommand, o->local_command); 2536 dump_cfg_string(oLocalCommand, o->local_command);
2537 dump_cfg_string(oRemoteCommand, o->remote_command);
2582 dump_cfg_string(oLogLevel, log_level_name(o->log_level)); 2538 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
2583 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); 2539 dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC);
2584#ifdef ENABLE_PKCS11 2540#ifdef ENABLE_PKCS11
@@ -2631,10 +2587,6 @@ dump_client_config(Options *o, const char *host)
2631 printf("\n"); 2587 printf("\n");
2632 } 2588 }
2633 2589
2634 /* oCipher */
2635 if (o->cipher != SSH_CIPHER_NOT_SET)
2636 printf("Cipher %s\n", cipher_name(o->cipher));
2637
2638 /* oControlPersist */ 2590 /* oControlPersist */
2639 if (o->control_persist == 0 || o->control_persist_timeout == 0) 2591 if (o->control_persist == 0 || o->control_persist_timeout == 0)
2640 dump_cfg_fmtint(oControlPersist, o->control_persist); 2592 dump_cfg_fmtint(oControlPersist, o->control_persist);
diff --git a/readconf.h b/readconf.h
index cef55f71c..22fe5c187 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.117 2016/07/15 00:24:30 djm Exp $ */ 1/* $OpenBSD: readconf.h,v 1.123 2017/09/03 23:33:13 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,9 +37,6 @@ typedef struct {
37 char *xauth_location; /* Location for xauth program */ 37 char *xauth_location; /* Location for xauth program */
38 struct ForwardOptions fwd_opts; /* forwarding options */ 38 struct ForwardOptions fwd_opts; /* forwarding options */
39 int use_privileged_port; /* Don't use privileged port if false. */ 39 int use_privileged_port; /* Don't use privileged port if false. */
40 int rhosts_rsa_authentication; /* Try rhosts with RSA
41 * authentication. */
42 int rsa_authentication; /* Try RSA authentication. */
43 int pubkey_authentication; /* Try ssh2 pubkey authentication. */ 40 int pubkey_authentication; /* Try ssh2 pubkey authentication. */
44 int hostbased_authentication; /* ssh2's rhosts_rsa */ 41 int hostbased_authentication; /* ssh2's rhosts_rsa */
45 int challenge_response_authentication; 42 int challenge_response_authentication;
@@ -54,11 +51,10 @@ typedef struct {
54 int check_host_ip; /* Also keep track of keys for IP address */ 51 int check_host_ip; /* Also keep track of keys for IP address */
55 int strict_host_key_checking; /* Strict host key checking. */ 52 int strict_host_key_checking; /* Strict host key checking. */
56 int compression; /* Compress packets in both directions. */ 53 int compression; /* Compress packets in both directions. */
57 int compression_level; /* Compression level 1 (fast) to 9
58 * (best). */
59 int tcp_keep_alive; /* Set SO_KEEPALIVE. */ 54 int tcp_keep_alive; /* Set SO_KEEPALIVE. */
60 int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ 55 int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */
61 int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ 56 int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */
57 SyslogFacility log_facility; /* Facility for system logging. */
62 LogLevel log_level; /* Level for logging. */ 58 LogLevel log_level; /* Level for logging. */
63 59
64 int port; /* Port to connect. */ 60 int port; /* Port to connect. */
@@ -69,12 +65,10 @@ typedef struct {
69 * aborting connection attempt */ 65 * aborting connection attempt */
70 int number_of_password_prompts; /* Max number of password 66 int number_of_password_prompts; /* Max number of password
71 * prompts. */ 67 * prompts. */
72 int cipher; /* Cipher to use. */
73 char *ciphers; /* SSH2 ciphers in order of preference. */ 68 char *ciphers; /* SSH2 ciphers in order of preference. */
74 char *macs; /* SSH2 macs in order of preference. */ 69 char *macs; /* SSH2 macs in order of preference. */
75 char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */ 70 char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */
76 char *kex_algorithms; /* SSH2 kex methods in order of preference. */ 71 char *kex_algorithms; /* SSH2 kex methods in order of preference. */
77 int protocol; /* Protocol in order of preference. */
78 char *hostname; /* Real host to connect. */ 72 char *hostname; /* Real host to connect. */
79 char *host_key_alias; /* hostname alias for .ssh/known_hosts */ 73 char *host_key_alias; /* hostname alias for .ssh/known_hosts */
80 char *proxy_command; /* Proxy command for connecting the host. */ 74 char *proxy_command; /* Proxy command for connecting the host. */
@@ -140,6 +134,7 @@ typedef struct {
140 134
141 char *local_command; 135 char *local_command;
142 int permit_local_command; 136 int permit_local_command;
137 char *remote_command;
143 int visual_host_key; 138 int visual_host_key;
144 139
145 int request_tty; 140 int request_tty;
@@ -195,6 +190,11 @@ typedef struct {
195#define SSH_UPDATE_HOSTKEYS_YES 1 190#define SSH_UPDATE_HOSTKEYS_YES 1
196#define SSH_UPDATE_HOSTKEYS_ASK 2 191#define SSH_UPDATE_HOSTKEYS_ASK 2
197 192
193#define SSH_STRICT_HOSTKEY_OFF 0
194#define SSH_STRICT_HOSTKEY_NEW 1
195#define SSH_STRICT_HOSTKEY_YES 2
196#define SSH_STRICT_HOSTKEY_ASK 3
197
198void initialize_options(Options *); 198void initialize_options(Options *);
199void fill_default_options(Options *); 199void fill_default_options(Options *);
200void fill_default_options_for_canonicalization(Options *); 200void fill_default_options_for_canonicalization(Options *);
diff --git a/regress/Makefile b/regress/Makefile
index b23496b98..7d50f9cfa 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.94 2016/12/16 03:51:19 dtucker Exp $ 1# $OpenBSD: Makefile,v 1.95 2017/06/24 06:35:24 djm Exp $
2 2
3REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec 3REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec
4tests: prep $(REGRESS_TARGETS) 4tests: prep $(REGRESS_TARGETS)
@@ -79,7 +79,8 @@ LTESTS= connect \
79 principals-command \ 79 principals-command \
80 cert-file \ 80 cert-file \
81 cfginclude \ 81 cfginclude \
82 allow-deny-users 82 allow-deny-users \
83 authinfo
83 84
84 85
85# dhgex \ 86# dhgex \
@@ -89,30 +90,33 @@ INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
89 90
90#LTESTS= cipher-speed 91#LTESTS= cipher-speed
91 92
92USERNAME!= id -un 93USERNAME= ${LOGNAME}
93CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ 94CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \
94 authorized_keys_${USERNAME}.* \ 95 authorized_keys_${USERNAME}.* \
95 authorized_principals_${USERNAME} \ 96 authorized_principals_${USERNAME} \
96 banner.in banner.out cert_host_key* cert_user_key* \ 97 banner.in banner.out cert_host_key* cert_user_key* \
97 copy.1 copy.2 data ed25519-agent ed25519-agent* \ 98 copy.1 copy.2 data ed25519-agent ed25519-agent* \
98 ed25519-agent.pub empty.in expect failed-regress.log \ 99 ed25519-agent.pub ed25519 ed25519.pub empty.in \
99 failed-ssh.log failed-sshd.log hkr.* host.rsa host.rsa1 \ 100 expect failed-regress.log failed-ssh.log failed-sshd.log \
100 host_* host_ca_key* host_krl_* host_revoked_* key.* \ 101 hkr.* host.ed25519 host.rsa host.rsa1 host_* \
101 key.dsa-* key.ecdsa-* key.ed25519-512 key.ed25519-512.pub \ 102 host_ca_key* host_krl_* host_revoked_* key.* \
102 key.rsa-* keys-command-args kh.* known_hosts \ 103 key.dsa-* key.ecdsa-* key.ed25519-512 \
103 known_hosts-cert known_hosts.* krl-* ls.copy modpipe \ 104 key.ed25519-512.pub key.rsa-* keys-command-args kh.* \
104 netcat pidfile putty.rsa2 ready regress.log remote_pid \ 105 known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \
105 revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa1 \ 106 modpipe netcat no_identity_config \
106 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \ 107 pidfile putty.rsa2 ready regress.log \
108 remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \
109 rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \
107 rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ 110 rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \
108 scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ 111 scp-ssh-wrapper.scp setuid-allowed sftp-server.log \
109 sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ 112 sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \
110 ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ 113 ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \
111 ssh_proxy_envpass sshd.log sshd_config sshd_config.orig \ 114 ssh_proxy_envpass sshd.log sshd_config sshd_config_minimal \
112 sshd_proxy sshd_proxy.* sshd_proxy_bak sshd_proxy_orig \ 115 sshd_config.orig sshd_proxy sshd_proxy.* sshd_proxy_bak \
113 t10.out t10.out.pub t12.out t12.out.pub t2.out t3.out \ 116 sshd_proxy_orig t10.out t10.out.pub t12.out t12.out.pub \
114 t6.out1 t6.out2 t7.out t7.out.pub t8.out t8.out.pub \ 117 t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \
115 t9.out t9.out.pub testdata user_*key* user_ca* user_key* 118 t8.out t8.out.pub t9.out t9.out.pub testdata \
119 user_*key* user_ca* user_key*
116 120
117SUDO_CLEAN+= /var/run/testdata_${USERNAME} /var/run/keycommand_${USERNAME} 121SUDO_CLEAN+= /var/run/testdata_${USERNAME} /var/run/keycommand_${USERNAME}
118 122
diff --git a/regress/agent-getpeereid.sh b/regress/agent-getpeereid.sh
index 34bced154..037a50914 100644
--- a/regress/agent-getpeereid.sh
+++ b/regress/agent-getpeereid.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: agent-getpeereid.sh,v 1.8 2017/01/06 02:51:16 djm Exp $ 1# $OpenBSD: agent-getpeereid.sh,v 1.9 2017/09/13 14:58:26 bluhm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="disallow agent attach from other uid" 4tid="disallow agent attach from other uid"
diff --git a/regress/agent-pkcs11.sh b/regress/agent-pkcs11.sh
index 3aa20c8b1..db3018b88 100644
--- a/regress/agent-pkcs11.sh
+++ b/regress/agent-pkcs11.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: agent-pkcs11.sh,v 1.2 2015/01/12 11:46:32 djm Exp $ 1# $OpenBSD: agent-pkcs11.sh,v 1.3 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="pkcs11 agent test" 4tid="pkcs11 agent test"
@@ -53,7 +53,7 @@ else
53 fi 53 fi
54 54
55 trace "pkcs11 connect via agent" 55 trace "pkcs11 connect via agent"
56 ${SSH} -2 -F $OBJ/ssh_proxy somehost exit 5 56 ${SSH} -F $OBJ/ssh_proxy somehost exit 5
57 r=$? 57 r=$?
58 if [ $r -ne 5 ]; then 58 if [ $r -ne 5 ]; then
59 fail "ssh connect failed (exit code $r)" 59 fail "ssh connect failed (exit code $r)"
diff --git a/regress/agent.sh b/regress/agent.sh
index c5e2794b7..0baf0c74a 100644
--- a/regress/agent.sh
+++ b/regress/agent.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: agent.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: agent.sh,v 1.12 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="simple agent test" 4tid="simple agent test"
@@ -46,28 +46,24 @@ else
46 fi 46 fi
47 47
48 trace "simple connect via agent" 48 trace "simple connect via agent"
49 for p in ${SSH_PROTOCOLS}; do 49 ${SSH} -F $OBJ/ssh_proxy somehost exit 52
50 ${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p 50 r=$?
51 r=$? 51 if [ $r -ne 52 ]; then
52 if [ $r -ne 5$p ]; then 52 fail "ssh connect with failed (exit code $r)"
53 fail "ssh connect with protocol $p failed (exit code $r)" 53 fi
54 fi
55 done
56 54
57 trace "agent forwarding" 55 trace "agent forwarding"
58 for p in ${SSH_PROTOCOLS}; do 56 ${SSH} -A -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 57 r=$?
60 r=$? 58 if [ $r -ne 0 ]; then
61 if [ $r -ne 0 ]; then 59 fail "ssh-add -l via agent fwd failed (exit code $r)"
62 fail "ssh-add -l via agent fwd proto $p failed (exit code $r)" 60 fi
63 fi 61 ${SSH} -A -F $OBJ/ssh_proxy somehost \
64 ${SSH} -A -$p -F $OBJ/ssh_proxy somehost \ 62 "${SSH} -F $OBJ/ssh_proxy somehost exit 52"
65 "${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p" 63 r=$?
66 r=$? 64 if [ $r -ne 52 ]; then
67 if [ $r -ne 5$p ]; then 65 fail "agent fwd failed (exit code $r)"
68 fail "agent fwd proto $p failed (exit code $r)" 66 fi
69 fi
70 done
71 67
72 trace "delete all agent keys" 68 trace "delete all agent keys"
73 ${SSHADD} -D > /dev/null 2>&1 69 ${SSHADD} -D > /dev/null 2>&1
diff --git a/regress/authinfo.sh b/regress/authinfo.sh
new file mode 100644
index 000000000..e725296c9
--- /dev/null
+++ b/regress/authinfo.sh
@@ -0,0 +1,17 @@
1# $OpenBSD: authinfo.sh,v 1.1 2017/06/24 06:35:24 djm Exp $
2# Placed in the Public Domain.
3
4tid="authinfo"
5
6# Ensure the environment variable doesn't leak when ExposeAuthInfo=no.
7verbose "ExposeAuthInfo=no"
8env SSH_USER_AUTH=blah ${SSH} -F $OBJ/ssh_proxy x \
9 'test -z "$SSH_USER_AUTH"' || fail "SSH_USER_AUTH present"
10
11verbose "ExposeAuthInfo=yes"
12echo ExposeAuthInfo=yes >> $OBJ/sshd_proxy
13${SSH} -F $OBJ/ssh_proxy x \
14 'grep ^publickey "$SSH_USER_AUTH" /dev/null >/dev/null' ||
15 fail "ssh with ExposeAuthInfo failed"
16
17# XXX test multiple auth and key contents
diff --git a/regress/banner.sh b/regress/banner.sh
index 0b9c95007..0d9654fe2 100644
--- a/regress/banner.sh
+++ b/regress/banner.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: banner.sh,v 1.2 2003/10/11 11:49:49 dtucker Exp $ 1# $OpenBSD: banner.sh,v 1.3 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="banner" 4tid="banner"
@@ -9,7 +9,7 @@ touch $OBJ/empty.in
9 9
10trace "test missing banner file" 10trace "test missing banner file"
11verbose "test $tid: missing banner file" 11verbose "test $tid: missing banner file"
12( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \ 12( ${SSH} -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
13 cmp $OBJ/empty.in $OBJ/banner.out ) || \ 13 cmp $OBJ/empty.in $OBJ/banner.out ) || \
14 fail "missing banner file" 14 fail "missing banner file"
15 15
@@ -30,14 +30,14 @@ for s in 0 10 100 1000 10000 100000 ; do
30 30
31 trace "test banner size $s" 31 trace "test banner size $s"
32 verbose "test $tid: size $s" 32 verbose "test $tid: size $s"
33 ( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \ 33 ( ${SSH} -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
34 cmp $OBJ/banner.in $OBJ/banner.out ) || \ 34 cmp $OBJ/banner.in $OBJ/banner.out ) || \
35 fail "banner size $s mismatch" 35 fail "banner size $s mismatch"
36done 36done
37 37
38trace "test suppress banner (-q)" 38trace "test suppress banner (-q)"
39verbose "test $tid: suppress banner (-q)" 39verbose "test $tid: suppress banner (-q)"
40( ${SSH} -q -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \ 40( ${SSH} -q -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
41 cmp $OBJ/empty.in $OBJ/banner.out ) || \ 41 cmp $OBJ/empty.in $OBJ/banner.out ) || \
42 fail "suppress banner (-q)" 42 fail "suppress banner (-q)"
43 43
diff --git a/regress/broken-pipe.sh b/regress/broken-pipe.sh
index a416f7a3b..c69276e27 100644
--- a/regress/broken-pipe.sh
+++ b/regress/broken-pipe.sh
@@ -1,15 +1,12 @@
1# $OpenBSD: broken-pipe.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: broken-pipe.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="broken pipe test" 4tid="broken pipe test"
5 5
6for p in ${SSH_PROTOCOLS}; do 6for i in 1 2 3 4; do
7 trace "protocol $p" 7 ${SSH} -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true
8 for i in 1 2 3 4; do 8 r=$?
9 ${SSH} -$p -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true 9 if [ $r -ne 0 ]; then
10 r=$? 10 fail "broken pipe returns $r"
11 if [ $r -ne 0 ]; then 11 fi
12 fail "broken pipe returns $r for protocol $p"
13 fi
14 done
15done 12done
diff --git a/regress/brokenkeys.sh b/regress/brokenkeys.sh
index 3e70c348a..9d5a54fa9 100644
--- a/regress/brokenkeys.sh
+++ b/regress/brokenkeys.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: brokenkeys.sh,v 1.1 2004/10/29 23:59:22 djm Exp $ 1# $OpenBSD: brokenkeys.sh,v 1.2 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="broken keys" 4tid="broken keys"
@@ -14,9 +14,9 @@ echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEABTM= bad key" > $KEYS
14cat ${KEYS}.bak >> ${KEYS} 14cat ${KEYS}.bak >> ${KEYS}
15cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER 15cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
16 16
17${SSH} -2 -F $OBJ/ssh_config somehost true 17${SSH} -F $OBJ/ssh_config somehost true
18if [ $? -ne 0 ]; then 18if [ $? -ne 0 ]; then
19 fail "ssh connect with protocol $p failed" 19 fail "ssh connect with failed"
20fi 20fi
21 21
22mv ${KEYS}.bak ${KEYS} 22mv ${KEYS}.bak ${KEYS}
diff --git a/regress/cert-file.sh b/regress/cert-file.sh
index 43b8e0201..8fd62c773 100644
--- a/regress/cert-file.sh
+++ b/regress/cert-file.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: cert-file.sh,v 1.5 2017/03/11 23:44:16 djm Exp $ 1# $OpenBSD: cert-file.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="ssh with certificates" 4tid="ssh with certificates"
@@ -54,66 +54,64 @@ cat $OBJ/ssh_proxy | grep -v IdentityFile > $OBJ/no_identity_config
54# XXX: verify that certificate used was what we expect. Needs exposure of 54# XXX: verify that certificate used was what we expect. Needs exposure of
55# keys via enviornment variable or similar. 55# keys via enviornment variable or similar.
56 56
57for p in ${SSH_PROTOCOLS}; do
58 # Key with no .pub should work - finding the equivalent *-cert.pub. 57 # Key with no .pub should work - finding the equivalent *-cert.pub.
59 verbose "protocol $p: identity cert with no plain public file" 58verbose "identity cert with no plain public file"
60 ${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \ 59${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
61 -i $OBJ/user_key3 somehost exit 5$p 60 -i $OBJ/user_key3 somehost exit 52
62 [ $? -ne 5$p ] && fail "ssh failed" 61[ $? -ne 52 ] && fail "ssh failed"
63 62
64 # CertificateFile matching private key with no .pub file should work. 63# CertificateFile matching private key with no .pub file should work.
65 verbose "protocol $p: CertificateFile with no plain public file" 64verbose "CertificateFile with no plain public file"
66 ${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \ 65${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
67 -oCertificateFile=$OBJ/user_key3-cert.pub \ 66 -oCertificateFile=$OBJ/user_key3-cert.pub \
68 -i $OBJ/user_key3 somehost exit 5$p 67 -i $OBJ/user_key3 somehost exit 52
69 [ $? -ne 5$p ] && fail "ssh failed" 68[ $? -ne 52 ] && fail "ssh failed"
70 69
71 # Just keys should fail 70# Just keys should fail
72 verbose "protocol $p: plain keys" 71verbose "plain keys"
73 ${SSH} $opts2 somehost exit 5$p 72${SSH} $opts2 somehost exit 52
74 r=$? 73r=$?
75 if [ $r -eq 5$p ]; then 74if [ $r -eq 52 ]; then
76 fail "ssh succeeded with no certs in protocol $p" 75 fail "ssh succeeded with no certs"
77 fi 76fi
78 77
79 # Keys with untrusted cert should fail. 78# Keys with untrusted cert should fail.
80 verbose "protocol $p: untrusted cert" 79verbose "untrusted cert"
81 opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" 80opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
82 ${SSH} $opts3 somehost exit 5$p 81${SSH} $opts3 somehost exit 52
83 r=$? 82r=$?
84 if [ $r -eq 5$p ]; then 83if [ $r -eq 52 ]; then
85 fail "ssh succeeded with bad cert in protocol $p" 84 fail "ssh succeeded with bad cert"
86 fi 85fi
87 86
88 # Good cert with bad key should fail. 87# Good cert with bad key should fail.
89 verbose "protocol $p: good cert, bad key" 88verbose "good cert, bad key"
90 opts3="$opts -i $OBJ/user_key2" 89opts3="$opts -i $OBJ/user_key2"
91 opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" 90opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
92 ${SSH} $opts3 somehost exit 5$p 91${SSH} $opts3 somehost exit 52
93 r=$? 92r=$?
94 if [ $r -eq 5$p ]; then 93if [ $r -eq 52 ]; then
95 fail "ssh succeeded with no matching key in protocol $p" 94 fail "ssh succeeded with no matching key"
96 fi 95fi
97 96
98 # Keys with one trusted cert, should succeed. 97# Keys with one trusted cert, should succeed.
99 verbose "protocol $p: single trusted" 98verbose "single trusted"
100 opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub" 99opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
101 ${SSH} $opts3 somehost exit 5$p 100${SSH} $opts3 somehost exit 52
102 r=$? 101r=$?
103 if [ $r -ne 5$p ]; then 102if [ $r -ne 52 ]; then
104 fail "ssh failed with trusted cert and key in protocol $p" 103 fail "ssh failed with trusted cert and key"
105 fi 104fi
106 105
107 # Multiple certs and keys, with one trusted cert, should succeed. 106# Multiple certs and keys, with one trusted cert, should succeed.
108 verbose "protocol $p: multiple trusted" 107verbose "multiple trusted"
109 opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" 108opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
110 opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" 109opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
111 ${SSH} $opts3 somehost exit 5$p 110${SSH} $opts3 somehost exit 52
112 r=$? 111r=$?
113 if [ $r -ne 5$p ]; then 112if [ $r -ne 52 ]; then
114 fail "ssh failed with multiple certs in protocol $p" 113 fail "ssh failed with multiple certs"
115 fi 114fi
116done
117 115
118#next, using an agent in combination with the keys 116#next, using an agent in combination with the keys
119SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1 117SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1
@@ -139,26 +137,25 @@ if [ $? -ne 0 ]; then
139fi 137fi
140 138
141# try ssh with the agent and certificates 139# try ssh with the agent and certificates
142# note: ssh agent only uses certificates in protocol 2
143opts="-F $OBJ/ssh_proxy" 140opts="-F $OBJ/ssh_proxy"
144# with no certificates, shoud fail 141# with no certificates, shoud fail
145${SSH} -2 $opts somehost exit 52 142${SSH} $opts somehost exit 52
146if [ $? -eq 52 ]; then 143if [ $? -eq 52 ]; then
147 fail "ssh connect with agent in protocol 2 succeeded with no cert" 144 fail "ssh connect with agent in succeeded with no cert"
148fi 145fi
149 146
150#with an untrusted certificate, should fail 147#with an untrusted certificate, should fail
151opts="$opts -oCertificateFile=$OBJ/cert_user_key1_2.pub" 148opts="$opts -oCertificateFile=$OBJ/cert_user_key1_2.pub"
152${SSH} -2 $opts somehost exit 52 149${SSH} $opts somehost exit 52
153if [ $? -eq 52 ]; then 150if [ $? -eq 52 ]; then
154 fail "ssh connect with agent in protocol 2 succeeded with bad cert" 151 fail "ssh connect with agent in succeeded with bad cert"
155fi 152fi
156 153
157#with an additional trusted certificate, should succeed 154#with an additional trusted certificate, should succeed
158opts="$opts -oCertificateFile=$OBJ/cert_user_key1_1.pub" 155opts="$opts -oCertificateFile=$OBJ/cert_user_key1_1.pub"
159${SSH} -2 $opts somehost exit 52 156${SSH} $opts somehost exit 52
160if [ $? -ne 52 ]; then 157if [ $? -ne 52 ]; then
161 fail "ssh connect with agent in protocol 2 failed with good cert" 158 fail "ssh connect with agent in failed with good cert"
162fi 159fi
163 160
164trace "kill agent" 161trace "kill agent"
diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh
index 62261cf8b..3d5732a5d 100644
--- a/regress/cert-hostkey.sh
+++ b/regress/cert-hostkey.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: cert-hostkey.sh,v 1.14 2016/05/02 09:52:00 djm Exp $ 1# $OpenBSD: cert-hostkey.sh,v 1.15 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="certified host keys" 4tid="certified host keys"
@@ -104,7 +104,7 @@ attempt_connect() {
104 shift; shift 104 shift; shift
105 verbose "$tid: $_ident expect success $_expect_success" 105 verbose "$tid: $_ident expect success $_expect_success"
106 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert 106 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
107 ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ 107 ${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
108 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ 108 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
109 "$@" -F $OBJ/ssh_proxy somehost true 109 "$@" -F $OBJ/ssh_proxy somehost true
110 _r=$? 110 _r=$?
@@ -169,7 +169,7 @@ for privsep in yes no ; do
169 ) > $OBJ/sshd_proxy 169 ) > $OBJ/sshd_proxy
170 170
171 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert 171 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
172 ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ 172 ${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
173 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ 173 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
174 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 174 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
175 if [ $? -eq 0 ]; then 175 if [ $? -eq 0 ]; then
@@ -190,7 +190,7 @@ for ktype in $PLAIN_TYPES ; do
190 echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub 190 echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
191 ) > $OBJ/sshd_proxy 191 ) > $OBJ/sshd_proxy
192 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert 192 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
193 ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ 193 ${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
194 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ 194 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
195 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 195 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
196 if [ $? -eq 0 ]; then 196 if [ $? -eq 0 ]; then
@@ -222,7 +222,7 @@ test_one() {
222 ) > $OBJ/sshd_proxy 222 ) > $OBJ/sshd_proxy
223 223
224 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert 224 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
225 ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ 225 ${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
226 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ 226 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
227 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 227 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
228 rc=$? 228 rc=$?
@@ -271,7 +271,7 @@ for ktype in $PLAIN_TYPES ; do
271 echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub 271 echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
272 ) > $OBJ/sshd_proxy 272 ) > $OBJ/sshd_proxy
273 273
274 ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ 274 ${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
275 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ 275 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
276 -F $OBJ/ssh_proxy somehost true 276 -F $OBJ/ssh_proxy somehost true
277 if [ $? -ne 0 ]; then 277 if [ $? -ne 0 ]; then
@@ -303,7 +303,7 @@ for kt in $PLAIN_TYPES ; do
303 ) > $OBJ/sshd_proxy 303 ) > $OBJ/sshd_proxy
304 304
305 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert 305 cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
306 ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ 306 ${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
307 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ 307 -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
308 -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1 308 -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1
309 if [ $? -eq 0 ]; then 309 if [ $? -eq 0 ]; then
diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh
index 7005fd55e..6a23fe300 100644
--- a/regress/cert-userkey.sh
+++ b/regress/cert-userkey.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: cert-userkey.sh,v 1.17 2016/11/30 03:01:33 djm Exp $ 1# $OpenBSD: cert-userkey.sh,v 1.18 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="certified user keys" 4tid="certified user keys"
@@ -67,7 +67,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
67 # Missing authorized_principals 67 # Missing authorized_principals
68 verbose "$tid: ${_prefix} missing authorized_principals" 68 verbose "$tid: ${_prefix} missing authorized_principals"
69 rm -f $OBJ/authorized_principals_$USER 69 rm -f $OBJ/authorized_principals_$USER
70 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 70 ${SSH} -i $OBJ/cert_user_key_${ktype} \
71 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 71 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
72 if [ $? -eq 0 ]; then 72 if [ $? -eq 0 ]; then
73 fail "ssh cert connect succeeded unexpectedly" 73 fail "ssh cert connect succeeded unexpectedly"
@@ -76,7 +76,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
76 # Empty authorized_principals 76 # Empty authorized_principals
77 verbose "$tid: ${_prefix} empty authorized_principals" 77 verbose "$tid: ${_prefix} empty authorized_principals"
78 echo > $OBJ/authorized_principals_$USER 78 echo > $OBJ/authorized_principals_$USER
79 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 79 ${SSH} -i $OBJ/cert_user_key_${ktype} \
80 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 80 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
81 if [ $? -eq 0 ]; then 81 if [ $? -eq 0 ]; then
82 fail "ssh cert connect succeeded unexpectedly" 82 fail "ssh cert connect succeeded unexpectedly"
@@ -85,7 +85,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
85 # Wrong authorized_principals 85 # Wrong authorized_principals
86 verbose "$tid: ${_prefix} wrong authorized_principals" 86 verbose "$tid: ${_prefix} wrong authorized_principals"
87 echo gregorsamsa > $OBJ/authorized_principals_$USER 87 echo gregorsamsa > $OBJ/authorized_principals_$USER
88 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 88 ${SSH} -i $OBJ/cert_user_key_${ktype} \
89 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 89 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
90 if [ $? -eq 0 ]; then 90 if [ $? -eq 0 ]; then
91 fail "ssh cert connect succeeded unexpectedly" 91 fail "ssh cert connect succeeded unexpectedly"
@@ -94,7 +94,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
94 # Correct authorized_principals 94 # Correct authorized_principals
95 verbose "$tid: ${_prefix} correct authorized_principals" 95 verbose "$tid: ${_prefix} correct authorized_principals"
96 echo mekmitasdigoat > $OBJ/authorized_principals_$USER 96 echo mekmitasdigoat > $OBJ/authorized_principals_$USER
97 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 97 ${SSH} -i $OBJ/cert_user_key_${ktype} \
98 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 98 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
99 if [ $? -ne 0 ]; then 99 if [ $? -ne 0 ]; then
100 fail "ssh cert connect failed" 100 fail "ssh cert connect failed"
@@ -103,7 +103,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
103 # authorized_principals with bad key option 103 # authorized_principals with bad key option
104 verbose "$tid: ${_prefix} authorized_principals bad key opt" 104 verbose "$tid: ${_prefix} authorized_principals bad key opt"
105 echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER 105 echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER
106 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 106 ${SSH} -i $OBJ/cert_user_key_${ktype} \
107 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 107 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
108 if [ $? -eq 0 ]; then 108 if [ $? -eq 0 ]; then
109 fail "ssh cert connect succeeded unexpectedly" 109 fail "ssh cert connect succeeded unexpectedly"
@@ -113,7 +113,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
113 verbose "$tid: ${_prefix} authorized_principals command=false" 113 verbose "$tid: ${_prefix} authorized_principals command=false"
114 echo 'command="false" mekmitasdigoat' > \ 114 echo 'command="false" mekmitasdigoat' > \
115 $OBJ/authorized_principals_$USER 115 $OBJ/authorized_principals_$USER
116 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 116 ${SSH} -i $OBJ/cert_user_key_${ktype} \
117 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 117 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
118 if [ $? -eq 0 ]; then 118 if [ $? -eq 0 ]; then
119 fail "ssh cert connect succeeded unexpectedly" 119 fail "ssh cert connect succeeded unexpectedly"
@@ -124,7 +124,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
124 verbose "$tid: ${_prefix} authorized_principals command=true" 124 verbose "$tid: ${_prefix} authorized_principals command=true"
125 echo 'command="true" mekmitasdigoat' > \ 125 echo 'command="true" mekmitasdigoat' > \
126 $OBJ/authorized_principals_$USER 126 $OBJ/authorized_principals_$USER
127 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 127 ${SSH} -i $OBJ/cert_user_key_${ktype} \
128 -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 128 -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1
129 if [ $? -ne 0 ]; then 129 if [ $? -ne 0 ]; then
130 fail "ssh cert connect failed" 130 fail "ssh cert connect failed"
@@ -148,7 +148,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
148 printf 'cert-authority,principals="gregorsamsa" ' 148 printf 'cert-authority,principals="gregorsamsa" '
149 cat $OBJ/user_ca_key.pub 149 cat $OBJ/user_ca_key.pub
150 ) > $OBJ/authorized_keys_$USER 150 ) > $OBJ/authorized_keys_$USER
151 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 151 ${SSH} -i $OBJ/cert_user_key_${ktype} \
152 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 152 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
153 if [ $? -eq 0 ]; then 153 if [ $? -eq 0 ]; then
154 fail "ssh cert connect succeeded unexpectedly" 154 fail "ssh cert connect succeeded unexpectedly"
@@ -160,7 +160,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
160 printf 'cert-authority,principals="mekmitasdigoat" ' 160 printf 'cert-authority,principals="mekmitasdigoat" '
161 cat $OBJ/user_ca_key.pub 161 cat $OBJ/user_ca_key.pub
162 ) > $OBJ/authorized_keys_$USER 162 ) > $OBJ/authorized_keys_$USER
163 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 163 ${SSH} -i $OBJ/cert_user_key_${ktype} \
164 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 164 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
165 if [ $? -ne 0 ]; then 165 if [ $? -ne 0 ]; then
166 fail "ssh cert connect failed" 166 fail "ssh cert connect failed"
@@ -198,7 +198,7 @@ basic_tests() {
198 echo "PubkeyAcceptedKeyTypes ${t}" 198 echo "PubkeyAcceptedKeyTypes ${t}"
199 ) > $OBJ/ssh_proxy 199 ) > $OBJ/ssh_proxy
200 200
201 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 201 ${SSH} -i $OBJ/cert_user_key_${ktype} \
202 -F $OBJ/ssh_proxy somehost true 202 -F $OBJ/ssh_proxy somehost true
203 if [ $? -ne 0 ]; then 203 if [ $? -ne 0 ]; then
204 fail "ssh cert connect failed" 204 fail "ssh cert connect failed"
@@ -215,7 +215,7 @@ basic_tests() {
215 ) > $OBJ/sshd_proxy 215 ) > $OBJ/sshd_proxy
216 cp $OBJ/cert_user_key_${ktype}.pub \ 216 cp $OBJ/cert_user_key_${ktype}.pub \
217 $OBJ/cert_user_key_revoked 217 $OBJ/cert_user_key_revoked
218 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 218 ${SSH} -i $OBJ/cert_user_key_${ktype} \
219 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 219 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
220 if [ $? -eq 0 ]; then 220 if [ $? -eq 0 ]; then
221 fail "ssh cert connect succeeded unexpecedly" 221 fail "ssh cert connect succeeded unexpecedly"
@@ -224,14 +224,14 @@ basic_tests() {
224 rm $OBJ/cert_user_key_revoked 224 rm $OBJ/cert_user_key_revoked
225 ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \ 225 ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \
226 $OBJ/cert_user_key_${ktype}.pub 226 $OBJ/cert_user_key_${ktype}.pub
227 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 227 ${SSH} -i $OBJ/cert_user_key_${ktype} \
228 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 228 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
229 if [ $? -eq 0 ]; then 229 if [ $? -eq 0 ]; then
230 fail "ssh cert connect succeeded unexpecedly" 230 fail "ssh cert connect succeeded unexpecedly"
231 fi 231 fi
232 verbose "$tid: ${_prefix} empty KRL" 232 verbose "$tid: ${_prefix} empty KRL"
233 ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked 233 ${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked
234 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 234 ${SSH} -i $OBJ/cert_user_key_${ktype} \
235 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 235 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
236 if [ $? -ne 0 ]; then 236 if [ $? -ne 0 ]; then
237 fail "ssh cert connect failed" 237 fail "ssh cert connect failed"
@@ -246,7 +246,7 @@ basic_tests() {
246 echo "PubkeyAcceptedKeyTypes ${t}" 246 echo "PubkeyAcceptedKeyTypes ${t}"
247 echo "$extra_sshd" 247 echo "$extra_sshd"
248 ) > $OBJ/sshd_proxy 248 ) > $OBJ/sshd_proxy
249 ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ 249 ${SSH} -i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
250 somehost true >/dev/null 2>&1 250 somehost true >/dev/null 2>&1
251 if [ $? -eq 0 ]; then 251 if [ $? -eq 0 ]; then
252 fail "ssh cert connect succeeded unexpecedly" 252 fail "ssh cert connect succeeded unexpecedly"
@@ -260,7 +260,7 @@ basic_tests() {
260 echo "$extra_sshd" 260 echo "$extra_sshd"
261 ) > $OBJ/sshd_proxy 261 ) > $OBJ/sshd_proxy
262 verbose "$tid: ensure CA key does not authenticate user" 262 verbose "$tid: ensure CA key does not authenticate user"
263 ${SSH} -2i $OBJ/user_ca_key \ 263 ${SSH} -i $OBJ/user_ca_key \
264 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 264 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
265 if [ $? -eq 0 ]; then 265 if [ $? -eq 0 ]; then
266 fail "ssh cert connect with CA key succeeded unexpectedly" 266 fail "ssh cert connect with CA key succeeded unexpectedly"
@@ -307,7 +307,7 @@ test_one() {
307 $sign_opts $OBJ/cert_user_key_${ktype} || 307 $sign_opts $OBJ/cert_user_key_${ktype} ||
308 fail "couldn't sign cert_user_key_${ktype}" 308 fail "couldn't sign cert_user_key_${ktype}"
309 309
310 ${SSH} -2i $OBJ/cert_user_key_${ktype} \ 310 ${SSH} -i $OBJ/cert_user_key_${ktype} \
311 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 311 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
312 rc=$? 312 rc=$?
313 if [ "x$result" = "xsuccess" ] ; then 313 if [ "x$result" = "xsuccess" ] ; then
@@ -378,7 +378,7 @@ for ktype in $PLAIN_TYPES ; do
378 -n $USER $OBJ/cert_user_key_${ktype} || 378 -n $USER $OBJ/cert_user_key_${ktype} ||
379 fatal "couldn't sign cert_user_key_${ktype}" 379 fatal "couldn't sign cert_user_key_${ktype}"
380 verbose "$tid: user ${ktype} connect wrong cert" 380 verbose "$tid: user ${ktype} connect wrong cert"
381 ${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \ 381 ${SSH} -i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
382 somehost true >/dev/null 2>&1 382 somehost true >/dev/null 2>&1
383 if [ $? -eq 0 ]; then 383 if [ $? -eq 0 ]; then
384 fail "ssh cert connect $ident succeeded unexpectedly" 384 fail "ssh cert connect $ident succeeded unexpectedly"
diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh
index 056296398..2504d04f4 100644
--- a/regress/cfgmatch.sh
+++ b/regress/cfgmatch.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: cfgmatch.sh,v 1.9 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: cfgmatch.sh,v 1.10 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="sshd_config match" 4tid="sshd_config match"
@@ -13,7 +13,7 @@ echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_proxy
13start_client() 13start_client()
14{ 14{
15 rm -f $pidfile 15 rm -f $pidfile
16 ${SSH} -q -$p $fwd "$@" somehost \ 16 ${SSH} -q $fwd "$@" somehost \
17 exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' \ 17 exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' \
18 >>$TEST_REGRESS_LOGFILE 2>&1 & 18 >>$TEST_REGRESS_LOGFILE 2>&1 &
19 client_pid=$! 19 client_pid=$!
@@ -56,22 +56,18 @@ 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
59for p in ${SSH_PROTOCOLS}; do 59trace "match permitopen localhost"
60 trace "match permitopen localhost proto $p" 60start_client -F $OBJ/ssh_config
61 start_client -F $OBJ/ssh_config 61${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true || \
62 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ 62 fail "match permitopen permit"
63 fail "match permitopen permit proto $p" 63stop_client
64 stop_client
65done
66 64
67# Same but from different source. This should not be permitted 65# Same but from different source. This should not be permitted
68for p in ${SSH_PROTOCOLS}; do 66trace "match permitopen proxy"
69 trace "match permitopen proxy proto $p" 67start_client -F $OBJ/ssh_proxy
70 start_client -F $OBJ/ssh_proxy 68${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true && \
71 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ 69 fail "match permitopen deny"
72 fail "match permitopen deny proto $p" 70stop_client
73 stop_client
74done
75 71
76# Retry previous with key option, should also be denied. 72# Retry previous with key option, should also be denied.
77cp /dev/null $OBJ/authorized_keys_$USER 73cp /dev/null $OBJ/authorized_keys_$USER
@@ -79,23 +75,19 @@ for t in ${SSH_KEYTYPES}; do
79 printf 'permitopen="127.0.0.1:'$PORT'" ' >> $OBJ/authorized_keys_$USER 75 printf 'permitopen="127.0.0.1:'$PORT'" ' >> $OBJ/authorized_keys_$USER
80 cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER 76 cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
81done 77done
82for p in ${SSH_PROTOCOLS}; do 78trace "match permitopen proxy w/key opts"
83 trace "match permitopen proxy w/key opts proto $p" 79start_client -F $OBJ/ssh_proxy
84 start_client -F $OBJ/ssh_proxy 80${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true && \
85 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ 81 fail "match permitopen deny w/key opt"
86 fail "match permitopen deny w/key opt proto $p" 82stop_client
87 stop_client
88done
89 83
90# Test both sshd_config and key options permitting the same dst/port pair. 84# Test both sshd_config and key options permitting the same dst/port pair.
91# Should be permitted. 85# Should be permitted.
92for p in ${SSH_PROTOCOLS}; do 86trace "match permitopen localhost"
93 trace "match permitopen localhost proto $p" 87start_client -F $OBJ/ssh_config
94 start_client -F $OBJ/ssh_config 88${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true || \
95 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ 89 fail "match permitopen permit"
96 fail "match permitopen permit proto $p" 90stop_client
97 stop_client
98done
99 91
100cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy 92cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
101echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy 93echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy
@@ -103,13 +95,11 @@ echo "Match User $USER" >>$OBJ/sshd_proxy
103echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy 95echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy
104 96
105# Test that a Match overrides a PermitOpen in the global section 97# Test that a Match overrides a PermitOpen in the global section
106for p in ${SSH_PROTOCOLS}; do 98trace "match permitopen proxy w/key opts"
107 trace "match permitopen proxy w/key opts proto $p" 99start_client -F $OBJ/ssh_proxy
108 start_client -F $OBJ/ssh_proxy 100${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true && \
109 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ 101 fail "match override permitopen"
110 fail "match override permitopen proto $p" 102stop_client
111 stop_client
112done
113 103
114cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy 104cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
115echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy 105echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy
@@ -118,10 +108,8 @@ echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy
118 108
119# Test that a rule that doesn't match doesn't override, plus test a 109# Test that a rule that doesn't match doesn't override, plus test a
120# PermitOpen entry that's not at the start of the list 110# PermitOpen entry that's not at the start of the list
121for p in ${SSH_PROTOCOLS}; do 111trace "nomatch permitopen proxy w/key opts"
122 trace "nomatch permitopen proxy w/key opts proto $p" 112start_client -F $OBJ/ssh_proxy
123 start_client -F $OBJ/ssh_proxy 113${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true || \
124 ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ 114 fail "nomatch override permitopen"
125 fail "nomatch override permitopen proto $p" 115stop_client
126 stop_client
127done
diff --git a/regress/cipher-speed.sh b/regress/cipher-speed.sh
index 575dc2341..5da95b3a9 100644
--- a/regress/cipher-speed.sh
+++ b/regress/cipher-speed.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: cipher-speed.sh,v 1.13 2015/03/24 20:22:17 markus Exp $ 1# $OpenBSD: cipher-speed.sh,v 1.14 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="cipher speed" 4tid="cipher speed"
@@ -12,16 +12,16 @@ getbytes ()
12tries="1 2" 12tries="1 2"
13 13
14for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do 14for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do
15 trace "proto 2 cipher $c mac $m" 15 trace "cipher $c mac $m"
16 for x in $tries; do 16 for x in $tries; do
17 printf "%-60s" "$c/$m:" 17 printf "%-60s" "$c/$m:"
18 ( ${SSH} -o 'compression no' \ 18 ( ${SSH} -o 'compression no' \
19 -F $OBJ/ssh_proxy -2 -m $m -c $c somehost \ 19 -F $OBJ/ssh_proxy -m $m -c $c somehost \
20 exec sh -c \'"dd of=/dev/null obs=32k"\' \ 20 exec sh -c \'"dd of=/dev/null obs=32k"\' \
21 < ${DATA} ) 2>&1 | getbytes 21 < ${DATA} ) 2>&1 | getbytes
22 22
23 if [ $? -ne 0 ]; then 23 if [ $? -ne 0 ]; then
24 fail "ssh -2 failed with mac $m cipher $c" 24 fail "ssh failed with mac $m cipher $c"
25 fi 25 fi
26 done 26 done
27 # No point trying all MACs for AEAD ciphers since they are ignored. 27 # No point trying all MACs for AEAD ciphers since they are ignored.
@@ -30,22 +30,3 @@ for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do
30 fi 30 fi
31 n=`expr $n + 1` 31 n=`expr $n + 1`
32done; done 32done; done
33
34if ssh_version 1; then
35 ciphers="3des blowfish"
36else
37 ciphers=""
38fi
39for c in $ciphers; do
40 trace "proto 1 cipher $c"
41 for x in $tries; do
42 printf "%-60s" "$c:"
43 ( ${SSH} -o 'compression no' \
44 -F $OBJ/ssh_proxy -1 -c $c somehost \
45 exec sh -c \'"dd of=/dev/null obs=32k"\' \
46 < ${DATA} ) 2>&1 | getbytes
47 if [ $? -ne 0 ]; then
48 fail "ssh -1 failed with cipher $c"
49 fi
50 done
51done
diff --git a/regress/connect-privsep.sh b/regress/connect-privsep.sh
index 81cedc7e5..b6abb65e3 100644
--- a/regress/connect-privsep.sh
+++ b/regress/connect-privsep.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: connect-privsep.sh,v 1.8 2016/11/01 13:43:27 tb Exp $ 1# $OpenBSD: connect-privsep.sh,v 1.9 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="proxy connect with privsep" 4tid="proxy connect with privsep"
@@ -6,23 +6,19 @@ tid="proxy connect with privsep"
6cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig 6cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
7echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy 7echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy
8 8
9for p in ${SSH_PROTOCOLS}; do 9${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
10 ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true 10if [ $? -ne 0 ]; then
11 if [ $? -ne 0 ]; then 11 fail "ssh privsep+proxyconnect failed"
12 fail "ssh privsep+proxyconnect protocol $p failed" 12fi
13 fi
14done
15 13
16cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy 14cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
17echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy 15echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy
18 16
19for p in ${SSH_PROTOCOLS}; do 17${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
20 ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true 18if [ $? -ne 0 ]; then
21 if [ $? -ne 0 ]; then 19 # XXX replace this with fail once sandbox has stabilised
22 # XXX replace this with fail once sandbox has stabilised 20 warn "ssh privsep/sandbox+proxyconnect failed"
23 warn "ssh privsep/sandbox+proxyconnect protocol $p failed" 21fi
24 fi
25done
26 22
27# Because sandbox is sensitive to changes in libc, especially malloc, retest 23# Because sandbox is sensitive to changes in libc, especially malloc, retest
28# with every malloc.conf option (and none). 24# with every malloc.conf option (and none).
@@ -32,10 +28,8 @@ else
32 mopts=`echo $TEST_MALLOC_OPTIONS | sed 's/./& /g'` 28 mopts=`echo $TEST_MALLOC_OPTIONS | sed 's/./& /g'`
33fi 29fi
34for m in '' $mopts ; do 30for m in '' $mopts ; do
35 for p in ${SSH_PROTOCOLS}; do 31 env MALLOC_OPTIONS="$m" ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
36 env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
37 if [ $? -ne 0 ]; then 32 if [ $? -ne 0 ]; then
38 fail "ssh privsep/sandbox+proxyconnect protocol $p mopt '$m' failed" 33 fail "ssh privsep/sandbox+proxyconnect mopt '$m' failed"
39 fi 34 fi
40 done
41done 35done
diff --git a/regress/connect.sh b/regress/connect.sh
index f0d55d343..1b344b603 100644
--- a/regress/connect.sh
+++ b/regress/connect.sh
@@ -1,13 +1,11 @@
1# $OpenBSD: connect.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: connect.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="simple connect" 4tid="simple connect"
5 5
6start_sshd 6start_sshd
7 7
8for p in ${SSH_PROTOCOLS}; do 8${SSH} -F $OBJ/ssh_config somehost true
9 ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true 9if [ $? -ne 0 ]; then
10 if [ $? -ne 0 ]; then 10 fail "ssh connect with failed"
11 fail "ssh connect with protocol $p failed" 11fi
12 fi
13done
diff --git a/regress/dhgex.sh b/regress/dhgex.sh
index e7c573397..61fc178e8 100644
--- a/regress/dhgex.sh
+++ b/regress/dhgex.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: dhgex.sh,v 1.3 2015/10/23 02:22:01 dtucker Exp $ 1# $OpenBSD: dhgex.sh,v 1.4 2017/05/08 01:52:49 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="dhgex" 4tid="dhgex"
@@ -54,7 +54,6 @@ check()
54 54
55#check 2048 3des-cbc 55#check 2048 3des-cbc
56check 3072 `${SSH} -Q cipher | grep 128` 56check 3072 `${SSH} -Q cipher | grep 128`
57check 3072 arcfour blowfish-cbc
58check 7680 `${SSH} -Q cipher | grep 192` 57check 7680 `${SSH} -Q cipher | grep 192`
59check 8192 `${SSH} -Q cipher | grep 256` 58check 8192 `${SSH} -Q cipher | grep 256`
60check 8192 rijndael-cbc@lysator.liu.se chacha20-poly1305@openssh.com 59check 8192 rijndael-cbc@lysator.liu.se chacha20-poly1305@openssh.com
diff --git a/regress/dynamic-forward.sh b/regress/dynamic-forward.sh
index dd67c9639..84f8ee192 100644
--- a/regress/dynamic-forward.sh
+++ b/regress/dynamic-forward.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: dynamic-forward.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: dynamic-forward.sh,v 1.13 2017/09/21 19:18:12 markus Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="dynamic forwarding" 4tid="dynamic forwarding"
@@ -17,33 +17,34 @@ trace "will use ProxyCommand $proxycmd"
17 17
18start_sshd 18start_sshd
19 19
20for p in ${SSH_PROTOCOLS}; do 20for d in D R; 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"
24
24 while [ "$error" -ne 0 -a "$n" -lt 3 ]; do 25 while [ "$error" -ne 0 -a "$n" -lt 3 ]; do
25 n=`expr $n + 1` 26 n=`expr $n + 1`
26 ${SSH} -$p -F $OBJ/ssh_config -f -D $FWDPORT -q \ 27 ${SSH} -F $OBJ/ssh_config -f -$d $FWDPORT -q \
27 -oExitOnForwardFailure=yes somehost exec sh -c \ 28 -oExitOnForwardFailure=yes somehost exec sh -c \
28 \'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\' 29 \'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\'
29 error=$? 30 error=$?
30 if [ "$error" -ne 0 ]; then 31 if [ "$error" -ne 0 ]; then
31 trace "forward failed proto $p attempt $n err $error" 32 trace "forward failed attempt $n err $error"
32 sleep $n 33 sleep $n
33 fi 34 fi
34 done 35 done
35 if [ "$error" -ne 0 ]; then 36 if [ "$error" -ne 0 ]; then
36 fatal "failed to start dynamic forwarding proto $p" 37 fatal "failed to start dynamic forwarding"
37 fi 38 fi
38 39
39 for s in 4 5; do 40 for s in 4 5; do
40 for h in 127.0.0.1 localhost; do 41 for h in 127.0.0.1 localhost; do
41 trace "testing ssh protocol $p socks version $s host $h" 42 trace "testing ssh socks version $s host $h (-$d)"
42 ${SSH} -F $OBJ/ssh_config \ 43 ${SSH} -F $OBJ/ssh_config \
43 -o "ProxyCommand ${proxycmd}${s} $h $PORT" \ 44 -o "ProxyCommand ${proxycmd}${s} $h $PORT" \
44 somehost cat $DATA > $OBJ/ls.copy 45 somehost cat ${DATA} > ${COPY}
45 test -f $OBJ/ls.copy || fail "failed copy $DATA" 46 test -f ${COPY} || fail "failed copy ${DATA}"
46 cmp $DATA $OBJ/ls.copy || fail "corrupted copy of $DATA" 47 cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
47 done 48 done
48 done 49 done
49 50
@@ -56,4 +57,5 @@ for p in ${SSH_PROTOCOLS}; do
56 else 57 else
57 fail "no pid file: $OBJ/remote_pid" 58 fail "no pid file: $OBJ/remote_pid"
58 fi 59 fi
60
59done 61done
diff --git a/regress/exit-status.sh b/regress/exit-status.sh
index 397d8d732..aadf99fb3 100644
--- a/regress/exit-status.sh
+++ b/regress/exit-status.sh
@@ -1,24 +1,22 @@
1# $OpenBSD: exit-status.sh,v 1.7 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: exit-status.sh,v 1.8 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="remote exit status" 4tid="remote exit status"
5 5
6for p in ${SSH_PROTOCOLS}; do 6for s in 0 1 4 5 44; do
7 for s in 0 1 4 5 44; do 7 trace "status $s"
8 trace "proto $p status $s" 8 verbose "test $tid: status $s"
9 verbose "test $tid: proto $p status $s" 9 ${SSH} -F $OBJ/ssh_proxy otherhost exit $s
10 ${SSH} -$p -F $OBJ/ssh_proxy otherhost exit $s 10 r=$?
11 r=$? 11 if [ $r -ne $s ]; then
12 if [ $r -ne $s ]; then 12 fail "exit code mismatch for: $r != $s"
13 fail "exit code mismatch for protocol $p: $r != $s" 13 fi
14 fi
15 14
16 # same with early close of stdout/err 15 # same with early close of stdout/err
17 ${SSH} -$p -F $OBJ/ssh_proxy -n otherhost \ 16 ${SSH} -F $OBJ/ssh_proxy -n otherhost exec \
18 exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' 17 sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\'
19 r=$? 18 r=$?
20 if [ $r -ne $s ]; then 19 if [ $r -ne $s ]; then
21 fail "exit code (with sleep) mismatch for protocol $p: $r != $s" 20 fail "exit code (with sleep) mismatch for: $r != $s"
22 fi 21 fi
23 done
24done 22done
diff --git a/regress/forcecommand.sh b/regress/forcecommand.sh
index 8a9b090ea..e059f1fdb 100644
--- a/regress/forcecommand.sh
+++ b/regress/forcecommand.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: forcecommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: forcecommand.sh,v 1.4 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="forced command" 4tid="forced command"
@@ -11,11 +11,8 @@ for t in ${SSH_KEYTYPES}; do
11 cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER 11 cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
12done 12done
13 13
14for p in ${SSH_PROTOCOLS}; do 14trace "forced command in key option"
15 trace "forced command in key option proto $p" 15${SSH} -F $OBJ/ssh_proxy somehost false || fail "forced command in key"
16 ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ ||
17 fail "forced command in key proto $p"
18done
19 16
20cp /dev/null $OBJ/authorized_keys_$USER 17cp /dev/null $OBJ/authorized_keys_$USER
21for t in ${SSH_KEYTYPES}; do 18for t in ${SSH_KEYTYPES}; do
@@ -26,19 +23,13 @@ done
26cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy 23cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
27echo "ForceCommand true" >> $OBJ/sshd_proxy 24echo "ForceCommand true" >> $OBJ/sshd_proxy
28 25
29for p in ${SSH_PROTOCOLS}; do 26trace "forced command in sshd_config overrides key option"
30 trace "forced command in sshd_config overrides key option proto $p" 27${SSH} -F $OBJ/ssh_proxy somehost false || fail "forced command in key"
31 ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ ||
32 fail "forced command in key proto $p"
33done
34 28
35cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy 29cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
36echo "ForceCommand false" >> $OBJ/sshd_proxy 30echo "ForceCommand false" >> $OBJ/sshd_proxy
37echo "Match User $USER" >> $OBJ/sshd_proxy 31echo "Match User $USER" >> $OBJ/sshd_proxy
38echo " ForceCommand true" >> $OBJ/sshd_proxy 32echo " ForceCommand true" >> $OBJ/sshd_proxy
39 33
40for p in ${SSH_PROTOCOLS}; do 34trace "forced command with match"
41 trace "forced command with match proto $p" 35${SSH} -F $OBJ/ssh_proxy somehost false || fail "forced command in key"
42 ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ ||
43 fail "forced command in key proto $p"
44done
diff --git a/regress/forward-control.sh b/regress/forward-control.sh
index 91957098f..2e9dbb53a 100644
--- a/regress/forward-control.sh
+++ b/regress/forward-control.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: forward-control.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: forward-control.sh,v 1.4 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="sshd control of local and remote forwarding" 4tid="sshd control of local and remote forwarding"
@@ -32,13 +32,12 @@ wait_for_process_to_exit() {
32 return 0 32 return 0
33} 33}
34 34
35# usage: check_lfwd protocol Y|N message 35# usage: check_lfwd Y|N message
36check_lfwd() { 36check_lfwd() {
37 _proto=$1 37 _expected=$1
38 _expected=$2 38 _message=$2
39 _message=$3
40 rm -f $READY 39 rm -f $READY
41 ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \ 40 ${SSH} -F $OBJ/ssh_proxy \
42 -L$LFWD_PORT:127.0.0.1:$PORT \ 41 -L$LFWD_PORT:127.0.0.1:$PORT \
43 -o ExitOnForwardFailure=yes \ 42 -o ExitOnForwardFailure=yes \
44 -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ 43 -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \
@@ -62,13 +61,12 @@ check_lfwd() {
62 fi 61 fi
63} 62}
64 63
65# usage: check_rfwd protocol Y|N message 64# usage: check_rfwd Y|N message
66check_rfwd() { 65check_rfwd() {
67 _proto=$1 66 _expected=$1
68 _expected=$2 67 _message=$2
69 _message=$3
70 rm -f $READY 68 rm -f $READY
71 ${SSH} -oProtocol=$_proto -F $OBJ/ssh_proxy \ 69 ${SSH} -F $OBJ/ssh_proxy \
72 -R$RFWD_PORT:127.0.0.1:$PORT \ 70 -R$RFWD_PORT:127.0.0.1:$PORT \
73 -o ExitOnForwardFailure=yes \ 71 -o ExitOnForwardFailure=yes \
74 -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \ 72 -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \
@@ -99,10 +97,8 @@ cp ${OBJ}/sshd_proxy ${OBJ}/sshd_proxy.bak
99cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak 97cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak
100 98
101# Sanity check: ensure the default config allows forwarding 99# Sanity check: ensure the default config allows forwarding
102for p in ${SSH_PROTOCOLS} ; do 100check_lfwd Y "default configuration"
103 check_lfwd $p Y "proto $p, default configuration" 101check_rfwd Y "default configuration"
104 check_rfwd $p Y "proto $p, default configuration"
105done
106 102
107# Usage: all_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N 103# Usage: all_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N
108all_tests() { 104all_tests() {
@@ -115,49 +111,46 @@ all_tests() {
115 _permit_rfwd=$7 111 _permit_rfwd=$7
116 _badfwd=127.0.0.1:22 112 _badfwd=127.0.0.1:22
117 _goodfwd=127.0.0.1:${PORT} 113 _goodfwd=127.0.0.1:${PORT}
118 for _proto in ${SSH_PROTOCOLS} ; do 114 cp ${OBJ}/authorized_keys_${USER}.bak ${OBJ}/authorized_keys_${USER}
119 cp ${OBJ}/authorized_keys_${USER}.bak \ 115 _prefix="AllowTcpForwarding=$_tcpfwd"
120 ${OBJ}/authorized_keys_${USER} 116 # No PermitOpen
121 _prefix="proto $_proto, AllowTcpForwarding=$_tcpfwd" 117 ( cat ${OBJ}/sshd_proxy.bak ;
122 # No PermitOpen 118 echo "AllowTcpForwarding $_tcpfwd" ) \
123 ( cat ${OBJ}/sshd_proxy.bak ; 119 > ${OBJ}/sshd_proxy
124 echo "AllowTcpForwarding $_tcpfwd" ) \ 120 check_lfwd $_plain_lfwd "$_prefix"
125 > ${OBJ}/sshd_proxy 121 check_rfwd $_plain_rfwd "$_prefix"
126 check_lfwd $_proto $_plain_lfwd "$_prefix" 122 # PermitOpen via sshd_config that doesn't match
127 check_rfwd $_proto $_plain_rfwd "$_prefix" 123 ( cat ${OBJ}/sshd_proxy.bak ;
128 # PermitOpen via sshd_config that doesn't match 124 echo "AllowTcpForwarding $_tcpfwd" ;
129 ( cat ${OBJ}/sshd_proxy.bak ; 125 echo "PermitOpen $_badfwd" ) \
130 echo "AllowTcpForwarding $_tcpfwd" ; 126 > ${OBJ}/sshd_proxy
131 echo "PermitOpen $_badfwd" ) \ 127 check_lfwd $_nopermit_lfwd "$_prefix, !PermitOpen"
132 > ${OBJ}/sshd_proxy 128 check_rfwd $_nopermit_rfwd "$_prefix, !PermitOpen"
133 check_lfwd $_proto $_nopermit_lfwd "$_prefix, !PermitOpen" 129 # PermitOpen via sshd_config that does match
134 check_rfwd $_proto $_nopermit_rfwd "$_prefix, !PermitOpen" 130 ( cat ${OBJ}/sshd_proxy.bak ;
135 # PermitOpen via sshd_config that does match 131 echo "AllowTcpForwarding $_tcpfwd" ;
136 ( cat ${OBJ}/sshd_proxy.bak ; 132 echo "PermitOpen $_badfwd $_goodfwd" ) \
137 echo "AllowTcpForwarding $_tcpfwd" ; 133 > ${OBJ}/sshd_proxy
138 echo "PermitOpen $_badfwd $_goodfwd" ) \ 134 # NB. permitopen via authorized_keys should have same
139 > ${OBJ}/sshd_proxy 135 # success/fail as via sshd_config
140 # NB. permitopen via authorized_keys should have same 136 # permitopen via authorized_keys that doesn't match
141 # success/fail as via sshd_config 137 sed "s/^/permitopen=\"$_badfwd\" /" \
142 # permitopen via authorized_keys that doesn't match 138 < ${OBJ}/authorized_keys_${USER}.bak \
143 sed "s/^/permitopen=\"$_badfwd\" /" \ 139 > ${OBJ}/authorized_keys_${USER} || fatal "sed 1 fail"
144 < ${OBJ}/authorized_keys_${USER}.bak \ 140 ( cat ${OBJ}/sshd_proxy.bak ;
145 > ${OBJ}/authorized_keys_${USER} || fatal "sed 1 fail" 141 echo "AllowTcpForwarding $_tcpfwd" ) \
146 ( cat ${OBJ}/sshd_proxy.bak ; 142 > ${OBJ}/sshd_proxy
147 echo "AllowTcpForwarding $_tcpfwd" ) \ 143 check_lfwd $_nopermit_lfwd "$_prefix, !permitopen"
148 > ${OBJ}/sshd_proxy 144 check_rfwd $_nopermit_rfwd "$_prefix, !permitopen"
149 check_lfwd $_proto $_nopermit_lfwd "$_prefix, !permitopen" 145 # permitopen via authorized_keys that does match
150 check_rfwd $_proto $_nopermit_rfwd "$_prefix, !permitopen" 146 sed "s/^/permitopen=\"$_badfwd\",permitopen=\"$_goodfwd\" /" \
151 # permitopen via authorized_keys that does match 147 < ${OBJ}/authorized_keys_${USER}.bak \
152 sed "s/^/permitopen=\"$_badfwd\",permitopen=\"$_goodfwd\" /" \ 148 > ${OBJ}/authorized_keys_${USER} || fatal "sed 2 fail"
153 < ${OBJ}/authorized_keys_${USER}.bak \ 149 ( cat ${OBJ}/sshd_proxy.bak ;
154 > ${OBJ}/authorized_keys_${USER} || fatal "sed 2 fail" 150 echo "AllowTcpForwarding $_tcpfwd" ) \
155 ( cat ${OBJ}/sshd_proxy.bak ; 151 > ${OBJ}/sshd_proxy
156 echo "AllowTcpForwarding $_tcpfwd" ) \ 152 check_lfwd $_permit_lfwd "$_prefix, permitopen"
157 > ${OBJ}/sshd_proxy 153 check_rfwd $_permit_rfwd "$_prefix, permitopen"
158 check_lfwd $_proto $_permit_lfwd "$_prefix, permitopen"
159 check_rfwd $_proto $_permit_rfwd "$_prefix, permitopen"
160 done
161} 154}
162 155
163# no-permitopen mismatch-permitopen match-permitopen 156# no-permitopen mismatch-permitopen match-permitopen
diff --git a/regress/forwarding.sh b/regress/forwarding.sh
index 45c596d7d..39fccba73 100644
--- a/regress/forwarding.sh
+++ b/regress/forwarding.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: forwarding.sh,v 1.19 2017/01/30 05:22:14 djm Exp $ 1# $OpenBSD: forwarding.sh,v 1.20 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="local and remote forwarding" 4tid="local and remote forwarding"
@@ -22,30 +22,24 @@ for j in 0 1 2; do
22 last=$a 22 last=$a
23 done 23 done
24done 24done
25for p in ${SSH_PROTOCOLS}; do
26 q=`expr 3 - $p`
27 if ! ssh_version $q; then
28 q=$p
29 fi
30 trace "start forwarding, fork to background"
31 rm -f $CTL
32 ${SSH} -S $CTL -M -$p -F $OBJ/ssh_config -f $fwd somehost sleep 10
33 25
34 trace "transfer over forwarded channels and check result" 26trace "start forwarding, fork to background"
35 ${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \ 27rm -f $CTL
36 somehost cat ${DATA} > ${COPY} 28${SSH} -S $CTL -M -F $OBJ/ssh_config -f $fwd somehost sleep 10
37 test -s ${COPY} || fail "failed copy of ${DATA}"
38 cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
39 29
40 ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 30trace "transfer over forwarded channels and check result"
41done 31${SSH} -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \
32 somehost cat ${DATA} > ${COPY}
33test -s ${COPY} || fail "failed copy of ${DATA}"
34cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
35
36${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
42 37
43for p in ${SSH_PROTOCOLS}; do
44for d in L R; do 38for d in L R; do
45 trace "exit on -$d forward failure, proto $p" 39 trace "exit on -$d forward failure"
46 40
47 # this one should succeed 41 # this one should succeed
48 ${SSH} -$p -F $OBJ/ssh_config \ 42 ${SSH} -F $OBJ/ssh_config \
49 -$d ${base}01:127.0.0.1:$PORT \ 43 -$d ${base}01:127.0.0.1:$PORT \
50 -$d ${base}02:127.0.0.1:$PORT \ 44 -$d ${base}02:127.0.0.1:$PORT \
51 -$d ${base}03:127.0.0.1:$PORT \ 45 -$d ${base}03:127.0.0.1:$PORT \
@@ -55,7 +49,7 @@ for d in L R; do
55 fatal "connection failed, should not" 49 fatal "connection failed, should not"
56 else 50 else
57 # this one should fail 51 # this one should fail
58 ${SSH} -q -$p -F $OBJ/ssh_config \ 52 ${SSH} -q -F $OBJ/ssh_config \
59 -$d ${base}01:127.0.0.1:$PORT \ 53 -$d ${base}01:127.0.0.1:$PORT \
60 -$d ${base}02:127.0.0.1:$PORT \ 54 -$d ${base}02:127.0.0.1:$PORT \
61 -$d ${base}03:127.0.0.1:$PORT \ 55 -$d ${base}03:127.0.0.1:$PORT \
@@ -68,82 +62,74 @@ for d in L R; do
68 fi 62 fi
69 fi 63 fi
70done 64done
71done
72 65
73for p in ${SSH_PROTOCOLS}; do 66trace "simple clear forwarding"
74 trace "simple clear forwarding proto $p" 67${SSH} -F $OBJ/ssh_config -oClearAllForwardings=yes somehost true
75 ${SSH} -$p -F $OBJ/ssh_config -oClearAllForwardings=yes somehost true 68
76 69trace "clear local forward"
77 trace "clear local forward proto $p" 70rm -f $CTL
78 rm -f $CTL 71${SSH} -S $CTL -M -f -F $OBJ/ssh_config -L ${base}01:127.0.0.1:$PORT \
79 ${SSH} -S $CTL -M -$p -f -F $OBJ/ssh_config -L ${base}01:127.0.0.1:$PORT \ 72 -oClearAllForwardings=yes somehost sleep 10
80 -oClearAllForwardings=yes somehost sleep 10 73if [ $? != 0 ]; then
81 if [ $? != 0 ]; then 74 fail "connection failed with cleared local forwarding"
82 fail "connection failed with cleared local forwarding" 75else
83 else 76 # this one should fail
84 # this one should fail 77 ${SSH} -F $OBJ/ssh_config -p ${base}01 somehost true \
85 ${SSH} -$p -F $OBJ/ssh_config -p ${base}01 somehost true \ 78 >>$TEST_REGRESS_LOGFILE 2>&1 && \
86 >>$TEST_REGRESS_LOGFILE 2>&1 && \ 79 fail "local forwarding not cleared"
87 fail "local forwarding not cleared" 80fi
88 fi 81${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
89 ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 82
90 83trace "clear remote forward"
91 trace "clear remote forward proto $p" 84rm -f $CTL
92 rm -f $CTL 85${SSH} -S $CTL -M -f -F $OBJ/ssh_config -R ${base}01:127.0.0.1:$PORT \
93 ${SSH} -S $CTL -M -$p -f -F $OBJ/ssh_config -R ${base}01:127.0.0.1:$PORT \ 86 -oClearAllForwardings=yes somehost sleep 10
94 -oClearAllForwardings=yes somehost sleep 10 87if [ $? != 0 ]; then
95 if [ $? != 0 ]; then 88 fail "connection failed with cleared remote forwarding"
96 fail "connection failed with cleared remote forwarding" 89else
97 else 90 # this one should fail
98 # this one should fail 91 ${SSH} -F $OBJ/ssh_config -p ${base}01 somehost true \
99 ${SSH} -$p -F $OBJ/ssh_config -p ${base}01 somehost true \ 92 >>$TEST_REGRESS_LOGFILE 2>&1 && \
100 >>$TEST_REGRESS_LOGFILE 2>&1 && \ 93 fail "remote forwarding not cleared"
101 fail "remote forwarding not cleared" 94fi
102 fi 95${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
103 ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 96
104done 97trace "stdio forwarding"
105 98cmd="${SSH} -F $OBJ/ssh_config"
106for p in 2; do 99$cmd -o "ProxyCommand $cmd -q -W localhost:$PORT somehost" somehost true
107 trace "stdio forwarding proto $p" 100if [ $? != 0 ]; then
108 cmd="${SSH} -$p -F $OBJ/ssh_config" 101 fail "stdio forwarding"
109 $cmd -o "ProxyCommand $cmd -q -W localhost:$PORT somehost" \ 102fi
110 somehost true
111 if [ $? != 0 ]; then
112 fail "stdio forwarding proto $p"
113 fi
114done
115 103
116echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config 104echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config
117echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config 105echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config
118for p in ${SSH_PROTOCOLS}; do
119 trace "config file: start forwarding, fork to background"
120 rm -f $CTL
121 ${SSH} -S $CTL -M -$p -F $OBJ/ssh_config -f somehost sleep 10
122
123 trace "config file: transfer over forwarded channels and check result"
124 ${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \
125 somehost cat ${DATA} > ${COPY}
126 test -s ${COPY} || fail "failed copy of ${DATA}"
127 cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
128
129 ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
130done
131 106
132for p in 2; do 107trace "config file: start forwarding, fork to background"
133 trace "transfer over chained unix domain socket forwards and check result" 108rm -f $CTL
134 rm -f $OBJ/unix-[123].fwd 109${SSH} -S $CTL -M -F $OBJ/ssh_config -f somehost sleep 10
135 rm -f $CTL $CTL.[123] 110
136 ${SSH} -S $CTL -M -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost sleep 10 111trace "config file: transfer over forwarded channels and check result"
137 ${SSH} -S $CTL.1 -M -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost sleep 10 112${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \
138 ${SSH} -S $CTL.2 -M -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost sleep 10 113 somehost cat ${DATA} > ${COPY}
139 ${SSH} -S $CTL.3 -M -f -F $OBJ/ssh_config -L[$OBJ/unix-3.fwd]:127.0.0.1:$PORT somehost sleep 10 114test -s ${COPY} || fail "failed copy of ${DATA}"
140 ${SSH} -F $OBJ/ssh_config -p${base}01 -o 'ConnectionAttempts=4' \ 115cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
141 somehost cat ${DATA} > ${COPY} 116
142 test -s ${COPY} || fail "failed copy ${DATA}" 117${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
143 cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" 118
144 119trace "transfer over chained unix domain socket forwards and check result"
145 ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 120rm -f $OBJ/unix-[123].fwd
146 ${SSH} -F $OBJ/ssh_config -S $CTL.1 -O exit somehost 121rm -f $CTL $CTL.[123]
147 ${SSH} -F $OBJ/ssh_config -S $CTL.2 -O exit somehost 122${SSH} -S $CTL -M -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost sleep 10
148 ${SSH} -F $OBJ/ssh_config -S $CTL.3 -O exit somehost 123${SSH} -S $CTL.1 -M -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost sleep 10
149done 124${SSH} -S $CTL.2 -M -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost sleep 10
125${SSH} -S $CTL.3 -M -f -F $OBJ/ssh_config -L[$OBJ/unix-3.fwd]:127.0.0.1:$PORT somehost sleep 10
126${SSH} -F $OBJ/ssh_config -p${base}01 -o 'ConnectionAttempts=4' \
127 somehost cat ${DATA} > ${COPY}
128test -s ${COPY} || fail "failed copy ${DATA}"
129cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
130
131${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost
132${SSH} -F $OBJ/ssh_config -S $CTL.1 -O exit somehost
133${SSH} -F $OBJ/ssh_config -S $CTL.2 -O exit somehost
134${SSH} -F $OBJ/ssh_config -S $CTL.3 -O exit somehost
135
diff --git a/regress/host-expand.sh b/regress/host-expand.sh
index 2a95bfe1b..9444f7fb6 100644
--- a/regress/host-expand.sh
+++ b/regress/host-expand.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: host-expand.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: host-expand.sh,v 1.5 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="expand %h and %n" 4tid="expand %h and %n"
@@ -11,9 +11,6 @@ somehost
11127.0.0.1 11127.0.0.1
12EOE 12EOE
13 13
14for p in ${SSH_PROTOCOLS}; do 14${SSH} -F $OBJ/ssh_proxy somehost true >$OBJ/actual
15 verbose "test $tid: proto $p" 15diff $OBJ/expect $OBJ/actual || fail "$tid"
16 ${SSH} -F $OBJ/ssh_proxy -$p somehost true >$OBJ/actual
17 diff $OBJ/expect $OBJ/actual || fail "$tid proto $p"
18done
19 16
diff --git a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh
index 094700da6..811b6b9ab 100644
--- a/regress/hostkey-agent.sh
+++ b/regress/hostkey-agent.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: hostkey-agent.sh,v 1.6 2015/07/10 06:23:25 markus Exp $ 1# $OpenBSD: hostkey-agent.sh,v 1.7 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="hostkey agent" 4tid="hostkey agent"
@@ -40,7 +40,7 @@ for ps in no yes; do
40 cp $OBJ/known_hosts.orig $OBJ/known_hosts 40 cp $OBJ/known_hosts.orig $OBJ/known_hosts
41 SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` 41 SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'`
42 if [ $? -ne 0 ]; then 42 if [ $? -ne 0 ]; then
43 fail "protocol $p privsep=$ps failed" 43 fail "privsep=$ps failed"
44 fi 44 fi
45 if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then 45 if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
46 fail "bad SSH_CONNECTION key type $k privsep=$ps" 46 fail "bad SSH_CONNECTION key type $k privsep=$ps"
diff --git a/regress/integrity.sh b/regress/integrity.sh
index 1df2924f5..3eda40f0a 100644
--- a/regress/integrity.sh
+++ b/regress/integrity.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: integrity.sh,v 1.20 2017/01/06 02:26:10 dtucker Exp $ 1# $OpenBSD: integrity.sh,v 1.23 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="integrity" 4tid="integrity"
@@ -46,7 +46,7 @@ for m in $macs; do
46 macopt="-m $m -c aes128-ctr" 46 macopt="-m $m -c aes128-ctr"
47 fi 47 fi
48 verbose "test $tid: $m @$off" 48 verbose "test $tid: $m @$off"
49 ${SSH} $macopt -2F $OBJ/ssh_proxy -o "$pxy" \ 49 ${SSH} $macopt -F $OBJ/ssh_proxy -o "$pxy" \
50 -oServerAliveInterval=1 -oServerAliveCountMax=30 \ 50 -oServerAliveInterval=1 -oServerAliveCountMax=30 \
51 999.999.999.999 'printf "%4096s" " "' >/dev/null 51 999.999.999.999 'printf "%4096s" " "' >/dev/null
52 if [ $? -eq 0 ]; then 52 if [ $? -eq 0 ]; then
@@ -60,14 +60,16 @@ for m in $macs; do
60 Corrupted?MAC* | *message?authentication?code?incorrect*) 60 Corrupted?MAC* | *message?authentication?code?incorrect*)
61 emac=`expr $emac + 1`; skip=0;; 61 emac=`expr $emac + 1`; skip=0;;
62 padding*) epad=`expr $epad + 1`; skip=0;; 62 padding*) epad=`expr $epad + 1`; skip=0;;
63 *Timeout,?server*)
64 etmo=`expr $etmo + 1`; skip=0;;
63 *) fail "unexpected error mac $m at $off: $out";; 65 *) fail "unexpected error mac $m at $off: $out";;
64 esac 66 esac
65 done 67 done
66 verbose "test $tid: $ecnt errors: mac $emac padding $epad length $elen" 68 verbose "test $tid: $ecnt errors: mac $emac padding $epad length $elen timeout $etmo"
67 if [ $emac -eq 0 ]; then 69 if [ $emac -eq 0 ]; then
68 fail "$m: no mac errors" 70 fail "$m: no mac errors"
69 fi 71 fi
70 expect=`expr $ecnt - $epad - $elen` 72 expect=`expr $ecnt - $epad - $elen - $etmo`
71 if [ $emac -ne $expect ]; then 73 if [ $emac -ne $expect ]; then
72 fail "$m: expected $expect mac errors, got $emac" 74 fail "$m: expected $expect mac errors, got $emac"
73 fi 75 fi
diff --git a/regress/key-options.sh b/regress/key-options.sh
index 7a68ad358..2adee6833 100644
--- a/regress/key-options.sh
+++ b/regress/key-options.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: key-options.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: key-options.sh,v 1.4 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="key options" 4tid="key options"
@@ -8,64 +8,56 @@ authkeys="$OBJ/authorized_keys_${USER}"
8cp $authkeys $origkeys 8cp $authkeys $origkeys
9 9
10# Test command= forced command 10# Test command= forced command
11for p in ${SSH_PROTOCOLS}; do 11for 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 12 sed "s/.*/$c &/" $origkeys >$authkeys
14 verbose "key option proto $p $c" 13 verbose "key option $c"
15 r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost echo foo` 14 r=`${SSH} -q -F $OBJ/ssh_proxy somehost echo foo`
16 if [ "$r" = "foo" ]; then 15 if [ "$r" = "foo" ]; then
17 fail "key option forced command not restricted" 16 fail "key option forced command not restricted"
18 fi 17 fi
19 if [ "$r" != "bar" ]; then 18 if [ "$r" != "bar" ]; then
20 fail "key option forced command not executed" 19 fail "key option forced command not executed"
21 fi 20 fi
22 done
23done 21done
24 22
25# Test no-pty 23# Test no-pty
26sed 's/.*/no-pty &/' $origkeys >$authkeys 24sed 's/.*/no-pty &/' $origkeys >$authkeys
27for p in ${SSH_PROTOCOLS}; do 25verbose "key option proto no-pty"
28 verbose "key option proto $p no-pty" 26r=`${SSH} -q -F $OBJ/ssh_proxy somehost tty`
29 r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost tty` 27if [ -f "$r" ]; then
30 if [ -f "$r" ]; then 28 fail "key option failed no-pty (pty $r)"
31 fail "key option failed proto $p no-pty (pty $r)" 29fi
32 fi
33done
34 30
35# Test environment= 31# Test environment=
36echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy 32echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy
37sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys 33sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys
38for p in ${SSH_PROTOCOLS}; do 34verbose "key option environment"
39 verbose "key option proto $p environment" 35r=`${SSH} -q -F $OBJ/ssh_proxy somehost 'echo $FOO'`
40 r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo $FOO'` 36if [ "$r" != "bar" ]; then
41 if [ "$r" != "bar" ]; then 37 fail "key option environment not set"
42 fail "key option environment not set" 38fi
43 fi
44done
45 39
46# Test from= restriction 40# Test from= restriction
47start_sshd 41start_sshd
48for p in ${SSH_PROTOCOLS}; do 42for 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 43 cat $origkeys >$authkeys
51 ${SSH} -$p -q -F $OBJ/ssh_proxy somehost true 44 ${SSH} -q -F $OBJ/ssh_proxy somehost true
52 if [ $? -ne 0 ]; then 45 if [ $? -ne 0 ]; then
53 fail "key option proto $p failed without restriction" 46 fail "key option failed without restriction"
54 fi 47 fi
55 48
56 sed 's/.*/from="'"$f"'" &/' $origkeys >$authkeys 49 sed 's/.*/from="'"$f"'" &/' $origkeys >$authkeys
57 from=`head -1 $authkeys | cut -f1 -d ' '` 50 from=`head -1 $authkeys | cut -f1 -d ' '`
58 verbose "key option proto $p $from" 51 verbose "key option $from"
59 r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo true'` 52 r=`${SSH} -q -F $OBJ/ssh_proxy somehost 'echo true'`
60 if [ "$r" = "true" ]; then 53 if [ "$r" = "true" ]; then
61 fail "key option proto $p $from not restricted" 54 fail "key option $from not restricted"
62 fi 55 fi
63 56
64 r=`${SSH} -$p -q -F $OBJ/ssh_config somehost 'echo true'` 57 r=`${SSH} -q -F $OBJ/ssh_config somehost 'echo true'`
65 if [ "$r" != "true" ]; then 58 if [ "$r" != "true" ]; then
66 fail "key option proto $p $from not allowed but should be" 59 fail "key option $from not allowed but should be"
67 fi 60 fi
68 done
69done 61done
70 62
71rm -f "$origkeys" 63rm -f "$origkeys"
diff --git a/regress/keygen-change.sh b/regress/keygen-change.sh
index e56185050..8b8acd52f 100644
--- a/regress/keygen-change.sh
+++ b/regress/keygen-change.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: keygen-change.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: keygen-change.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="change passphrase for key" 4tid="change passphrase for key"
@@ -7,9 +7,6 @@ S1="secret1"
7S2="2secret" 7S2="2secret"
8 8
9KEYTYPES=`${SSH} -Q key-plain` 9KEYTYPES=`${SSH} -Q key-plain`
10if ssh_version 1; then
11 KEYTYPES="${KEYTYPES} rsa1"
12fi
13 10
14for t in $KEYTYPES; do 11for t in $KEYTYPES; do
15 # generate user key for agent 12 # generate user key for agent
diff --git a/regress/keyscan.sh b/regress/keyscan.sh
index f97364b76..3bde1219a 100644
--- a/regress/keyscan.sh
+++ b/regress/keyscan.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: keyscan.sh,v 1.5 2015/09/11 03:44:21 djm Exp $ 1# $OpenBSD: keyscan.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="keyscan" 4tid="keyscan"
@@ -9,10 +9,6 @@ rm -f ${OBJ}/host.dsa
9start_sshd 9start_sshd
10 10
11KEYTYPES=`${SSH} -Q key-plain` 11KEYTYPES=`${SSH} -Q key-plain`
12if ssh_version 1; then
13 KEYTYPES="${KEYTYPES} rsa1"
14fi
15
16for t in $KEYTYPES; do 12for t in $KEYTYPES; do
17 trace "keyscan type $t" 13 trace "keyscan type $t"
18 ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \ 14 ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \
diff --git a/regress/keytype.sh b/regress/keytype.sh
index 8f697788f..88b022de4 100644
--- a/regress/keytype.sh
+++ b/regress/keytype.sh
@@ -1,13 +1,8 @@
1# $OpenBSD: keytype.sh,v 1.4 2015/07/10 06:23:25 markus Exp $ 1# $OpenBSD: keytype.sh,v 1.5 2017/03/20 22:08:06 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="login with different key types" 4tid="login with different key types"
5 5
6TIME=`which time 2>/dev/null`
7if test ! -x "$TIME"; then
8 TIME=""
9fi
10
11cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak 6cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
12cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak 7cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak
13 8
@@ -26,8 +21,8 @@ for kt in $ktypes; do
26 rm -f $OBJ/key.$kt 21 rm -f $OBJ/key.$kt
27 bits=`echo ${kt} | awk -F- '{print $2}'` 22 bits=`echo ${kt} | awk -F- '{print $2}'`
28 type=`echo ${kt} | awk -F- '{print $1}'` 23 type=`echo ${kt} | awk -F- '{print $1}'`
29 printf "keygen $type, $bits bits:\t" 24 verbose "keygen $type, $bits bits"
30 ${TIME} ${SSHKEYGEN} -b $bits -q -N '' -t $type -f $OBJ/key.$kt ||\ 25 ${SSHKEYGEN} -b $bits -q -N '' -t $type -f $OBJ/key.$kt ||\
31 fail "ssh-keygen for type $type, $bits bits failed" 26 fail "ssh-keygen for type $type, $bits bits failed"
32done 27done
33 28
@@ -63,8 +58,8 @@ for ut in $ktypes; do
63 ) > $OBJ/known_hosts 58 ) > $OBJ/known_hosts
64 cat $OBJ/key.$ut.pub > $OBJ/authorized_keys_$USER 59 cat $OBJ/key.$ut.pub > $OBJ/authorized_keys_$USER
65 for i in $tries; do 60 for i in $tries; do
66 printf "userkey $ut, hostkey ${ht}:\t" 61 verbose "userkey $ut, hostkey ${ht}"
67 ${TIME} ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true 62 ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
68 if [ $? -ne 0 ]; then 63 if [ $? -ne 0 ]; then
69 fail "ssh userkey $ut, hostkey $ht failed" 64 fail "ssh userkey $ut, hostkey $ht failed"
70 fi 65 fi
diff --git a/regress/localcommand.sh b/regress/localcommand.sh
index 220f19a4d..5224a16b2 100644
--- a/regress/localcommand.sh
+++ b/regress/localcommand.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: localcommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: localcommand.sh,v 1.4 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="localcommand" 4tid="localcommand"
@@ -6,10 +6,8 @@ tid="localcommand"
6echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy 6echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy
7echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy 7echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy
8 8
9for p in ${SSH_PROTOCOLS}; do 9verbose "test $tid: proto $p localcommand"
10 verbose "test $tid: proto $p localcommand" 10a=`${SSH} -F $OBJ/ssh_proxy somehost true`
11 a=`${SSH} -F $OBJ/ssh_proxy -$p somehost true` 11if [ "$a" != "foo" ] ; then
12 if [ "$a" != "foo" ] ; then 12 fail "$tid proto $p"
13 fail "$tid proto $p" 13fi
14 fi
15done
diff --git a/regress/login-timeout.sh b/regress/login-timeout.sh
index 12207fd99..4c2d07dc2 100644
--- a/regress/login-timeout.sh
+++ b/regress/login-timeout.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: login-timeout.sh,v 1.8 2016/12/16 01:06:27 dtucker Exp $ 1# $OpenBSD: login-timeout.sh,v 1.9 2017/08/07 00:53:51 dtucker Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="connect after login grace timeout" 4tid="connect after login grace timeout"
@@ -10,23 +10,9 @@ echo "LoginGraceTime 10s" >> $OBJ/sshd_config
10echo "MaxStartups 1" >> $OBJ/sshd_config 10echo "MaxStartups 1" >> $OBJ/sshd_config
11start_sshd 11start_sshd
12 12
13(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 & 13(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 &
14sleep 15 14sleep 15
15${SSH} -F $OBJ/ssh_config somehost true 15${SSH} -F $OBJ/ssh_config somehost true
16if [ $? -ne 0 ]; then 16if [ $? -ne 0 ]; then
17 fail "ssh connect after login grace timeout failed with privsep" 17 fail "ssh connect after login grace timeout failed"
18fi
19
20stop_sshd
21
22trace "test login grace without privsep"
23echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config
24start_sshd
25sleep 1
26
27(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 &
28sleep 15
29${SSH} -F $OBJ/ssh_config somehost true
30if [ $? -ne 0 ]; then
31 fail "ssh connect after login grace timeout failed without privsep"
32fi 18fi
diff --git a/regress/misc/fuzz-harness/Makefile b/regress/misc/fuzz-harness/Makefile
new file mode 100644
index 000000000..8fbfc20c6
--- /dev/null
+++ b/regress/misc/fuzz-harness/Makefile
@@ -0,0 +1,22 @@
1# NB. libssh and libopenbsd-compat should be built with the same sanitizer opts.
2CXX=clang++-3.9
3FUZZ_FLAGS=-fsanitize=address,undefined -fsanitize-coverage=edge
4FUZZ_LIBS=-lFuzzer
5
6CXXFLAGS=-O2 -g -Wall -Wextra -I ../../.. $(FUZZ_FLAGS)
7LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g $(FUZZ_FLAGS)
8LIBS=-lssh -lopenbsd-compat -lcrypto $(FUZZ_LIBS)
9
10all: pubkey_fuzz sig_fuzz
11
12.cc.o:
13 $(CXX) $(CXXFLAGS) -c $< -o $@
14
15pubkey_fuzz: pubkey_fuzz.o
16 $(CXX) -o $@ pubkey_fuzz.o $(LDFLAGS) $(LIBS)
17
18sig_fuzz: sig_fuzz.o
19 $(CXX) -o $@ sig_fuzz.o $(LDFLAGS) $(LIBS)
20
21clean:
22 -rm -f *.o pubkey_fuzz sig_fuzz
diff --git a/regress/misc/fuzz-harness/README b/regress/misc/fuzz-harness/README
new file mode 100644
index 000000000..ae6fbe75d
--- /dev/null
+++ b/regress/misc/fuzz-harness/README
@@ -0,0 +1 @@
This directory contains fuzzing harnesses for use with clang's libfuzzer.
diff --git a/regress/misc/fuzz-harness/pubkey_fuzz.cc b/regress/misc/fuzz-harness/pubkey_fuzz.cc
new file mode 100644
index 000000000..8bbc11093
--- /dev/null
+++ b/regress/misc/fuzz-harness/pubkey_fuzz.cc
@@ -0,0 +1,18 @@
1#include <stddef.h>
2#include <stdio.h>
3#include <stdint.h>
4
5extern "C" {
6
7#include "sshkey.h"
8
9int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
10{
11 struct sshkey *k = NULL;
12 int r = sshkey_from_blob(data, size, &k);
13 if (r == 0) sshkey_free(k);
14 return 0;
15}
16
17} // extern
18
diff --git a/regress/misc/fuzz-harness/sig_fuzz.cc b/regress/misc/fuzz-harness/sig_fuzz.cc
new file mode 100644
index 000000000..0e535b49a
--- /dev/null
+++ b/regress/misc/fuzz-harness/sig_fuzz.cc
@@ -0,0 +1,50 @@
1// cc_fuzz_target test for public key parsing.
2
3#include <stddef.h>
4#include <stdio.h>
5#include <stdint.h>
6#include <stdlib.h>
7#include <string.h>
8
9extern "C" {
10
11#include "includes.h"
12#include "sshkey.h"
13#include "ssherr.h"
14
15static struct sshkey *generate_or_die(int type, unsigned bits) {
16 int r;
17 struct sshkey *ret;
18 if ((r = sshkey_generate(type, bits, &ret)) != 0) {
19 fprintf(stderr, "generate(%d, %u): %s", type, bits, ssh_err(r));
20 abort();
21 }
22 return ret;
23}
24
25int LLVMFuzzerTestOneInput(const uint8_t* sig, size_t slen)
26{
27#ifdef WITH_OPENSSL
28 static struct sshkey *rsa = generate_or_die(KEY_RSA, 2048);
29 static struct sshkey *dsa = generate_or_die(KEY_DSA, 1024);
30 static struct sshkey *ecdsa256 = generate_or_die(KEY_ECDSA, 256);
31 static struct sshkey *ecdsa384 = generate_or_die(KEY_ECDSA, 384);
32 static struct sshkey *ecdsa521 = generate_or_die(KEY_ECDSA, 521);
33#endif
34 static struct sshkey *ed25519 = generate_or_die(KEY_ED25519, 0);
35 static const char *data = "If everyone started announcing his nose had "
36 "run away, I don’t know how it would all end";
37 static const size_t dlen = strlen(data);
38
39#ifdef WITH_OPENSSL
40 sshkey_verify(rsa, sig, slen, (const u_char *)data, dlen, 0);
41 sshkey_verify(dsa, sig, slen, (const u_char *)data, dlen, 0);
42 sshkey_verify(ecdsa256, sig, slen, (const u_char *)data, dlen, 0);
43 sshkey_verify(ecdsa384, sig, slen, (const u_char *)data, dlen, 0);
44 sshkey_verify(ecdsa521, sig, slen, (const u_char *)data, dlen, 0);
45#endif
46 sshkey_verify(ed25519, sig, slen, (const u_char *)data, dlen, 0);
47 return 0;
48}
49
50} // extern
diff --git a/regress/misc/kexfuzz/Makefile b/regress/misc/kexfuzz/Makefile
index 3018b632f..d0aca8dfe 100644
--- a/regress/misc/kexfuzz/Makefile
+++ b/regress/misc/kexfuzz/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.1 2016/03/04 02:30:37 djm Exp $ 1# $OpenBSD: Makefile,v 1.2 2017/04/17 11:02:31 jsg Exp $
2 2
3.include <bsd.own.mk> 3.include <bsd.own.mk>
4.include <bsd.obj.mk> 4.include <bsd.obj.mk>
@@ -49,7 +49,7 @@ CDIAGFLAGS+= -Wswitch
49CDIAGFLAGS+= -Wtrigraphs 49CDIAGFLAGS+= -Wtrigraphs
50CDIAGFLAGS+= -Wuninitialized 50CDIAGFLAGS+= -Wuninitialized
51CDIAGFLAGS+= -Wunused 51CDIAGFLAGS+= -Wunused
52.if ${COMPILER_VERSION} == "gcc4" 52.if ${COMPILER_VERSION:L} != "gcc3"
53CDIAGFLAGS+= -Wpointer-sign 53CDIAGFLAGS+= -Wpointer-sign
54CDIAGFLAGS+= -Wold-style-definition 54CDIAGFLAGS+= -Wold-style-definition
55.endif 55.endif
diff --git a/regress/misc/kexfuzz/kexfuzz.c b/regress/misc/kexfuzz/kexfuzz.c
index 67058027f..3e2c48160 100644
--- a/regress/misc/kexfuzz/kexfuzz.c
+++ b/regress/misc/kexfuzz/kexfuzz.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexfuzz.c,v 1.3 2016/10/11 21:49:54 djm Exp $ */ 1/* $OpenBSD: kexfuzz.c,v 1.4 2017/04/30 23:34:55 djm Exp $ */
2/* 2/*
3 * Fuzz harness for KEX code 3 * Fuzz harness for KEX code
4 * 4 *
@@ -418,7 +418,7 @@ main(int argc, char **argv)
418 close(fd); 418 close(fd);
419 /* XXX check that it is a private key */ 419 /* XXX check that it is a private key */
420 /* XXX support certificates */ 420 /* XXX support certificates */
421 if (key == NULL || key->type == KEY_UNSPEC || key->type == KEY_RSA1) 421 if (key == NULL || key->type == KEY_UNSPEC)
422 badusage("Invalid key file (-k flag)"); 422 badusage("Invalid key file (-k flag)");
423 423
424 /* Replace (fuzz) mode */ 424 /* Replace (fuzz) mode */
diff --git a/regress/multiplex.sh b/regress/multiplex.sh
index acb9234d9..078a53a88 100644
--- a/regress/multiplex.sh
+++ b/regress/multiplex.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: multiplex.sh,v 1.27 2014/12/22 06:14:29 djm Exp $ 1# $OpenBSD: multiplex.sh,v 1.28 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4CTL=/tmp/openssh.regress.ctl-sock.$$ 4CTL=/tmp/openssh.regress.ctl-sock.$$
@@ -101,7 +101,7 @@ for s in 0 1 4 5 44; do
101 ${SSH} -F $OBJ/ssh_config -S $CTL otherhost exit $s 101 ${SSH} -F $OBJ/ssh_config -S $CTL otherhost exit $s
102 r=$? 102 r=$?
103 if [ $r -ne $s ]; then 103 if [ $r -ne $s ]; then
104 fail "exit code mismatch for protocol $p: $r != $s" 104 fail "exit code mismatch: $r != $s"
105 fi 105 fi
106 106
107 # same with early close of stdout/err 107 # same with early close of stdout/err
@@ -110,7 +110,7 @@ for s in 0 1 4 5 44; do
110 exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' 110 exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\'
111 r=$? 111 r=$?
112 if [ $r -ne $s ]; then 112 if [ $r -ne $s ]; then
113 fail "exit code (with sleep) mismatch for protocol $p: $r != $s" 113 fail "exit code (with sleep) mismatch: $r != $s"
114 fi 114 fi
115done 115done
116 116
diff --git a/regress/principals-command.sh b/regress/principals-command.sh
index 9b38eb105..bcc68e80b 100644
--- a/regress/principals-command.sh
+++ b/regress/principals-command.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: principals-command.sh,v 1.3 2016/09/26 21:34:38 bluhm Exp $ 1# $OpenBSD: principals-command.sh,v 1.4 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="authorized principals command" 4tid="authorized principals command"
@@ -78,7 +78,7 @@ if [ -x $PRINCIPALS_COMMAND ]; then
78 # Empty authorized_principals 78 # Empty authorized_principals
79 verbose "$tid: ${_prefix} empty authorized_principals" 79 verbose "$tid: ${_prefix} empty authorized_principals"
80 echo > $OBJ/authorized_principals_$USER 80 echo > $OBJ/authorized_principals_$USER
81 ${SSH} -2i $OBJ/cert_user_key \ 81 ${SSH} -i $OBJ/cert_user_key \
82 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 82 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
83 if [ $? -eq 0 ]; then 83 if [ $? -eq 0 ]; then
84 fail "ssh cert connect succeeded unexpectedly" 84 fail "ssh cert connect succeeded unexpectedly"
@@ -87,7 +87,7 @@ if [ -x $PRINCIPALS_COMMAND ]; then
87 # Wrong authorized_principals 87 # Wrong authorized_principals
88 verbose "$tid: ${_prefix} wrong authorized_principals" 88 verbose "$tid: ${_prefix} wrong authorized_principals"
89 echo gregorsamsa > $OBJ/authorized_principals_$USER 89 echo gregorsamsa > $OBJ/authorized_principals_$USER
90 ${SSH} -2i $OBJ/cert_user_key \ 90 ${SSH} -i $OBJ/cert_user_key \
91 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 91 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
92 if [ $? -eq 0 ]; then 92 if [ $? -eq 0 ]; then
93 fail "ssh cert connect succeeded unexpectedly" 93 fail "ssh cert connect succeeded unexpectedly"
@@ -96,7 +96,7 @@ if [ -x $PRINCIPALS_COMMAND ]; then
96 # Correct authorized_principals 96 # Correct authorized_principals
97 verbose "$tid: ${_prefix} correct authorized_principals" 97 verbose "$tid: ${_prefix} correct authorized_principals"
98 echo mekmitasdigoat > $OBJ/authorized_principals_$USER 98 echo mekmitasdigoat > $OBJ/authorized_principals_$USER
99 ${SSH} -2i $OBJ/cert_user_key \ 99 ${SSH} -i $OBJ/cert_user_key \
100 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 100 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
101 if [ $? -ne 0 ]; then 101 if [ $? -ne 0 ]; then
102 fail "ssh cert connect failed" 102 fail "ssh cert connect failed"
@@ -105,7 +105,7 @@ if [ -x $PRINCIPALS_COMMAND ]; then
105 # authorized_principals with bad key option 105 # authorized_principals with bad key option
106 verbose "$tid: ${_prefix} authorized_principals bad key opt" 106 verbose "$tid: ${_prefix} authorized_principals bad key opt"
107 echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER 107 echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER
108 ${SSH} -2i $OBJ/cert_user_key \ 108 ${SSH} -i $OBJ/cert_user_key \
109 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 109 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
110 if [ $? -eq 0 ]; then 110 if [ $? -eq 0 ]; then
111 fail "ssh cert connect succeeded unexpectedly" 111 fail "ssh cert connect succeeded unexpectedly"
@@ -115,7 +115,7 @@ if [ -x $PRINCIPALS_COMMAND ]; then
115 verbose "$tid: ${_prefix} authorized_principals command=false" 115 verbose "$tid: ${_prefix} authorized_principals command=false"
116 echo 'command="false" mekmitasdigoat' > \ 116 echo 'command="false" mekmitasdigoat' > \
117 $OBJ/authorized_principals_$USER 117 $OBJ/authorized_principals_$USER
118 ${SSH} -2i $OBJ/cert_user_key \ 118 ${SSH} -i $OBJ/cert_user_key \
119 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 119 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
120 if [ $? -eq 0 ]; then 120 if [ $? -eq 0 ]; then
121 fail "ssh cert connect succeeded unexpectedly" 121 fail "ssh cert connect succeeded unexpectedly"
@@ -125,7 +125,7 @@ if [ -x $PRINCIPALS_COMMAND ]; then
125 verbose "$tid: ${_prefix} authorized_principals command=true" 125 verbose "$tid: ${_prefix} authorized_principals command=true"
126 echo 'command="true" mekmitasdigoat' > \ 126 echo 'command="true" mekmitasdigoat' > \
127 $OBJ/authorized_principals_$USER 127 $OBJ/authorized_principals_$USER
128 ${SSH} -2i $OBJ/cert_user_key \ 128 ${SSH} -i $OBJ/cert_user_key \
129 -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 129 -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1
130 if [ $? -ne 0 ]; then 130 if [ $? -ne 0 ]; then
131 fail "ssh cert connect failed" 131 fail "ssh cert connect failed"
@@ -144,7 +144,7 @@ if [ -x $PRINCIPALS_COMMAND ]; then
144 printf 'cert-authority,principals="gregorsamsa" ' 144 printf 'cert-authority,principals="gregorsamsa" '
145 cat $OBJ/user_ca_key.pub 145 cat $OBJ/user_ca_key.pub
146 ) > $OBJ/authorized_keys_$USER 146 ) > $OBJ/authorized_keys_$USER
147 ${SSH} -2i $OBJ/cert_user_key \ 147 ${SSH} -i $OBJ/cert_user_key \
148 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 148 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
149 if [ $? -eq 0 ]; then 149 if [ $? -eq 0 ]; then
150 fail "ssh cert connect succeeded unexpectedly" 150 fail "ssh cert connect succeeded unexpectedly"
@@ -156,7 +156,7 @@ if [ -x $PRINCIPALS_COMMAND ]; then
156 printf 'cert-authority,principals="mekmitasdigoat" ' 156 printf 'cert-authority,principals="mekmitasdigoat" '
157 cat $OBJ/user_ca_key.pub 157 cat $OBJ/user_ca_key.pub
158 ) > $OBJ/authorized_keys_$USER 158 ) > $OBJ/authorized_keys_$USER
159 ${SSH} -2i $OBJ/cert_user_key \ 159 ${SSH} -i $OBJ/cert_user_key \
160 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 160 -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
161 if [ $? -ne 0 ]; then 161 if [ $? -ne 0 ]; then
162 fail "ssh cert connect failed" 162 fail "ssh cert connect failed"
diff --git a/regress/proto-mismatch.sh b/regress/proto-mismatch.sh
index 9e8024beb..6ab28c9a7 100644
--- a/regress/proto-mismatch.sh
+++ b/regress/proto-mismatch.sh
@@ -1,21 +1,17 @@
1# $OpenBSD: proto-mismatch.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: proto-mismatch.sh,v 1.5 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="protocol version mismatch" 4tid="protocol version mismatch"
5 5
6mismatch () 6mismatch ()
7{ 7{
8 server=$1
9 client=$2 8 client=$2
10 banner=`echo ${client} | ${SSHD} -o "Protocol=${server}" -i -f ${OBJ}/sshd_proxy` 9 banner=`echo ${client} | ${SSHD} -i -f ${OBJ}/sshd_proxy`
11 r=$? 10 r=$?
12 trace "sshd prints ${banner}" 11 trace "sshd prints ${banner}"
13 if [ $r -ne 255 ]; then 12 if [ $r -ne 255 ]; then
14 fail "sshd prints ${banner} and accepts connect with version ${client}" 13 fail "sshd prints ${banner} but accepts version ${client}"
15 fi 14 fi
16} 15}
17 16
18mismatch 2 SSH-1.5-HALLO 17mismatch SSH-1.5-HALLO
19if ssh_version 1; then
20 mismatch 1 SSH-2.0-HALLO
21fi
diff --git a/regress/proto-version.sh b/regress/proto-version.sh
index cf4946115..1f33b1f00 100644
--- a/regress/proto-version.sh
+++ b/regress/proto-version.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: proto-version.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: proto-version.sh,v 1.7 2017/06/07 01:48:15 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="sshd version with different protocol combinations" 4tid="sshd version with different protocol combinations"
@@ -6,9 +6,8 @@ tid="sshd version with different protocol combinations"
6# we just start sshd in inetd mode and check the banner 6# we just start sshd in inetd mode and check the banner
7check_version () 7check_version ()
8{ 8{
9 version=$1 9 expect=$1
10 expect=$2 10 banner=`printf '' | ${SSHD} -i -f ${OBJ}/sshd_proxy`
11 banner=`printf '' | ${SSHD} -o "Protocol=${version}" -i -f ${OBJ}/sshd_proxy`
12 case ${banner} in 11 case ${banner} in
13 SSH-1.99-*) 12 SSH-1.99-*)
14 proto=199 13 proto=199
@@ -24,13 +23,8 @@ check_version ()
24 ;; 23 ;;
25 esac 24 esac
26 if [ ${expect} -ne ${proto} ]; then 25 if [ ${expect} -ne ${proto} ]; then
27 fail "wrong protocol version ${banner} for ${version}" 26 fail "wrong protocol version ${banner}"
28 fi 27 fi
29} 28}
30 29
31check_version 2 20 30check_version 20
32if ssh_version 1; then
33 check_version 2,1 199
34 check_version 1,2 199
35 check_version 1 15
36fi
diff --git a/regress/proxy-connect.sh b/regress/proxy-connect.sh
index b7a43fabe..f1b9d9f76 100644
--- a/regress/proxy-connect.sh
+++ b/regress/proxy-connect.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: proxy-connect.sh,v 1.9 2016/02/17 02:24:17 djm Exp $ 1# $OpenBSD: proxy-connect.sh,v 1.10 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="proxy connect" 4tid="proxy connect"
@@ -6,27 +6,22 @@ tid="proxy connect"
6mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig 6mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
7 7
8for ps in no yes; do 8for 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 for c in no yes; do
12 for p in ${SSH_PROTOCOLS}; do 12 verbose "plain username privsep=$ps comp=$c"
13 for c in no yes; do 13 opts="-oCompression=$c -F $OBJ/ssh_proxy"
14 verbose "plain username protocol $p privsep=$ps comp=$c" 14 SSH_CONNECTION=`${SSH} $opts 999.999.999.999 'echo $SSH_CONNECTION'`
15 opts="-$p -oCompression=$c -F $OBJ/ssh_proxy" 15 if [ $? -ne 0 ]; then
16 SSH_CONNECTION=`${SSH} $opts 999.999.999.999 'echo $SSH_CONNECTION'` 16 fail "ssh proxyconnect privsep=$ps comp=$c failed"
17 if [ $? -ne 0 ]; then 17 fi
18 fail "ssh proxyconnect protocol $p privsep=$ps comp=$c failed" 18 if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then
19 fi 19 fail "bad SSH_CONNECTION privsep=$ps comp=$c: " \
20 if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then 20 "$SSH_CONNECTION"
21 fail "bad SSH_CONNECTION protocol $p privsep=$ps comp=$c: " \ 21 fi
22 "$SSH_CONNECTION" 22 done
23 fi
24 done
25 done
26done 23done
27 24
28for p in ${SSH_PROTOCOLS}; do 25verbose "username with style"
29 verbose "username with style protocol $p" 26${SSH} -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \
30 ${SSH} -$p -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \ 27 fail "ssh proxyconnect failed"
31 fail "ssh proxyconnect protocol $p failed"
32done
diff --git a/regress/putty-ciphers.sh b/regress/putty-ciphers.sh
index 9adba674e..419daabba 100644
--- a/regress/putty-ciphers.sh
+++ b/regress/putty-ciphers.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: putty-ciphers.sh,v 1.5 2016/11/25 03:02:01 dtucker Exp $ 1# $OpenBSD: putty-ciphers.sh,v 1.6 2017/05/08 01:52:49 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="putty ciphers" 4tid="putty ciphers"
@@ -8,7 +8,7 @@ if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
8 exit 0 8 exit 0
9fi 9fi
10 10
11for c in aes blowfish 3des arcfour aes128-ctr aes192-ctr aes256-ctr ; do 11for c in aes 3des aes128-ctr aes192-ctr aes256-ctr ; do
12 verbose "$tid: cipher $c" 12 verbose "$tid: cipher $c"
13 cp ${OBJ}/.putty/sessions/localhost_proxy \ 13 cp ${OBJ}/.putty/sessions/localhost_proxy \
14 ${OBJ}/.putty/sessions/cipher_$c 14 ${OBJ}/.putty/sessions/cipher_$c
diff --git a/regress/putty-transfer.sh b/regress/putty-transfer.sh
index 8eb6ae0c0..32c79f9ea 100644
--- a/regress/putty-transfer.sh
+++ b/regress/putty-transfer.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: putty-transfer.sh,v 1.4 2016/11/25 03:02:01 dtucker Exp $ 1# $OpenBSD: putty-transfer.sh,v 1.5 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="putty transfer data" 4tid="putty transfer data"
@@ -8,33 +8,30 @@ if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then
8 exit 0 8 exit 0
9fi 9fi
10 10
11# XXX support protocol 1 too 11for c in 0 1 ; do
12for p in 2; do 12 verbose "$tid: compression $c"
13 for c in 0 1 ; do 13 rm -f ${COPY}
14 verbose "$tid: proto $p compression $c" 14 cp ${OBJ}/.putty/sessions/localhost_proxy \
15 ${OBJ}/.putty/sessions/compression_$c
16 echo "Compression=$c" >> ${OBJ}/.putty/sessions/kex_$k
17 env HOME=$PWD ${PLINK} -load compression_$c -batch \
18 -i putty.rsa cat ${DATA} > ${COPY}
19 if [ $? -ne 0 ]; then
20 fail "ssh cat $DATA failed"
21 fi
22 cmp ${DATA} ${COPY} || fail "corrupted copy"
23
24 for s in 10 100 1k 32k 64k 128k 256k; do
25 trace "compression $c dd-size ${s}"
15 rm -f ${COPY} 26 rm -f ${COPY}
16 cp ${OBJ}/.putty/sessions/localhost_proxy \ 27 dd if=$DATA obs=${s} 2> /dev/null | \
17 ${OBJ}/.putty/sessions/compression_$c 28 env HOME=$PWD ${PLINK} -load compression_$c \
18 echo "Compression=$c" >> ${OBJ}/.putty/sessions/kex_$k 29 -batch -i putty.rsa \
19 env HOME=$PWD ${PLINK} -load compression_$c -batch \ 30 "cat > ${COPY}"
20 -i putty.rsa$p cat ${DATA} > ${COPY}
21 if [ $? -ne 0 ]; then 31 if [ $? -ne 0 ]; then
22 fail "ssh cat $DATA failed" 32 fail "ssh cat $DATA failed"
23 fi 33 fi
24 cmp ${DATA} ${COPY} || fail "corrupted copy" 34 cmp $DATA ${COPY} || fail "corrupted copy"
25
26 for s in 10 100 1k 32k 64k 128k 256k; do
27 trace "proto $p compression $c dd-size ${s}"
28 rm -f ${COPY}
29 dd if=$DATA obs=${s} 2> /dev/null | \
30 env HOME=$PWD ${PLINK} -load compression_$c \
31 -batch -i putty.rsa$p \
32 "cat > ${COPY}"
33 if [ $? -ne 0 ]; then
34 fail "ssh cat $DATA failed"
35 fi
36 cmp $DATA ${COPY} || fail "corrupted copy"
37 done
38 done 35 done
39done 36done
40rm -f ${COPY} 37rm -f ${COPY}
diff --git a/regress/reconfigure.sh b/regress/reconfigure.sh
index eecddd3c7..dd15eddb2 100644
--- a/regress/reconfigure.sh
+++ b/regress/reconfigure.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: reconfigure.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: reconfigure.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="simple connect after reconfigure" 4tid="simple connect after reconfigure"
@@ -18,12 +18,10 @@ fi
18start_sshd 18start_sshd
19 19
20trace "connect before restart" 20trace "connect before restart"
21for p in ${SSH_PROTOCOLS} ; do 21${SSH} -F $OBJ/ssh_config somehost true
22 ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true 22if [ $? -ne 0 ]; then
23 if [ $? -ne 0 ]; then 23 fail "ssh connect with failed before reconfigure"
24 fail "ssh connect with protocol $p failed before reconfigure" 24fi
25 fi
26done
27 25
28PID=`$SUDO cat $PIDFILE` 26PID=`$SUDO cat $PIDFILE`
29rm -f $PIDFILE 27rm -f $PIDFILE
@@ -39,9 +37,7 @@ done
39test -f $PIDFILE || fatal "sshd did not restart" 37test -f $PIDFILE || fatal "sshd did not restart"
40 38
41trace "connect after restart" 39trace "connect after restart"
42for p in ${SSH_PROTOCOLS} ; do 40${SSH} -F $OBJ/ssh_config somehost true
43 ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true 41if [ $? -ne 0 ]; then
44 if [ $? -ne 0 ]; then 42 fail "ssh connect with failed after reconfigure"
45 fail "ssh connect with protocol $p failed after reconfigure" 43fi
46 fi
47done
diff --git a/regress/reexec.sh b/regress/reexec.sh
index 72957d4cd..2192456cd 100644
--- a/regress/reexec.sh
+++ b/regress/reexec.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: reexec.sh,v 1.10 2016/12/16 01:06:27 dtucker Exp $ 1# $OpenBSD: reexec.sh,v 1.12 2017/08/07 03:52:55 dtucker Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="reexec tests" 4tid="reexec tests"
@@ -19,16 +19,13 @@ start_sshd_copy ()
19copy_tests () 19copy_tests ()
20{ 20{
21 rm -f ${COPY} 21 rm -f ${COPY}
22 for p in ${SSH_PROTOCOLS} ; do 22 ${SSH} -nq -F $OBJ/ssh_config somehost \
23 verbose "$tid: proto $p" 23 cat ${DATA} > ${COPY}
24 ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \ 24 if [ $? -ne 0 ]; then
25 cat ${DATA} > ${COPY} 25 fail "ssh cat $DATA failed"
26 if [ $? -ne 0 ]; then 26 fi
27 fail "ssh cat $DATA failed" 27 cmp ${DATA} ${COPY} || fail "corrupted copy"
28 fi 28 rm -f ${COPY}
29 cmp ${DATA} ${COPY} || fail "corrupted copy"
30 rm -f ${COPY}
31 done
32} 29}
33 30
34verbose "test config passing" 31verbose "test config passing"
@@ -54,17 +51,4 @@ rm -f $SSHD_COPY
54copy_tests 51copy_tests
55 52
56stop_sshd 53stop_sshd
57
58verbose "test reexec fallback without privsep"
59
60cp $OBJ/sshd_config.orig $OBJ/sshd_config
61echo "UsePrivilegeSeparation=no" >> $OBJ/sshd_config
62
63start_sshd_copy
64rm -f $SSHD_COPY
65
66copy_tests
67
68stop_sshd
69
70fi 54fi
diff --git a/regress/ssh-com.sh b/regress/ssh-com.sh
index 4371d5279..b1a2505d1 100644
--- a/regress/ssh-com.sh
+++ b/regress/ssh-com.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: ssh-com.sh,v 1.9 2015/05/08 07:29:00 djm Exp $ 1# $OpenBSD: ssh-com.sh,v 1.10 2017/05/08 01:52:49 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="connect to ssh.com server" 4tid="connect to ssh.com server"
@@ -87,7 +87,7 @@ for v in ${VERSIONS}; do
87 fail "ssh connect to sshd2 ${v} failed" 87 fail "ssh connect to sshd2 ${v} failed"
88 fi 88 fi
89 89
90 ciphers="3des-cbc blowfish-cbc arcfour" 90 ciphers="3des-cbc"
91 macs="hmac-md5" 91 macs="hmac-md5"
92 case $v in 92 case $v in
93 2.4.*) 93 2.4.*)
diff --git a/regress/stderr-after-eof.sh b/regress/stderr-after-eof.sh
index 218ac6b68..9065245e8 100644
--- a/regress/stderr-after-eof.sh
+++ b/regress/stderr-after-eof.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: stderr-after-eof.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $ 1# $OpenBSD: stderr-after-eof.sh,v 1.3 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="stderr data after eof" 4tid="stderr data after eof"
@@ -10,7 +10,7 @@ for i in 1 2 3 4 5 6; do
10 (date;echo $i) | md5 >> ${DATA} 10 (date;echo $i) | md5 >> ${DATA}
11done 11done
12 12
13${SSH} -2 -F $OBJ/ssh_proxy otherhost \ 13${SSH} -F $OBJ/ssh_proxy otherhost \
14 exec sh -c \'"exec > /dev/null; sleep 2; cat ${DATA} 1>&2 $s"\' \ 14 exec sh -c \'"exec > /dev/null; sleep 2; cat ${DATA} 1>&2 $s"\' \
15 2> ${COPY} 15 2> ${COPY}
16r=$? 16r=$?
diff --git a/regress/stderr-data.sh b/regress/stderr-data.sh
index 8c8149a73..0ceb72b3a 100644
--- a/regress/stderr-data.sh
+++ b/regress/stderr-data.sh
@@ -1,13 +1,12 @@
1# $OpenBSD: stderr-data.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: stderr-data.sh,v 1.5 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="stderr data transfer" 4tid="stderr data transfer"
5 5
6for n in '' -n; do 6for n in '' -n; do
7for p in ${SSH_PROTOCOLS}; do 7 verbose "test $tid: ($n)"
8 verbose "test $tid: proto $p ($n)" 8 ${SSH} $n -F $OBJ/ssh_proxy otherhost exec \
9 ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ 9 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"\' \
11 2> ${COPY} 10 2> ${COPY}
12 r=$? 11 r=$?
13 if [ $r -ne 0 ]; then 12 if [ $r -ne 0 ]; then
@@ -16,8 +15,8 @@ for p in ${SSH_PROTOCOLS}; do
16 cmp ${DATA} ${COPY} || fail "stderr corrupt" 15 cmp ${DATA} ${COPY} || fail "stderr corrupt"
17 rm -f ${COPY} 16 rm -f ${COPY}
18 17
19 ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ 18 ${SSH} $n -F $OBJ/ssh_proxy otherhost exec \
20 exec sh -c \'"echo a; exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ 19 sh -c \'"echo a; exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \
21 > /dev/null 2> ${COPY} 20 > /dev/null 2> ${COPY}
22 r=$? 21 r=$?
23 if [ $r -ne 0 ]; then 22 if [ $r -ne 0 ]; then
@@ -26,4 +25,3 @@ for p in ${SSH_PROTOCOLS}; do
26 cmp ${DATA} ${COPY} || fail "stderr corrupt" 25 cmp ${DATA} ${COPY} || fail "stderr corrupt"
27 rm -f ${COPY} 26 rm -f ${COPY}
28done 27done
29done
diff --git a/regress/test-exec.sh b/regress/test-exec.sh
index dc033cd96..68f010b70 100644
--- a/regress/test-exec.sh
+++ b/regress/test-exec.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: test-exec.sh,v 1.59 2017/02/07 23:03:11 dtucker Exp $ 1# $OpenBSD: test-exec.sh,v 1.61 2017/07/28 10:32:08 dtucker Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4#SUDO=sudo 4#SUDO=sudo
@@ -130,12 +130,6 @@ if [ "x$TEST_SSH_CONCH" != "x" ]; then
130 esac 130 esac
131fi 131fi
132 132
133SSH_PROTOCOLS=2
134#SSH_PROTOCOLS=`$SSH -Q protocol-version`
135if [ "x$TEST_SSH_PROTOCOLS" != "x" ]; then
136 SSH_PROTOCOLS="${TEST_SSH_PROTOCOLS}"
137fi
138
139# Path to sshd must be absolute for rexec 133# Path to sshd must be absolute for rexec
140case "$SSHD" in 134case "$SSHD" in
141/*) ;; 135/*) ;;
@@ -310,8 +304,15 @@ stop_sshd ()
310 i=`expr $i + 1` 304 i=`expr $i + 1`
311 sleep $i 305 sleep $i
312 done 306 done
313 test -f $PIDFILE && \ 307 if test -f $PIDFILE; then
314 fatal "sshd didn't exit port $PORT pid $pid" 308 if $SUDO kill -0 $pid; then
309 echo "sshd didn't exit " \
310 "port $PORT pid $pid"
311 else
312 echo "sshd died without cleanup"
313 fi
314 exit 1
315 fi
315 fi 316 fi
316 fi 317 fi
317 fi 318 fi
@@ -386,22 +387,11 @@ fatal ()
386 exit $RESULT 387 exit $RESULT
387} 388}
388 389
389ssh_version ()
390{
391 echo ${SSH_PROTOCOLS} | grep "$1" >/dev/null
392}
393
394RESULT=0 390RESULT=0
395PIDFILE=$OBJ/pidfile 391PIDFILE=$OBJ/pidfile
396 392
397trap fatal 3 2 393trap fatal 3 2
398 394
399if ssh_version 1; then
400 PROTO="2,1"
401else
402 PROTO="2"
403fi
404
405# create server config 395# create server config
406cat << EOF > $OBJ/sshd_config 396cat << EOF > $OBJ/sshd_config
407 StrictModes no 397 StrictModes no
@@ -460,11 +450,8 @@ fi
460 450
461rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER 451rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER
462 452
463if ssh_version 1; then 453SSH_KEYTYPES="rsa ed25519"
464 SSH_KEYTYPES="rsa rsa1" 454
465else
466 SSH_KEYTYPES="rsa ed25519"
467fi
468trace "generate keys" 455trace "generate keys"
469for t in ${SSH_KEYTYPES}; do 456for t in ${SSH_KEYTYPES}; do
470 # generate user key 457 # generate user key
diff --git a/regress/transfer.sh b/regress/transfer.sh
index 36c14634a..cf174a006 100644
--- a/regress/transfer.sh
+++ b/regress/transfer.sh
@@ -1,26 +1,23 @@
1# $OpenBSD: transfer.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ 1# $OpenBSD: transfer.sh,v 1.4 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="transfer data" 4tid="transfer data"
5 5
6for p in ${SSH_PROTOCOLS}; do 6rm -f ${COPY}
7 verbose "$tid: proto $p" 7${SSH} -n -q -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY}
8if [ $? -ne 0 ]; then
9 fail "ssh cat $DATA failed"
10fi
11cmp ${DATA} ${COPY} || fail "corrupted copy"
12
13for s in 10 100 1k 32k 64k 128k 256k; do
14 trace "dd-size ${s}"
8 rm -f ${COPY} 15 rm -f ${COPY}
9 ${SSH} -n -q -$p -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY} 16 dd if=$DATA obs=${s} 2> /dev/null | \
17 ${SSH} -q -F $OBJ/ssh_proxy somehost "cat > ${COPY}"
10 if [ $? -ne 0 ]; then 18 if [ $? -ne 0 ]; then
11 fail "ssh cat $DATA failed" 19 fail "ssh cat $DATA failed"
12 fi 20 fi
13 cmp ${DATA} ${COPY} || fail "corrupted copy" 21 cmp $DATA ${COPY} || fail "corrupted copy"
14
15 for s in 10 100 1k 32k 64k 128k 256k; do
16 trace "proto $p dd-size ${s}"
17 rm -f ${COPY}
18 dd if=$DATA obs=${s} 2> /dev/null | \
19 ${SSH} -q -$p -F $OBJ/ssh_proxy somehost "cat > ${COPY}"
20 if [ $? -ne 0 ]; then
21 fail "ssh cat $DATA failed"
22 fi
23 cmp $DATA ${COPY} || fail "corrupted copy"
24 done
25done 22done
26rm -f ${COPY} 23rm -f ${COPY}
diff --git a/regress/try-ciphers.sh b/regress/try-ciphers.sh
index 889a735d2..e04268ba3 100644
--- a/regress/try-ciphers.sh
+++ b/regress/try-ciphers.sh
@@ -1,4 +1,4 @@
1# $OpenBSD: try-ciphers.sh,v 1.25 2015/03/24 20:22:17 markus Exp $ 1# $OpenBSD: try-ciphers.sh,v 1.26 2017/04/30 23:34:55 djm Exp $
2# Placed in the Public Domain. 2# Placed in the Public Domain.
3 3
4tid="try ciphers" 4tid="try ciphers"
@@ -8,14 +8,14 @@ cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
8for c in `${SSH} -Q cipher`; do 8for c in `${SSH} -Q cipher`; do
9 n=0 9 n=0
10 for m in `${SSH} -Q mac`; do 10 for m in `${SSH} -Q mac`; do
11 trace "proto 2 cipher $c mac $m" 11 trace "cipher $c mac $m"
12 verbose "test $tid: proto 2 cipher $c mac $m" 12 verbose "test $tid: cipher $c mac $m"
13 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy 13 cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
14 echo "Ciphers=$c" >> $OBJ/sshd_proxy 14 echo "Ciphers=$c" >> $OBJ/sshd_proxy
15 echo "MACs=$m" >> $OBJ/sshd_proxy 15 echo "MACs=$m" >> $OBJ/sshd_proxy
16 ${SSH} -F $OBJ/ssh_proxy -2 -m $m -c $c somehost true 16 ${SSH} -F $OBJ/ssh_proxy -m $m -c $c somehost true
17 if [ $? -ne 0 ]; then 17 if [ $? -ne 0 ]; then
18 fail "ssh -2 failed with mac $m cipher $c" 18 fail "ssh failed with mac $m cipher $c"
19 fi 19 fi
20 # No point trying all MACs for AEAD ciphers since they 20 # No point trying all MACs for AEAD ciphers since they
21 # are ignored. 21 # are ignored.
@@ -26,17 +26,3 @@ for c in `${SSH} -Q cipher`; do
26 done 26 done
27done 27done
28 28
29if ssh_version 1; then
30 ciphers="3des blowfish"
31else
32 ciphers=""
33fi
34for c in $ciphers; do
35 trace "proto 1 cipher $c"
36 verbose "test $tid: proto 1 cipher $c"
37 ${SSH} -F $OBJ/ssh_proxy -1 -c $c somehost true
38 if [ $? -ne 0 ]; then
39 fail "ssh -1 failed with cipher $c"
40 fi
41done
42
diff --git a/regress/unittests/Makefile.inc b/regress/unittests/Makefile.inc
index 3d9eaba5c..36d1ff42c 100644
--- a/regress/unittests/Makefile.inc
+++ b/regress/unittests/Makefile.inc
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile.inc,v 1.9 2016/11/01 13:43:27 tb Exp $ 1# $OpenBSD: Makefile.inc,v 1.11 2017/04/30 23:33:48 djm Exp $
2 2
3.include <bsd.own.mk> 3.include <bsd.own.mk>
4.include <bsd.obj.mk> 4.include <bsd.obj.mk>
@@ -30,7 +30,7 @@ CDIAGFLAGS+= -Wswitch
30CDIAGFLAGS+= -Wtrigraphs 30CDIAGFLAGS+= -Wtrigraphs
31CDIAGFLAGS+= -Wuninitialized 31CDIAGFLAGS+= -Wuninitialized
32CDIAGFLAGS+= -Wunused 32CDIAGFLAGS+= -Wunused
33.if ${COMPILER_VERSION} == "gcc4" 33.if ${COMPILER_VERSION:L} != "gcc3"
34CDIAGFLAGS+= -Wpointer-sign 34CDIAGFLAGS+= -Wpointer-sign
35CDIAGFLAGS+= -Wold-style-definition 35CDIAGFLAGS+= -Wold-style-definition
36.endif 36.endif
diff --git a/regress/unittests/hostkeys/mktestdata.sh b/regress/unittests/hostkeys/mktestdata.sh
index 36890ba11..5a46de990 100644
--- a/regress/unittests/hostkeys/mktestdata.sh
+++ b/regress/unittests/hostkeys/mktestdata.sh
@@ -1,11 +1,11 @@
1#!/bin/sh 1#!/bin/sh
2# $OpenBSD: mktestdata.sh,v 1.1 2015/02/16 22:18:34 djm Exp $ 2# $OpenBSD: mktestdata.sh,v 1.2 2017/04/30 23:33:48 djm Exp $
3 3
4set -ex 4set -ex
5 5
6cd testdata 6cd testdata
7 7
8rm -f rsa1* rsa* dsa* ecdsa* ed25519* 8rm -f rsa* dsa* ecdsa* ed25519*
9rm -f known_hosts* 9rm -f known_hosts*
10 10
11gen_all() { 11gen_all() {
@@ -13,13 +13,12 @@ gen_all() {
13 _ecdsa_bits=256 13 _ecdsa_bits=256
14 test "x$_n" = "x1" && _ecdsa_bits=384 14 test "x$_n" = "x1" && _ecdsa_bits=384
15 test "x$_n" = "x2" && _ecdsa_bits=521 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 16 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 17 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 18 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 19 ssh-keygen -qt ed25519 -C "ED25519 #$_n" -N "" -f ed25519_$_n
21 # Don't need private keys 20 # Don't need private keys
22 rm -f rsa1_$_n rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n 21 rm -f rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n
23} 22}
24 23
25hentries() { 24hentries() {
@@ -64,7 +63,6 @@ rm -f known_hosts_hash_frag.old
64 echo 63 echo
65 64
66 echo "# Revoked and CA keys" 65 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 66 printf "@revoked sisyphus.example.com " ; cat ed25519_4.pub
69 printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub 67 printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub
70 printf "@cert-authority *.example.com " ; cat dsa_4.pub 68 printf "@cert-authority *.example.com " ; cat dsa_4.pub
@@ -72,19 +70,13 @@ rm -f known_hosts_hash_frag.old
72 printf "\n" 70 printf "\n"
73 echo "# Some invalid lines" 71 echo "# Some invalid lines"
74 # Invalid marker 72 # Invalid marker
75 printf "@what sisyphus.example.com " ; cat rsa1_1.pub 73 printf "@what sisyphus.example.com " ; cat dsa_1.pub
76 # Key missing 74 # Key missing
77 echo "sisyphus.example.com " 75 echo "sisyphus.example.com "
78 # Key blob missing 76 # Key blob missing
79 echo "prometheus.example.com ssh-ed25519 " 77 echo "prometheus.example.com ssh-ed25519 "
80 # Key blob truncated 78 # Key blob truncated
81 echo "sisyphus.example.com ssh-dsa AAAATgAAAAdz" 79 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 80 # Invalid type
89 echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" 81 echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg=="
90 # Type mismatch with blob 82 # Type mismatch with blob
diff --git a/regress/unittests/hostkeys/test_iterate.c b/regress/unittests/hostkeys/test_iterate.c
index 2eaaf063a..751825dda 100644
--- a/regress/unittests/hostkeys/test_iterate.c
+++ b/regress/unittests/hostkeys/test_iterate.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: test_iterate.c,v 1.4 2015/03/31 22:59:01 djm Exp $ */ 1/* $OpenBSD: test_iterate.c,v 1.5 2017/04/30 23:33:48 djm Exp $ */
2/* 2/*
3 * Regress test for hostfile.h hostkeys_foreach() 3 * Regress test for hostfile.h hostkeys_foreach()
4 * 4 *
@@ -90,14 +90,6 @@ check(struct hostkey_foreach_line *l, void *_ctx)
90 expected_keytype = (parse_key || expected->no_parse_keytype < 0) ? 90 expected_keytype = (parse_key || expected->no_parse_keytype < 0) ?
91 expected->l.keytype : expected->no_parse_keytype; 91 expected->l.keytype : expected->no_parse_keytype;
92 92
93#ifndef WITH_SSH1
94 if (parse_key && (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 93#ifndef OPENSSL_HAS_ECC
102 if (expected->l.keytype == KEY_ECDSA || 94 if (expected->l.keytype == KEY_ECDSA ||
103 expected->no_parse_keytype == KEY_ECDSA) { 95 expected->no_parse_keytype == KEY_ECDSA) {
@@ -150,10 +142,6 @@ prepare_expected(struct expected *expected, size_t n)
150 for (i = 0; i < n; i++) { 142 for (i = 0; i < n; i++) {
151 if (expected[i].key_file == NULL) 143 if (expected[i].key_file == NULL)
152 continue; 144 continue;
153#ifndef WITH_SSH1
154 if (expected[i].l.keytype == KEY_RSA1)
155 continue;
156#endif
157#ifndef OPENSSL_HAS_ECC 145#ifndef OPENSSL_HAS_ECC
158 if (expected[i].l.keytype == KEY_ECDSA) 146 if (expected[i].l.keytype == KEY_ECDSA)
159 continue; 147 continue;
@@ -217,22 +205,9 @@ struct expected expected_full[] = {
217 NULL, /* filled at runtime */ 205 NULL, /* filled at runtime */
218 "ED25519 #1", 206 "ED25519 #1",
219 } }, 207 } },
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, { 208 { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
234 NULL, 209 NULL,
235 6, 210 5,
236 HKF_STATUS_OK, 211 HKF_STATUS_OK,
237 0, 212 0,
238 NULL, 213 NULL,
@@ -245,7 +220,7 @@ struct expected expected_full[] = {
245 } }, 220 } },
246 { NULL, -1, -1, 0, 0, 0, 0, -1, { 221 { NULL, -1, -1, 0, 0, 0, 0, -1, {
247 NULL, 222 NULL,
248 7, 223 6,
249 HKF_STATUS_COMMENT, 224 HKF_STATUS_COMMENT,
250 0, 225 0,
251 "", 226 "",
@@ -258,7 +233,7 @@ struct expected expected_full[] = {
258 } }, 233 } },
259 { NULL, -1, -1, 0, 0, 0, 0, -1, { 234 { NULL, -1, -1, 0, 0, 0, 0, -1, {
260 NULL, 235 NULL,
261 8, 236 7,
262 HKF_STATUS_COMMENT, 237 HKF_STATUS_COMMENT,
263 0, 238 0,
264 "# Plain host keys, hostnames + addresses", 239 "# Plain host keys, hostnames + addresses",
@@ -271,7 +246,7 @@ struct expected expected_full[] = {
271 } }, 246 } },
272 { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 247 { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
273 NULL, 248 NULL,
274 9, 249 8,
275 HKF_STATUS_OK, 250 HKF_STATUS_OK,
276 0, 251 0,
277 NULL, 252 NULL,
@@ -284,7 +259,7 @@ struct expected expected_full[] = {
284 } }, 259 } },
285 { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 260 { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
286 NULL, 261 NULL,
287 10, 262 9,
288 HKF_STATUS_OK, 263 HKF_STATUS_OK,
289 0, 264 0,
290 NULL, 265 NULL,
@@ -297,7 +272,7 @@ struct expected expected_full[] = {
297 } }, 272 } },
298 { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 273 { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
299 NULL, 274 NULL,
300 11, 275 10,
301 HKF_STATUS_OK, 276 HKF_STATUS_OK,
302 0, 277 0,
303 NULL, 278 NULL,
@@ -308,22 +283,9 @@ struct expected expected_full[] = {
308 NULL, /* filled at runtime */ 283 NULL, /* filled at runtime */
309 "ED25519 #2", 284 "ED25519 #2",
310 } }, 285 } },
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, { 286 { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
325 NULL, 287 NULL,
326 13, 288 11,
327 HKF_STATUS_OK, 289 HKF_STATUS_OK,
328 0, 290 0,
329 NULL, 291 NULL,
@@ -336,7 +298,7 @@ struct expected expected_full[] = {
336 } }, 298 } },
337 { NULL, -1, -1, 0, 0, 0, 0, -1, { 299 { NULL, -1, -1, 0, 0, 0, 0, -1, {
338 NULL, 300 NULL,
339 14, 301 12,
340 HKF_STATUS_COMMENT, 302 HKF_STATUS_COMMENT,
341 0, 303 0,
342 "", 304 "",
@@ -349,7 +311,7 @@ struct expected expected_full[] = {
349 } }, 311 } },
350 { NULL, -1, -1, 0, 0, 0, 0, -1, { 312 { NULL, -1, -1, 0, 0, 0, 0, -1, {
351 NULL, 313 NULL,
352 15, 314 13,
353 HKF_STATUS_COMMENT, 315 HKF_STATUS_COMMENT,
354 0, 316 0,
355 "# Some hosts with wildcard names / IPs", 317 "# Some hosts with wildcard names / IPs",
@@ -362,7 +324,7 @@ struct expected expected_full[] = {
362 } }, 324 } },
363 { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 325 { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
364 NULL, 326 NULL,
365 16, 327 14,
366 HKF_STATUS_OK, 328 HKF_STATUS_OK,
367 0, 329 0,
368 NULL, 330 NULL,
@@ -375,7 +337,7 @@ struct expected expected_full[] = {
375 } }, 337 } },
376 { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 338 { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
377 NULL, 339 NULL,
378 17, 340 15,
379 HKF_STATUS_OK, 341 HKF_STATUS_OK,
380 0, 342 0,
381 NULL, 343 NULL,
@@ -388,7 +350,7 @@ struct expected expected_full[] = {
388 } }, 350 } },
389 { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { 351 { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
390 NULL, 352 NULL,
391 18, 353 16,
392 HKF_STATUS_OK, 354 HKF_STATUS_OK,
393 0, 355 0,
394 NULL, 356 NULL,
@@ -399,22 +361,9 @@ struct expected expected_full[] = {
399 NULL, /* filled at runtime */ 361 NULL, /* filled at runtime */
400 "ED25519 #3", 362 "ED25519 #3",
401 } }, 363 } },
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, { 364 { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, {
416 NULL, 365 NULL,
417 20, 366 17,
418 HKF_STATUS_OK, 367 HKF_STATUS_OK,
419 0, 368 0,
420 NULL, 369 NULL,
@@ -427,7 +376,7 @@ struct expected expected_full[] = {
427 } }, 376 } },
428 { NULL, -1, -1, 0, 0, 0, 0, -1, { 377 { NULL, -1, -1, 0, 0, 0, 0, -1, {
429 NULL, 378 NULL,
430 21, 379 18,
431 HKF_STATUS_COMMENT, 380 HKF_STATUS_COMMENT,
432 0, 381 0,
433 "", 382 "",
@@ -440,7 +389,7 @@ struct expected expected_full[] = {
440 } }, 389 } },
441 { NULL, -1, -1, 0, 0, 0, 0, -1, { 390 { NULL, -1, -1, 0, 0, 0, 0, -1, {
442 NULL, 391 NULL,
443 22, 392 19,
444 HKF_STATUS_COMMENT, 393 HKF_STATUS_COMMENT,
445 0, 394 0,
446 "# Hashed hostname and address entries", 395 "# Hashed hostname and address entries",
@@ -453,7 +402,7 @@ struct expected expected_full[] = {
453 } }, 402 } },
454 { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { 403 { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
455 NULL, 404 NULL,
456 23, 405 20,
457 HKF_STATUS_OK, 406 HKF_STATUS_OK,
458 0, 407 0,
459 NULL, 408 NULL,
@@ -466,7 +415,7 @@ struct expected expected_full[] = {
466 } }, 415 } },
467 { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { 416 { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
468 NULL, 417 NULL,
469 24, 418 21,
470 HKF_STATUS_OK, 419 HKF_STATUS_OK,
471 0, 420 0,
472 NULL, 421 NULL,
@@ -479,7 +428,7 @@ struct expected expected_full[] = {
479 } }, 428 } },
480 { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { 429 { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
481 NULL, 430 NULL,
482 25, 431 22,
483 HKF_STATUS_OK, 432 HKF_STATUS_OK,
484 0, 433 0,
485 NULL, 434 NULL,
@@ -490,22 +439,9 @@ struct expected expected_full[] = {
490 NULL, /* filled at runtime */ 439 NULL, /* filled at runtime */
491 "ED25519 #5", 440 "ED25519 #5",
492 } }, 441 } },
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, { 442 { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, {
507 NULL, 443 NULL,
508 27, 444 23,
509 HKF_STATUS_OK, 445 HKF_STATUS_OK,
510 0, 446 0,
511 NULL, 447 NULL,
@@ -518,7 +454,7 @@ struct expected expected_full[] = {
518 } }, 454 } },
519 { NULL, -1, -1, 0, 0, 0, 0, -1, { 455 { NULL, -1, -1, 0, 0, 0, 0, -1, {
520 NULL, 456 NULL,
521 28, 457 24,
522 HKF_STATUS_COMMENT, 458 HKF_STATUS_COMMENT,
523 0, 459 0,
524 "", 460 "",
@@ -536,7 +472,7 @@ struct expected expected_full[] = {
536 */ 472 */
537 { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { 473 { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
538 NULL, 474 NULL,
539 29, 475 25,
540 HKF_STATUS_OK, 476 HKF_STATUS_OK,
541 0, 477 0,
542 NULL, 478 NULL,
@@ -549,7 +485,7 @@ struct expected expected_full[] = {
549 } }, 485 } },
550 { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { 486 { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
551 NULL, 487 NULL,
552 30, 488 26,
553 HKF_STATUS_OK, 489 HKF_STATUS_OK,
554 0, 490 0,
555 NULL, 491 NULL,
@@ -562,7 +498,7 @@ struct expected expected_full[] = {
562 } }, 498 } },
563 { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { 499 { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
564 NULL, 500 NULL,
565 31, 501 27,
566 HKF_STATUS_OK, 502 HKF_STATUS_OK,
567 0, 503 0,
568 NULL, 504 NULL,
@@ -575,7 +511,7 @@ struct expected expected_full[] = {
575 } }, 511 } },
576 { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { 512 { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
577 NULL, 513 NULL,
578 32, 514 28,
579 HKF_STATUS_OK, 515 HKF_STATUS_OK,
580 0, 516 0,
581 NULL, 517 NULL,
@@ -588,7 +524,7 @@ struct expected expected_full[] = {
588 } }, 524 } },
589 { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { 525 { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
590 NULL, 526 NULL,
591 33, 527 29,
592 HKF_STATUS_OK, 528 HKF_STATUS_OK,
593 0, 529 0,
594 NULL, 530 NULL,
@@ -601,7 +537,7 @@ struct expected expected_full[] = {
601 } }, 537 } },
602 { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { 538 { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
603 NULL, 539 NULL,
604 34, 540 30,
605 HKF_STATUS_OK, 541 HKF_STATUS_OK,
606 0, 542 0,
607 NULL, 543 NULL,
@@ -614,7 +550,7 @@ struct expected expected_full[] = {
614 } }, 550 } },
615 { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { 551 { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
616 NULL, 552 NULL,
617 35, 553 31,
618 HKF_STATUS_OK, 554 HKF_STATUS_OK,
619 0, 555 0,
620 NULL, 556 NULL,
@@ -627,7 +563,7 @@ struct expected expected_full[] = {
627 } }, 563 } },
628 { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { 564 { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
629 NULL, 565 NULL,
630 36, 566 32,
631 HKF_STATUS_OK, 567 HKF_STATUS_OK,
632 0, 568 0,
633 NULL, 569 NULL,
@@ -640,7 +576,7 @@ struct expected expected_full[] = {
640 } }, 576 } },
641 { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { 577 { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
642 NULL, 578 NULL,
643 37, 579 33,
644 HKF_STATUS_OK, 580 HKF_STATUS_OK,
645 0, 581 0,
646 NULL, 582 NULL,
@@ -651,48 +587,9 @@ struct expected expected_full[] = {
651 NULL, /* filled at runtime */ 587 NULL, /* filled at runtime */
652 "ED25519 #6", 588 "ED25519 #6",
653 } }, 589 } },
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, { 590 { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, {
694 NULL, 591 NULL,
695 41, 592 34,
696 HKF_STATUS_OK, 593 HKF_STATUS_OK,
697 0, 594 0,
698 NULL, 595 NULL,
@@ -705,7 +602,7 @@ struct expected expected_full[] = {
705 } }, 602 } },
706 { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { 603 { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, {
707 NULL, 604 NULL,
708 42, 605 35,
709 HKF_STATUS_OK, 606 HKF_STATUS_OK,
710 0, 607 0,
711 NULL, 608 NULL,
@@ -718,7 +615,7 @@ struct expected expected_full[] = {
718 } }, 615 } },
719 { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { 616 { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, {
720 NULL, 617 NULL,
721 43, 618 36,
722 HKF_STATUS_OK, 619 HKF_STATUS_OK,
723 0, 620 0,
724 NULL, 621 NULL,
@@ -731,7 +628,7 @@ struct expected expected_full[] = {
731 } }, 628 } },
732 { NULL, -1, -1, 0, 0, 0, 0, -1, { 629 { NULL, -1, -1, 0, 0, 0, 0, -1, {
733 NULL, 630 NULL,
734 44, 631 37,
735 HKF_STATUS_COMMENT, 632 HKF_STATUS_COMMENT,
736 0, 633 0,
737 "", 634 "",
@@ -744,7 +641,7 @@ struct expected expected_full[] = {
744 } }, 641 } },
745 { NULL, -1, -1, 0, 0, 0, 0, -1, { 642 { NULL, -1, -1, 0, 0, 0, 0, -1, {
746 NULL, 643 NULL,
747 45, 644 38,
748 HKF_STATUS_COMMENT, 645 HKF_STATUS_COMMENT,
749 0, 646 0,
750 "", 647 "",
@@ -757,7 +654,7 @@ struct expected expected_full[] = {
757 } }, 654 } },
758 { NULL, -1, -1, 0, 0, 0, 0, -1, { 655 { NULL, -1, -1, 0, 0, 0, 0, -1, {
759 NULL, 656 NULL,
760 46, 657 39,
761 HKF_STATUS_COMMENT, 658 HKF_STATUS_COMMENT,
762 0, 659 0,
763 "# Revoked and CA keys", 660 "# Revoked and CA keys",
@@ -768,22 +665,9 @@ struct expected expected_full[] = {
768 NULL, 665 NULL,
769 NULL, 666 NULL,
770 } }, 667 } },
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, { 668 { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
785 NULL, 669 NULL,
786 48, 670 40,
787 HKF_STATUS_OK, 671 HKF_STATUS_OK,
788 0, 672 0,
789 NULL, 673 NULL,
@@ -796,7 +680,7 @@ struct expected expected_full[] = {
796 } }, 680 } },
797 { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { 681 { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
798 NULL, 682 NULL,
799 49, 683 41,
800 HKF_STATUS_OK, 684 HKF_STATUS_OK,
801 0, 685 0,
802 NULL, 686 NULL,
@@ -809,7 +693,7 @@ struct expected expected_full[] = {
809 } }, 693 } },
810 { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, { 694 { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, {
811 NULL, 695 NULL,
812 50, 696 42,
813 HKF_STATUS_OK, 697 HKF_STATUS_OK,
814 0, 698 0,
815 NULL, 699 NULL,
@@ -822,7 +706,7 @@ struct expected expected_full[] = {
822 } }, 706 } },
823 { NULL, -1, -1, 0, 0, 0, 0, -1, { 707 { NULL, -1, -1, 0, 0, 0, 0, -1, {
824 NULL, 708 NULL,
825 51, 709 43,
826 HKF_STATUS_COMMENT, 710 HKF_STATUS_COMMENT,
827 0, 711 0,
828 "", 712 "",
@@ -835,7 +719,7 @@ struct expected expected_full[] = {
835 } }, 719 } },
836 { NULL, -1, -1, 0, 0, 0, 0, -1, { 720 { NULL, -1, -1, 0, 0, 0, 0, -1, {
837 NULL, 721 NULL,
838 52, 722 44,
839 HKF_STATUS_COMMENT, 723 HKF_STATUS_COMMENT,
840 0, 724 0,
841 "# Some invalid lines", 725 "# Some invalid lines",
@@ -848,7 +732,7 @@ struct expected expected_full[] = {
848 } }, 732 } },
849 { NULL, -1, -1, 0, 0, 0, 0, -1, { 733 { NULL, -1, -1, 0, 0, 0, 0, -1, {
850 NULL, 734 NULL,
851 53, 735 45,
852 HKF_STATUS_INVALID, 736 HKF_STATUS_INVALID,
853 0, 737 0,
854 NULL, 738 NULL,
@@ -861,7 +745,7 @@ struct expected expected_full[] = {
861 } }, 745 } },
862 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 746 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
863 NULL, 747 NULL,
864 54, 748 46,
865 HKF_STATUS_INVALID, 749 HKF_STATUS_INVALID,
866 0, 750 0,
867 NULL, 751 NULL,
@@ -874,7 +758,7 @@ struct expected expected_full[] = {
874 } }, 758 } },
875 { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { 759 { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, {
876 NULL, 760 NULL,
877 55, 761 47,
878 HKF_STATUS_INVALID, 762 HKF_STATUS_INVALID,
879 0, 763 0,
880 NULL, 764 NULL,
@@ -887,33 +771,7 @@ struct expected expected_full[] = {
887 } }, 771 } },
888 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { 772 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
889 NULL, 773 NULL,
890 56, 774 48,
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 */ 775 HKF_STATUS_INVALID, /* Would be ok if key not parsed */
918 0, 776 0,
919 NULL, 777 NULL,
@@ -924,22 +782,9 @@ struct expected expected_full[] = {
924 NULL, 782 NULL,
925 NULL, 783 NULL,
926 } }, 784 } },
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, { 785 { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, {
941 NULL, 786 NULL,
942 60, 787 49,
943 HKF_STATUS_INVALID, 788 HKF_STATUS_INVALID,
944 0, 789 0,
945 NULL, 790 NULL,
@@ -952,7 +797,7 @@ struct expected expected_full[] = {
952 } }, 797 } },
953 { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, { 798 { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, {
954 NULL, 799 NULL,
955 61, 800 50,
956 HKF_STATUS_INVALID, /* Would be ok if key not parsed */ 801 HKF_STATUS_INVALID, /* Would be ok if key not parsed */
957 0, 802 0,
958 NULL, 803 NULL,
diff --git a/regress/unittests/hostkeys/testdata/known_hosts b/regress/unittests/hostkeys/testdata/known_hosts
index 3740f674b..4446f45df 100644
--- a/regress/unittests/hostkeys/testdata/known_hosts
+++ b/regress/unittests/hostkeys/testdata/known_hosts
@@ -2,60 +2,49 @@
2sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 2sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1
3sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 3sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1
4sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 4sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1
5sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
6sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 5sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1
7 6
8# Plain host keys, hostnames + addresses 7# Plain host keys, hostnames + addresses
9prometheus.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 8prometheus.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
10prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 9prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2
11prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 10prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2
12prometheus.example.com,192.0.2.1,2001:db8::1 1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2
13prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 11prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2
14 12
15# Some hosts with wildcard names / IPs 13# 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 14*.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 15*.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 16*.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 17*.example.com,192.0.2.*,2001:* ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3
21 18
22# Hashed hostname and address entries 19# 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 20|1|z3xOIdT5ue3Vuf3MzT67kaioqjw=|GZhhe5uwDOBQrC9N4cCjpbLpSn4= 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 21|1|B7t/AYabn8zgwU47Cb4A/Nqt3eI=|arQPZyRphkzisr7w6wwikvhaOyE= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5
25|1|fOGqe75X5ZpTz4c7DitP4E8/y30=|Lmcch2fh54bUYoV//S2VqDFVeiY= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 22|1|JR81WxEocTP5d7goIRkl8fHBbno=|l6sj6FOsoXxgEZMzn/BnOfPKN68= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5
26|1|0RVzLjY3lwE3MRweguaAXaCCWk8=|DbcIgJQcRZJMYI6NYDOM6oJycPk= 1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 23|1|W7x4zY6KtTZJgsopyOusJqvVPag=|QauLt7hKezBZFZi2i4Xopho7Nsk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5
27|1|4q79XnHpKBNQhyMLAqbPPDN+JKo=|k1Wvjjb52zDdrXWM801+wX5oH8U= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5
28 24
29|1|0M6PIx6THA3ipIOvTl3fcgn2z+A=|bwEJAOwJz+Sm7orFdgj170mD/zY= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 25|1|mxnU8luzqWLvfVi5qBm5xVIyCRM=|9Epopft7LBd80Bf6RmWPIpwa8yU= 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 26|1|klvLmvh2vCpkNMDEjVvrE8SJWTg=|e/dqEEBLnbgqmwEesl4cDRu/7TM= 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 27|1|wsk3ddB3UjuxEsoeNCeZjZ6NvZs=|O3O/q2Z/u7DrxoTiIq6kzCevQT0= 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 28|1|B8epmkLSni+vGZDijr/EwxeR2k4=|7ct8yzNOVJhKm3ZD2w0XIT7df8E= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
33|1|wY53mZNASDJ5/P3JYCJ4FUNa6WQ=|v8p0MfV5lqlZB2J0yLxl/gsWVQo= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 29|1|JojD885UhYhbCu571rgyM/5PpYU=|BJaU2aE1FebQZy3B5tzTDRWFRG0= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
34|1|horeoyFPwfKhyFN+zJZ5LCfOo/I=|2ofvp0tNwCbKsV8FuiFA4gQG2Z8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 30|1|5t7UDHDybVrDZVQPCpwdnr6nk4k=|EqJ73W/veIL3H2x+YWHcJxI5ETA= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6
35|1|Aw4fXumZfx6jEIJuDGIyeEMd81A=|5FdLtdm2JeKNsS8IQeQlGYIadOE= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 31|1|OCcBfGc/b9+ip+W6Gp+3ftdluO4=|VbrKUdzOOtIBOOmEE+jlK4SD3Xc= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
36|1|+dGUNpv6GblrDd5fgHLlOWpSbEo=|He/pQ1yJjtiCyTNWpGwjBD4sZFI= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 32|1|9fLN0YdP+BJ25lKuKvYuOdUo93w=|vZyr0rOiX01hv5XbghhHMW+Zb3U= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
37|1|E/PACGl8m1T7QnPedOoooozstP0=|w6DQAFT8yZgj0Hlkz5R1TppYHCA= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 33|1|nc9RoaaQ0s5jdPxwlUmluGHU3uk=|un6OsJajokKQ3MgyS9mfDNeyP6U= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6
38|1|SaoyMStgxpYfwedSXBAghi8Zo0s=|Gz78k69GaE6iViV3OOvbStKqyTA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 34|1|rsHB6juT9q6GOY91qOeOwL6TSJE=|ps/vXF9Izuues5PbOn887Gw/2Dg= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
39|1|8qfGeiT5WTCzWYbXPQ+lsLg7km4=|1sIBwiSUr8IGkvrUGm3/9QYurmA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 35|1|BsckdLH2aRyWQooRmv+Yo3t4dKg=|Lf3tJc5Iyx0KxNwAG89FsImsfEE= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6
40|1|87M1OtyHg1BZiDY3rT6lYsZFnAU=|eddAQVcMNbn2OB87XWXFQnYo6R4= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 36|1|plqkBA4hq7UATyd5+/Xl+zL7ghw=|stacofaUed46666mfqxp9gJFjt4= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #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 37
45 38
46# Revoked and CA keys 39# 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 40@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 41@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 42@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 43
52# Some invalid lines 44# Some invalid lines
53@what sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 45@what sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1
54sisyphus.example.com 46sisyphus.example.com
55prometheus.example.com ssh-ed25519 47prometheus.example.com ssh-ed25519
56sisyphus.example.com ssh-dsa AAAATgAAAAdz 48sisyphus.example.com ssh-dsa AAAATgAAAAdz
57prometheus.example.com 1024
58sisyphus.example.com 1024 65535
59prometheus.example.com 1025 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1
60sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== 49sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==
61prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== 50prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==
diff --git a/regress/unittests/sshkey/mktestdata.sh b/regress/unittests/sshkey/mktestdata.sh
index e11100145..8047bc62f 100755
--- a/regress/unittests/sshkey/mktestdata.sh
+++ b/regress/unittests/sshkey/mktestdata.sh
@@ -1,25 +1,8 @@
1#!/bin/sh 1#!/bin/sh
2# $OpenBSD: mktestdata.sh,v 1.5 2015/07/07 14:53:30 markus Exp $ 2# $OpenBSD: mktestdata.sh,v 1.6 2017/04/30 23:33:48 djm Exp $
3 3
4PW=mekmitasdigoat 4PW=mekmitasdigoat
5 5
6rsa1_params() {
7 _in="$1"
8 _outbase="$2"
9 set -e
10 ssh-keygen -f $_in -e -m pkcs8 | \
11 openssl rsa -noout -text -pubin | \
12 awk '/^Modulus:$/,/^Exponent:/' | \
13 grep -v '^[a-zA-Z]' | tr -d ' \n:' > ${_outbase}.n
14 # XXX need conversion support in ssh-keygen for the other params
15 for x in n ; do
16 echo "" >> ${_outbase}.$x
17 echo ============ ${_outbase}.$x
18 cat ${_outbase}.$x
19 echo ============
20 done
21}
22
23rsa_params() { 6rsa_params() {
24 _in="$1" 7 _in="$1"
25 _outbase="$2" 8 _outbase="$2"
@@ -87,20 +70,18 @@ set -ex
87 70
88cd testdata 71cd testdata
89 72
90rm -f rsa1_1 rsa_1 dsa_1 ecdsa_1 ed25519_1 73rm -f rsa_1 dsa_1 ecdsa_1 ed25519_1
91rm -f rsa1_2 rsa_2 dsa_2 ecdsa_2 ed25519_2 74rm -f rsa_2 dsa_2 ecdsa_2 ed25519_2
92rm -f rsa_n dsa_n ecdsa_n # new-format keys 75rm -f rsa_n dsa_n ecdsa_n # new-format keys
93rm -f rsa1_1_pw rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw 76rm -f rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw
94rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw 77rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw
95rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb 78rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb
96 79
97ssh-keygen -t rsa1 -b 1024 -C "RSA1 test key #1" -N "" -f rsa1_1
98ssh-keygen -t rsa -b 1024 -C "RSA test key #1" -N "" -f rsa_1 80ssh-keygen -t rsa -b 1024 -C "RSA test key #1" -N "" -f rsa_1
99ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1 81ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1
100ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1 82ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1
101ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1 83ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1
102 84
103ssh-keygen -t rsa1 -b 2048 -C "RSA1 test key #2" -N "" -f rsa1_2
104ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2 85ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2
105ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2 86ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2
106ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2 87ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2
@@ -110,7 +91,6 @@ cp rsa_1 rsa_n
110cp dsa_1 dsa_n 91cp dsa_1 dsa_n
111cp ecdsa_1 ecdsa_n 92cp ecdsa_1 ecdsa_n
112 93
113cp rsa1_1 rsa1_1_pw
114cp rsa_1 rsa_1_pw 94cp rsa_1 rsa_1_pw
115cp dsa_1 dsa_1_pw 95cp dsa_1 dsa_1_pw
116cp ecdsa_1 ecdsa_1_pw 96cp ecdsa_1 ecdsa_1_pw
@@ -119,7 +99,6 @@ cp rsa_1 rsa_n_pw
119cp dsa_1 dsa_n_pw 99cp dsa_1 dsa_n_pw
120cp ecdsa_1 ecdsa_n_pw 100cp ecdsa_1 ecdsa_n_pw
121 101
122ssh-keygen -pf rsa1_1_pw -N "$PW"
123ssh-keygen -pf rsa_1_pw -N "$PW" 102ssh-keygen -pf rsa_1_pw -N "$PW"
124ssh-keygen -pf dsa_1_pw -N "$PW" 103ssh-keygen -pf dsa_1_pw -N "$PW"
125ssh-keygen -pf ecdsa_1_pw -N "$PW" 104ssh-keygen -pf ecdsa_1_pw -N "$PW"
@@ -128,8 +107,6 @@ ssh-keygen -opf rsa_n_pw -N "$PW"
128ssh-keygen -opf dsa_n_pw -N "$PW" 107ssh-keygen -opf dsa_n_pw -N "$PW"
129ssh-keygen -opf ecdsa_n_pw -N "$PW" 108ssh-keygen -opf ecdsa_n_pw -N "$PW"
130 109
131rsa1_params rsa1_1 rsa1_1.param
132rsa1_params rsa1_2 rsa1_2.param
133rsa_params rsa_1 rsa_1.param 110rsa_params rsa_1 rsa_1.param
134rsa_params rsa_2 rsa_2.param 111rsa_params rsa_2 rsa_2.param
135dsa_params dsa_1 dsa_1.param 112dsa_params dsa_1 dsa_1.param
@@ -160,12 +137,10 @@ ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \
160ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ 137ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \
161 -V 19990101:20110101 -z 8 ed25519_1.pub 138 -V 19990101:20110101 -z 8 ed25519_1.pub
162 139
163ssh-keygen -lf rsa1_1 | awk '{print $2}' > rsa1_1.fp
164ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp 140ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp
165ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp 141ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp
166ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp 142ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp
167ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp 143ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp
168ssh-keygen -lf rsa1_2 | awk '{print $2}' > rsa1_2.fp
169ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp 144ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp
170ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp 145ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp
171ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp 146ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp
@@ -176,12 +151,10 @@ ssh-keygen -lf ecdsa_1-cert.pub | awk '{print $2}' > ecdsa_1-cert.fp
176ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp 151ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp
177ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp 152ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp
178 153
179ssh-keygen -Bf rsa1_1 | awk '{print $2}' > rsa1_1.fp.bb
180ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb 154ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb
181ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb 155ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb
182ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb 156ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb
183ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb 157ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb
184ssh-keygen -Bf rsa1_2 | awk '{print $2}' > rsa1_2.fp.bb
185ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb 158ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb
186ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb 159ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb
187ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb 160ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb
diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c
index 906491f2b..99b7e21c0 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.5 2015/10/06 01:20:59 djm Exp $ */ 1/* $OpenBSD: test_file.c,v 1.6 2017/04/30 23:33:48 djm Exp $ */
2/* 2/*
3 * Regress test for sshkey.h key management API 3 * Regress test for sshkey.h key management API
4 * 4 *
@@ -51,55 +51,6 @@ sshkey_file_tests(void)
51 pw = load_text_file("pw"); 51 pw = load_text_file("pw");
52 TEST_DONE(); 52 TEST_DONE();
53 53
54#ifdef WITH_SSH1
55 TEST_START("parse RSA1 from private");
56 buf = load_file("rsa1_1");
57 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
58 sshbuf_free(buf);
59 ASSERT_PTR_NE(k1, NULL);
60 a = load_bignum("rsa1_1.param.n");
61 ASSERT_BIGNUM_EQ(k1->rsa->n, a);
62 BN_free(a);
63 TEST_DONE();
64
65 TEST_START("parse RSA1 from private w/ passphrase");
66 buf = load_file("rsa1_1_pw");
67 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf,
68 (const char *)sshbuf_ptr(pw), &k2, NULL), 0);
69 sshbuf_free(buf);
70 ASSERT_PTR_NE(k2, NULL);
71 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
72 sshkey_free(k2);
73 TEST_DONE();
74
75 TEST_START("load RSA1 from public");
76 ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa1_1.pub"), &k2,
77 NULL), 0);
78 ASSERT_PTR_NE(k2, NULL);
79 ASSERT_INT_EQ(sshkey_equal(k1, k2), 1);
80 sshkey_free(k2);
81 TEST_DONE();
82
83 TEST_START("RSA1 key hex fingerprint");
84 buf = load_text_file("rsa1_1.fp");
85 cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA256, SSH_FP_BASE64);
86 ASSERT_PTR_NE(cp, NULL);
87 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
88 sshbuf_free(buf);
89 free(cp);
90 TEST_DONE();
91
92 TEST_START("RSA1 key bubblebabble fingerprint");
93 buf = load_text_file("rsa1_1.fp.bb");
94 cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE);
95 ASSERT_PTR_NE(cp, NULL);
96 ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf));
97 sshbuf_free(buf);
98 free(cp);
99 TEST_DONE();
100
101 sshkey_free(k1);
102#endif
103 54
104 TEST_START("parse RSA from private"); 55 TEST_START("parse RSA from private");
105 buf = load_file("rsa_1"); 56 buf = load_file("rsa_1");
diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c
index 1f414e0ac..6706045d5 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.6 2015/12/07 02:20:46 djm Exp $ */ 1/* $OpenBSD: test_fuzz.c,v 1.7 2017/04/30 23:33:48 djm Exp $ */
2/* 2/*
3 * Fuzz tests for key parsing 3 * Fuzz tests for key parsing
4 * 4 *
@@ -104,49 +104,6 @@ sshkey_fuzz_tests(void)
104 struct fuzz *fuzz; 104 struct fuzz *fuzz;
105 int r; 105 int r;
106 106
107#ifdef WITH_SSH1
108 TEST_START("fuzz RSA1 private");
109 buf = load_file("rsa1_1");
110 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
111 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
112 sshbuf_mutable_ptr(buf), sshbuf_len(buf));
113 ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0);
114 sshkey_free(k1);
115 sshbuf_free(buf);
116 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
117 TEST_ONERROR(onerror, fuzz);
118 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
119 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
120 ASSERT_INT_EQ(r, 0);
121 if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0)
122 sshkey_free(k1);
123 sshbuf_reset(fuzzed);
124 }
125 sshbuf_free(fuzzed);
126 fuzz_cleanup(fuzz);
127 TEST_DONE();
128
129 TEST_START("fuzz RSA1 public");
130 buf = load_file("rsa1_1_pw");
131 fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP |
132 FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END,
133 sshbuf_mutable_ptr(buf), sshbuf_len(buf));
134 ASSERT_INT_EQ(sshkey_parse_public_rsa1_fileblob(buf, &k1, NULL), 0);
135 sshkey_free(k1);
136 sshbuf_free(buf);
137 ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL);
138 TEST_ONERROR(onerror, fuzz);
139 for(; !fuzz_done(fuzz); fuzz_next(fuzz)) {
140 r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz));
141 ASSERT_INT_EQ(r, 0);
142 if (sshkey_parse_public_rsa1_fileblob(fuzzed, &k1, NULL) == 0)
143 sshkey_free(k1);
144 sshbuf_reset(fuzzed);
145 }
146 sshbuf_free(fuzzed);
147 fuzz_cleanup(fuzz);
148 TEST_DONE();
149#endif
150 107
151 TEST_START("fuzz RSA private"); 108 TEST_START("fuzz RSA private");
152 buf = load_file("rsa_1"); 109 buf = load_file("rsa_1");
diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c
index 1476dc2e3..0a73322a3 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.10 2016/05/02 09:52:00 djm Exp $ */ 1/* $OpenBSD: test_sshkey.c,v 1.12 2017/05/08 06:08:42 djm Exp $ */
2/* 2/*
3 * Regress test for sshkey.h key management API 3 * Regress test for sshkey.h key management API
4 * 4 *
@@ -193,16 +193,6 @@ sshkey_tests(void)
193 sshkey_free(k1); 193 sshkey_free(k1);
194 TEST_DONE(); 194 TEST_DONE();
195 195
196 TEST_START("new/free KEY_RSA1");
197 k1 = sshkey_new(KEY_RSA1);
198 ASSERT_PTR_NE(k1, NULL);
199 ASSERT_PTR_NE(k1->rsa, NULL);
200 ASSERT_PTR_NE(k1->rsa->n, NULL);
201 ASSERT_PTR_NE(k1->rsa->e, NULL);
202 ASSERT_PTR_EQ(k1->rsa->p, NULL);
203 sshkey_free(k1);
204 TEST_DONE();
205
206 TEST_START("new/free KEY_RSA"); 196 TEST_START("new/free KEY_RSA");
207 k1 = sshkey_new(KEY_RSA); 197 k1 = sshkey_new(KEY_RSA);
208 ASSERT_PTR_NE(k1, NULL); 198 ASSERT_PTR_NE(k1, NULL);
@@ -263,19 +253,19 @@ sshkey_tests(void)
263 253
264 TEST_START("generate KEY_RSA too small modulus"); 254 TEST_START("generate KEY_RSA too small modulus");
265 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1), 255 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 128, &k1),
266 SSH_ERR_INVALID_ARGUMENT); 256 SSH_ERR_KEY_LENGTH);
267 ASSERT_PTR_EQ(k1, NULL); 257 ASSERT_PTR_EQ(k1, NULL);
268 TEST_DONE(); 258 TEST_DONE();
269 259
270 TEST_START("generate KEY_RSA too large modulus"); 260 TEST_START("generate KEY_RSA too large modulus");
271 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1), 261 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1 << 20, &k1),
272 SSH_ERR_INVALID_ARGUMENT); 262 SSH_ERR_KEY_LENGTH);
273 ASSERT_PTR_EQ(k1, NULL); 263 ASSERT_PTR_EQ(k1, NULL);
274 TEST_DONE(); 264 TEST_DONE();
275 265
276 TEST_START("generate KEY_DSA wrong bits"); 266 TEST_START("generate KEY_DSA wrong bits");
277 ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1), 267 ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 2048, &k1),
278 SSH_ERR_INVALID_ARGUMENT); 268 SSH_ERR_KEY_LENGTH);
279 ASSERT_PTR_EQ(k1, NULL); 269 ASSERT_PTR_EQ(k1, NULL);
280 sshkey_free(k1); 270 sshkey_free(k1);
281 TEST_DONE(); 271 TEST_DONE();
@@ -283,7 +273,7 @@ sshkey_tests(void)
283#ifdef OPENSSL_HAS_ECC 273#ifdef OPENSSL_HAS_ECC
284 TEST_START("generate KEY_ECDSA wrong bits"); 274 TEST_START("generate KEY_ECDSA wrong bits");
285 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), 275 ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1),
286 SSH_ERR_INVALID_ARGUMENT); 276 SSH_ERR_KEY_LENGTH);
287 ASSERT_PTR_EQ(k1, NULL); 277 ASSERT_PTR_EQ(k1, NULL);
288 sshkey_free(k1); 278 sshkey_free(k1);
289 TEST_DONE(); 279 TEST_DONE();
@@ -291,7 +281,7 @@ sshkey_tests(void)
291 281
292 TEST_START("generate KEY_RSA"); 282 TEST_START("generate KEY_RSA");
293 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 767, &kr), 283 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 767, &kr),
294 SSH_ERR_INVALID_ARGUMENT); 284 SSH_ERR_KEY_LENGTH);
295 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); 285 ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
296 ASSERT_PTR_NE(kr, NULL); 286 ASSERT_PTR_NE(kr, NULL);
297 ASSERT_PTR_NE(kr->rsa, NULL); 287 ASSERT_PTR_NE(kr->rsa, NULL);
diff --git a/regress/yes-head.sh b/regress/yes-head.sh
index 1fc754211..fce2f6580 100644
--- a/regress/yes-head.sh
+++ b/regress/yes-head.sh
@@ -3,13 +3,11 @@
3 3
4tid="yes pipe head" 4tid="yes pipe head"
5 5
6for p in ${SSH_PROTOCOLS}; do 6lines=`${SSH} -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)` 7if [ $? -ne 0 ]; then
8 if [ $? -ne 0 ]; then 8 fail "yes|head test failed"
9 fail "yes|head test failed" 9 lines = 0;
10 lines = 0; 10fi
11 fi 11if [ $lines -ne 2000 ]; then
12 if [ $lines -ne 2000 ]; then 12 fail "yes|head returns $lines lines instead of 2000"
13 fail "yes|head returns $lines lines instead of 2000" 13fi
14 fi
15done
diff --git a/rsa.c b/rsa.c
deleted file mode 100644
index 5ecacef90..000000000
--- a/rsa.c
+++ /dev/null
@@ -1,188 +0,0 @@
1/* $OpenBSD: rsa.c,v 1.32 2014/06/24 01:13:21 djm Exp $ */
2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 *
7 * As far as I am concerned, the code I have written for this software
8 * can be used freely for any purpose. Any derived versions of this
9 * software must be clearly marked as such, and if the derived work is
10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell".
12 *
13 *
14 * Copyright (c) 1999 Niels Provos. All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 *
37 * Description of the RSA algorithm can be found e.g. from the following
38 * sources:
39 *
40 * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994.
41 *
42 * Jennifer Seberry and Josed Pieprzyk: Cryptography: An Introduction to
43 * Computer Security. Prentice-Hall, 1989.
44 *
45 * Man Young Rhee: Cryptography and Secure Data Communications. McGraw-Hill,
46 * 1994.
47 *
48 * R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic Communications
49 * System and Method. US Patent 4,405,829, 1983.
50 *
51 * Hans Riesel: Prime Numbers and Computer Methods for Factorization.
52 * Birkhauser, 1994.
53 *
54 * The RSA Frequently Asked Questions document by RSA Data Security,
55 * Inc., 1995.
56 *
57 * RSA in 3 lines of perl by Adam Back <aba@atlax.ex.ac.uk>, 1995, as
58 * included below:
59 *
60 * [gone - had to be deleted - what a pity]
61 */
62
63#include "includes.h"
64
65#include <sys/types.h>
66
67#include <stdarg.h>
68#include <string.h>
69
70#include "rsa.h"
71#include "log.h"
72#include "ssherr.h"
73
74int
75rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
76{
77 u_char *inbuf = NULL, *outbuf = NULL;
78 int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR;
79
80 if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e))
81 return SSH_ERR_INVALID_ARGUMENT;
82
83 olen = BN_num_bytes(key->n);
84 if ((outbuf = malloc(olen)) == NULL) {
85 r = SSH_ERR_ALLOC_FAIL;
86 goto out;
87 }
88
89 ilen = BN_num_bytes(in);
90 if ((inbuf = malloc(ilen)) == NULL) {
91 r = SSH_ERR_ALLOC_FAIL;
92 goto out;
93 }
94 BN_bn2bin(in, inbuf);
95
96 if ((len = RSA_public_encrypt(ilen, inbuf, outbuf, key,
97 RSA_PKCS1_PADDING)) <= 0) {
98 r = SSH_ERR_LIBCRYPTO_ERROR;
99 goto out;
100 }
101
102 if (BN_bin2bn(outbuf, len, out) == NULL) {
103 r = SSH_ERR_LIBCRYPTO_ERROR;
104 goto out;
105 }
106 r = 0;
107
108 out:
109 if (outbuf != NULL) {
110 explicit_bzero(outbuf, olen);
111 free(outbuf);
112 }
113 if (inbuf != NULL) {
114 explicit_bzero(inbuf, ilen);
115 free(inbuf);
116 }
117 return r;
118}
119
120int
121rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
122{
123 u_char *inbuf = NULL, *outbuf = NULL;
124 int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR;
125
126 olen = BN_num_bytes(key->n);
127 if ((outbuf = malloc(olen)) == NULL) {
128 r = SSH_ERR_ALLOC_FAIL;
129 goto out;
130 }
131
132 ilen = BN_num_bytes(in);
133 if ((inbuf = malloc(ilen)) == NULL) {
134 r = SSH_ERR_ALLOC_FAIL;
135 goto out;
136 }
137 BN_bn2bin(in, inbuf);
138
139 if ((len = RSA_private_decrypt(ilen, inbuf, outbuf, key,
140 RSA_PKCS1_PADDING)) <= 0) {
141 r = SSH_ERR_LIBCRYPTO_ERROR;
142 goto out;
143 } else if (BN_bin2bn(outbuf, len, out) == NULL) {
144 r = SSH_ERR_LIBCRYPTO_ERROR;
145 goto out;
146 }
147 r = 0;
148 out:
149 if (outbuf != NULL) {
150 explicit_bzero(outbuf, olen);
151 free(outbuf);
152 }
153 if (inbuf != NULL) {
154 explicit_bzero(inbuf, ilen);
155 free(inbuf);
156 }
157 return r;
158}
159
160/* calculate p-1 and q-1 */
161int
162rsa_generate_additional_parameters(RSA *rsa)
163{
164 BIGNUM *aux = NULL;
165 BN_CTX *ctx = NULL;
166 int r;
167
168 if ((ctx = BN_CTX_new()) == NULL)
169 return SSH_ERR_ALLOC_FAIL;
170 if ((aux = BN_new()) == NULL) {
171 r = SSH_ERR_ALLOC_FAIL;
172 goto out;
173 }
174
175 if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
176 (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
177 (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
178 (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) {
179 r = SSH_ERR_LIBCRYPTO_ERROR;
180 goto out;
181 }
182 r = 0;
183 out:
184 BN_clear_free(aux);
185 BN_CTX_free(ctx);
186 return r;
187}
188
diff --git a/rsa.h b/rsa.h
deleted file mode 100644
index c476707d5..000000000
--- a/rsa.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/* $OpenBSD: rsa.h,v 1.17 2014/06/24 01:13:21 djm Exp $ */
2
3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * All rights reserved
7 * RSA key generation, encryption and decryption.
8 *
9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose. Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 */
15
16#ifndef RSA_H
17#define RSA_H
18
19#include <openssl/bn.h>
20#include <openssl/rsa.h>
21
22int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *);
23int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *);
24int rsa_generate_additional_parameters(RSA *);
25
26#endif /* RSA_H */
diff --git a/sandbox-capsicum.c b/sandbox-capsicum.c
index 655f0d217..e10bad7e8 100644
--- a/sandbox-capsicum.c
+++ b/sandbox-capsicum.c
@@ -22,7 +22,7 @@
22#include <sys/param.h> 22#include <sys/param.h>
23#include <sys/time.h> 23#include <sys/time.h>
24#include <sys/resource.h> 24#include <sys/resource.h>
25#include <sys/capability.h> 25#include <sys/capsicum.h>
26 26
27#include <errno.h> 27#include <errno.h>
28#include <stdarg.h> 28#include <stdarg.h>
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index 3a1aedce7..ca75cc719 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -50,6 +50,9 @@
50#include <elf.h> 50#include <elf.h>
51 51
52#include <asm/unistd.h> 52#include <asm/unistd.h>
53#ifdef __s390__
54#include <asm/zcrypt.h>
55#endif
53 56
54#include <errno.h> 57#include <errno.h>
55#include <signal.h> 58#include <signal.h>
@@ -222,6 +225,7 @@ static const struct sock_filter preauth_insns[] = {
222#endif 225#endif
223#ifdef __NR_socketcall 226#ifdef __NR_socketcall
224 SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN), 227 SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN),
228 SC_DENY(__NR_socketcall, EACCES),
225#endif 229#endif
226#if defined(__NR_ioctl) && defined(__s390__) 230#if defined(__NR_ioctl) && defined(__s390__)
227 /* Allow ioctls for ICA crypto card on s390 */ 231 /* Allow ioctls for ICA crypto card on s390 */
@@ -235,7 +239,7 @@ static const struct sock_filter preauth_insns[] = {
235 * x86-64 syscall under some circumstances, e.g. 239 * x86-64 syscall under some circumstances, e.g.
236 * https://bugs.debian.org/849923 240 * https://bugs.debian.org/849923
237 */ 241 */
238 SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT); 242 SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT),
239#endif 243#endif
240 244
241 /* Default deny */ 245 /* Default deny */
diff --git a/sandbox-solaris.c b/sandbox-solaris.c
index 343a01022..56ddb9a99 100644
--- a/sandbox-solaris.c
+++ b/sandbox-solaris.c
@@ -62,6 +62,12 @@ ssh_sandbox_init(struct monitor *monitor)
62#ifdef PRIV_NET_ACCESS 62#ifdef PRIV_NET_ACCESS
63 priv_delset(box->pset, PRIV_NET_ACCESS) != 0 || 63 priv_delset(box->pset, PRIV_NET_ACCESS) != 0 ||
64#endif 64#endif
65#ifdef PRIV_DAX_ACCESS
66 priv_delset(box->pset, PRIV_DAX_ACCESS) != 0 ||
67#endif
68#ifdef PRIV_SYS_IB_INFO
69 priv_delset(box->pset, PRIV_SYS_IB_INFO) != 0 ||
70#endif
65 priv_delset(box->pset, PRIV_PROC_EXEC) != 0 || 71 priv_delset(box->pset, PRIV_PROC_EXEC) != 0 ||
66 priv_delset(box->pset, PRIV_PROC_FORK) != 0 || 72 priv_delset(box->pset, PRIV_PROC_FORK) != 0 ||
67 priv_delset(box->pset, PRIV_PROC_INFO) != 0 || 73 priv_delset(box->pset, PRIV_PROC_INFO) != 0 ||
diff --git a/scp.0 b/scp.0
index 46a084698..0cb7726c7 100644
--- a/scp.0
+++ b/scp.0
@@ -4,7 +4,7 @@ NAME
4 scp M-bM-^@M-^S secure copy (remote file copy program) 4 scp M-bM-^@M-^S secure copy (remote file copy program)
5 5
6SYNOPSIS 6SYNOPSIS
7 scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] 7 scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
8 [-l limit] [-o ssh_option] [-P port] [-S program] 8 [-l limit] [-o ssh_option] [-P port] [-S program]
9 [[user@]host1:]file1 ... [[user@]host2:]file2 9 [[user@]host1:]file1 ... [[user@]host2:]file2
10 10
@@ -22,10 +22,6 @@ DESCRIPTION
22 22
23 The options are as follows: 23 The options are as follows:
24 24
25 -1 Forces scp to use protocol 1.
26
27 -2 Forces scp to use protocol 2.
28
29 -3 Copies between two remote hosts are transferred through the local 25 -3 Copies between two remote hosts are transferred through the local
30 host. Without this option the data is copied directly between 26 host. Without this option the data is copied directly between
31 the two remote hosts. Note that this option disables the 27 the two remote hosts. Note that this option disables the
@@ -75,10 +71,8 @@ DESCRIPTION
75 CertificateFile 71 CertificateFile
76 ChallengeResponseAuthentication 72 ChallengeResponseAuthentication
77 CheckHostIP 73 CheckHostIP
78 Cipher
79 Ciphers 74 Ciphers
80 Compression 75 Compression
81 CompressionLevel
82 ConnectionAttempts 76 ConnectionAttempts
83 ConnectTimeout 77 ConnectTimeout
84 ControlMaster 78 ControlMaster
@@ -109,14 +103,11 @@ DESCRIPTION
109 PKCS11Provider 103 PKCS11Provider
110 Port 104 Port
111 PreferredAuthentications 105 PreferredAuthentications
112 Protocol
113 ProxyCommand 106 ProxyCommand
114 ProxyJump 107 ProxyJump
115 PubkeyAcceptedKeyTypes 108 PubkeyAcceptedKeyTypes
116 PubkeyAuthentication 109 PubkeyAuthentication
117 RekeyLimit 110 RekeyLimit
118 RhostsRSAAuthentication
119 RSAAuthentication
120 SendEnv 111 SendEnv
121 ServerAliveInterval 112 ServerAliveInterval
122 ServerAliveCountMax 113 ServerAliveCountMax
@@ -165,4 +156,4 @@ AUTHORS
165 Timo Rinne <tri@iki.fi> 156 Timo Rinne <tri@iki.fi>
166 Tatu Ylonen <ylo@cs.hut.fi> 157 Tatu Ylonen <ylo@cs.hut.fi>
167 158
168OpenBSD 6.0 July 16, 2016 OpenBSD 6.0 159OpenBSD 6.2 May 3, 2017 OpenBSD 6.2
diff --git a/scp.1 b/scp.1
index 4ae877753..76ce33361 100644
--- a/scp.1
+++ b/scp.1
@@ -8,9 +8,9 @@
8.\" 8.\"
9.\" Created: Sun May 7 00:14:37 1995 ylo 9.\" Created: Sun May 7 00:14:37 1995 ylo
10.\" 10.\"
11.\" $OpenBSD: scp.1,v 1.71 2016/07/16 06:57:55 jmc Exp $ 11.\" $OpenBSD: scp.1,v 1.74 2017/05/03 21:49:18 naddy Exp $
12.\" 12.\"
13.Dd $Mdocdate: July 16 2016 $ 13.Dd $Mdocdate: May 3 2017 $
14.Dt SCP 1 14.Dt SCP 1
15.Os 15.Os
16.Sh NAME 16.Sh NAME
@@ -19,7 +19,7 @@
19.Sh SYNOPSIS 19.Sh SYNOPSIS
20.Nm scp 20.Nm scp
21.Bk -words 21.Bk -words
22.Op Fl 12346BCpqrv 22.Op Fl 346BCpqrv
23.Op Fl c Ar cipher 23.Op Fl c Ar cipher
24.Op Fl F Ar ssh_config 24.Op Fl F Ar ssh_config
25.Op Fl i Ar identity_file 25.Op Fl i Ar identity_file
@@ -65,14 +65,6 @@ Copies between two remote hosts are also permitted.
65.Pp 65.Pp
66The options are as follows: 66The options are as follows:
67.Bl -tag -width Ds 67.Bl -tag -width Ds
68.It Fl 1
69Forces
70.Nm
71to use protocol 1.
72.It Fl 2
73Forces
74.Nm
75to use protocol 2.
76.It Fl 3 68.It Fl 3
77Copies between two remote hosts are transferred through the local host. 69Copies between two remote hosts are transferred through the local host.
78Without this option the data is copied directly between the two remote 70Without this option the data is copied directly between the two remote
@@ -136,10 +128,8 @@ For full details of the options listed below, and their possible values, see
136.It CertificateFile 128.It CertificateFile
137.It ChallengeResponseAuthentication 129.It ChallengeResponseAuthentication
138.It CheckHostIP 130.It CheckHostIP
139.It Cipher
140.It Ciphers 131.It Ciphers
141.It Compression 132.It Compression
142.It CompressionLevel
143.It ConnectionAttempts 133.It ConnectionAttempts
144.It ConnectTimeout 134.It ConnectTimeout
145.It ControlMaster 135.It ControlMaster
@@ -170,14 +160,11 @@ For full details of the options listed below, and their possible values, see
170.It PKCS11Provider 160.It PKCS11Provider
171.It Port 161.It Port
172.It PreferredAuthentications 162.It PreferredAuthentications
173.It Protocol
174.It ProxyCommand 163.It ProxyCommand
175.It ProxyJump 164.It ProxyJump
176.It PubkeyAcceptedKeyTypes 165.It PubkeyAcceptedKeyTypes
177.It PubkeyAuthentication 166.It PubkeyAuthentication
178.It RekeyLimit 167.It RekeyLimit
179.It RhostsRSAAuthentication
180.It RSAAuthentication
181.It SendEnv 168.It SendEnv
182.It ServerAliveInterval 169.It ServerAliveInterval
183.It ServerAliveCountMax 170.It ServerAliveCountMax
diff --git a/scp.c b/scp.c
index b4db85198..a533eb097 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: scp.c,v 1.187 2016/09/12 01:22:38 deraadt Exp $ */ 1/* $OpenBSD: scp.c,v 1.192 2017/05/31 09:15:42 deraadt Exp $ */
2/* 2/*
3 * scp - secure remote copy. This is basically patched BSD rcp which 3 * scp - secure remote copy. This is basically patched BSD rcp which
4 * uses ssh to do the data transfer (instead of using rcmd). 4 * uses ssh to do the data transfer (instead of using rcmd).
@@ -99,6 +99,9 @@
99#include <pwd.h> 99#include <pwd.h>
100#include <signal.h> 100#include <signal.h>
101#include <stdarg.h> 101#include <stdarg.h>
102#ifdef HAVE_STDINT_H
103#include <stdint.h>
104#endif
102#include <stdio.h> 105#include <stdio.h>
103#include <stdlib.h> 106#include <stdlib.h>
104#include <string.h> 107#include <string.h>
@@ -403,7 +406,11 @@ main(int argc, char **argv)
403 switch (ch) { 406 switch (ch) {
404 /* User-visible flags. */ 407 /* User-visible flags. */
405 case '1': 408 case '1':
409 fatal("SSH protocol v.1 is no longer supported");
410 break;
406 case '2': 411 case '2':
412 /* Ignored */
413 break;
407 case '4': 414 case '4':
408 case '6': 415 case '6':
409 case 'C': 416 case 'C':
@@ -915,6 +922,11 @@ rsource(char *name, struct stat *statp)
915 (void) response(); 922 (void) response();
916} 923}
917 924
925#define TYPE_OVERFLOW(type, val) \
926 ((sizeof(type) == 4 && (val) > INT32_MAX) || \
927 (sizeof(type) == 8 && (val) > INT64_MAX) || \
928 (sizeof(type) != 4 && sizeof(type) != 8))
929
918void 930void
919sink(int argc, char **argv) 931sink(int argc, char **argv)
920{ 932{
@@ -938,6 +950,9 @@ sink(int argc, char **argv)
938#define mtime tv[1] 950#define mtime tv[1]
939#define SCREWUP(str) { why = str; goto screwup; } 951#define SCREWUP(str) { why = str; goto screwup; }
940 952
953 if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0))
954 SCREWUP("Unexpected off_t/time_t size");
955
941 setimes = targisdir = 0; 956 setimes = targisdir = 0;
942 mask = umask(0); 957 mask = umask(0);
943 if (!pflag) 958 if (!pflag)
@@ -996,8 +1011,7 @@ sink(int argc, char **argv)
996 ull = strtoull(cp, &cp, 10); 1011 ull = strtoull(cp, &cp, 10);
997 if (!cp || *cp++ != ' ') 1012 if (!cp || *cp++ != ' ')
998 SCREWUP("mtime.sec not delimited"); 1013 SCREWUP("mtime.sec not delimited");
999 if ((time_t)ull < 0 || 1014 if (TYPE_OVERFLOW(time_t, ull))
1000 (unsigned long long)(time_t)ull != ull)
1001 setimes = 0; /* out of range */ 1015 setimes = 0; /* out of range */
1002 mtime.tv_sec = ull; 1016 mtime.tv_sec = ull;
1003 mtime.tv_usec = strtol(cp, &cp, 10); 1017 mtime.tv_usec = strtol(cp, &cp, 10);
@@ -1009,8 +1023,7 @@ sink(int argc, char **argv)
1009 ull = strtoull(cp, &cp, 10); 1023 ull = strtoull(cp, &cp, 10);
1010 if (!cp || *cp++ != ' ') 1024 if (!cp || *cp++ != ' ')
1011 SCREWUP("atime.sec not delimited"); 1025 SCREWUP("atime.sec not delimited");
1012 if ((time_t)ull < 0 || 1026 if (TYPE_OVERFLOW(time_t, ull))
1013 (unsigned long long)(time_t)ull != ull)
1014 setimes = 0; /* out of range */ 1027 setimes = 0; /* out of range */
1015 atime.tv_sec = ull; 1028 atime.tv_sec = ull;
1016 atime.tv_usec = strtol(cp, &cp, 10); 1029 atime.tv_usec = strtol(cp, &cp, 10);
@@ -1043,10 +1056,15 @@ sink(int argc, char **argv)
1043 if (*cp++ != ' ') 1056 if (*cp++ != ' ')
1044 SCREWUP("mode not delimited"); 1057 SCREWUP("mode not delimited");
1045 1058
1046 for (size = 0; isdigit((unsigned char)*cp);) 1059 if (!isdigit((unsigned char)*cp))
1047 size = size * 10 + (*cp++ - '0'); 1060 SCREWUP("size not present");
1048 if (*cp++ != ' ') 1061 ull = strtoull(cp, &cp, 10);
1062 if (!cp || *cp++ != ' ')
1049 SCREWUP("size not delimited"); 1063 SCREWUP("size not delimited");
1064 if (TYPE_OVERFLOW(off_t, ull))
1065 SCREWUP("size out of range");
1066 size = (off_t)ull;
1067
1050 if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { 1068 if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) {
1051 run_err("error: unexpected filename: %s", cp); 1069 run_err("error: unexpected filename: %s", cp);
1052 exit(1); 1070 exit(1);
@@ -1256,7 +1274,7 @@ void
1256usage(void) 1274usage(void)
1257{ 1275{
1258 (void) fprintf(stderr, 1276 (void) fprintf(stderr,
1259 "usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" 1277 "usage: scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
1260 " [-l limit] [-o ssh_option] [-P port] [-S program]\n" 1278 " [-l limit] [-o ssh_option] [-P port] [-S program]\n"
1261 " [[user@]host1:]file1 ... [[user@]host2:]file2\n"); 1279 " [[user@]host1:]file1 ... [[user@]host2:]file2\n");
1262 exit(1); 1280 exit(1);
@@ -1350,11 +1368,7 @@ allocbuf(BUF *bp, int fd, int blksize)
1350#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 1368#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
1351 if (bp->cnt >= size) 1369 if (bp->cnt >= size)
1352 return (bp); 1370 return (bp);
1353 if (bp->buf == NULL) 1371 bp->buf = xrecallocarray(bp->buf, bp->cnt, size, 1);
1354 bp->buf = xmalloc(size);
1355 else
1356 bp->buf = xreallocarray(bp->buf, 1, size);
1357 memset(bp->buf, 0, size);
1358 bp->cnt = size; 1372 bp->cnt = size;
1359 return (bp); 1373 return (bp);
1360} 1374}
diff --git a/servconf.c b/servconf.c
index 56b831652..2c321a4ad 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.306 2017/03/14 07:19:07 djm Exp $ */ 2/* $OpenBSD: servconf.c,v 1.312 2017/10/02 19:33:20 djm Exp $ */
3/* 3/*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved 5 * All rights reserved
@@ -149,7 +149,7 @@ initialize_server_options(ServerOptions *options)
149 options->num_authkeys_files = 0; 149 options->num_authkeys_files = 0;
150 options->num_accept_env = 0; 150 options->num_accept_env = 0;
151 options->permit_tun = -1; 151 options->permit_tun = -1;
152 options->num_permitted_opens = -1; 152 options->permitted_opens = NULL;
153 options->adm_forced_command = NULL; 153 options->adm_forced_command = NULL;
154 options->chroot_directory = NULL; 154 options->chroot_directory = NULL;
155 options->authorized_keys_command = NULL; 155 options->authorized_keys_command = NULL;
@@ -164,6 +164,7 @@ initialize_server_options(ServerOptions *options)
164 options->version_addendum = NULL; 164 options->version_addendum = NULL;
165 options->fingerprint_hash = -1; 165 options->fingerprint_hash = -1;
166 options->disable_forwarding = -1; 166 options->disable_forwarding = -1;
167 options->expose_userauth_info = -1;
167} 168}
168 169
169/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ 170/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@@ -333,6 +334,8 @@ fill_default_server_options(ServerOptions *options)
333 options->fingerprint_hash = SSH_FP_HASH_DEFAULT; 334 options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
334 if (options->disable_forwarding == -1) 335 if (options->disable_forwarding == -1)
335 options->disable_forwarding = 0; 336 options->disable_forwarding = 0;
337 if (options->expose_userauth_info == -1)
338 options->expose_userauth_info = 0;
336 339
337 assemble_algorithms(options); 340 assemble_algorithms(options);
338 341
@@ -418,6 +421,7 @@ typedef enum {
418 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, 421 sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
419 sStreamLocalBindMask, sStreamLocalBindUnlink, 422 sStreamLocalBindMask, sStreamLocalBindUnlink,
420 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, 423 sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding,
424 sExposeAuthInfo,
421 sDeprecated, sIgnore, sUnsupported 425 sDeprecated, sIgnore, sUnsupported
422} ServerOpCodes; 426} ServerOpCodes;
423 427
@@ -449,7 +453,7 @@ static struct {
449 { "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL }, 453 { "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL },
450 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, 454 { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
451 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, 455 { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
452 { "loglevel", sLogLevel, SSHCFG_GLOBAL }, 456 { "loglevel", sLogLevel, SSHCFG_ALL },
453 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, 457 { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
454 { "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL }, 458 { "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL },
455 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, 459 { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
@@ -561,6 +565,7 @@ static struct {
561 { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, 565 { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
562 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, 566 { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
563 { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, 567 { "disableforwarding", sDisableForwarding, SSHCFG_ALL },
568 { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL },
564 { NULL, sBadOption, 0 } 569 { NULL, sBadOption, 0 }
565}; 570};
566 571
@@ -692,6 +697,44 @@ process_queued_listen_addrs(ServerOptions *options)
692 options->num_queued_listens = 0; 697 options->num_queued_listens = 0;
693} 698}
694 699
700/*
701 * Inform channels layer of permitopen options from configuration.
702 */
703void
704process_permitopen(struct ssh *ssh, ServerOptions *options)
705{
706 u_int i;
707 int port;
708 char *host, *arg, *oarg;
709
710 channel_clear_adm_permitted_opens(ssh);
711 if (options->num_permitted_opens == 0)
712 return; /* permit any */
713
714 /* handle keywords: "any" / "none" */
715 if (options->num_permitted_opens == 1 &&
716 strcmp(options->permitted_opens[0], "any") == 0)
717 return;
718 if (options->num_permitted_opens == 1 &&
719 strcmp(options->permitted_opens[0], "none") == 0) {
720 channel_disable_adm_local_opens(ssh);
721 return;
722 }
723 /* Otherwise treat it as a list of permitted host:port */
724 for (i = 0; i < options->num_permitted_opens; i++) {
725 oarg = arg = xstrdup(options->permitted_opens[i]);
726 host = hpdelim(&arg);
727 if (host == NULL)
728 fatal("%s: missing host in PermitOpen", __func__);
729 host = cleanhostname(host);
730 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
731 fatal("%s: bad port number in PermitOpen", __func__);
732 /* Send it to channels layer */
733 channel_add_adm_permitted_opens(ssh, host, port);
734 free(oarg);
735 }
736}
737
695struct connection_info * 738struct connection_info *
696get_connection_info(int populate, int use_dns) 739get_connection_info(int populate, int use_dns)
697{ 740{
@@ -935,13 +978,6 @@ static const struct multistate multistate_gatewayports[] = {
935 { "no", 0 }, 978 { "no", 0 },
936 { NULL, -1 } 979 { NULL, -1 }
937}; 980};
938static const struct multistate multistate_privsep[] = {
939 { "yes", PRIVSEP_NOSANDBOX },
940 { "sandbox", PRIVSEP_ON },
941 { "nosandbox", PRIVSEP_NOSANDBOX },
942 { "no", PRIVSEP_OFF },
943 { NULL, -1 }
944};
945static const struct multistate multistate_tcpfwd[] = { 981static const struct multistate multistate_tcpfwd[] = {
946 { "yes", FORWARD_ALLOW }, 982 { "yes", FORWARD_ALLOW },
947 { "all", FORWARD_ALLOW }, 983 { "all", FORWARD_ALLOW },
@@ -956,7 +992,7 @@ process_server_config_line(ServerOptions *options, char *line,
956 const char *filename, int linenum, int *activep, 992 const char *filename, int linenum, int *activep,
957 struct connection_info *connectinfo) 993 struct connection_info *connectinfo)
958{ 994{
959 char *cp, **charptr, *arg, *p; 995 char *cp, **charptr, *arg, *arg2, *p;
960 int cmdline = 0, *intptr, value, value2, n, port; 996 int cmdline = 0, *intptr, value, value2, n, port;
961 SyslogFacility *log_facility_ptr; 997 SyslogFacility *log_facility_ptr;
962 LogLevel *log_level_ptr; 998 LogLevel *log_level_ptr;
@@ -1352,7 +1388,7 @@ process_server_config_line(ServerOptions *options, char *line,
1352 if (value == SYSLOG_LEVEL_NOT_SET) 1388 if (value == SYSLOG_LEVEL_NOT_SET)
1353 fatal("%.200s line %d: unsupported log level '%s'", 1389 fatal("%.200s line %d: unsupported log level '%s'",
1354 filename, linenum, arg ? arg : "<NONE>"); 1390 filename, linenum, arg ? arg : "<NONE>");
1355 if (*log_level_ptr == -1) 1391 if (*activep && *log_level_ptr == -1)
1356 *log_level_ptr = (LogLevel) value; 1392 *log_level_ptr = (LogLevel) value;
1357 break; 1393 break;
1358 1394
@@ -1627,24 +1663,18 @@ process_server_config_line(ServerOptions *options, char *line,
1627 if (!arg || *arg == '\0') 1663 if (!arg || *arg == '\0')
1628 fatal("%s line %d: missing PermitOpen specification", 1664 fatal("%s line %d: missing PermitOpen specification",
1629 filename, linenum); 1665 filename, linenum);
1630 n = options->num_permitted_opens; /* modified later */ 1666 i = options->num_permitted_opens; /* modified later */
1631 if (strcmp(arg, "any") == 0) { 1667 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
1632 if (*activep && n == -1) { 1668 if (*activep && i == 0) {
1633 channel_clear_adm_permitted_opens();
1634 options->num_permitted_opens = 0;
1635 }
1636 break;
1637 }
1638 if (strcmp(arg, "none") == 0) {
1639 if (*activep && n == -1) {
1640 options->num_permitted_opens = 1; 1669 options->num_permitted_opens = 1;
1641 channel_disable_adm_local_opens(); 1670 options->permitted_opens = xcalloc(1,
1671 sizeof(*options->permitted_opens));
1672 options->permitted_opens[0] = xstrdup(arg);
1642 } 1673 }
1643 break; 1674 break;
1644 } 1675 }
1645 if (*activep && n == -1)
1646 channel_clear_adm_permitted_opens();
1647 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { 1676 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1677 arg2 = xstrdup(arg);
1648 p = hpdelim(&arg); 1678 p = hpdelim(&arg);
1649 if (p == NULL) 1679 if (p == NULL)
1650 fatal("%s line %d: missing host in PermitOpen", 1680 fatal("%s line %d: missing host in PermitOpen",
@@ -1653,9 +1683,16 @@ process_server_config_line(ServerOptions *options, char *line,
1653 if (arg == NULL || ((port = permitopen_port(arg)) < 0)) 1683 if (arg == NULL || ((port = permitopen_port(arg)) < 0))
1654 fatal("%s line %d: bad port number in " 1684 fatal("%s line %d: bad port number in "
1655 "PermitOpen", filename, linenum); 1685 "PermitOpen", filename, linenum);
1656 if (*activep && n == -1) 1686 if (*activep && i == 0) {
1657 options->num_permitted_opens = 1687 options->permitted_opens = xrecallocarray(
1658 channel_add_adm_permitted_opens(p, port); 1688 options->permitted_opens,
1689 options->num_permitted_opens,
1690 options->num_permitted_opens + 1,
1691 sizeof(*options->permitted_opens));
1692 i = options->num_permitted_opens++;
1693 options->permitted_opens[i] = arg2;
1694 } else
1695 free(arg2);
1659 } 1696 }
1660 break; 1697 break;
1661 1698
@@ -1842,6 +1879,10 @@ process_server_config_line(ServerOptions *options, char *line,
1842 options->fingerprint_hash = value; 1879 options->fingerprint_hash = value;
1843 break; 1880 break;
1844 1881
1882 case sExposeAuthInfo:
1883 intptr = &options->expose_userauth_info;
1884 goto parse_flag;
1885
1845 case sDeprecated: 1886 case sDeprecated:
1846 case sIgnore: 1887 case sIgnore:
1847 case sUnsupported: 1888 case sUnsupported:
@@ -1980,6 +2021,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1980 M_CP_INTOPT(allow_streamlocal_forwarding); 2021 M_CP_INTOPT(allow_streamlocal_forwarding);
1981 M_CP_INTOPT(allow_agent_forwarding); 2022 M_CP_INTOPT(allow_agent_forwarding);
1982 M_CP_INTOPT(disable_forwarding); 2023 M_CP_INTOPT(disable_forwarding);
2024 M_CP_INTOPT(expose_userauth_info);
1983 M_CP_INTOPT(permit_tun); 2025 M_CP_INTOPT(permit_tun);
1984 M_CP_INTOPT(fwd_opts.gateway_ports); 2026 M_CP_INTOPT(fwd_opts.gateway_ports);
1985 M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); 2027 M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
@@ -1996,6 +2038,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1996 M_CP_INTOPT(ip_qos_bulk); 2038 M_CP_INTOPT(ip_qos_bulk);
1997 M_CP_INTOPT(rekey_limit); 2039 M_CP_INTOPT(rekey_limit);
1998 M_CP_INTOPT(rekey_interval); 2040 M_CP_INTOPT(rekey_interval);
2041 M_CP_INTOPT(log_level);
1999 2042
2000 /* 2043 /*
2001 * The bind_mask is a mode_t that may be unsigned, so we can't use 2044 * The bind_mask is a mode_t that may be unsigned, so we can't use
@@ -2020,6 +2063,13 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2020 dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ 2063 dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \
2021 } \ 2064 } \
2022} while(0) 2065} while(0)
2066#define M_CP_STRARRAYOPT_ALLOC(n, num_n) do { \
2067 if (src->num_n != 0) { \
2068 dst->n = xcalloc(src->num_n, sizeof(*dst->n)); \
2069 M_CP_STRARRAYOPT(n, num_n); \
2070 dst->num_n = src->num_n; \
2071 } \
2072} while(0)
2023 2073
2024 /* See comment in servconf.h */ 2074 /* See comment in servconf.h */
2025 COPY_MATCH_STRING_OPTS(); 2075 COPY_MATCH_STRING_OPTS();
@@ -2050,6 +2100,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
2050#undef M_CP_INTOPT 2100#undef M_CP_INTOPT
2051#undef M_CP_STROPT 2101#undef M_CP_STROPT
2052#undef M_CP_STRARRAYOPT 2102#undef M_CP_STRARRAYOPT
2103#undef M_CP_STRARRAYOPT_ALLOC
2053 2104
2054void 2105void
2055parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, 2106parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
@@ -2278,6 +2329,7 @@ dump_config(ServerOptions *o)
2278 dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); 2329 dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
2279 dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 2330 dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
2280 dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); 2331 dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
2332 dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info);
2281 2333
2282 /* string arguments */ 2334 /* string arguments */
2283 dump_cfg_string(sPidFile, o->pid_file); 2335 dump_cfg_string(sPidFile, o->pid_file);
@@ -2347,5 +2399,12 @@ dump_config(ServerOptions *o)
2347 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit, 2399 printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
2348 o->rekey_interval); 2400 o->rekey_interval);
2349 2401
2350 channel_print_adm_permitted_opens(); 2402 printf("permitopen");
2403 if (o->num_permitted_opens == 0)
2404 printf(" any");
2405 else {
2406 for (i = 0; i < o->num_permitted_opens; i++)
2407 printf(" %s", o->permitted_opens[i]);
2408 }
2409 printf("\n");
2351} 2410}
diff --git a/servconf.h b/servconf.h
index 5853a9747..1dca702e6 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.h,v 1.123 2016/11/30 03:00:05 djm Exp $ */ 1/* $OpenBSD: servconf.h,v 1.126 2017/10/02 19:33:20 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -48,12 +48,19 @@
48#define FORWARD_LOCAL (1<<1) 48#define FORWARD_LOCAL (1<<1)
49#define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL) 49#define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL)
50 50
51/* PermitOpen */
52#define PERMITOPEN_ANY 0
53#define PERMITOPEN_NONE -2
54
51#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ 55#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
52#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ 56#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
53 57
54/* Magic name for internal sftp-server */ 58/* Magic name for internal sftp-server */
55#define INTERNAL_SFTP_NAME "internal-sftp" 59#define INTERNAL_SFTP_NAME "internal-sftp"
56 60
61struct ssh;
62struct fwd_perm_list;
63
57typedef struct { 64typedef struct {
58 u_int num_ports; 65 u_int num_ports;
59 u_int ports_from_cmdline; 66 u_int ports_from_cmdline;
@@ -169,7 +176,8 @@ typedef struct {
169 176
170 int permit_tun; 177 int permit_tun;
171 178
172 int num_permitted_opens; 179 char **permitted_opens;
180 u_int num_permitted_opens; /* May also be one of PERMITOPEN_* */
173 181
174 char *chroot_directory; 182 char *chroot_directory;
175 char *revoked_keys_file; 183 char *revoked_keys_file;
@@ -189,6 +197,7 @@ typedef struct {
189 char *auth_methods[MAX_AUTH_METHODS]; 197 char *auth_methods[MAX_AUTH_METHODS];
190 198
191 int fingerprint_hash; 199 int fingerprint_hash;
200 int expose_userauth_info;
192} ServerOptions; 201} ServerOptions;
193 202
194/* Information about the incoming connection as used by Match */ 203/* Information about the incoming connection as used by Match */
@@ -228,6 +237,7 @@ struct connection_info {
228 M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \ 237 M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
229 M_CP_STRARRAYOPT(accept_env, num_accept_env); \ 238 M_CP_STRARRAYOPT(accept_env, num_accept_env); \
230 M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \ 239 M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
240 M_CP_STRARRAYOPT_ALLOC(permitted_opens, num_permitted_opens); \
231 } while (0) 241 } while (0)
232 242
233struct connection_info *get_connection_info(int, int); 243struct connection_info *get_connection_info(int, int);
@@ -235,6 +245,7 @@ void initialize_server_options(ServerOptions *);
235void fill_default_server_options(ServerOptions *); 245void fill_default_server_options(ServerOptions *);
236int process_server_config_line(ServerOptions *, char *, const char *, int, 246int process_server_config_line(ServerOptions *, char *, const char *, int,
237 int *, struct connection_info *); 247 int *, struct connection_info *);
248void process_permitopen(struct ssh *ssh, ServerOptions *options);
238void load_server_config(const char *, Buffer *); 249void load_server_config(const char *, Buffer *);
239void parse_server_config(ServerOptions *, const char *, Buffer *, 250void parse_server_config(ServerOptions *, const char *, Buffer *,
240 struct connection_info *); 251 struct connection_info *);
diff --git a/serverloop.c b/serverloop.c
index 2976f5594..24bbae322 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.191 2017/02/01 02:59:09 dtucker Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.198 2017/09/12 06:35:32 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -165,7 +165,7 @@ sigterm_handler(int sig)
165} 165}
166 166
167static void 167static void
168client_alive_check(void) 168client_alive_check(struct ssh *ssh)
169{ 169{
170 int channel_id; 170 int channel_id;
171 171
@@ -179,12 +179,13 @@ client_alive_check(void)
179 * send a bogus global/channel request with "wantreply", 179 * send a bogus global/channel request with "wantreply",
180 * we should get back a failure 180 * we should get back a failure
181 */ 181 */
182 if ((channel_id = channel_find_open()) == -1) { 182 if ((channel_id = channel_find_open(ssh)) == -1) {
183 packet_start(SSH2_MSG_GLOBAL_REQUEST); 183 packet_start(SSH2_MSG_GLOBAL_REQUEST);
184 packet_put_cstring("keepalive@openssh.com"); 184 packet_put_cstring("keepalive@openssh.com");
185 packet_put_char(1); /* boolean: want reply */ 185 packet_put_char(1); /* boolean: want reply */
186 } else { 186 } else {
187 channel_request_start(channel_id, "keepalive@openssh.com", 1); 187 channel_request_start(ssh, channel_id,
188 "keepalive@openssh.com", 1);
188 } 189 }
189 packet_send(); 190 packet_send();
190} 191}
@@ -196,7 +197,8 @@ client_alive_check(void)
196 * for the duration of the wait (0 = infinite). 197 * for the duration of the wait (0 = infinite).
197 */ 198 */
198static void 199static void
199wait_until_can_do_something(int connection_in, int connection_out, 200wait_until_can_do_something(struct ssh *ssh,
201 int connection_in, int connection_out,
200 fd_set **readsetp, fd_set **writesetp, int *maxfdp, 202 fd_set **readsetp, fd_set **writesetp, int *maxfdp,
201 u_int *nallocp, u_int64_t max_time_ms) 203 u_int *nallocp, u_int64_t max_time_ms)
202{ 204{
@@ -204,10 +206,11 @@ wait_until_can_do_something(int connection_in, int connection_out,
204 int ret; 206 int ret;
205 time_t minwait_secs = 0; 207 time_t minwait_secs = 0;
206 int client_alive_scheduled = 0; 208 int client_alive_scheduled = 0;
209 static time_t last_client_time;
207 210
208 /* Allocate and update select() masks for channel descriptors. */ 211 /* Allocate and update select() masks for channel descriptors. */
209 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 212 channel_prepare_select(ssh, readsetp, writesetp, maxfdp,
210 &minwait_secs, 0); 213 nallocp, &minwait_secs);
211 214
212 /* XXX need proper deadline system for rekey/client alive */ 215 /* XXX need proper deadline system for rekey/client alive */
213 if (minwait_secs != 0) 216 if (minwait_secs != 0)
@@ -268,8 +271,19 @@ wait_until_can_do_something(int connection_in, int connection_out,
268 memset(*writesetp, 0, *nallocp); 271 memset(*writesetp, 0, *nallocp);
269 if (errno != EINTR) 272 if (errno != EINTR)
270 error("select: %.100s", strerror(errno)); 273 error("select: %.100s", strerror(errno));
271 } else if (ret == 0 && client_alive_scheduled) 274 } else if (client_alive_scheduled) {
272 client_alive_check(); 275 time_t now = monotime();
276
277 if (ret == 0) { /* timeout */
278 client_alive_check(ssh);
279 } else if (FD_ISSET(connection_in, *readsetp)) {
280 last_client_time = now;
281 } else if (last_client_time != 0 && last_client_time +
282 options.client_alive_interval <= now) {
283 client_alive_check(ssh);
284 last_client_time = now;
285 }
286 }
273 287
274 notify_done(*readsetp); 288 notify_done(*readsetp);
275} 289}
@@ -279,9 +293,8 @@ wait_until_can_do_something(int connection_in, int connection_out,
279 * in buffers and processed later. 293 * in buffers and processed later.
280 */ 294 */
281static int 295static int
282process_input(fd_set *readset, int connection_in) 296process_input(struct ssh *ssh, fd_set *readset, int connection_in)
283{ 297{
284 struct ssh *ssh = active_state; /* XXX */
285 int len; 298 int len;
286 char buf[16384]; 299 char buf[16384];
287 300
@@ -321,13 +334,13 @@ process_output(fd_set *writeset, int connection_out)
321} 334}
322 335
323static void 336static void
324process_buffered_input_packets(void) 337process_buffered_input_packets(struct ssh *ssh)
325{ 338{
326 dispatch_run(DISPATCH_NONBLOCK, NULL, active_state); 339 ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, NULL);
327} 340}
328 341
329static void 342static void
330collect_children(void) 343collect_children(struct ssh *ssh)
331{ 344{
332 pid_t pid; 345 pid_t pid;
333 sigset_t oset, nset; 346 sigset_t oset, nset;
@@ -342,14 +355,14 @@ collect_children(void)
342 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || 355 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
343 (pid < 0 && errno == EINTR)) 356 (pid < 0 && errno == EINTR))
344 if (pid > 0) 357 if (pid > 0)
345 session_close_by_pid(pid, status); 358 session_close_by_pid(ssh, pid, status);
346 child_terminated = 0; 359 child_terminated = 0;
347 } 360 }
348 sigprocmask(SIG_SETMASK, &oset, NULL); 361 sigprocmask(SIG_SETMASK, &oset, NULL);
349} 362}
350 363
351void 364void
352server_loop2(Authctxt *authctxt) 365server_loop2(struct ssh *ssh, Authctxt *authctxt)
353{ 366{
354 fd_set *readset = NULL, *writeset = NULL; 367 fd_set *readset = NULL, *writeset = NULL;
355 int max_fd; 368 int max_fd;
@@ -377,18 +390,17 @@ server_loop2(Authctxt *authctxt)
377 server_init_dispatch(); 390 server_init_dispatch();
378 391
379 for (;;) { 392 for (;;) {
380 process_buffered_input_packets(); 393 process_buffered_input_packets(ssh);
381 394
382 if (!ssh_packet_is_rekeying(active_state) && 395 if (!ssh_packet_is_rekeying(ssh) &&
383 packet_not_very_much_data_to_write()) 396 packet_not_very_much_data_to_write())
384 channel_output_poll(); 397 channel_output_poll(ssh);
385 if (options.rekey_interval > 0 && 398 if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh))
386 !ssh_packet_is_rekeying(active_state))
387 rekey_timeout_ms = packet_get_rekey_timeout() * 1000; 399 rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
388 else 400 else
389 rekey_timeout_ms = 0; 401 rekey_timeout_ms = 0;
390 402
391 wait_until_can_do_something(connection_in, connection_out, 403 wait_until_can_do_something(ssh, connection_in, connection_out,
392 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms); 404 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms);
393 405
394 if (received_sigterm) { 406 if (received_sigterm) {
@@ -397,27 +409,27 @@ server_loop2(Authctxt *authctxt)
397 cleanup_exit(255); 409 cleanup_exit(255);
398 } 410 }
399 411
400 collect_children(); 412 collect_children(ssh);
401 if (!ssh_packet_is_rekeying(active_state)) 413 if (!ssh_packet_is_rekeying(ssh))
402 channel_after_select(readset, writeset); 414 channel_after_select(ssh, readset, writeset);
403 if (process_input(readset, connection_in) < 0) 415 if (process_input(ssh, readset, connection_in) < 0)
404 break; 416 break;
405 process_output(writeset, connection_out); 417 process_output(writeset, connection_out);
406 } 418 }
407 collect_children(); 419 collect_children(ssh);
408 420
409 free(readset); 421 free(readset);
410 free(writeset); 422 free(writeset);
411 423
412 /* free all channels, no more reads and writes */ 424 /* free all channels, no more reads and writes */
413 channel_free_all(); 425 channel_free_all(ssh);
414 426
415 /* free remaining sessions, e.g. remove wtmp entries */ 427 /* free remaining sessions, e.g. remove wtmp entries */
416 session_destroy_all(NULL); 428 session_destroy_all(ssh, NULL);
417} 429}
418 430
419static int 431static int
420server_input_keep_alive(int type, u_int32_t seq, void *ctxt) 432server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
421{ 433{
422 debug("Got %d/%u for keepalive", type, seq); 434 debug("Got %d/%u for keepalive", type, seq);
423 /* 435 /*
@@ -430,7 +442,7 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
430} 442}
431 443
432static Channel * 444static Channel *
433server_request_direct_tcpip(int *reason, const char **errmsg) 445server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
434{ 446{
435 Channel *c = NULL; 447 Channel *c = NULL;
436 char *target, *originator; 448 char *target, *originator;
@@ -448,7 +460,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
448 /* XXX fine grained permissions */ 460 /* XXX fine grained permissions */
449 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && 461 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
450 !no_port_forwarding_flag && !options.disable_forwarding) { 462 !no_port_forwarding_flag && !options.disable_forwarding) {
451 c = channel_connect_to_port(target, target_port, 463 c = channel_connect_to_port(ssh, target, target_port,
452 "direct-tcpip", "direct-tcpip", reason, errmsg); 464 "direct-tcpip", "direct-tcpip", reason, errmsg);
453 } else { 465 } else {
454 logit("refused local port forward: " 466 logit("refused local port forward: "
@@ -465,7 +477,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
465} 477}
466 478
467static Channel * 479static Channel *
468server_request_direct_streamlocal(void) 480server_request_direct_streamlocal(struct ssh *ssh)
469{ 481{
470 Channel *c = NULL; 482 Channel *c = NULL;
471 char *target, *originator; 483 char *target, *originator;
@@ -487,7 +499,7 @@ server_request_direct_streamlocal(void)
487 if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && 499 if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
488 !no_port_forwarding_flag && !options.disable_forwarding && 500 !no_port_forwarding_flag && !options.disable_forwarding &&
489 (pw->pw_uid == 0 || use_privsep)) { 501 (pw->pw_uid == 0 || use_privsep)) {
490 c = channel_connect_to_path(target, 502 c = channel_connect_to_path(ssh, target,
491 "direct-streamlocal@openssh.com", "direct-streamlocal"); 503 "direct-streamlocal@openssh.com", "direct-streamlocal");
492 } else { 504 } else {
493 logit("refused streamlocal port forward: " 505 logit("refused streamlocal port forward: "
@@ -502,7 +514,7 @@ server_request_direct_streamlocal(void)
502} 514}
503 515
504static Channel * 516static Channel *
505server_request_tun(void) 517server_request_tun(struct ssh *ssh)
506{ 518{
507 Channel *c = NULL; 519 Channel *c = NULL;
508 int mode, tun; 520 int mode, tun;
@@ -532,12 +544,12 @@ server_request_tun(void)
532 sock = tun_open(tun, mode); 544 sock = tun_open(tun, mode);
533 if (sock < 0) 545 if (sock < 0)
534 goto done; 546 goto done;
535 c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, 547 c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
536 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); 548 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
537 c->datagram = 1; 549 c->datagram = 1;
538#if defined(SSH_TUN_FILTER) 550#if defined(SSH_TUN_FILTER)
539 if (mode == SSH_TUNMODE_POINTOPOINT) 551 if (mode == SSH_TUNMODE_POINTOPOINT)
540 channel_register_filter(c->self, sys_tun_infilter, 552 channel_register_filter(ssh, c->self, sys_tun_infilter,
541 sys_tun_outfilter, NULL, NULL); 553 sys_tun_outfilter, NULL, NULL);
542#endif 554#endif
543 555
@@ -548,7 +560,7 @@ server_request_tun(void)
548} 560}
549 561
550static Channel * 562static Channel *
551server_request_session(void) 563server_request_session(struct ssh *ssh)
552{ 564{
553 Channel *c; 565 Channel *c;
554 566
@@ -566,20 +578,20 @@ server_request_session(void)
566 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all 578 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
567 * CHANNEL_REQUEST messages is registered. 579 * CHANNEL_REQUEST messages is registered.
568 */ 580 */
569 c = channel_new("session", SSH_CHANNEL_LARVAL, 581 c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL,
570 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 582 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
571 0, "server-session", 1); 583 0, "server-session", 1);
572 if (session_open(the_authctxt, c->self) != 1) { 584 if (session_open(the_authctxt, c->self) != 1) {
573 debug("session open failed, free channel %d", c->self); 585 debug("session open failed, free channel %d", c->self);
574 channel_free(c); 586 channel_free(ssh, c);
575 return NULL; 587 return NULL;
576 } 588 }
577 channel_register_cleanup(c->self, session_close_by_channel, 0); 589 channel_register_cleanup(ssh, c->self, session_close_by_channel, 0);
578 return c; 590 return c;
579} 591}
580 592
581static int 593static int
582server_input_channel_open(int type, u_int32_t seq, void *ctxt) 594server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
583{ 595{
584 Channel *c = NULL; 596 Channel *c = NULL;
585 char *ctype; 597 char *ctype;
@@ -596,17 +608,18 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
596 ctype, rchan, rwindow, rmaxpack); 608 ctype, rchan, rwindow, rmaxpack);
597 609
598 if (strcmp(ctype, "session") == 0) { 610 if (strcmp(ctype, "session") == 0) {
599 c = server_request_session(); 611 c = server_request_session(ssh);
600 } else if (strcmp(ctype, "direct-tcpip") == 0) { 612 } else if (strcmp(ctype, "direct-tcpip") == 0) {
601 c = server_request_direct_tcpip(&reason, &errmsg); 613 c = server_request_direct_tcpip(ssh, &reason, &errmsg);
602 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) { 614 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) {
603 c = server_request_direct_streamlocal(); 615 c = server_request_direct_streamlocal(ssh);
604 } else if (strcmp(ctype, "tun@openssh.com") == 0) { 616 } else if (strcmp(ctype, "tun@openssh.com") == 0) {
605 c = server_request_tun(); 617 c = server_request_tun(ssh);
606 } 618 }
607 if (c != NULL) { 619 if (c != NULL) {
608 debug("server_input_channel_open: confirm %s", ctype); 620 debug("server_input_channel_open: confirm %s", ctype);
609 c->remote_id = rchan; 621 c->remote_id = rchan;
622 c->have_remote_id = 1;
610 c->remote_window = rwindow; 623 c->remote_window = rwindow;
611 c->remote_maxpacket = rmaxpack; 624 c->remote_maxpacket = rmaxpack;
612 if (c->type != SSH_CHANNEL_CONNECTING) { 625 if (c->type != SSH_CHANNEL_CONNECTING) {
@@ -633,9 +646,8 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
633} 646}
634 647
635static int 648static int
636server_input_hostkeys_prove(struct sshbuf **respp) 649server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
637{ 650{
638 struct ssh *ssh = active_state; /* XXX */
639 struct sshbuf *resp = NULL; 651 struct sshbuf *resp = NULL;
640 struct sshbuf *sigbuf = NULL; 652 struct sshbuf *sigbuf = NULL;
641 struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; 653 struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
@@ -703,7 +715,7 @@ server_input_hostkeys_prove(struct sshbuf **respp)
703} 715}
704 716
705static int 717static int
706server_input_global_request(int type, u_int32_t seq, void *ctxt) 718server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
707{ 719{
708 char *rtype; 720 char *rtype;
709 int want_reply; 721 int want_reply;
@@ -738,7 +750,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
738 packet_send_debug("Server has disabled port forwarding."); 750 packet_send_debug("Server has disabled port forwarding.");
739 } else { 751 } else {
740 /* Start listening on the port */ 752 /* Start listening on the port */
741 success = channel_setup_remote_fwd_listener(&fwd, 753 success = channel_setup_remote_fwd_listener(ssh, &fwd,
742 &allocated_listen_port, &options.fwd_opts); 754 &allocated_listen_port, &options.fwd_opts);
743 } 755 }
744 free(fwd.listen_host); 756 free(fwd.listen_host);
@@ -756,7 +768,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
756 debug("%s: cancel-tcpip-forward addr %s port %d", __func__, 768 debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
757 fwd.listen_host, fwd.listen_port); 769 fwd.listen_host, fwd.listen_port);
758 770
759 success = channel_cancel_rport_listener(&fwd); 771 success = channel_cancel_rport_listener(ssh, &fwd);
760 free(fwd.listen_host); 772 free(fwd.listen_host);
761 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) { 773 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
762 struct Forward fwd; 774 struct Forward fwd;
@@ -775,7 +787,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
775 "streamlocal forwarding."); 787 "streamlocal forwarding.");
776 } else { 788 } else {
777 /* Start listening on the socket */ 789 /* Start listening on the socket */
778 success = channel_setup_remote_fwd_listener( 790 success = channel_setup_remote_fwd_listener(ssh,
779 &fwd, NULL, &options.fwd_opts); 791 &fwd, NULL, &options.fwd_opts);
780 } 792 }
781 free(fwd.listen_path); 793 free(fwd.listen_path);
@@ -787,19 +799,19 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
787 debug("%s: cancel-streamlocal-forward path %s", __func__, 799 debug("%s: cancel-streamlocal-forward path %s", __func__,
788 fwd.listen_path); 800 fwd.listen_path);
789 801
790 success = channel_cancel_rport_listener(&fwd); 802 success = channel_cancel_rport_listener(ssh, &fwd);
791 free(fwd.listen_path); 803 free(fwd.listen_path);
792 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { 804 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
793 no_more_sessions = 1; 805 no_more_sessions = 1;
794 success = 1; 806 success = 1;
795 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { 807 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
796 success = server_input_hostkeys_prove(&resp); 808 success = server_input_hostkeys_prove(ssh, &resp);
797 } 809 }
798 if (want_reply) { 810 if (want_reply) {
799 packet_start(success ? 811 packet_start(success ?
800 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 812 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
801 if (success && resp != NULL) 813 if (success && resp != NULL)
802 ssh_packet_put_raw(active_state, sshbuf_ptr(resp), 814 ssh_packet_put_raw(ssh, sshbuf_ptr(resp),
803 sshbuf_len(resp)); 815 sshbuf_len(resp));
804 packet_send(); 816 packet_send();
805 packet_write_wait(); 817 packet_write_wait();
@@ -810,7 +822,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
810} 822}
811 823
812static int 824static int
813server_input_channel_req(int type, u_int32_t seq, void *ctxt) 825server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
814{ 826{
815 Channel *c; 827 Channel *c;
816 int id, reply, success = 0; 828 int id, reply, success = 0;
@@ -823,16 +835,19 @@ server_input_channel_req(int type, u_int32_t seq, void *ctxt)
823 debug("server_input_channel_req: channel %d request %s reply %d", 835 debug("server_input_channel_req: channel %d request %s reply %d",
824 id, rtype, reply); 836 id, rtype, reply);
825 837
826 if ((c = channel_lookup(id)) == NULL) 838 if ((c = channel_lookup(ssh, id)) == NULL)
827 packet_disconnect("server_input_channel_req: " 839 packet_disconnect("server_input_channel_req: "
828 "unknown channel %d", id); 840 "unknown channel %d", id);
829 if (!strcmp(rtype, "eow@openssh.com")) { 841 if (!strcmp(rtype, "eow@openssh.com")) {
830 packet_check_eom(); 842 packet_check_eom();
831 chan_rcvd_eow(c); 843 chan_rcvd_eow(ssh, c);
832 } else if ((c->type == SSH_CHANNEL_LARVAL || 844 } else if ((c->type == SSH_CHANNEL_LARVAL ||
833 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) 845 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
834 success = session_input_channel_req(c, rtype); 846 success = session_input_channel_req(ssh, c, rtype);
835 if (reply && !(c->flags & CHAN_CLOSE_SENT)) { 847 if (reply && !(c->flags & CHAN_CLOSE_SENT)) {
848 if (!c->have_remote_id)
849 fatal("%s: channel %d: no remote_id",
850 __func__, c->self);
836 packet_start(success ? 851 packet_start(success ?
837 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 852 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
838 packet_put_int(c->remote_id); 853 packet_put_int(c->remote_id);
diff --git a/serverloop.h b/serverloop.h
index d5fbda16f..fd2cf63f7 100644
--- a/serverloop.h
+++ b/serverloop.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.h,v 1.7 2016/08/13 17:47:41 markus Exp $ */ 1/* $OpenBSD: serverloop.h,v 1.8 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -21,6 +21,8 @@
21#ifndef SERVERLOOP_H 21#ifndef SERVERLOOP_H
22#define SERVERLOOP_H 22#define SERVERLOOP_H
23 23
24void server_loop2(Authctxt *); 24struct ssh;
25
26void server_loop2(struct ssh *, Authctxt *);
25 27
26#endif 28#endif
diff --git a/session.c b/session.c
index a08aa69d1..4bccb62d1 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.c,v 1.286 2016/11/30 03:00:05 djm Exp $ */ 1/* $OpenBSD: session.c,v 1.292 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved 4 * All rights reserved
@@ -94,6 +94,7 @@
94#include "kex.h" 94#include "kex.h"
95#include "monitor_wrap.h" 95#include "monitor_wrap.h"
96#include "sftp.h" 96#include "sftp.h"
97#include "atomicio.h"
97 98
98#if defined(KRB5) && defined(USE_AFS) 99#if defined(KRB5) && defined(USE_AFS)
99#include <kafs.h> 100#include <kafs.h>
@@ -112,29 +113,28 @@
112/* func */ 113/* func */
113 114
114Session *session_new(void); 115Session *session_new(void);
115void session_set_fds(Session *, int, int, int, int, int); 116void session_set_fds(struct ssh *, Session *, int, int, int, int, int);
116void session_pty_cleanup(Session *); 117void session_pty_cleanup(Session *);
117void session_proctitle(Session *); 118void session_proctitle(Session *);
118int session_setup_x11fwd(Session *); 119int session_setup_x11fwd(struct ssh *, Session *);
119int do_exec_pty(Session *, const char *); 120int do_exec_pty(struct ssh *, Session *, const char *);
120int do_exec_no_pty(Session *, const char *); 121int do_exec_no_pty(struct ssh *, Session *, const char *);
121int do_exec(Session *, const char *); 122int do_exec(struct ssh *, Session *, const char *);
122void do_login(Session *, const char *); 123void do_login(struct ssh *, Session *, const char *);
124void do_child(struct ssh *, Session *, const char *);
123#ifdef LOGIN_NEEDS_UTMPX 125#ifdef LOGIN_NEEDS_UTMPX
124static void do_pre_login(Session *s); 126static void do_pre_login(Session *s);
125#endif 127#endif
126void do_child(Session *, const char *);
127void do_motd(void); 128void do_motd(void);
128int check_quietlogin(Session *, const char *); 129int check_quietlogin(Session *, const char *);
129 130
130static void do_authenticated2(Authctxt *); 131static void do_authenticated2(struct ssh *, Authctxt *);
131 132
132static int session_pty_req(Session *); 133static int session_pty_req(struct ssh *, Session *);
133 134
134/* import */ 135/* import */
135extern ServerOptions options; 136extern ServerOptions options;
136extern char *__progname; 137extern char *__progname;
137extern int log_stderr;
138extern int debug_flag; 138extern int debug_flag;
139extern u_int utmp_len; 139extern u_int utmp_len;
140extern int startup_pipe; 140extern int startup_pipe;
@@ -161,6 +161,9 @@ login_cap_t *lc;
161static int is_child = 0; 161static int is_child = 0;
162static int in_chroot = 0; 162static int in_chroot = 0;
163 163
164/* File containing userauth info, if ExposeAuthInfo set */
165static char *auth_info_file = NULL;
166
164/* Name and directory of socket for authentication agent forwarding. */ 167/* Name and directory of socket for authentication agent forwarding. */
165static char *auth_sock_name = NULL; 168static char *auth_sock_name = NULL;
166static char *auth_sock_dir = NULL; 169static char *auth_sock_dir = NULL;
@@ -180,7 +183,7 @@ auth_sock_cleanup_proc(struct passwd *pw)
180} 183}
181 184
182static int 185static int
183auth_input_request_forwarding(struct passwd * pw) 186auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
184{ 187{
185 Channel *nc; 188 Channel *nc;
186 int sock = -1; 189 int sock = -1;
@@ -220,7 +223,7 @@ auth_input_request_forwarding(struct passwd * pw)
220 goto authsock_err; 223 goto authsock_err;
221 224
222 /* Allocate a channel for the authentication agent socket. */ 225 /* Allocate a channel for the authentication agent socket. */
223 nc = channel_new("auth socket", 226 nc = channel_new(ssh, "auth socket",
224 SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, 227 SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
225 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 228 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
226 0, "auth socket", 1); 229 0, "auth socket", 1);
@@ -250,8 +253,42 @@ display_loginmsg(void)
250 } 253 }
251} 254}
252 255
256static void
257prepare_auth_info_file(struct passwd *pw, struct sshbuf *info)
258{
259 int fd = -1, success = 0;
260
261 if (!options.expose_userauth_info || info == NULL)
262 return;
263
264 temporarily_use_uid(pw);
265 auth_info_file = xstrdup("/tmp/sshauth.XXXXXXXXXXXXXXX");
266 if ((fd = mkstemp(auth_info_file)) == -1) {
267 error("%s: mkstemp: %s", __func__, strerror(errno));
268 goto out;
269 }
270 if (atomicio(vwrite, fd, sshbuf_mutable_ptr(info),
271 sshbuf_len(info)) != sshbuf_len(info)) {
272 error("%s: write: %s", __func__, strerror(errno));
273 goto out;
274 }
275 if (close(fd) != 0) {
276 error("%s: close: %s", __func__, strerror(errno));
277 goto out;
278 }
279 success = 1;
280 out:
281 if (!success) {
282 if (fd != -1)
283 close(fd);
284 free(auth_info_file);
285 auth_info_file = NULL;
286 }
287 restore_uid();
288}
289
253void 290void
254do_authenticated(Authctxt *authctxt) 291do_authenticated(struct ssh *ssh, Authctxt *authctxt)
255{ 292{
256 setproctitle("%s", authctxt->pw->pw_name); 293 setproctitle("%s", authctxt->pw->pw_name);
257 294
@@ -259,14 +296,17 @@ do_authenticated(Authctxt *authctxt)
259 /* XXX - streamlocal? */ 296 /* XXX - streamlocal? */
260 if (no_port_forwarding_flag || options.disable_forwarding || 297 if (no_port_forwarding_flag || options.disable_forwarding ||
261 (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) 298 (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
262 channel_disable_adm_local_opens(); 299 channel_disable_adm_local_opens(ssh);
263 else 300 else
264 channel_permit_all_opens(); 301 channel_permit_all_opens(ssh);
265 302
266 auth_debug_send(); 303 auth_debug_send();
267 304
268 do_authenticated2(authctxt); 305 prepare_auth_info_file(authctxt->pw, authctxt->session_info);
269 do_cleanup(authctxt); 306
307 do_authenticated2(ssh, authctxt);
308
309 do_cleanup(ssh, authctxt);
270} 310}
271 311
272/* Check untrusted xauth strings for metacharacters */ 312/* Check untrusted xauth strings for metacharacters */
@@ -291,7 +331,7 @@ xauth_valid_string(const char *s)
291 * setting up file descriptors and such. 331 * setting up file descriptors and such.
292 */ 332 */
293int 333int
294do_exec_no_pty(Session *s, const char *command) 334do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
295{ 335{
296 pid_t pid; 336 pid_t pid;
297 337
@@ -364,10 +404,6 @@ do_exec_no_pty(Session *s, const char *command)
364 case 0: 404 case 0:
365 is_child = 1; 405 is_child = 1;
366 406
367 /* Child. Reinitialize the log since the pid has changed. */
368 log_init(__progname, options.log_level,
369 options.log_facility, log_stderr);
370
371 /* 407 /*
372 * Create a new session and process group since the 4.4BSD 408 * Create a new session and process group since the 4.4BSD
373 * setlogin() affects the entire process group. 409 * setlogin() affects the entire process group.
@@ -420,7 +456,7 @@ do_exec_no_pty(Session *s, const char *command)
420#endif 456#endif
421 457
422 /* Do processing for the child (exec command etc). */ 458 /* Do processing for the child (exec command etc). */
423 do_child(s, command); 459 do_child(ssh, s, command);
424 /* NOTREACHED */ 460 /* NOTREACHED */
425 default: 461 default:
426 break; 462 break;
@@ -451,7 +487,7 @@ do_exec_no_pty(Session *s, const char *command)
451 close(pout[1]); 487 close(pout[1]);
452 close(perr[1]); 488 close(perr[1]);
453 489
454 session_set_fds(s, pin[1], pout[0], perr[0], 490 session_set_fds(ssh, s, pin[1], pout[0], perr[0],
455 s->is_subsystem, 0); 491 s->is_subsystem, 0);
456#else 492#else
457 /* We are the parent. Close the child sides of the socket pairs. */ 493 /* We are the parent. Close the child sides of the socket pairs. */
@@ -475,7 +511,7 @@ do_exec_no_pty(Session *s, const char *command)
475 * lastlog, and other such operations. 511 * lastlog, and other such operations.
476 */ 512 */
477int 513int
478do_exec_pty(Session *s, const char *command) 514do_exec_pty(struct ssh *ssh, Session *s, const char *command)
479{ 515{
480 int fdout, ptyfd, ttyfd, ptymaster; 516 int fdout, ptyfd, ttyfd, ptymaster;
481 pid_t pid; 517 pid_t pid;
@@ -522,9 +558,6 @@ do_exec_pty(Session *s, const char *command)
522 close(fdout); 558 close(fdout);
523 close(ptymaster); 559 close(ptymaster);
524 560
525 /* Child. Reinitialize the log because the pid has changed. */
526 log_init(__progname, options.log_level,
527 options.log_facility, log_stderr);
528 /* Close the master side of the pseudo tty. */ 561 /* Close the master side of the pseudo tty. */
529 close(ptyfd); 562 close(ptyfd);
530 563
@@ -547,13 +580,13 @@ do_exec_pty(Session *s, const char *command)
547 cray_init_job(s->pw); /* set up cray jid and tmpdir */ 580 cray_init_job(s->pw); /* set up cray jid and tmpdir */
548#endif /* _UNICOS */ 581#endif /* _UNICOS */
549#ifndef HAVE_OSF_SIA 582#ifndef HAVE_OSF_SIA
550 do_login(s, command); 583 do_login(ssh, s, command);
551#endif 584#endif
552 /* 585 /*
553 * Do common processing for the child, such as execing 586 * Do common processing for the child, such as execing
554 * the command. 587 * the command.
555 */ 588 */
556 do_child(s, command); 589 do_child(ssh, s, command);
557 /* NOTREACHED */ 590 /* NOTREACHED */
558 default: 591 default:
559 break; 592 break;
@@ -575,7 +608,7 @@ do_exec_pty(Session *s, const char *command)
575 s->ptymaster = ptymaster; 608 s->ptymaster = ptymaster;
576 packet_set_interactive(1, 609 packet_set_interactive(1,
577 options.ip_qos_interactive, options.ip_qos_bulk); 610 options.ip_qos_interactive, options.ip_qos_bulk);
578 session_set_fds(s, ptyfd, fdout, -1, 1, 1); 611 session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1);
579 return 0; 612 return 0;
580} 613}
581 614
@@ -613,9 +646,8 @@ do_pre_login(Session *s)
613 * to be forced, execute that instead. 646 * to be forced, execute that instead.
614 */ 647 */
615int 648int
616do_exec(Session *s, const char *command) 649do_exec(struct ssh *ssh, Session *s, const char *command)
617{ 650{
618 struct ssh *ssh = active_state; /* XXX */
619 int ret; 651 int ret;
620 const char *forced = NULL, *tty = NULL; 652 const char *forced = NULL, *tty = NULL;
621 char session_type[1024]; 653 char session_type[1024];
@@ -674,9 +706,9 @@ do_exec(Session *s, const char *command)
674 } 706 }
675#endif 707#endif
676 if (s->ttyfd != -1) 708 if (s->ttyfd != -1)
677 ret = do_exec_pty(s, command); 709 ret = do_exec_pty(ssh, s, command);
678 else 710 else
679 ret = do_exec_no_pty(s, command); 711 ret = do_exec_no_pty(ssh, s, command);
680 712
681 original_command = NULL; 713 original_command = NULL;
682 714
@@ -692,9 +724,8 @@ do_exec(Session *s, const char *command)
692 724
693/* administrative, login(1)-like work */ 725/* administrative, login(1)-like work */
694void 726void
695do_login(Session *s, const char *command) 727do_login(struct ssh *ssh, Session *s, const char *command)
696{ 728{
697 struct ssh *ssh = active_state; /* XXX */
698 socklen_t fromlen; 729 socklen_t fromlen;
699 struct sockaddr_storage from; 730 struct sockaddr_storage from;
700 struct passwd * pw = s->pw; 731 struct passwd * pw = s->pw;
@@ -792,65 +823,6 @@ check_quietlogin(Session *s, const char *command)
792} 823}
793 824
794/* 825/*
795 * Sets the value of the given variable in the environment. If the variable
796 * already exists, its value is overridden.
797 */
798void
799child_set_env(char ***envp, u_int *envsizep, const char *name,
800 const char *value)
801{
802 char **env;
803 u_int envsize;
804 u_int i, namelen;
805
806 if (strchr(name, '=') != NULL) {
807 error("Invalid environment variable \"%.100s\"", name);
808 return;
809 }
810
811 /*
812 * If we're passed an uninitialized list, allocate a single null
813 * entry before continuing.
814 */
815 if (*envp == NULL && *envsizep == 0) {
816 *envp = xmalloc(sizeof(char *));
817 *envp[0] = NULL;
818 *envsizep = 1;
819 }
820
821 /*
822 * Find the slot where the value should be stored. If the variable
823 * already exists, we reuse the slot; otherwise we append a new slot
824 * at the end of the array, expanding if necessary.
825 */
826 env = *envp;
827 namelen = strlen(name);
828 for (i = 0; env[i]; i++)
829 if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
830 break;
831 if (env[i]) {
832 /* Reuse the slot. */
833 free(env[i]);
834 } else {
835 /* New variable. Expand if necessary. */
836 envsize = *envsizep;
837 if (i >= envsize - 1) {
838 if (envsize >= 1000)
839 fatal("child_set_env: too many env vars");
840 envsize += 50;
841 env = (*envp) = xreallocarray(env, envsize, sizeof(char *));
842 *envsizep = envsize;
843 }
844 /* Need to set the NULL pointer at end of array beyond the new slot. */
845 env[i + 1] = NULL;
846 }
847
848 /* Allocate space and format the variable in the appropriate slot. */
849 env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
850 snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
851}
852
853/*
854 * Reads environment variables from the given file and adds/overrides them 826 * Reads environment variables from the given file and adds/overrides them
855 * into the environment. If the file does not exist, this does nothing. 827 * into the environment. If the file does not exist, this does nothing.
856 * Otherwise, it must consist of empty lines, comments (line starts with '#') 828 * Otherwise, it must consist of empty lines, comments (line starts with '#')
@@ -951,8 +923,9 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
951} 923}
952#endif /* HAVE_ETC_DEFAULT_LOGIN */ 924#endif /* HAVE_ETC_DEFAULT_LOGIN */
953 925
954void 926static void
955copy_environment(char **source, char ***env, u_int *envsize) 927copy_environment_blacklist(char **source, char ***env, u_int *envsize,
928 const char *blacklist)
956{ 929{
957 char *var_name, *var_val; 930 char *var_name, *var_val;
958 int i; 931 int i;
@@ -968,17 +941,25 @@ copy_environment(char **source, char ***env, u_int *envsize)
968 } 941 }
969 *var_val++ = '\0'; 942 *var_val++ = '\0';
970 943
971 debug3("Copy environment: %s=%s", var_name, var_val); 944 if (blacklist == NULL ||
972 child_set_env(env, envsize, var_name, var_val); 945 match_pattern_list(var_name, blacklist, 0) != 1) {
946 debug3("Copy environment: %s=%s", var_name, var_val);
947 child_set_env(env, envsize, var_name, var_val);
948 }
973 949
974 free(var_name); 950 free(var_name);
975 } 951 }
976} 952}
977 953
954void
955copy_environment(char **source, char ***env, u_int *envsize)
956{
957 copy_environment_blacklist(source, env, envsize, NULL);
958}
959
978static char ** 960static char **
979do_setup_env(Session *s, const char *shell) 961do_setup_env(struct ssh *ssh, Session *s, const char *shell)
980{ 962{
981 struct ssh *ssh = active_state; /* XXX */
982 char buf[256]; 963 char buf[256];
983 u_int i, envsize; 964 u_int i, envsize;
984 char **env, *laddr; 965 char **env, *laddr;
@@ -1085,6 +1066,8 @@ do_setup_env(Session *s, const char *shell)
1085 free(laddr); 1066 free(laddr);
1086 child_set_env(&env, &envsize, "SSH_CONNECTION", buf); 1067 child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1087 1068
1069 if (auth_info_file != NULL)
1070 child_set_env(&env, &envsize, "SSH_USER_AUTH", auth_info_file);
1088 if (s->ttyfd != -1) 1071 if (s->ttyfd != -1)
1089 child_set_env(&env, &envsize, "SSH_TTY", s->tty); 1072 child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1090 if (s->term) 1073 if (s->term)
@@ -1134,12 +1117,16 @@ do_setup_env(Session *s, const char *shell)
1134 if (options.use_pam) { 1117 if (options.use_pam) {
1135 char **p; 1118 char **p;
1136 1119
1120 /*
1121 * Don't allow SSH_AUTH_INFO variables posted to PAM to leak
1122 * back into the environment.
1123 */
1137 p = fetch_pam_child_environment(); 1124 p = fetch_pam_child_environment();
1138 copy_environment(p, &env, &envsize); 1125 copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*");
1139 free_pam_environment(p); 1126 free_pam_environment(p);
1140 1127
1141 p = fetch_pam_environment(); 1128 p = fetch_pam_environment();
1142 copy_environment(p, &env, &envsize); 1129 copy_environment_blacklist(p, &env, &envsize, "SSH_AUTH_INFO*");
1143 free_pam_environment(p); 1130 free_pam_environment(p);
1144 } 1131 }
1145#endif /* USE_PAM */ 1132#endif /* USE_PAM */
@@ -1431,7 +1418,7 @@ do_pwchange(Session *s)
1431} 1418}
1432 1419
1433static void 1420static void
1434child_close_fds(void) 1421child_close_fds(struct ssh *ssh)
1435{ 1422{
1436 extern int auth_sock; 1423 extern int auth_sock;
1437 1424
@@ -1451,7 +1438,7 @@ child_close_fds(void)
1451 * open in the parent. 1438 * open in the parent.
1452 */ 1439 */
1453 /* XXX better use close-on-exec? -markus */ 1440 /* XXX better use close-on-exec? -markus */
1454 channel_close_all(); 1441 channel_close_all(ssh);
1455 1442
1456 /* 1443 /*
1457 * Close any extra file descriptors. Note that there may still be 1444 * Close any extra file descriptors. Note that there may still be
@@ -1475,7 +1462,7 @@ child_close_fds(void)
1475 */ 1462 */
1476#define ARGV_MAX 10 1463#define ARGV_MAX 10
1477void 1464void
1478do_child(Session *s, const char *command) 1465do_child(struct ssh *ssh, Session *s, const char *command)
1479{ 1466{
1480 extern char **environ; 1467 extern char **environ;
1481 char **env; 1468 char **env;
@@ -1486,11 +1473,12 @@ do_child(Session *s, const char *command)
1486 1473
1487 /* remove hostkey from the child's memory */ 1474 /* remove hostkey from the child's memory */
1488 destroy_sensitive_data(); 1475 destroy_sensitive_data();
1476 packet_clear_keys();
1489 1477
1490 /* Force a password change */ 1478 /* Force a password change */
1491 if (s->authctxt->force_pwchange) { 1479 if (s->authctxt->force_pwchange) {
1492 do_setusercontext(pw); 1480 do_setusercontext(pw);
1493 child_close_fds(); 1481 child_close_fds(ssh);
1494 do_pwchange(s); 1482 do_pwchange(s);
1495 exit(1); 1483 exit(1);
1496 } 1484 }
@@ -1539,7 +1527,7 @@ do_child(Session *s, const char *command)
1539 * Make sure $SHELL points to the shell from the password file, 1527 * Make sure $SHELL points to the shell from the password file,
1540 * even if shell is overridden from login.conf 1528 * even if shell is overridden from login.conf
1541 */ 1529 */
1542 env = do_setup_env(s, shell); 1530 env = do_setup_env(ssh, s, shell);
1543 1531
1544#ifdef HAVE_LOGIN_CAP 1532#ifdef HAVE_LOGIN_CAP
1545 shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); 1533 shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
@@ -1552,7 +1540,7 @@ do_child(Session *s, const char *command)
1552 * closed before building the environment, as we call 1540 * closed before building the environment, as we call
1553 * ssh_remote_ipaddr there. 1541 * ssh_remote_ipaddr there.
1554 */ 1542 */
1555 child_close_fds(); 1543 child_close_fds(ssh);
1556 1544
1557 /* 1545 /*
1558 * Must take new environment into use so that .ssh/rc, 1546 * Must take new environment into use so that .ssh/rc,
@@ -1710,8 +1698,8 @@ session_new(void)
1710 return NULL; 1698 return NULL;
1711 debug2("%s: allocate (allocated %d max %d)", 1699 debug2("%s: allocate (allocated %d max %d)",
1712 __func__, sessions_nalloc, options.max_sessions); 1700 __func__, sessions_nalloc, options.max_sessions);
1713 tmp = xreallocarray(sessions, sessions_nalloc + 1, 1701 tmp = xrecallocarray(sessions, sessions_nalloc,
1714 sizeof(*sessions)); 1702 sessions_nalloc + 1, sizeof(*sessions));
1715 if (tmp == NULL) { 1703 if (tmp == NULL) {
1716 error("%s: cannot allocate %d sessions", 1704 error("%s: cannot allocate %d sessions",
1717 __func__, sessions_nalloc + 1); 1705 __func__, sessions_nalloc + 1);
@@ -1849,7 +1837,7 @@ session_by_pid(pid_t pid)
1849} 1837}
1850 1838
1851static int 1839static int
1852session_window_change_req(Session *s) 1840session_window_change_req(struct ssh *ssh, Session *s)
1853{ 1841{
1854 s->col = packet_get_int(); 1842 s->col = packet_get_int();
1855 s->row = packet_get_int(); 1843 s->row = packet_get_int();
@@ -1861,7 +1849,7 @@ session_window_change_req(Session *s)
1861} 1849}
1862 1850
1863static int 1851static int
1864session_pty_req(Session *s) 1852session_pty_req(struct ssh *ssh, Session *s)
1865{ 1853{
1866 u_int len; 1854 u_int len;
1867 int n_bytes; 1855 int n_bytes;
@@ -1914,7 +1902,7 @@ session_pty_req(Session *s)
1914} 1902}
1915 1903
1916static int 1904static int
1917session_subsystem_req(Session *s) 1905session_subsystem_req(struct ssh *ssh, Session *s)
1918{ 1906{
1919 struct stat st; 1907 struct stat st;
1920 u_int len; 1908 u_int len;
@@ -1941,7 +1929,7 @@ session_subsystem_req(Session *s)
1941 s->is_subsystem = SUBSYSTEM_EXT; 1929 s->is_subsystem = SUBSYSTEM_EXT;
1942 debug("subsystem: exec() %s", cmd); 1930 debug("subsystem: exec() %s", cmd);
1943 } 1931 }
1944 success = do_exec(s, cmd) == 0; 1932 success = do_exec(ssh, s, cmd) == 0;
1945 break; 1933 break;
1946 } 1934 }
1947 } 1935 }
@@ -1954,7 +1942,7 @@ session_subsystem_req(Session *s)
1954} 1942}
1955 1943
1956static int 1944static int
1957session_x11_req(Session *s) 1945session_x11_req(struct ssh *ssh, Session *s)
1958{ 1946{
1959 int success; 1947 int success;
1960 1948
@@ -1971,7 +1959,7 @@ session_x11_req(Session *s)
1971 1959
1972 if (xauth_valid_string(s->auth_proto) && 1960 if (xauth_valid_string(s->auth_proto) &&
1973 xauth_valid_string(s->auth_data)) 1961 xauth_valid_string(s->auth_data))
1974 success = session_setup_x11fwd(s); 1962 success = session_setup_x11fwd(ssh, s);
1975 else { 1963 else {
1976 success = 0; 1964 success = 0;
1977 error("Invalid X11 forwarding data"); 1965 error("Invalid X11 forwarding data");
@@ -1986,26 +1974,26 @@ session_x11_req(Session *s)
1986} 1974}
1987 1975
1988static int 1976static int
1989session_shell_req(Session *s) 1977session_shell_req(struct ssh *ssh, Session *s)
1990{ 1978{
1991 packet_check_eom(); 1979 packet_check_eom();
1992 return do_exec(s, NULL) == 0; 1980 return do_exec(ssh, s, NULL) == 0;
1993} 1981}
1994 1982
1995static int 1983static int
1996session_exec_req(Session *s) 1984session_exec_req(struct ssh *ssh, Session *s)
1997{ 1985{
1998 u_int len, success; 1986 u_int len, success;
1999 1987
2000 char *command = packet_get_string(&len); 1988 char *command = packet_get_string(&len);
2001 packet_check_eom(); 1989 packet_check_eom();
2002 success = do_exec(s, command) == 0; 1990 success = do_exec(ssh, s, command) == 0;
2003 free(command); 1991 free(command);
2004 return success; 1992 return success;
2005} 1993}
2006 1994
2007static int 1995static int
2008session_break_req(Session *s) 1996session_break_req(struct ssh *ssh, Session *s)
2009{ 1997{
2010 1998
2011 packet_get_int(); /* ignored */ 1999 packet_get_int(); /* ignored */
@@ -2017,7 +2005,7 @@ session_break_req(Session *s)
2017} 2005}
2018 2006
2019static int 2007static int
2020session_env_req(Session *s) 2008session_env_req(struct ssh *ssh, Session *s)
2021{ 2009{
2022 char *name, *val; 2010 char *name, *val;
2023 u_int name_len, val_len, i; 2011 u_int name_len, val_len, i;
@@ -2035,8 +2023,8 @@ session_env_req(Session *s)
2035 for (i = 0; i < options.num_accept_env; i++) { 2023 for (i = 0; i < options.num_accept_env; i++) {
2036 if (match_pattern(name, options.accept_env[i])) { 2024 if (match_pattern(name, options.accept_env[i])) {
2037 debug2("Setting env %d: %s=%s", s->num_env, name, val); 2025 debug2("Setting env %d: %s=%s", s->num_env, name, val);
2038 s->env = xreallocarray(s->env, s->num_env + 1, 2026 s->env = xrecallocarray(s->env, s->num_env,
2039 sizeof(*s->env)); 2027 s->num_env + 1, sizeof(*s->env));
2040 s->env[s->num_env].name = name; 2028 s->env[s->num_env].name = name;
2041 s->env[s->num_env].val = val; 2029 s->env[s->num_env].val = val;
2042 s->num_env++; 2030 s->num_env++;
@@ -2052,7 +2040,7 @@ session_env_req(Session *s)
2052} 2040}
2053 2041
2054static int 2042static int
2055session_auth_agent_req(Session *s) 2043session_auth_agent_req(struct ssh *ssh, Session *s)
2056{ 2044{
2057 static int called = 0; 2045 static int called = 0;
2058 packet_check_eom(); 2046 packet_check_eom();
@@ -2064,22 +2052,21 @@ session_auth_agent_req(Session *s)
2064 return 0; 2052 return 0;
2065 } else { 2053 } else {
2066 called = 1; 2054 called = 1;
2067 return auth_input_request_forwarding(s->pw); 2055 return auth_input_request_forwarding(ssh, s->pw);
2068 } 2056 }
2069} 2057}
2070 2058
2071int 2059int
2072session_input_channel_req(Channel *c, const char *rtype) 2060session_input_channel_req(struct ssh *ssh, Channel *c, const char *rtype)
2073{ 2061{
2074 int success = 0; 2062 int success = 0;
2075 Session *s; 2063 Session *s;
2076 2064
2077 if ((s = session_by_channel(c->self)) == NULL) { 2065 if ((s = session_by_channel(c->self)) == NULL) {
2078 logit("session_input_channel_req: no session %d req %.100s", 2066 logit("%s: no session %d req %.100s", __func__, c->self, rtype);
2079 c->self, rtype);
2080 return 0; 2067 return 0;
2081 } 2068 }
2082 debug("session_input_channel_req: session %d req %s", s->self, rtype); 2069 debug("%s: session %d req %s", __func__, s->self, rtype);
2083 2070
2084 /* 2071 /*
2085 * a session is in LARVAL state until a shell, a command 2072 * a session is in LARVAL state until a shell, a command
@@ -2087,33 +2074,33 @@ session_input_channel_req(Channel *c, const char *rtype)
2087 */ 2074 */
2088 if (c->type == SSH_CHANNEL_LARVAL) { 2075 if (c->type == SSH_CHANNEL_LARVAL) {
2089 if (strcmp(rtype, "shell") == 0) { 2076 if (strcmp(rtype, "shell") == 0) {
2090 success = session_shell_req(s); 2077 success = session_shell_req(ssh, s);
2091 } else if (strcmp(rtype, "exec") == 0) { 2078 } else if (strcmp(rtype, "exec") == 0) {
2092 success = session_exec_req(s); 2079 success = session_exec_req(ssh, s);
2093 } else if (strcmp(rtype, "pty-req") == 0) { 2080 } else if (strcmp(rtype, "pty-req") == 0) {
2094 success = session_pty_req(s); 2081 success = session_pty_req(ssh, s);
2095 } else if (strcmp(rtype, "x11-req") == 0) { 2082 } else if (strcmp(rtype, "x11-req") == 0) {
2096 success = session_x11_req(s); 2083 success = session_x11_req(ssh, s);
2097 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { 2084 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
2098 success = session_auth_agent_req(s); 2085 success = session_auth_agent_req(ssh, s);
2099 } else if (strcmp(rtype, "subsystem") == 0) { 2086 } else if (strcmp(rtype, "subsystem") == 0) {
2100 success = session_subsystem_req(s); 2087 success = session_subsystem_req(ssh, s);
2101 } else if (strcmp(rtype, "env") == 0) { 2088 } else if (strcmp(rtype, "env") == 0) {
2102 success = session_env_req(s); 2089 success = session_env_req(ssh, s);
2103 } 2090 }
2104 } 2091 }
2105 if (strcmp(rtype, "window-change") == 0) { 2092 if (strcmp(rtype, "window-change") == 0) {
2106 success = session_window_change_req(s); 2093 success = session_window_change_req(ssh, s);
2107 } else if (strcmp(rtype, "break") == 0) { 2094 } else if (strcmp(rtype, "break") == 0) {
2108 success = session_break_req(s); 2095 success = session_break_req(ssh, s);
2109 } 2096 }
2110 2097
2111 return success; 2098 return success;
2112} 2099}
2113 2100
2114void 2101void
2115session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr, 2102session_set_fds(struct ssh *ssh, Session *s,
2116 int is_tty) 2103 int fdin, int fdout, int fderr, int ignore_fderr, int is_tty)
2117{ 2104{
2118 /* 2105 /*
2119 * now that have a child and a pipe to the child, 2106 * now that have a child and a pipe to the child,
@@ -2121,7 +2108,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
2121 */ 2108 */
2122 if (s->chanid == -1) 2109 if (s->chanid == -1)
2123 fatal("no channel for session %d", s->self); 2110 fatal("no channel for session %d", s->self);
2124 channel_set_fds(s->chanid, 2111 channel_set_fds(ssh, s->chanid,
2125 fdout, fdin, fderr, 2112 fdout, fdin, fderr,
2126 ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, 2113 ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2127 1, is_tty, CHAN_SES_WINDOW_DEFAULT); 2114 1, is_tty, CHAN_SES_WINDOW_DEFAULT);
@@ -2192,40 +2179,40 @@ sig2name(int sig)
2192} 2179}
2193 2180
2194static void 2181static void
2195session_close_x11(int id) 2182session_close_x11(struct ssh *ssh, int id)
2196{ 2183{
2197 Channel *c; 2184 Channel *c;
2198 2185
2199 if ((c = channel_by_id(id)) == NULL) { 2186 if ((c = channel_by_id(ssh, id)) == NULL) {
2200 debug("session_close_x11: x11 channel %d missing", id); 2187 debug("%s: x11 channel %d missing", __func__, id);
2201 } else { 2188 } else {
2202 /* Detach X11 listener */ 2189 /* Detach X11 listener */
2203 debug("session_close_x11: detach x11 channel %d", id); 2190 debug("%s: detach x11 channel %d", __func__, id);
2204 channel_cancel_cleanup(id); 2191 channel_cancel_cleanup(ssh, id);
2205 if (c->ostate != CHAN_OUTPUT_CLOSED) 2192 if (c->ostate != CHAN_OUTPUT_CLOSED)
2206 chan_mark_dead(c); 2193 chan_mark_dead(ssh, c);
2207 } 2194 }
2208} 2195}
2209 2196
2210static void 2197static void
2211session_close_single_x11(int id, void *arg) 2198session_close_single_x11(struct ssh *ssh, int id, void *arg)
2212{ 2199{
2213 Session *s; 2200 Session *s;
2214 u_int i; 2201 u_int i;
2215 2202
2216 debug3("session_close_single_x11: channel %d", id); 2203 debug3("%s: channel %d", __func__, id);
2217 channel_cancel_cleanup(id); 2204 channel_cancel_cleanup(ssh, id);
2218 if ((s = session_by_x11_channel(id)) == NULL) 2205 if ((s = session_by_x11_channel(id)) == NULL)
2219 fatal("session_close_single_x11: no x11 channel %d", id); 2206 fatal("%s: no x11 channel %d", __func__, id);
2220 for (i = 0; s->x11_chanids[i] != -1; i++) { 2207 for (i = 0; s->x11_chanids[i] != -1; i++) {
2221 debug("session_close_single_x11: session %d: " 2208 debug("%s: session %d: closing channel %d",
2222 "closing channel %d", s->self, s->x11_chanids[i]); 2209 __func__, s->self, s->x11_chanids[i]);
2223 /* 2210 /*
2224 * The channel "id" is already closing, but make sure we 2211 * The channel "id" is already closing, but make sure we
2225 * close all of its siblings. 2212 * close all of its siblings.
2226 */ 2213 */
2227 if (s->x11_chanids[i] != id) 2214 if (s->x11_chanids[i] != id)
2228 session_close_x11(s->x11_chanids[i]); 2215 session_close_x11(ssh, s->x11_chanids[i]);
2229 } 2216 }
2230 free(s->x11_chanids); 2217 free(s->x11_chanids);
2231 s->x11_chanids = NULL; 2218 s->x11_chanids = NULL;
@@ -2240,22 +2227,22 @@ session_close_single_x11(int id, void *arg)
2240} 2227}
2241 2228
2242static void 2229static void
2243session_exit_message(Session *s, int status) 2230session_exit_message(struct ssh *ssh, Session *s, int status)
2244{ 2231{
2245 Channel *c; 2232 Channel *c;
2246 2233
2247 if ((c = channel_lookup(s->chanid)) == NULL) 2234 if ((c = channel_lookup(ssh, s->chanid)) == NULL)
2248 fatal("session_exit_message: session %d: no channel %d", 2235 fatal("%s: session %d: no channel %d",
2249 s->self, s->chanid); 2236 __func__, s->self, s->chanid);
2250 debug("session_exit_message: session %d channel %d pid %ld", 2237 debug("%s: session %d channel %d pid %ld",
2251 s->self, s->chanid, (long)s->pid); 2238 __func__, s->self, s->chanid, (long)s->pid);
2252 2239
2253 if (WIFEXITED(status)) { 2240 if (WIFEXITED(status)) {
2254 channel_request_start(s->chanid, "exit-status", 0); 2241 channel_request_start(ssh, s->chanid, "exit-status", 0);
2255 packet_put_int(WEXITSTATUS(status)); 2242 packet_put_int(WEXITSTATUS(status));
2256 packet_send(); 2243 packet_send();
2257 } else if (WIFSIGNALED(status)) { 2244 } else if (WIFSIGNALED(status)) {
2258 channel_request_start(s->chanid, "exit-signal", 0); 2245 channel_request_start(ssh, s->chanid, "exit-signal", 0);
2259 packet_put_cstring(sig2name(WTERMSIG(status))); 2246 packet_put_cstring(sig2name(WTERMSIG(status)));
2260#ifdef WCOREDUMP 2247#ifdef WCOREDUMP
2261 packet_put_char(WCOREDUMP(status)? 1 : 0); 2248 packet_put_char(WCOREDUMP(status)? 1 : 0);
@@ -2271,14 +2258,14 @@ session_exit_message(Session *s, int status)
2271 } 2258 }
2272 2259
2273 /* disconnect channel */ 2260 /* disconnect channel */
2274 debug("session_exit_message: release channel %d", s->chanid); 2261 debug("%s: release channel %d", __func__, s->chanid);
2275 2262
2276 /* 2263 /*
2277 * Adjust cleanup callback attachment to send close messages when 2264 * Adjust cleanup callback attachment to send close messages when
2278 * the channel gets EOF. The session will be then be closed 2265 * the channel gets EOF. The session will be then be closed
2279 * by session_close_by_channel when the childs close their fds. 2266 * by session_close_by_channel when the childs close their fds.
2280 */ 2267 */
2281 channel_register_cleanup(c->self, session_close_by_channel, 1); 2268 channel_register_cleanup(ssh, c->self, session_close_by_channel, 1);
2282 2269
2283 /* 2270 /*
2284 * emulate a write failure with 'chan_write_failed', nobody will be 2271 * emulate a write failure with 'chan_write_failed', nobody will be
@@ -2287,13 +2274,12 @@ session_exit_message(Session *s, int status)
2287 * be some more data waiting in the pipe. 2274 * be some more data waiting in the pipe.
2288 */ 2275 */
2289 if (c->ostate != CHAN_OUTPUT_CLOSED) 2276 if (c->ostate != CHAN_OUTPUT_CLOSED)
2290 chan_write_failed(c); 2277 chan_write_failed(ssh, c);
2291} 2278}
2292 2279
2293void 2280void
2294session_close(Session *s) 2281session_close(struct ssh *ssh, Session *s)
2295{ 2282{
2296 struct ssh *ssh = active_state; /* XXX */
2297 u_int i; 2283 u_int i;
2298 2284
2299 verbose("Close session: user %s from %.200s port %d id %d", 2285 verbose("Close session: user %s from %.200s port %d id %d",
@@ -2323,16 +2309,15 @@ session_close(Session *s)
2323} 2309}
2324 2310
2325void 2311void
2326session_close_by_pid(pid_t pid, int status) 2312session_close_by_pid(struct ssh *ssh, pid_t pid, int status)
2327{ 2313{
2328 Session *s = session_by_pid(pid); 2314 Session *s = session_by_pid(pid);
2329 if (s == NULL) { 2315 if (s == NULL) {
2330 debug("session_close_by_pid: no session for pid %ld", 2316 debug("%s: no session for pid %ld", __func__, (long)pid);
2331 (long)pid);
2332 return; 2317 return;
2333 } 2318 }
2334 if (s->chanid != -1) 2319 if (s->chanid != -1)
2335 session_exit_message(s, status); 2320 session_exit_message(ssh, s, status);
2336 if (s->ttyfd != -1) 2321 if (s->ttyfd != -1)
2337 session_pty_cleanup(s); 2322 session_pty_cleanup(s);
2338 s->pid = 0; 2323 s->pid = 0;
@@ -2343,19 +2328,18 @@ session_close_by_pid(pid_t pid, int status)
2343 * the session 'child' itself dies 2328 * the session 'child' itself dies
2344 */ 2329 */
2345void 2330void
2346session_close_by_channel(int id, void *arg) 2331session_close_by_channel(struct ssh *ssh, int id, void *arg)
2347{ 2332{
2348 Session *s = session_by_channel(id); 2333 Session *s = session_by_channel(id);
2349 u_int i; 2334 u_int i;
2350 2335
2351 if (s == NULL) { 2336 if (s == NULL) {
2352 debug("session_close_by_channel: no session for id %d", id); 2337 debug("%s: no session for id %d", __func__, id);
2353 return; 2338 return;
2354 } 2339 }
2355 debug("session_close_by_channel: channel %d child %ld", 2340 debug("%s: channel %d child %ld", __func__, id, (long)s->pid);
2356 id, (long)s->pid);
2357 if (s->pid != 0) { 2341 if (s->pid != 0) {
2358 debug("session_close_by_channel: channel %d: has child", id); 2342 debug("%s: channel %d: has child", __func__, id);
2359 /* 2343 /*
2360 * delay detach of session, but release pty, since 2344 * delay detach of session, but release pty, since
2361 * the fd's to the child are already closed 2345 * the fd's to the child are already closed
@@ -2365,22 +2349,22 @@ session_close_by_channel(int id, void *arg)
2365 return; 2349 return;
2366 } 2350 }
2367 /* detach by removing callback */ 2351 /* detach by removing callback */
2368 channel_cancel_cleanup(s->chanid); 2352 channel_cancel_cleanup(ssh, s->chanid);
2369 2353
2370 /* Close any X11 listeners associated with this session */ 2354 /* Close any X11 listeners associated with this session */
2371 if (s->x11_chanids != NULL) { 2355 if (s->x11_chanids != NULL) {
2372 for (i = 0; s->x11_chanids[i] != -1; i++) { 2356 for (i = 0; s->x11_chanids[i] != -1; i++) {
2373 session_close_x11(s->x11_chanids[i]); 2357 session_close_x11(ssh, s->x11_chanids[i]);
2374 s->x11_chanids[i] = -1; 2358 s->x11_chanids[i] = -1;
2375 } 2359 }
2376 } 2360 }
2377 2361
2378 s->chanid = -1; 2362 s->chanid = -1;
2379 session_close(s); 2363 session_close(ssh, s);
2380} 2364}
2381 2365
2382void 2366void
2383session_destroy_all(void (*closefunc)(Session *)) 2367session_destroy_all(struct ssh *ssh, void (*closefunc)(Session *))
2384{ 2368{
2385 int i; 2369 int i;
2386 for (i = 0; i < sessions_nalloc; i++) { 2370 for (i = 0; i < sessions_nalloc; i++) {
@@ -2389,7 +2373,7 @@ session_destroy_all(void (*closefunc)(Session *))
2389 if (closefunc != NULL) 2373 if (closefunc != NULL)
2390 closefunc(s); 2374 closefunc(s);
2391 else 2375 else
2392 session_close(s); 2376 session_close(ssh, s);
2393 } 2377 }
2394 } 2378 }
2395} 2379}
@@ -2432,7 +2416,7 @@ session_proctitle(Session *s)
2432} 2416}
2433 2417
2434int 2418int
2435session_setup_x11fwd(Session *s) 2419session_setup_x11fwd(struct ssh *ssh, Session *s)
2436{ 2420{
2437 struct stat st; 2421 struct stat st;
2438 char display[512], auth_display[512]; 2422 char display[512], auth_display[512];
@@ -2456,14 +2440,14 @@ session_setup_x11fwd(Session *s)
2456 debug("X11 display already set."); 2440 debug("X11 display already set.");
2457 return 0; 2441 return 0;
2458 } 2442 }
2459 if (x11_create_display_inet(options.x11_display_offset, 2443 if (x11_create_display_inet(ssh, options.x11_display_offset,
2460 options.x11_use_localhost, s->single_connection, 2444 options.x11_use_localhost, s->single_connection,
2461 &s->display_number, &s->x11_chanids) == -1) { 2445 &s->display_number, &s->x11_chanids) == -1) {
2462 debug("x11_create_display_inet failed."); 2446 debug("x11_create_display_inet failed.");
2463 return 0; 2447 return 0;
2464 } 2448 }
2465 for (i = 0; s->x11_chanids[i] != -1; i++) { 2449 for (i = 0; s->x11_chanids[i] != -1; i++) {
2466 channel_register_cleanup(s->x11_chanids[i], 2450 channel_register_cleanup(ssh, s->x11_chanids[i],
2467 session_close_single_x11, 0); 2451 session_close_single_x11, 0);
2468 } 2452 }
2469 2453
@@ -2508,13 +2492,13 @@ session_setup_x11fwd(Session *s)
2508} 2492}
2509 2493
2510static void 2494static void
2511do_authenticated2(Authctxt *authctxt) 2495do_authenticated2(struct ssh *ssh, Authctxt *authctxt)
2512{ 2496{
2513 server_loop2(authctxt); 2497 server_loop2(ssh, authctxt);
2514} 2498}
2515 2499
2516void 2500void
2517do_cleanup(Authctxt *authctxt) 2501do_cleanup(struct ssh *ssh, Authctxt *authctxt)
2518{ 2502{
2519 static int called = 0; 2503 static int called = 0;
2520 2504
@@ -2556,12 +2540,21 @@ do_cleanup(Authctxt *authctxt)
2556 /* remove agent socket */ 2540 /* remove agent socket */
2557 auth_sock_cleanup_proc(authctxt->pw); 2541 auth_sock_cleanup_proc(authctxt->pw);
2558 2542
2543 /* remove userauth info */
2544 if (auth_info_file != NULL) {
2545 temporarily_use_uid(authctxt->pw);
2546 unlink(auth_info_file);
2547 restore_uid();
2548 free(auth_info_file);
2549 auth_info_file = NULL;
2550 }
2551
2559 /* 2552 /*
2560 * Cleanup ptys/utmp only if privsep is disabled, 2553 * Cleanup ptys/utmp only if privsep is disabled,
2561 * or if running in monitor. 2554 * or if running in monitor.
2562 */ 2555 */
2563 if (!use_privsep || mm_is_monitor()) 2556 if (!use_privsep || mm_is_monitor())
2564 session_destroy_all(session_pty_cleanup2); 2557 session_destroy_all(ssh, session_pty_cleanup2);
2565} 2558}
2566 2559
2567/* Return a name for the remote host that fits inside utmp_size */ 2560/* Return a name for the remote host that fits inside utmp_size */
diff --git a/session.h b/session.h
index 98e1dafee..54dd1f0ca 100644
--- a/session.h
+++ b/session.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.h,v 1.33 2016/08/13 17:47:41 markus Exp $ */ 1/* $OpenBSD: session.h,v 1.35 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -62,23 +62,21 @@ struct Session {
62 } *env; 62 } *env;
63}; 63};
64 64
65void do_authenticated(Authctxt *); 65void do_authenticated(struct ssh *, Authctxt *);
66void do_cleanup(Authctxt *); 66void do_cleanup(struct ssh *, Authctxt *);
67 67
68int session_open(Authctxt *, int); 68int session_open(Authctxt *, int);
69void session_unused(int); 69void session_unused(int);
70int session_input_channel_req(Channel *, const char *); 70int session_input_channel_req(struct ssh *, Channel *, const char *);
71void session_close_by_pid(pid_t, int); 71void session_close_by_pid(struct ssh *ssh, pid_t, int);
72void session_close_by_channel(int, void *); 72void session_close_by_channel(struct ssh *, int, void *);
73void session_destroy_all(void (*)(Session *)); 73void session_destroy_all(struct ssh *, void (*)(Session *));
74void session_pty_cleanup2(Session *); 74void session_pty_cleanup2(Session *);
75 75
76Session *session_new(void); 76Session *session_new(void);
77Session *session_by_tty(char *); 77Session *session_by_tty(char *);
78void session_close(Session *); 78void session_close(struct ssh *, Session *);
79void do_setusercontext(struct passwd *); 79void do_setusercontext(struct passwd *);
80void child_set_env(char ***envp, u_int *envsizep, const char *name,
81 const char *value);
82 80
83const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); 81const char *session_get_remote_name_or_ip(struct ssh *, u_int, int);
84 82
diff --git a/sftp-client.c b/sftp-client.c
index a6e832270..626330262 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-client.c,v 1.126 2017/01/03 05:46:51 djm Exp $ */ 1/* $OpenBSD: sftp-client.c,v 1.127 2017/08/11 04:41:08 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -140,7 +140,7 @@ get_msg(struct sftp_conn *conn, struct sshbuf *m)
140 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 140 fatal("%s: buffer error: %s", __func__, ssh_err(r));
141 if (atomicio6(read, conn->fd_in, p, 4, 141 if (atomicio6(read, conn->fd_in, p, 4,
142 conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) { 142 conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) {
143 if (errno == EPIPE) 143 if (errno == EPIPE || errno == ECONNRESET)
144 fatal("Connection closed"); 144 fatal("Connection closed");
145 else 145 else
146 fatal("Couldn't read packet: %s", strerror(errno)); 146 fatal("Couldn't read packet: %s", strerror(errno));
diff --git a/sftp-common.c b/sftp-common.c
index 3a70c52dd..13a7f5bec 100644
--- a/sftp-common.c
+++ b/sftp-common.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-common.c,v 1.29 2016/09/12 01:22:38 deraadt Exp $ */ 1/* $OpenBSD: sftp-common.c,v 1.30 2017/06/10 06:36:46 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2001 Damien Miller. All rights reserved. 4 * Copyright (c) 2001 Damien Miller. All rights reserved.
@@ -216,22 +216,21 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
216 int ulen, glen, sz = 0; 216 int ulen, glen, sz = 0;
217 struct tm *ltime = localtime(&st->st_mtime); 217 struct tm *ltime = localtime(&st->st_mtime);
218 char *user, *group; 218 char *user, *group;
219 char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; 219 char buf[1024], lc[8], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1];
220 char sbuf[FMT_SCALED_STRSIZE]; 220 char sbuf[FMT_SCALED_STRSIZE];
221 time_t now; 221 time_t now;
222 222
223 strmode(st->st_mode, mode); 223 strmode(st->st_mode, mode);
224 if (!remote) { 224 if (remote) {
225 user = user_from_uid(st->st_uid, 0);
226 } else {
227 snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid); 225 snprintf(ubuf, sizeof ubuf, "%u", (u_int)st->st_uid);
228 user = ubuf; 226 user = ubuf;
229 }
230 if (!remote) {
231 group = group_from_gid(st->st_gid, 0);
232 } else {
233 snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid); 227 snprintf(gbuf, sizeof gbuf, "%u", (u_int)st->st_gid);
234 group = gbuf; 228 group = gbuf;
229 strlcpy(lc, "?", sizeof(lc));
230 } else {
231 user = user_from_uid(st->st_uid, 0);
232 group = group_from_gid(st->st_gid, 0);
233 snprintf(lc, sizeof(lc), "%u", (u_int)st->st_nlink);
235 } 234 }
236 if (ltime != NULL) { 235 if (ltime != NULL) {
237 now = time(NULL); 236 now = time(NULL);
@@ -247,12 +246,12 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
247 glen = MAXIMUM(strlen(group), 8); 246 glen = MAXIMUM(strlen(group), 8);
248 if (si_units) { 247 if (si_units) {
249 fmt_scaled((long long)st->st_size, sbuf); 248 fmt_scaled((long long)st->st_size, sbuf);
250 snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8s %s %s", mode, 249 snprintf(buf, sizeof buf, "%s %3s %-*s %-*s %8s %s %s",
251 (u_int)st->st_nlink, ulen, user, glen, group, 250 mode, lc, ulen, user, glen, group,
252 sbuf, tbuf, name); 251 sbuf, tbuf, name);
253 } else { 252 } else {
254 snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, 253 snprintf(buf, sizeof buf, "%s %3s %-*s %-*s %8llu %s %s",
255 (u_int)st->st_nlink, ulen, user, glen, group, 254 mode, lc, ulen, user, glen, group,
256 (unsigned long long)st->st_size, tbuf, name); 255 (unsigned long long)st->st_size, tbuf, name);
257 } 256 }
258 return xstrdup(buf); 257 return xstrdup(buf);
diff --git a/sftp-server.0 b/sftp-server.0
index 20d477d49..4f994f4c5 100644
--- a/sftp-server.0
+++ b/sftp-server.0
@@ -93,4 +93,4 @@ HISTORY
93AUTHORS 93AUTHORS
94 Markus Friedl <markus@openbsd.org> 94 Markus Friedl <markus@openbsd.org>
95 95
96OpenBSD 6.0 December 11, 2014 OpenBSD 6.0 96OpenBSD 6.2 December 11, 2014 OpenBSD 6.2
diff --git a/sftp-server.c b/sftp-server.c
index 3619cdfc0..df0fb5068 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-server.c,v 1.110 2016/09/12 01:22:38 deraadt Exp $ */ 1/* $OpenBSD: sftp-server.c,v 1.111 2017/04/04 00:24:56 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
4 * 4 *
@@ -691,8 +691,8 @@ process_open(u_int32_t id)
691 logit("open \"%s\" flags %s mode 0%o", 691 logit("open \"%s\" flags %s mode 0%o",
692 name, string_from_portable(pflags), mode); 692 name, string_from_portable(pflags), mode);
693 if (readonly && 693 if (readonly &&
694 ((flags & O_ACCMODE) == O_WRONLY || 694 ((flags & O_ACCMODE) != O_RDONLY ||
695 (flags & O_ACCMODE) == O_RDWR)) { 695 (flags & (O_CREAT|O_TRUNC)) != 0)) {
696 verbose("Refusing open request in read-only mode"); 696 verbose("Refusing open request in read-only mode");
697 status = SSH2_FX_PERMISSION_DENIED; 697 status = SSH2_FX_PERMISSION_DENIED;
698 } else { 698 } else {
diff --git a/sftp.0 b/sftp.0
index 2e0c274d9..45b8faf55 100644
--- a/sftp.0
+++ b/sftp.0
@@ -4,7 +4,7 @@ NAME
4 sftp M-bM-^@M-^S secure file transfer program 4 sftp M-bM-^@M-^S secure file transfer program
5 5
6SYNOPSIS 6SYNOPSIS
7 sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] 7 sftp [-46aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]
8 [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] 8 [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit]
9 [-o ssh_option] [-P port] [-R num_requests] [-S program] 9 [-o ssh_option] [-P port] [-R num_requests] [-S program]
10 [-s subsystem | sftp_server] host 10 [-s subsystem | sftp_server] host
@@ -36,10 +36,6 @@ DESCRIPTION
36 36
37 The options are as follows: 37 The options are as follows:
38 38
39 -1 Specify the use of protocol version 1.
40
41 -2 Specify the use of protocol version 2.
42
43 -4 Forces sftp to use IPv4 addresses only. 39 -4 Forces sftp to use IPv4 addresses only.
44 40
45 -6 Forces sftp to use IPv6 addresses only. 41 -6 Forces sftp to use IPv6 addresses only.
@@ -111,10 +107,8 @@ DESCRIPTION
111 CertificateFile 107 CertificateFile
112 ChallengeResponseAuthentication 108 ChallengeResponseAuthentication
113 CheckHostIP 109 CheckHostIP
114 Cipher
115 Ciphers 110 Ciphers
116 Compression 111 Compression
117 CompressionLevel
118 ConnectionAttempts 112 ConnectionAttempts
119 ConnectTimeout 113 ConnectTimeout
120 ControlMaster 114 ControlMaster
@@ -145,13 +139,11 @@ DESCRIPTION
145 PKCS11Provider 139 PKCS11Provider
146 Port 140 Port
147 PreferredAuthentications 141 PreferredAuthentications
148 Protocol
149 ProxyCommand 142 ProxyCommand
150 ProxyJump 143 ProxyJump
144 PubkeyAcceptedKeyTypes
151 PubkeyAuthentication 145 PubkeyAuthentication
152 RekeyLimit 146 RekeyLimit
153 RhostsRSAAuthentication
154 RSAAuthentication
155 SendEnv 147 SendEnv
156 ServerAliveInterval 148 ServerAliveInterval
157 ServerAliveCountMax 149 ServerAliveCountMax
@@ -187,9 +179,8 @@ DESCRIPTION
187 179
188 -s subsystem | sftp_server 180 -s subsystem | sftp_server
189 Specifies the SSH2 subsystem or the path for an sftp server on 181 Specifies the SSH2 subsystem or the path for an sftp server on
190 the remote host. A path is useful for using sftp over protocol 182 the remote host. A path is useful when the remote sshd(8) does
191 version 1, or when the remote sshd(8) does not have an sftp 183 not have an sftp subsystem configured.
192 subsystem configured.
193 184
194 -v Raise logging level. This option is also passed to ssh. 185 -v Raise logging level. This option is also passed to ssh.
195 186
@@ -383,4 +374,4 @@ SEE ALSO
383 T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- 374 T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-
384 filexfer-00.txt, January 2001, work in progress material. 375 filexfer-00.txt, January 2001, work in progress material.
385 376
386OpenBSD 6.0 July 16, 2016 OpenBSD 6.0 377OpenBSD 6.2 May 3, 2017 OpenBSD 6.2
diff --git a/sftp.1 b/sftp.1
index fbdd00a1e..c218376fb 100644
--- a/sftp.1
+++ b/sftp.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: sftp.1,v 1.105 2016/07/16 06:57:55 jmc Exp $ 1.\" $OpenBSD: sftp.1,v 1.110 2017/05/03 21:49:18 naddy Exp $
2.\" 2.\"
3.\" Copyright (c) 2001 Damien Miller. All rights reserved. 3.\" Copyright (c) 2001 Damien Miller. All rights reserved.
4.\" 4.\"
@@ -22,7 +22,7 @@
22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24.\" 24.\"
25.Dd $Mdocdate: July 16 2016 $ 25.Dd $Mdocdate: May 3 2017 $
26.Dt SFTP 1 26.Dt SFTP 1
27.Os 27.Os
28.Sh NAME 28.Sh NAME
@@ -31,7 +31,7 @@
31.Sh SYNOPSIS 31.Sh SYNOPSIS
32.Nm sftp 32.Nm sftp
33.Bk -words 33.Bk -words
34.Op Fl 1246aCfpqrv 34.Op Fl 46aCfpqrv
35.Op Fl B Ar buffer_size 35.Op Fl B Ar buffer_size
36.Op Fl b Ar batchfile 36.Op Fl b Ar batchfile
37.Op Fl c Ar cipher 37.Op Fl c Ar cipher
@@ -95,10 +95,6 @@ names, IPv6 addresses must be enclosed in square brackets to avoid ambiguity.
95.Pp 95.Pp
96The options are as follows: 96The options are as follows:
97.Bl -tag -width Ds 97.Bl -tag -width Ds
98.It Fl 1
99Specify the use of protocol version 1.
100.It Fl 2
101Specify the use of protocol version 2.
102.It Fl 4 98.It Fl 4
103Forces 99Forces
104.Nm 100.Nm
@@ -201,10 +197,8 @@ For full details of the options listed below, and their possible values, see
201.It CertificateFile 197.It CertificateFile
202.It ChallengeResponseAuthentication 198.It ChallengeResponseAuthentication
203.It CheckHostIP 199.It CheckHostIP
204.It Cipher
205.It Ciphers 200.It Ciphers
206.It Compression 201.It Compression
207.It CompressionLevel
208.It ConnectionAttempts 202.It ConnectionAttempts
209.It ConnectTimeout 203.It ConnectTimeout
210.It ControlMaster 204.It ControlMaster
@@ -235,13 +229,11 @@ For full details of the options listed below, and their possible values, see
235.It PKCS11Provider 229.It PKCS11Provider
236.It Port 230.It Port
237.It PreferredAuthentications 231.It PreferredAuthentications
238.It Protocol
239.It ProxyCommand 232.It ProxyCommand
240.It ProxyJump 233.It ProxyJump
234.It PubkeyAcceptedKeyTypes
241.It PubkeyAuthentication 235.It PubkeyAuthentication
242.It RekeyLimit 236.It RekeyLimit
243.It RhostsRSAAuthentication
244.It RSAAuthentication
245.It SendEnv 237.It SendEnv
246.It ServerAliveInterval 238.It ServerAliveInterval
247.It ServerAliveCountMax 239.It ServerAliveCountMax
@@ -282,9 +274,7 @@ options.
282.It Fl s Ar subsystem | sftp_server 274.It Fl s Ar subsystem | sftp_server
283Specifies the SSH2 subsystem or the path for an sftp server 275Specifies the SSH2 subsystem or the path for an sftp server
284on the remote host. 276on the remote host.
285A path is useful for using 277A path is useful when the remote
286.Nm
287over protocol version 1, or when the remote
288.Xr sshd 8 278.Xr sshd 8
289does not have an sftp subsystem configured. 279does not have an sftp subsystem configured.
290.It Fl v 280.It Fl v
diff --git a/sftp.c b/sftp.c
index 76add3908..67110f738 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.178 2017/02/15 01:46:47 djm Exp $ */ 1/* $OpenBSD: sftp.c,v 1.180 2017/06/10 06:33:34 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -106,6 +106,7 @@ volatile sig_atomic_t interrupted = 0;
106 106
107/* I wish qsort() took a separate ctx for the comparison function...*/ 107/* I wish qsort() took a separate ctx for the comparison function...*/
108int sort_flag; 108int sort_flag;
109glob_t *sort_glob;
109 110
110/* Context used for commandline completion */ 111/* Context used for commandline completion */
111struct complete_ctx { 112struct complete_ctx {
@@ -879,6 +880,34 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
879 return (0); 880 return (0);
880} 881}
881 882
883static int
884sglob_comp(const void *aa, const void *bb)
885{
886 u_int a = *(const u_int *)aa;
887 u_int b = *(const u_int *)bb;
888 const char *ap = sort_glob->gl_pathv[a];
889 const char *bp = sort_glob->gl_pathv[b];
890 const struct stat *as = sort_glob->gl_statv[a];
891 const struct stat *bs = sort_glob->gl_statv[b];
892 int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1;
893
894#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1))
895 if (sort_flag & LS_NAME_SORT)
896 return (rmul * strcmp(ap, bp));
897 else if (sort_flag & LS_TIME_SORT) {
898#if defined(HAVE_STRUCT_STAT_ST_MTIM)
899 return (rmul * timespeccmp(&as->st_mtim, &bs->st_mtim, <));
900#elif defined(HAVE_STRUCT_STAT_ST_MTIME)
901 return (rmul * NCMP(as->st_mtime, bs->st_mtime));
902#else
903 return rmul * 1;
904#endif
905 } else if (sort_flag & LS_SIZE_SORT)
906 return (rmul * NCMP(as->st_size, bs->st_size));
907
908 fatal("Unknown ls sort type");
909}
910
882/* sftp ls.1 replacement which handles path globs */ 911/* sftp ls.1 replacement which handles path globs */
883static int 912static int
884do_globbed_ls(struct sftp_conn *conn, const char *path, 913do_globbed_ls(struct sftp_conn *conn, const char *path,
@@ -888,7 +917,8 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
888 glob_t g; 917 glob_t g;
889 int err, r; 918 int err, r;
890 struct winsize ws; 919 struct winsize ws;
891 u_int i, c = 1, colspace = 0, columns = 1, m = 0, width = 80; 920 u_int i, j, nentries, *indices = NULL, c = 1;
921 u_int colspace = 0, columns = 1, m = 0, width = 80;
892 922
893 memset(&g, 0, sizeof(g)); 923 memset(&g, 0, sizeof(g));
894 924
@@ -933,7 +963,26 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
933 colspace = width / columns; 963 colspace = width / columns;
934 } 964 }
935 965
936 for (i = 0; g.gl_pathv[i] && !interrupted; i++) { 966 /*
967 * Sorting: rather than mess with the contents of glob_t, prepare
968 * an array of indices into it and sort that. For the usual
969 * unsorted case, the indices are just the identity 1=1, 2=2, etc.
970 */
971 for (nentries = 0; g.gl_pathv[nentries] != NULL; nentries++)
972 ; /* count entries */
973 indices = calloc(nentries, sizeof(*indices));
974 for (i = 0; i < nentries; i++)
975 indices[i] = i;
976
977 if (lflag & SORT_FLAGS) {
978 sort_glob = &g;
979 sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);
980 qsort(indices, nentries, sizeof(*indices), sglob_comp);
981 sort_glob = NULL;
982 }
983
984 for (j = 0; j < nentries && !interrupted; j++) {
985 i = indices[j];
937 fname = path_strip(g.gl_pathv[i], strip_path); 986 fname = path_strip(g.gl_pathv[i], strip_path);
938 if (lflag & LS_LONG_VIEW) { 987 if (lflag & LS_LONG_VIEW) {
939 if (g.gl_statv[i] == NULL) { 988 if (g.gl_statv[i] == NULL) {
@@ -961,6 +1010,7 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
961 out: 1010 out:
962 if (g.gl_pathc) 1011 if (g.gl_pathc)
963 globfree(&g); 1012 globfree(&g);
1013 free(indices);
964 1014
965 return 0; 1015 return 0;
966} 1016}
@@ -2246,7 +2296,7 @@ usage(void)
2246 extern char *__progname; 2296 extern char *__progname;
2247 2297
2248 fprintf(stderr, 2298 fprintf(stderr,
2249 "usage: %s [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" 2299 "usage: %s [-46aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
2250 " [-D sftp_server_path] [-F ssh_config] " 2300 " [-D sftp_server_path] [-F ssh_config] "
2251 "[-i identity_file] [-l limit]\n" 2301 "[-i identity_file] [-l limit]\n"
2252 " [-o ssh_option] [-P port] [-R num_requests] " 2302 " [-o ssh_option] [-P port] [-R num_requests] "
diff --git a/ssh-add.0 b/ssh-add.0
index 706bfe661..2ef6c3da2 100644
--- a/ssh-add.0
+++ b/ssh-add.0
@@ -4,18 +4,18 @@ NAME
4 ssh-add M-bM-^@M-^S adds private key identities to the authentication agent 4 ssh-add M-bM-^@M-^S adds private key identities to the authentication agent
5 5
6SYNOPSIS 6SYNOPSIS
7 ssh-add [-cDdkLlXx] [-E fingerprint_hash] [-t life] [file ...] 7 ssh-add [-cDdkLlqXx] [-E fingerprint_hash] [-t life] [file ...]
8 ssh-add -s pkcs11 8 ssh-add -s pkcs11
9 ssh-add -e pkcs11 9 ssh-add -e pkcs11
10 10
11DESCRIPTION 11DESCRIPTION
12 ssh-add adds private key identities to the authentication agent, 12 ssh-add adds private key identities to the authentication agent,
13 ssh-agent(1). When run without arguments, it adds the files 13 ssh-agent(1). When run without arguments, it adds the files
14 ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and 14 ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, and ~/.ssh/id_ed25519.
15 ~/.ssh/identity. After loading a private key, ssh-add will try to load 15 After loading a private key, ssh-add will try to load corresponding
16 corresponding certificate information from the filename obtained by 16 certificate information from the filename obtained by appending -cert.pub
17 appending -cert.pub to the name of the private key file. Alternative 17 to the name of the private key file. Alternative file names can be given
18 file names can be given on the command line. 18 on the command line.
19 19
20 If any file requires a passphrase, ssh-add asks for the passphrase from 20 If any file requires a passphrase, ssh-add asks for the passphrase from
21 the user. The passphrase is read from the user's tty. ssh-add retries 21 the user. The passphrase is read from the user's tty. ssh-add retries
@@ -60,6 +60,8 @@ DESCRIPTION
60 -l Lists fingerprints of all identities currently represented by the 60 -l Lists fingerprints of all identities currently represented by the
61 agent. 61 agent.
62 62
63 -q Be quiet after a successful operation.
64
63 -s pkcs11 65 -s pkcs11
64 Add keys provided by the PKCS#11 shared library pkcs11. 66 Add keys provided by the PKCS#11 shared library pkcs11.
65 67
@@ -89,25 +91,17 @@ ENVIRONMENT
89 with the agent. 91 with the agent.
90 92
91FILES 93FILES
92 ~/.ssh/identity
93 Contains the protocol version 1 RSA authentication identity of
94 the user.
95
96 ~/.ssh/id_dsa 94 ~/.ssh/id_dsa
97 Contains the protocol version 2 DSA authentication identity of 95 Contains the DSA authentication identity of the user.
98 the user.
99 96
100 ~/.ssh/id_ecdsa 97 ~/.ssh/id_ecdsa
101 Contains the protocol version 2 ECDSA authentication identity of 98 Contains the ECDSA authentication identity of the user.
102 the user.
103 99
104 ~/.ssh/id_ed25519 100 ~/.ssh/id_ed25519
105 Contains the protocol version 2 Ed25519 authentication identity 101 Contains the Ed25519 authentication identity of the user.
106 of the user.
107 102
108 ~/.ssh/id_rsa 103 ~/.ssh/id_rsa
109 Contains the protocol version 2 RSA authentication identity of 104 Contains the RSA authentication identity of the user.
110 the user.
111 105
112 Identity files should not be readable by anyone but the user. Note that 106 Identity files should not be readable by anyone but the user. Note that
113 ssh-add ignores identity files if they are accessible by others. 107 ssh-add ignores identity files if they are accessible by others.
@@ -126,4 +120,4 @@ AUTHORS
126 created OpenSSH. Markus Friedl contributed the support for SSH protocol 120 created OpenSSH. Markus Friedl contributed the support for SSH protocol
127 versions 1.5 and 2.0. 121 versions 1.5 and 2.0.
128 122
129OpenBSD 6.0 March 30, 2015 OpenBSD 6.0 123OpenBSD 6.2 August 29, 2017 OpenBSD 6.2
diff --git a/ssh-add.1 b/ssh-add.1
index f02b595d5..d5da9279c 100644
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-add.1,v 1.62 2015/03/30 18:28:37 jmc Exp $ 1.\" $OpenBSD: ssh-add.1,v 1.66 2017/08/29 13:05:58 jmc Exp $
2.\" 2.\"
3.\" Author: Tatu Ylonen <ylo@cs.hut.fi> 3.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,7 +35,7 @@
35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37.\" 37.\"
38.Dd $Mdocdate: March 30 2015 $ 38.Dd $Mdocdate: August 29 2017 $
39.Dt SSH-ADD 1 39.Dt SSH-ADD 1
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -43,7 +43,7 @@
43.Nd adds private key identities to the authentication agent 43.Nd adds private key identities to the authentication agent
44.Sh SYNOPSIS 44.Sh SYNOPSIS
45.Nm ssh-add 45.Nm ssh-add
46.Op Fl cDdkLlXx 46.Op Fl cDdkLlqXx
47.Op Fl E Ar fingerprint_hash 47.Op Fl E Ar fingerprint_hash
48.Op Fl t Ar life 48.Op Fl t Ar life
49.Op Ar 49.Op Ar
@@ -59,9 +59,8 @@ When run without arguments, it adds the files
59.Pa ~/.ssh/id_rsa , 59.Pa ~/.ssh/id_rsa ,
60.Pa ~/.ssh/id_dsa , 60.Pa ~/.ssh/id_dsa ,
61.Pa ~/.ssh/id_ecdsa , 61.Pa ~/.ssh/id_ecdsa ,
62.Pa ~/.ssh/id_ed25519
63and 62and
64.Pa ~/.ssh/identity . 63.Pa ~/.ssh/id_ed25519 .
65After loading a private key, 64After loading a private key,
66.Nm 65.Nm
67will try to load corresponding certificate information from the 66will try to load corresponding certificate information from the
@@ -127,6 +126,8 @@ Lists public key parameters of all identities currently represented
127by the agent. 126by the agent.
128.It Fl l 127.It Fl l
129Lists fingerprints of all identities currently represented by the agent. 128Lists fingerprints of all identities currently represented by the agent.
129.It Fl q
130Be quiet after a successful operation.
130.It Fl s Ar pkcs11 131.It Fl s Ar pkcs11
131Add keys provided by the PKCS#11 shared library 132Add keys provided by the PKCS#11 shared library
132.Ar pkcs11 . 133.Ar pkcs11 .
@@ -174,16 +175,14 @@ socket used to communicate with the agent.
174.El 175.El
175.Sh FILES 176.Sh FILES
176.Bl -tag -width Ds 177.Bl -tag -width Ds
177.It Pa ~/.ssh/identity
178Contains the protocol version 1 RSA authentication identity of the user.
179.It Pa ~/.ssh/id_dsa 178.It Pa ~/.ssh/id_dsa
180Contains the protocol version 2 DSA authentication identity of the user. 179Contains the DSA authentication identity of the user.
181.It Pa ~/.ssh/id_ecdsa 180.It Pa ~/.ssh/id_ecdsa
182Contains the protocol version 2 ECDSA authentication identity of the user. 181Contains the ECDSA authentication identity of the user.
183.It Pa ~/.ssh/id_ed25519 182.It Pa ~/.ssh/id_ed25519
184Contains the protocol version 2 Ed25519 authentication identity of the user. 183Contains the Ed25519 authentication identity of the user.
185.It Pa ~/.ssh/id_rsa 184.It Pa ~/.ssh/id_rsa
186Contains the protocol version 2 RSA authentication identity of the user. 185Contains the RSA authentication identity of the user.
187.El 186.El
188.Pp 187.Pp
189Identity files should not be readable by anyone but the user. 188Identity files should not be readable by anyone but the user.
diff --git a/ssh-add.c b/ssh-add.c
index fb9a53e64..2afd48330 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-add.c,v 1.128 2016/02/15 09:47:49 dtucker Exp $ */ 1/* $OpenBSD: ssh-add.c,v 1.134 2017/08/29 09:42:29 dlg Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -55,7 +55,6 @@
55 55
56#include "xmalloc.h" 56#include "xmalloc.h"
57#include "ssh.h" 57#include "ssh.h"
58#include "rsa.h"
59#include "log.h" 58#include "log.h"
60#include "sshkey.h" 59#include "sshkey.h"
61#include "sshbuf.h" 60#include "sshbuf.h"
@@ -79,9 +78,6 @@ static char *default_files[] = {
79#endif 78#endif
80#endif /* WITH_OPENSSL */ 79#endif /* WITH_OPENSSL */
81 _PATH_SSH_CLIENT_ID_ED25519, 80 _PATH_SSH_CLIENT_ID_ED25519,
82#ifdef WITH_SSH1
83 _PATH_SSH_CLIENT_IDENTITY,
84#endif
85 NULL 81 NULL
86}; 82};
87 83
@@ -106,7 +102,7 @@ clear_pass(void)
106} 102}
107 103
108static int 104static int
109delete_file(int agent_fd, const char *filename, int key_only) 105delete_file(int agent_fd, const char *filename, int key_only, int qflag)
110{ 106{
111 struct sshkey *public, *cert = NULL; 107 struct sshkey *public, *cert = NULL;
112 char *certpath = NULL, *comment = NULL; 108 char *certpath = NULL, *comment = NULL;
@@ -117,7 +113,10 @@ delete_file(int agent_fd, const char *filename, int key_only)
117 return -1; 113 return -1;
118 } 114 }
119 if ((r = ssh_remove_identity(agent_fd, public)) == 0) { 115 if ((r = ssh_remove_identity(agent_fd, public)) == 0) {
120 fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); 116 if (!qflag) {
117 fprintf(stderr, "Identity removed: %s (%s)\n",
118 filename, comment);
119 }
121 ret = 0; 120 ret = 0;
122 } else 121 } else
123 fprintf(stderr, "Could not remove identity \"%s\": %s\n", 122 fprintf(stderr, "Could not remove identity \"%s\": %s\n",
@@ -142,8 +141,10 @@ delete_file(int agent_fd, const char *filename, int key_only)
142 certpath, filename); 141 certpath, filename);
143 142
144 if ((r = ssh_remove_identity(agent_fd, cert)) == 0) { 143 if ((r = ssh_remove_identity(agent_fd, cert)) == 0) {
145 fprintf(stderr, "Identity removed: %s (%s)\n", certpath, 144 if (!qflag) {
146 comment); 145 fprintf(stderr, "Identity removed: %s (%s)\n",
146 certpath, comment);
147 }
147 ret = 0; 148 ret = 0;
148 } else 149 } else
149 fprintf(stderr, "Could not remove identity \"%s\": %s\n", 150 fprintf(stderr, "Could not remove identity \"%s\": %s\n",
@@ -164,6 +165,11 @@ delete_all(int agent_fd)
164{ 165{
165 int ret = -1; 166 int ret = -1;
166 167
168 /*
169 * Since the agent might be forwarded, old or non-OpenSSH, when asked
170 * to remove all keys, attempt to remove both protocol v.1 and v.2
171 * keys.
172 */
167 if (ssh_remove_all_identities(agent_fd, 2) == 0) 173 if (ssh_remove_all_identities(agent_fd, 2) == 0)
168 ret = 0; 174 ret = 0;
169 /* ignore error-code for ssh1 */ 175 /* ignore error-code for ssh1 */
@@ -178,7 +184,7 @@ delete_all(int agent_fd)
178} 184}
179 185
180static int 186static int
181add_file(int agent_fd, const char *filename, int key_only) 187add_file(int agent_fd, const char *filename, int key_only, int qflag)
182{ 188{
183 struct sshkey *private, *cert; 189 struct sshkey *private, *cert;
184 char *comment = NULL; 190 char *comment = NULL;
@@ -304,7 +310,7 @@ add_file(int agent_fd, const char *filename, int key_only)
304 goto out; 310 goto out;
305 } 311 }
306 if ((r = sshkey_cert_copy(cert, private)) != 0) { 312 if ((r = sshkey_cert_copy(cert, private)) != 0) {
307 error("%s: key_cert_copy: %s", __func__, ssh_err(r)); 313 error("%s: sshkey_cert_copy: %s", __func__, ssh_err(r));
308 sshkey_free(cert); 314 sshkey_free(cert);
309 goto out; 315 goto out;
310 } 316 }
@@ -360,50 +366,36 @@ static int
360list_identities(int agent_fd, int do_fp) 366list_identities(int agent_fd, int do_fp)
361{ 367{
362 char *fp; 368 char *fp;
363 int r, had_identities = 0; 369 int r;
364 struct ssh_identitylist *idlist; 370 struct ssh_identitylist *idlist;
365 size_t i; 371 size_t i;
366#ifdef WITH_SSH1
367 int version = 1;
368#else
369 int version = 2;
370#endif
371 372
372 for (; version <= 2; version++) { 373 if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) {
373 if ((r = ssh_fetch_identitylist(agent_fd, version, 374 if (r != SSH_ERR_AGENT_NO_IDENTITIES)
374 &idlist)) != 0) { 375 fprintf(stderr, "error fetching identities: %s\n",
375 if (r != SSH_ERR_AGENT_NO_IDENTITIES) 376 ssh_err(r));
376 fprintf(stderr, "error fetching identities for " 377 else
377 "protocol %d: %s\n", version, ssh_err(r)); 378 printf("The agent has no identities.\n");
378 continue; 379 return -1;
379 } 380 }
380 for (i = 0; i < idlist->nkeys; i++) { 381 for (i = 0; i < idlist->nkeys; i++) {
381 had_identities = 1; 382 if (do_fp) {
382 if (do_fp) { 383 fp = sshkey_fingerprint(idlist->keys[i],
383 fp = sshkey_fingerprint(idlist->keys[i], 384 fingerprint_hash, SSH_FP_DEFAULT);
384 fingerprint_hash, SSH_FP_DEFAULT); 385 printf("%u %s %s (%s)\n", sshkey_size(idlist->keys[i]),
385 printf("%u %s %s (%s)\n", 386 fp == NULL ? "(null)" : fp, idlist->comments[i],
386 sshkey_size(idlist->keys[i]), 387 sshkey_type(idlist->keys[i]));
387 fp == NULL ? "(null)" : fp, 388 free(fp);
388 idlist->comments[i], 389 } else {
389 sshkey_type(idlist->keys[i])); 390 if ((r = sshkey_write(idlist->keys[i], stdout)) != 0) {
390 free(fp); 391 fprintf(stderr, "sshkey_write: %s\n",
391 } else { 392 ssh_err(r));
392 if ((r = sshkey_write(idlist->keys[i], 393 continue;
393 stdout)) != 0) {
394 fprintf(stderr, "sshkey_write: %s\n",
395 ssh_err(r));
396 continue;
397 }
398 fprintf(stdout, " %s\n", idlist->comments[i]);
399 } 394 }
395 fprintf(stdout, " %s\n", idlist->comments[i]);
400 } 396 }
401 ssh_free_identitylist(idlist);
402 }
403 if (!had_identities) {
404 printf("The agent has no identities.\n");
405 return -1;
406 } 397 }
398 ssh_free_identitylist(idlist);
407 return 0; 399 return 0;
408} 400}
409 401
@@ -440,13 +432,13 @@ lock_agent(int agent_fd, int lock)
440} 432}
441 433
442static int 434static int
443do_file(int agent_fd, int deleting, int key_only, char *file) 435do_file(int agent_fd, int deleting, int key_only, char *file, int qflag)
444{ 436{
445 if (deleting) { 437 if (deleting) {
446 if (delete_file(agent_fd, file, key_only) == -1) 438 if (delete_file(agent_fd, file, key_only, qflag) == -1)
447 return -1; 439 return -1;
448 } else { 440 } else {
449 if (add_file(agent_fd, file, key_only) == -1) 441 if (add_file(agent_fd, file, key_only, qflag) == -1)
450 return -1; 442 return -1;
451 } 443 }
452 return 0; 444 return 0;
@@ -469,6 +461,7 @@ usage(void)
469 fprintf(stderr, " -X Unlock agent.\n"); 461 fprintf(stderr, " -X Unlock agent.\n");
470 fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n"); 462 fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n");
471 fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n"); 463 fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n");
464 fprintf(stderr, " -q Be quiet after a successful operation.\n");
472} 465}
473 466
474int 467int
@@ -479,7 +472,7 @@ main(int argc, char **argv)
479 int agent_fd; 472 int agent_fd;
480 char *pkcs11provider = NULL; 473 char *pkcs11provider = NULL;
481 int r, i, ch, deleting = 0, ret = 0, key_only = 0; 474 int r, i, ch, deleting = 0, ret = 0, key_only = 0;
482 int xflag = 0, lflag = 0, Dflag = 0; 475 int xflag = 0, lflag = 0, Dflag = 0, qflag = 0;
483 476
484 ssh_malloc_init(); /* must be called before any mallocs */ 477 ssh_malloc_init(); /* must be called before any mallocs */
485 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 478 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
@@ -507,7 +500,7 @@ main(int argc, char **argv)
507 exit(2); 500 exit(2);
508 } 501 }
509 502
510 while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) { 503 while ((ch = getopt(argc, argv, "klLcdDxXE:e:qs:t:")) != -1) {
511 switch (ch) { 504 switch (ch) {
512 case 'E': 505 case 'E':
513 fingerprint_hash = ssh_digest_alg_by_name(optarg); 506 fingerprint_hash = ssh_digest_alg_by_name(optarg);
@@ -552,6 +545,9 @@ main(int argc, char **argv)
552 goto done; 545 goto done;
553 } 546 }
554 break; 547 break;
548 case 'q':
549 qflag = 1;
550 break;
555 default: 551 default:
556 usage(); 552 usage();
557 ret = 1; 553 ret = 1;
@@ -600,7 +596,8 @@ main(int argc, char **argv)
600 default_files[i]); 596 default_files[i]);
601 if (stat(buf, &st) < 0) 597 if (stat(buf, &st) < 0)
602 continue; 598 continue;
603 if (do_file(agent_fd, deleting, key_only, buf) == -1) 599 if (do_file(agent_fd, deleting, key_only, buf,
600 qflag) == -1)
604 ret = 1; 601 ret = 1;
605 else 602 else
606 count++; 603 count++;
@@ -610,7 +607,7 @@ main(int argc, char **argv)
610 } else { 607 } else {
611 for (i = 0; i < argc; i++) { 608 for (i = 0; i < argc; i++) {
612 if (do_file(agent_fd, deleting, key_only, 609 if (do_file(agent_fd, deleting, key_only,
613 argv[i]) == -1) 610 argv[i], qflag) == -1)
614 ret = 1; 611 ret = 1;
615 } 612 }
616 } 613 }
diff --git a/ssh-agent.0 b/ssh-agent.0
index bb3c8d605..86ac988bd 100644
--- a/ssh-agent.0
+++ b/ssh-agent.0
@@ -117,4 +117,4 @@ AUTHORS
117 created OpenSSH. Markus Friedl contributed the support for SSH protocol 117 created OpenSSH. Markus Friedl contributed the support for SSH protocol
118 versions 1.5 and 2.0. 118 versions 1.5 and 2.0.
119 119
120OpenBSD 6.0 November 30, 2016 OpenBSD 6.0 120OpenBSD 6.2 November 30, 2016 OpenBSD 6.2
diff --git a/ssh-agent.c b/ssh-agent.c
index b987562b9..0c6c36592 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.218 2017/03/15 03:52:30 deraadt Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.224 2017/07/24 04:34:28 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -60,6 +60,9 @@
60#ifdef HAVE_PATHS_H 60#ifdef HAVE_PATHS_H
61# include <paths.h> 61# include <paths.h>
62#endif 62#endif
63#ifdef HAVE_POLL_H
64# include <poll.h>
65#endif
63#include <signal.h> 66#include <signal.h>
64#include <stdarg.h> 67#include <stdarg.h>
65#include <stdio.h> 68#include <stdio.h>
@@ -73,7 +76,6 @@
73 76
74#include "xmalloc.h" 77#include "xmalloc.h"
75#include "ssh.h" 78#include "ssh.h"
76#include "rsa.h"
77#include "sshbuf.h" 79#include "sshbuf.h"
78#include "sshkey.h" 80#include "sshkey.h"
79#include "authfd.h" 81#include "authfd.h"
@@ -92,6 +94,9 @@
92# define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*" 94# define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"
93#endif 95#endif
94 96
97/* Maximum accepted message length */
98#define AGENT_MAX_LEN (256*1024)
99
95typedef enum { 100typedef enum {
96 AUTH_UNUSED, 101 AUTH_UNUSED,
97 AUTH_SOCKET, 102 AUTH_SOCKET,
@@ -118,13 +123,13 @@ typedef struct identity {
118 u_int confirm; 123 u_int confirm;
119} Identity; 124} Identity;
120 125
121typedef struct { 126struct idtable {
122 int nentries; 127 int nentries;
123 TAILQ_HEAD(idqueue, identity) idlist; 128 TAILQ_HEAD(idqueue, identity) idlist;
124} Idtab; 129};
125 130
126/* private key table, one per protocol version */ 131/* private key table */
127Idtab idtable[3]; 132struct idtable *idtab;
128 133
129int max_fd = 0; 134int max_fd = 0;
130 135
@@ -171,21 +176,9 @@ close_socket(SocketEntry *e)
171static void 176static void
172idtab_init(void) 177idtab_init(void)
173{ 178{
174 int i; 179 idtab = xcalloc(1, sizeof(*idtab));
175 180 TAILQ_INIT(&idtab->idlist);
176 for (i = 0; i <=2; i++) { 181 idtab->nentries = 0;
177 TAILQ_INIT(&idtable[i].idlist);
178 idtable[i].nentries = 0;
179 }
180}
181
182/* return private key table for requested protocol version */
183static Idtab *
184idtab_lookup(int version)
185{
186 if (version < 1 || version > 2)
187 fatal("internal error, bad protocol version %d", version);
188 return &idtable[version];
189} 182}
190 183
191static void 184static void
@@ -199,12 +192,11 @@ free_identity(Identity *id)
199 192
200/* return matching private key for given public key */ 193/* return matching private key for given public key */
201static Identity * 194static Identity *
202lookup_identity(struct sshkey *key, int version) 195lookup_identity(struct sshkey *key)
203{ 196{
204 Identity *id; 197 Identity *id;
205 198
206 Idtab *tab = idtab_lookup(version); 199 TAILQ_FOREACH(id, &idtab->idlist, next) {
207 TAILQ_FOREACH(id, &tab->idlist, next) {
208 if (sshkey_equal(key, id->key)) 200 if (sshkey_equal(key, id->key))
209 return (id); 201 return (id);
210 } 202 }
@@ -241,135 +233,30 @@ send_status(SocketEntry *e, int success)
241 233
242/* send list of supported public keys to 'client' */ 234/* send list of supported public keys to 'client' */
243static void 235static void
244process_request_identities(SocketEntry *e, int version) 236process_request_identities(SocketEntry *e)
245{ 237{
246 Idtab *tab = idtab_lookup(version);
247 Identity *id; 238 Identity *id;
248 struct sshbuf *msg; 239 struct sshbuf *msg;
249 int r; 240 int r;
250 241
251 if ((msg = sshbuf_new()) == NULL) 242 if ((msg = sshbuf_new()) == NULL)
252 fatal("%s: sshbuf_new failed", __func__); 243 fatal("%s: sshbuf_new failed", __func__);
253 if ((r = sshbuf_put_u8(msg, (version == 1) ? 244 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
254 SSH_AGENT_RSA_IDENTITIES_ANSWER : 245 (r = sshbuf_put_u32(msg, idtab->nentries)) != 0)
255 SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
256 (r = sshbuf_put_u32(msg, tab->nentries)) != 0)
257 fatal("%s: buffer error: %s", __func__, ssh_err(r));
258 TAILQ_FOREACH(id, &tab->idlist, next) {
259 if (id->key->type == KEY_RSA1) {
260#ifdef WITH_SSH1
261 if ((r = sshbuf_put_u32(msg,
262 BN_num_bits(id->key->rsa->n))) != 0 ||
263 (r = sshbuf_put_bignum1(msg,
264 id->key->rsa->e)) != 0 ||
265 (r = sshbuf_put_bignum1(msg,
266 id->key->rsa->n)) != 0)
267 fatal("%s: buffer error: %s",
268 __func__, ssh_err(r));
269#endif
270 } else {
271 u_char *blob;
272 size_t blen;
273
274 if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) {
275 error("%s: sshkey_to_blob: %s", __func__,
276 ssh_err(r));
277 continue;
278 }
279 if ((r = sshbuf_put_string(msg, blob, blen)) != 0)
280 fatal("%s: buffer error: %s",
281 __func__, ssh_err(r));
282 free(blob);
283 }
284 if ((r = sshbuf_put_cstring(msg, id->comment)) != 0)
285 fatal("%s: buffer error: %s", __func__, ssh_err(r));
286 }
287 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
288 fatal("%s: buffer error: %s", __func__, ssh_err(r));
289 sshbuf_free(msg);
290}
291
292#ifdef WITH_SSH1
293/* ssh1 only */
294static void
295process_authentication_challenge1(SocketEntry *e)
296{
297 u_char buf[32], mdbuf[16], session_id[16];
298 u_int response_type;
299 BIGNUM *challenge;
300 Identity *id;
301 int r, len;
302 struct sshbuf *msg;
303 struct ssh_digest_ctx *md;
304 struct sshkey *key;
305
306 if ((msg = sshbuf_new()) == NULL)
307 fatal("%s: sshbuf_new failed", __func__);
308 if ((key = sshkey_new(KEY_RSA1)) == NULL)
309 fatal("%s: sshkey_new failed", __func__);
310 if ((challenge = BN_new()) == NULL)
311 fatal("%s: BN_new failed", __func__);
312
313 if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */
314 (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
315 (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 ||
316 (r = sshbuf_get_bignum1(e->request, challenge)))
317 fatal("%s: buffer error: %s", __func__, ssh_err(r));
318
319 /* Only protocol 1.1 is supported */
320 if (sshbuf_len(e->request) == 0)
321 goto failure;
322 if ((r = sshbuf_get(e->request, session_id, sizeof(session_id))) != 0 ||
323 (r = sshbuf_get_u32(e->request, &response_type)) != 0)
324 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 246 fatal("%s: buffer error: %s", __func__, ssh_err(r));
325 if (response_type != 1) 247 TAILQ_FOREACH(id, &idtab->idlist, next) {
326 goto failure; 248 if ((r = sshkey_puts(id->key, msg)) != 0 ||
327 249 (r = sshbuf_put_cstring(msg, id->comment)) != 0) {
328 id = lookup_identity(key, 1); 250 error("%s: put key/comment: %s", __func__,
329 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
330 struct sshkey *private = id->key;
331 /* Decrypt the challenge using the private key. */
332 if ((r = rsa_private_decrypt(challenge, challenge,
333 private->rsa) != 0)) {
334 fatal("%s: rsa_public_encrypt: %s", __func__,
335 ssh_err(r)); 251 ssh_err(r));
336 goto failure; /* XXX ? */ 252 continue;
337 } 253 }
338
339 /* The response is MD5 of decrypted challenge plus session id */
340 len = BN_num_bytes(challenge);
341 if (len <= 0 || len > 32) {
342 logit("%s: bad challenge length %d", __func__, len);
343 goto failure;
344 }
345 memset(buf, 0, 32);
346 BN_bn2bin(challenge, buf + 32 - len);
347 if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
348 ssh_digest_update(md, buf, 32) < 0 ||
349 ssh_digest_update(md, session_id, 16) < 0 ||
350 ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0)
351 fatal("%s: md5 failed", __func__);
352 ssh_digest_free(md);
353
354 /* Send the response. */
355 if ((r = sshbuf_put_u8(msg, SSH_AGENT_RSA_RESPONSE)) != 0 ||
356 (r = sshbuf_put(msg, mdbuf, sizeof(mdbuf))) != 0)
357 fatal("%s: buffer error: %s", __func__, ssh_err(r));
358 goto send;
359 } 254 }
360
361 failure:
362 /* Unknown identity or protocol error. Send failure. */
363 if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
364 fatal("%s: buffer error: %s", __func__, ssh_err(r));
365 send:
366 if ((r = sshbuf_put_stringb(e->output, msg)) != 0) 255 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
367 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 256 fatal("%s: buffer error: %s", __func__, ssh_err(r));
368 sshkey_free(key);
369 BN_clear_free(challenge);
370 sshbuf_free(msg); 257 sshbuf_free(msg);
371} 258}
372#endif 259
373 260
374static char * 261static char *
375agent_decode_alg(struct sshkey *key, u_int flags) 262agent_decode_alg(struct sshkey *key, u_int flags)
@@ -387,27 +274,24 @@ agent_decode_alg(struct sshkey *key, u_int flags)
387static void 274static void
388process_sign_request2(SocketEntry *e) 275process_sign_request2(SocketEntry *e)
389{ 276{
390 u_char *blob, *data, *signature = NULL; 277 const u_char *data;
391 size_t blen, dlen, slen = 0; 278 u_char *signature = NULL;
279 size_t dlen, slen = 0;
392 u_int compat = 0, flags; 280 u_int compat = 0, flags;
393 int r, ok = -1; 281 int r, ok = -1;
394 struct sshbuf *msg; 282 struct sshbuf *msg;
395 struct sshkey *key; 283 struct sshkey *key = NULL;
396 struct identity *id; 284 struct identity *id;
397 285
398 if ((msg = sshbuf_new()) == NULL) 286 if ((msg = sshbuf_new()) == NULL)
399 fatal("%s: sshbuf_new failed", __func__); 287 fatal("%s: sshbuf_new failed", __func__);
400 if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0 || 288 if ((r = sshkey_froms(e->request, &key)) != 0 ||
401 (r = sshbuf_get_string(e->request, &data, &dlen)) != 0 || 289 (r = sshbuf_get_string_direct(e->request, &data, &dlen)) != 0 ||
402 (r = sshbuf_get_u32(e->request, &flags)) != 0) 290 (r = sshbuf_get_u32(e->request, &flags)) != 0)
403 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 291 fatal("%s: buffer error: %s", __func__, ssh_err(r));
404 if (flags & SSH_AGENT_OLD_SIGNATURE) 292 if (flags & SSH_AGENT_OLD_SIGNATURE)
405 compat = SSH_BUG_SIGBLOB; 293 compat = SSH_BUG_SIGBLOB;
406 if ((r = sshkey_from_blob(blob, blen, &key)) != 0) { 294 if ((id = lookup_identity(key)) == NULL) {
407 error("%s: cannot parse key blob: %s", __func__, ssh_err(r));
408 goto send;
409 }
410 if ((id = lookup_identity(key, 2)) == NULL) {
411 verbose("%s: %s key not found", __func__, sshkey_type(key)); 295 verbose("%s: %s key not found", __func__, sshkey_type(key));
412 goto send; 296 goto send;
413 } 297 }
@@ -435,90 +319,52 @@ process_sign_request2(SocketEntry *e)
435 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 319 fatal("%s: buffer error: %s", __func__, ssh_err(r));
436 320
437 sshbuf_free(msg); 321 sshbuf_free(msg);
438 free(data);
439 free(blob);
440 free(signature); 322 free(signature);
441} 323}
442 324
443/* shared */ 325/* shared */
444static void 326static void
445process_remove_identity(SocketEntry *e, int version) 327process_remove_identity(SocketEntry *e)
446{ 328{
447 size_t blen;
448 int r, success = 0; 329 int r, success = 0;
449 struct sshkey *key = NULL; 330 struct sshkey *key = NULL;
450 u_char *blob; 331 Identity *id;
451#ifdef WITH_SSH1
452 u_int bits;
453#endif /* WITH_SSH1 */
454
455 switch (version) {
456#ifdef WITH_SSH1
457 case 1:
458 if ((key = sshkey_new(KEY_RSA1)) == NULL) {
459 error("%s: sshkey_new failed", __func__);
460 return;
461 }
462 if ((r = sshbuf_get_u32(e->request, &bits)) != 0 ||
463 (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
464 (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0)
465 fatal("%s: buffer error: %s", __func__, ssh_err(r));
466 332
467 if (bits != sshkey_size(key)) 333 if ((r = sshkey_froms(e->request, &key)) != 0) {
468 logit("Warning: identity keysize mismatch: " 334 error("%s: get key: %s", __func__, ssh_err(r));
469 "actual %u, announced %u", 335 goto done;
470 sshkey_size(key), bits);
471 break;
472#endif /* WITH_SSH1 */
473 case 2:
474 if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0)
475 fatal("%s: buffer error: %s", __func__, ssh_err(r));
476 if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
477 error("%s: sshkey_from_blob failed: %s",
478 __func__, ssh_err(r));
479 free(blob);
480 break;
481 } 336 }
482 if (key != NULL) { 337 if ((id = lookup_identity(key)) == NULL) {
483 Identity *id = lookup_identity(key, version); 338 debug("%s: key not found", __func__);
484 if (id != NULL) { 339 goto done;
485 /*
486 * We have this key. Free the old key. Since we
487 * don't want to leave empty slots in the middle of
488 * the array, we actually free the key there and move
489 * all the entries between the empty slot and the end
490 * of the array.
491 */
492 Idtab *tab = idtab_lookup(version);
493 if (tab->nentries < 1)
494 fatal("process_remove_identity: "
495 "internal error: tab->nentries %d",
496 tab->nentries);
497 TAILQ_REMOVE(&tab->idlist, id, next);
498 free_identity(id);
499 tab->nentries--;
500 success = 1;
501 }
502 sshkey_free(key);
503 } 340 }
341 /* We have this key, free it. */
342 if (idtab->nentries < 1)
343 fatal("%s: internal error: nentries %d",
344 __func__, idtab->nentries);
345 TAILQ_REMOVE(&idtab->idlist, id, next);
346 free_identity(id);
347 idtab->nentries--;
348 sshkey_free(key);
349 success = 1;
350 done:
504 send_status(e, success); 351 send_status(e, success);
505} 352}
506 353
507static void 354static void
508process_remove_all_identities(SocketEntry *e, int version) 355process_remove_all_identities(SocketEntry *e)
509{ 356{
510 Idtab *tab = idtab_lookup(version);
511 Identity *id; 357 Identity *id;
512 358
513 /* Loop over all identities and clear the keys. */ 359 /* Loop over all identities and clear the keys. */
514 for (id = TAILQ_FIRST(&tab->idlist); id; 360 for (id = TAILQ_FIRST(&idtab->idlist); id;
515 id = TAILQ_FIRST(&tab->idlist)) { 361 id = TAILQ_FIRST(&idtab->idlist)) {
516 TAILQ_REMOVE(&tab->idlist, id, next); 362 TAILQ_REMOVE(&idtab->idlist, id, next);
517 free_identity(id); 363 free_identity(id);
518 } 364 }
519 365
520 /* Mark that there are no identities. */ 366 /* Mark that there are no identities. */
521 tab->nentries = 0; 367 idtab->nentries = 0;
522 368
523 /* Send success. */ 369 /* Send success. */
524 send_status(e, 1); 370 send_status(e, 1);
@@ -530,24 +376,19 @@ reaper(void)
530{ 376{
531 time_t deadline = 0, now = monotime(); 377 time_t deadline = 0, now = monotime();
532 Identity *id, *nxt; 378 Identity *id, *nxt;
533 int version; 379
534 Idtab *tab; 380 for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) {
535 381 nxt = TAILQ_NEXT(id, next);
536 for (version = 1; version < 3; version++) { 382 if (id->death == 0)
537 tab = idtab_lookup(version); 383 continue;
538 for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { 384 if (now >= id->death) {
539 nxt = TAILQ_NEXT(id, next); 385 debug("expiring key '%s'", id->comment);
540 if (id->death == 0) 386 TAILQ_REMOVE(&idtab->idlist, id, next);
541 continue; 387 free_identity(id);
542 if (now >= id->death) { 388 idtab->nentries--;
543 debug("expiring key '%s'", id->comment); 389 } else
544 TAILQ_REMOVE(&tab->idlist, id, next); 390 deadline = (deadline == 0) ? id->death :
545 free_identity(id); 391 MINIMUM(deadline, id->death);
546 tab->nentries--;
547 } else
548 deadline = (deadline == 0) ? id->death :
549 MINIMUM(deadline, id->death);
550 }
551 } 392 }
552 if (deadline == 0 || deadline <= now) 393 if (deadline == 0 || deadline <= now)
553 return 0; 394 return 0;
@@ -555,54 +396,9 @@ reaper(void)
555 return (deadline - now); 396 return (deadline - now);
556} 397}
557 398
558/*
559 * XXX this and the corresponding serialisation function probably belongs
560 * in key.c
561 */
562#ifdef WITH_SSH1
563static int
564agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp)
565{
566 struct sshkey *k = NULL;
567 int r = SSH_ERR_INTERNAL_ERROR;
568
569 *kp = NULL;
570 if ((k = sshkey_new_private(KEY_RSA1)) == NULL)
571 return SSH_ERR_ALLOC_FAIL;
572
573 if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */
574 (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 ||
575 (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 ||
576 (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 ||
577 (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 ||
578 /* SSH1 and SSL have p and q swapped */
579 (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */
580 (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */
581 goto out;
582
583 /* Generate additional parameters */
584 if ((r = rsa_generate_additional_parameters(k->rsa)) != 0)
585 goto out;
586 /* enable blinding */
587 if (RSA_blinding_on(k->rsa, NULL) != 1) {
588 r = SSH_ERR_LIBCRYPTO_ERROR;
589 goto out;
590 }
591
592 r = 0; /* success */
593 out:
594 if (r == 0)
595 *kp = k;
596 else
597 sshkey_free(k);
598 return r;
599}
600#endif /* WITH_SSH1 */
601
602static void 399static void
603process_add_identity(SocketEntry *e, int version) 400process_add_identity(SocketEntry *e)
604{ 401{
605 Idtab *tab = idtab_lookup(version);
606 Identity *id; 402 Identity *id;
607 int success = 0, confirm = 0; 403 int success = 0, confirm = 0;
608 u_int seconds; 404 u_int seconds;
@@ -612,17 +408,8 @@ process_add_identity(SocketEntry *e, int version)
612 u_char ctype; 408 u_char ctype;
613 int r = SSH_ERR_INTERNAL_ERROR; 409 int r = SSH_ERR_INTERNAL_ERROR;
614 410
615 switch (version) { 411 if ((r = sshkey_private_deserialize(e->request, &k)) != 0 ||
616#ifdef WITH_SSH1 412 k == NULL ||
617 case 1:
618 r = agent_decode_rsa1(e->request, &k);
619 break;
620#endif /* WITH_SSH1 */
621 case 2:
622 r = sshkey_private_deserialize(e->request, &k);
623 break;
624 }
625 if (r != 0 || k == NULL ||
626 (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { 413 (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
627 error("%s: decode private key: %s", __func__, ssh_err(r)); 414 error("%s: decode private key: %s", __func__, ssh_err(r));
628 goto err; 415 goto err;
@@ -658,12 +445,12 @@ process_add_identity(SocketEntry *e, int version)
658 success = 1; 445 success = 1;
659 if (lifetime && !death) 446 if (lifetime && !death)
660 death = monotime() + lifetime; 447 death = monotime() + lifetime;
661 if ((id = lookup_identity(k, version)) == NULL) { 448 if ((id = lookup_identity(k)) == NULL) {
662 id = xcalloc(1, sizeof(Identity)); 449 id = xcalloc(1, sizeof(Identity));
663 id->key = k; 450 id->key = k;
664 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 451 TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
665 /* Increment the number of identities. */ 452 /* Increment the number of identities. */
666 tab->nentries++; 453 idtab->nentries++;
667 } else { 454 } else {
668 sshkey_free(k); 455 sshkey_free(k);
669 free(id->comment); 456 free(id->comment);
@@ -724,17 +511,14 @@ process_lock_agent(SocketEntry *e, int lock)
724} 511}
725 512
726static void 513static void
727no_identities(SocketEntry *e, u_int type) 514no_identities(SocketEntry *e)
728{ 515{
729 struct sshbuf *msg; 516 struct sshbuf *msg;
730 int r; 517 int r;
731 518
732 if ((msg = sshbuf_new()) == NULL) 519 if ((msg = sshbuf_new()) == NULL)
733 fatal("%s: sshbuf_new failed", __func__); 520 fatal("%s: sshbuf_new failed", __func__);
734 if ((r = sshbuf_put_u8(msg, 521 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
735 (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ?
736 SSH_AGENT_RSA_IDENTITIES_ANSWER :
737 SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
738 (r = sshbuf_put_u32(msg, 0)) != 0 || 522 (r = sshbuf_put_u32(msg, 0)) != 0 ||
739 (r = sshbuf_put_stringb(e->output, msg)) != 0) 523 (r = sshbuf_put_stringb(e->output, msg)) != 0)
740 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 524 fatal("%s: buffer error: %s", __func__, ssh_err(r));
@@ -746,13 +530,12 @@ static void
746process_add_smartcard_key(SocketEntry *e) 530process_add_smartcard_key(SocketEntry *e)
747{ 531{
748 char *provider = NULL, *pin, canonical_provider[PATH_MAX]; 532 char *provider = NULL, *pin, canonical_provider[PATH_MAX];
749 int r, i, version, count = 0, success = 0, confirm = 0; 533 int r, i, count = 0, success = 0, confirm = 0;
750 u_int seconds; 534 u_int seconds;
751 time_t death = 0; 535 time_t death = 0;
752 u_char type; 536 u_char type;
753 struct sshkey **keys = NULL, *k; 537 struct sshkey **keys = NULL, *k;
754 Identity *id; 538 Identity *id;
755 Idtab *tab;
756 539
757 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || 540 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
758 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) 541 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
@@ -772,8 +555,7 @@ process_add_smartcard_key(SocketEntry *e)
772 confirm = 1; 555 confirm = 1;
773 break; 556 break;
774 default: 557 default:
775 error("process_add_smartcard_key: " 558 error("%s: Unknown constraint type %d", __func__, type);
776 "Unknown constraint type %d", type);
777 goto send; 559 goto send;
778 } 560 }
779 } 561 }
@@ -794,17 +576,15 @@ process_add_smartcard_key(SocketEntry *e)
794 count = pkcs11_add_provider(canonical_provider, pin, &keys); 576 count = pkcs11_add_provider(canonical_provider, pin, &keys);
795 for (i = 0; i < count; i++) { 577 for (i = 0; i < count; i++) {
796 k = keys[i]; 578 k = keys[i];
797 version = k->type == KEY_RSA1 ? 1 : 2; 579 if (lookup_identity(k) == NULL) {
798 tab = idtab_lookup(version);
799 if (lookup_identity(k, version) == NULL) {
800 id = xcalloc(1, sizeof(Identity)); 580 id = xcalloc(1, sizeof(Identity));
801 id->key = k; 581 id->key = k;
802 id->provider = xstrdup(canonical_provider); 582 id->provider = xstrdup(canonical_provider);
803 id->comment = xstrdup(canonical_provider); /* XXX */ 583 id->comment = xstrdup(canonical_provider); /* XXX */
804 id->death = death; 584 id->death = death;
805 id->confirm = confirm; 585 id->confirm = confirm;
806 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 586 TAILQ_INSERT_TAIL(&idtab->idlist, id, next);
807 tab->nentries++; 587 idtab->nentries++;
808 success = 1; 588 success = 1;
809 } else { 589 } else {
810 sshkey_free(k); 590 sshkey_free(k);
@@ -822,9 +602,8 @@ static void
822process_remove_smartcard_key(SocketEntry *e) 602process_remove_smartcard_key(SocketEntry *e)
823{ 603{
824 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; 604 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX];
825 int r, version, success = 0; 605 int r, success = 0;
826 Identity *id, *nxt; 606 Identity *id, *nxt;
827 Idtab *tab;
828 607
829 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || 608 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
830 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) 609 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
@@ -838,25 +617,21 @@ process_remove_smartcard_key(SocketEntry *e)
838 } 617 }
839 618
840 debug("%s: remove %.100s", __func__, canonical_provider); 619 debug("%s: remove %.100s", __func__, canonical_provider);
841 for (version = 1; version < 3; version++) { 620 for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) {
842 tab = idtab_lookup(version); 621 nxt = TAILQ_NEXT(id, next);
843 for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { 622 /* Skip file--based keys */
844 nxt = TAILQ_NEXT(id, next); 623 if (id->provider == NULL)
845 /* Skip file--based keys */ 624 continue;
846 if (id->provider == NULL) 625 if (!strcmp(canonical_provider, id->provider)) {
847 continue; 626 TAILQ_REMOVE(&idtab->idlist, id, next);
848 if (!strcmp(canonical_provider, id->provider)) { 627 free_identity(id);
849 TAILQ_REMOVE(&tab->idlist, id, next); 628 idtab->nentries--;
850 free_identity(id);
851 tab->nentries--;
852 }
853 } 629 }
854 } 630 }
855 if (pkcs11_del_provider(canonical_provider) == 0) 631 if (pkcs11_del_provider(canonical_provider) == 0)
856 success = 1; 632 success = 1;
857 else 633 else
858 error("process_remove_smartcard_key:" 634 error("%s: pkcs11_del_provider failed", __func__);
859 " pkcs11_del_provider failed");
860send: 635send:
861 free(provider); 636 free(provider);
862 send_status(e, success); 637 send_status(e, success);
@@ -865,88 +640,86 @@ send:
865 640
866/* dispatch incoming messages */ 641/* dispatch incoming messages */
867 642
868static void 643static int
869process_message(SocketEntry *e) 644process_message(u_int socknum)
870{ 645{
871 u_int msg_len; 646 u_int msg_len;
872 u_char type; 647 u_char type;
873 const u_char *cp; 648 const u_char *cp;
874 int r; 649 int r;
650 SocketEntry *e;
651
652 if (socknum >= sockets_alloc) {
653 fatal("%s: socket number %u >= allocated %u",
654 __func__, socknum, sockets_alloc);
655 }
656 e = &sockets[socknum];
875 657
876 if (sshbuf_len(e->input) < 5) 658 if (sshbuf_len(e->input) < 5)
877 return; /* Incomplete message. */ 659 return 0; /* Incomplete message header. */
878 cp = sshbuf_ptr(e->input); 660 cp = sshbuf_ptr(e->input);
879 msg_len = PEEK_U32(cp); 661 msg_len = PEEK_U32(cp);
880 if (msg_len > 256 * 1024) { 662 if (msg_len > AGENT_MAX_LEN) {
881 close_socket(e); 663 debug("%s: socket %u (fd=%d) message too long %u > %u",
882 return; 664 __func__, socknum, e->fd, msg_len, AGENT_MAX_LEN);
665 return -1;
883 } 666 }
884 if (sshbuf_len(e->input) < msg_len + 4) 667 if (sshbuf_len(e->input) < msg_len + 4)
885 return; 668 return 0; /* Incomplete message body. */
886 669
887 /* move the current input to e->request */ 670 /* move the current input to e->request */
888 sshbuf_reset(e->request); 671 sshbuf_reset(e->request);
889 if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 || 672 if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 ||
890 (r = sshbuf_get_u8(e->request, &type)) != 0) 673 (r = sshbuf_get_u8(e->request, &type)) != 0) {
674 if (r == SSH_ERR_MESSAGE_INCOMPLETE ||
675 r == SSH_ERR_STRING_TOO_LARGE) {
676 debug("%s: buffer error: %s", __func__, ssh_err(r));
677 return -1;
678 }
891 fatal("%s: buffer error: %s", __func__, ssh_err(r)); 679 fatal("%s: buffer error: %s", __func__, ssh_err(r));
680 }
681
682 debug("%s: socket %u (fd=%d) type %d", __func__, socknum, e->fd, type);
892 683
893 /* check wheter agent is locked */ 684 /* check wheter agent is locked */
894 if (locked && type != SSH_AGENTC_UNLOCK) { 685 if (locked && type != SSH_AGENTC_UNLOCK) {
895 sshbuf_reset(e->request); 686 sshbuf_reset(e->request);
896 switch (type) { 687 switch (type) {
897 case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
898 case SSH2_AGENTC_REQUEST_IDENTITIES: 688 case SSH2_AGENTC_REQUEST_IDENTITIES:
899 /* send empty lists */ 689 /* send empty lists */
900 no_identities(e, type); 690 no_identities(e);
901 break; 691 break;
902 default: 692 default:
903 /* send a fail message for all other request types */ 693 /* send a fail message for all other request types */
904 send_status(e, 0); 694 send_status(e, 0);
905 } 695 }
906 return; 696 return 0;
907 } 697 }
908 698
909 debug("type %d", type);
910 switch (type) { 699 switch (type) {
911 case SSH_AGENTC_LOCK: 700 case SSH_AGENTC_LOCK:
912 case SSH_AGENTC_UNLOCK: 701 case SSH_AGENTC_UNLOCK:
913 process_lock_agent(e, type == SSH_AGENTC_LOCK); 702 process_lock_agent(e, type == SSH_AGENTC_LOCK);
914 break; 703 break;
915#ifdef WITH_SSH1
916 /* ssh1 */
917 case SSH_AGENTC_RSA_CHALLENGE:
918 process_authentication_challenge1(e);
919 break;
920 case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
921 process_request_identities(e, 1);
922 break;
923 case SSH_AGENTC_ADD_RSA_IDENTITY:
924 case SSH_AGENTC_ADD_RSA_ID_CONSTRAINED:
925 process_add_identity(e, 1);
926 break;
927 case SSH_AGENTC_REMOVE_RSA_IDENTITY:
928 process_remove_identity(e, 1);
929 break;
930#endif
931 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: 704 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
932 process_remove_all_identities(e, 1); /* safe for !WITH_SSH1 */ 705 process_remove_all_identities(e); /* safe for !WITH_SSH1 */
933 break; 706 break;
934 /* ssh2 */ 707 /* ssh2 */
935 case SSH2_AGENTC_SIGN_REQUEST: 708 case SSH2_AGENTC_SIGN_REQUEST:
936 process_sign_request2(e); 709 process_sign_request2(e);
937 break; 710 break;
938 case SSH2_AGENTC_REQUEST_IDENTITIES: 711 case SSH2_AGENTC_REQUEST_IDENTITIES:
939 process_request_identities(e, 2); 712 process_request_identities(e);
940 break; 713 break;
941 case SSH2_AGENTC_ADD_IDENTITY: 714 case SSH2_AGENTC_ADD_IDENTITY:
942 case SSH2_AGENTC_ADD_ID_CONSTRAINED: 715 case SSH2_AGENTC_ADD_ID_CONSTRAINED:
943 process_add_identity(e, 2); 716 process_add_identity(e);
944 break; 717 break;
945 case SSH2_AGENTC_REMOVE_IDENTITY: 718 case SSH2_AGENTC_REMOVE_IDENTITY:
946 process_remove_identity(e, 2); 719 process_remove_identity(e);
947 break; 720 break;
948 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: 721 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
949 process_remove_all_identities(e, 2); 722 process_remove_all_identities(e);
950 break; 723 break;
951#ifdef ENABLE_PKCS11 724#ifdef ENABLE_PKCS11
952 case SSH_AGENTC_ADD_SMARTCARD_KEY: 725 case SSH_AGENTC_ADD_SMARTCARD_KEY:
@@ -964,6 +737,7 @@ process_message(SocketEntry *e)
964 send_status(e, 0); 737 send_status(e, 0);
965 break; 738 break;
966 } 739 }
740 return 0;
967} 741}
968 742
969static void 743static void
@@ -1005,19 +779,141 @@ new_socket(sock_type type, int fd)
1005} 779}
1006 780
1007static int 781static int
1008prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, 782handle_socket_read(u_int socknum)
1009 struct timeval **tvpp) 783{
784 struct sockaddr_un sunaddr;
785 socklen_t slen;
786 uid_t euid;
787 gid_t egid;
788 int fd;
789
790 slen = sizeof(sunaddr);
791 fd = accept(sockets[socknum].fd, (struct sockaddr *)&sunaddr, &slen);
792 if (fd < 0) {
793 error("accept from AUTH_SOCKET: %s", strerror(errno));
794 return -1;
795 }
796 if (getpeereid(fd, &euid, &egid) < 0) {
797 error("getpeereid %d failed: %s", fd, strerror(errno));
798 close(fd);
799 return -1;
800 }
801 if ((euid != 0) && (getuid() != euid)) {
802 error("uid mismatch: peer euid %u != uid %u",
803 (u_int) euid, (u_int) getuid());
804 close(fd);
805 return -1;
806 }
807 new_socket(AUTH_CONNECTION, fd);
808 return 0;
809}
810
811static int
812handle_conn_read(u_int socknum)
813{
814 char buf[1024];
815 ssize_t len;
816 int r;
817
818 if ((len = read(sockets[socknum].fd, buf, sizeof(buf))) <= 0) {
819 if (len == -1) {
820 if (errno == EAGAIN || errno == EINTR)
821 return 0;
822 error("%s: read error on socket %u (fd %d): %s",
823 __func__, socknum, sockets[socknum].fd,
824 strerror(errno));
825 }
826 return -1;
827 }
828 if ((r = sshbuf_put(sockets[socknum].input, buf, len)) != 0)
829 fatal("%s: buffer error: %s", __func__, ssh_err(r));
830 explicit_bzero(buf, sizeof(buf));
831 process_message(socknum);
832 return 0;
833}
834
835static int
836handle_conn_write(u_int socknum)
1010{ 837{
1011 u_int i, sz; 838 ssize_t len;
1012 int n = 0; 839 int r;
1013 static struct timeval tv; 840
841 if (sshbuf_len(sockets[socknum].output) == 0)
842 return 0; /* shouldn't happen */
843 if ((len = write(sockets[socknum].fd,
844 sshbuf_ptr(sockets[socknum].output),
845 sshbuf_len(sockets[socknum].output))) <= 0) {
846 if (len == -1) {
847 if (errno == EAGAIN || errno == EINTR)
848 return 0;
849 error("%s: read error on socket %u (fd %d): %s",
850 __func__, socknum, sockets[socknum].fd,
851 strerror(errno));
852 }
853 return -1;
854 }
855 if ((r = sshbuf_consume(sockets[socknum].output, len)) != 0)
856 fatal("%s: buffer error: %s", __func__, ssh_err(r));
857 return 0;
858}
859
860static void
861after_poll(struct pollfd *pfd, size_t npfd)
862{
863 size_t i;
864 u_int socknum;
865
866 for (i = 0; i < npfd; i++) {
867 if (pfd[i].revents == 0)
868 continue;
869 /* Find sockets entry */
870 for (socknum = 0; socknum < sockets_alloc; socknum++) {
871 if (sockets[socknum].type != AUTH_SOCKET &&
872 sockets[socknum].type != AUTH_CONNECTION)
873 continue;
874 if (pfd[i].fd == sockets[socknum].fd)
875 break;
876 }
877 if (socknum >= sockets_alloc) {
878 error("%s: no socket for fd %d", __func__, pfd[i].fd);
879 continue;
880 }
881 /* Process events */
882 switch (sockets[socknum].type) {
883 case AUTH_SOCKET:
884 if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 &&
885 handle_socket_read(socknum) != 0)
886 close_socket(&sockets[socknum]);
887 break;
888 case AUTH_CONNECTION:
889 if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 &&
890 handle_conn_read(socknum) != 0) {
891 close_socket(&sockets[socknum]);
892 break;
893 }
894 if ((pfd[i].revents & (POLLOUT|POLLHUP)) != 0 &&
895 handle_conn_write(socknum) != 0)
896 close_socket(&sockets[socknum]);
897 break;
898 default:
899 break;
900 }
901 }
902}
903
904static int
905prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp)
906{
907 struct pollfd *pfd = *pfdp;
908 size_t i, j, npfd = 0;
1014 time_t deadline; 909 time_t deadline;
1015 910
911 /* Count active sockets */
1016 for (i = 0; i < sockets_alloc; i++) { 912 for (i = 0; i < sockets_alloc; i++) {
1017 switch (sockets[i].type) { 913 switch (sockets[i].type) {
1018 case AUTH_SOCKET: 914 case AUTH_SOCKET:
1019 case AUTH_CONNECTION: 915 case AUTH_CONNECTION:
1020 n = MAXIMUM(n, sockets[i].fd); 916 npfd++;
1021 break; 917 break;
1022 case AUTH_UNUSED: 918 case AUTH_UNUSED:
1023 break; 919 break;
@@ -1026,28 +922,23 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
1026 break; 922 break;
1027 } 923 }
1028 } 924 }
925 if (npfd != *npfdp &&
926 (pfd = recallocarray(pfd, *npfdp, npfd, sizeof(*pfd))) == NULL)
927 fatal("%s: recallocarray failed", __func__);
928 *pfdp = pfd;
929 *npfdp = npfd;
1029 930
1030 sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); 931 for (i = j = 0; i < sockets_alloc; i++) {
1031 if (*fdrp == NULL || sz > *nallocp) {
1032 free(*fdrp);
1033 free(*fdwp);
1034 *fdrp = xmalloc(sz);
1035 *fdwp = xmalloc(sz);
1036 *nallocp = sz;
1037 }
1038 if (n < *fdl)
1039 debug("XXX shrink: %d < %d", n, *fdl);
1040 *fdl = n;
1041 memset(*fdrp, 0, sz);
1042 memset(*fdwp, 0, sz);
1043
1044 for (i = 0; i < sockets_alloc; i++) {
1045 switch (sockets[i].type) { 932 switch (sockets[i].type) {
1046 case AUTH_SOCKET: 933 case AUTH_SOCKET:
1047 case AUTH_CONNECTION: 934 case AUTH_CONNECTION:
1048 FD_SET(sockets[i].fd, *fdrp); 935 pfd[j].fd = sockets[i].fd;
936 pfd[j].revents = 0;
937 /* XXX backoff when input buffer full */
938 pfd[j].events = POLLIN;
1049 if (sshbuf_len(sockets[i].output) > 0) 939 if (sshbuf_len(sockets[i].output) > 0)
1050 FD_SET(sockets[i].fd, *fdwp); 940 pfd[j].events |= POLLOUT;
941 j++;
1051 break; 942 break;
1052 default: 943 default:
1053 break; 944 break;
@@ -1058,99 +949,17 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
1058 deadline = (deadline == 0) ? parent_alive_interval : 949 deadline = (deadline == 0) ? parent_alive_interval :
1059 MINIMUM(deadline, parent_alive_interval); 950 MINIMUM(deadline, parent_alive_interval);
1060 if (deadline == 0) { 951 if (deadline == 0) {
1061 *tvpp = NULL; 952 *timeoutp = -1; /* INFTIM */
1062 } else { 953 } else {
1063 tv.tv_sec = deadline; 954 if (deadline > INT_MAX / 1000)
1064 tv.tv_usec = 0; 955 *timeoutp = INT_MAX / 1000;
1065 *tvpp = &tv; 956 else
957 *timeoutp = deadline * 1000;
1066 } 958 }
1067 return (1); 959 return (1);
1068} 960}
1069 961
1070static void 962static void
1071after_select(fd_set *readset, fd_set *writeset)
1072{
1073 struct sockaddr_un sunaddr;
1074 socklen_t slen;
1075 char buf[1024];
1076 int len, sock, r;
1077 u_int i, orig_alloc;
1078 uid_t euid;
1079 gid_t egid;
1080
1081 for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++)
1082 switch (sockets[i].type) {
1083 case AUTH_UNUSED:
1084 break;
1085 case AUTH_SOCKET:
1086 if (FD_ISSET(sockets[i].fd, readset)) {
1087 slen = sizeof(sunaddr);
1088 sock = accept(sockets[i].fd,
1089 (struct sockaddr *)&sunaddr, &slen);
1090 if (sock < 0) {
1091 error("accept from AUTH_SOCKET: %s",
1092 strerror(errno));
1093 break;
1094 }
1095 if (getpeereid(sock, &euid, &egid) < 0) {
1096 error("getpeereid %d failed: %s",
1097 sock, strerror(errno));
1098 close(sock);
1099 break;
1100 }
1101 if ((euid != 0) && (getuid() != euid)) {
1102 error("uid mismatch: "
1103 "peer euid %u != uid %u",
1104 (u_int) euid, (u_int) getuid());
1105 close(sock);
1106 break;
1107 }
1108 new_socket(AUTH_CONNECTION, sock);
1109 }
1110 break;
1111 case AUTH_CONNECTION:
1112 if (sshbuf_len(sockets[i].output) > 0 &&
1113 FD_ISSET(sockets[i].fd, writeset)) {
1114 len = write(sockets[i].fd,
1115 sshbuf_ptr(sockets[i].output),
1116 sshbuf_len(sockets[i].output));
1117 if (len == -1 && (errno == EAGAIN ||
1118 errno == EWOULDBLOCK ||
1119 errno == EINTR))
1120 continue;
1121 if (len <= 0) {
1122 close_socket(&sockets[i]);
1123 break;
1124 }
1125 if ((r = sshbuf_consume(sockets[i].output,
1126 len)) != 0)
1127 fatal("%s: buffer error: %s",
1128 __func__, ssh_err(r));
1129 }
1130 if (FD_ISSET(sockets[i].fd, readset)) {
1131 len = read(sockets[i].fd, buf, sizeof(buf));
1132 if (len == -1 && (errno == EAGAIN ||
1133 errno == EWOULDBLOCK ||
1134 errno == EINTR))
1135 continue;
1136 if (len <= 0) {
1137 close_socket(&sockets[i]);
1138 break;
1139 }
1140 if ((r = sshbuf_put(sockets[i].input,
1141 buf, len)) != 0)
1142 fatal("%s: buffer error: %s",
1143 __func__, ssh_err(r));
1144 explicit_bzero(buf, sizeof(buf));
1145 process_message(&sockets[i]);
1146 }
1147 break;
1148 default:
1149 fatal("Unknown type %d", sockets[i].type);
1150 }
1151}
1152
1153static void
1154cleanup_socket(void) 963cleanup_socket(void)
1155{ 964{
1156 if (cleanup_pid != 0 && getpid() != cleanup_pid) 965 if (cleanup_pid != 0 && getpid() != cleanup_pid)
@@ -1209,9 +1018,7 @@ main(int ac, char **av)
1209{ 1018{
1210 int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0; 1019 int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0;
1211 int sock, fd, ch, result, saved_errno; 1020 int sock, fd, ch, result, saved_errno;
1212 u_int nalloc;
1213 char *shell, *format, *pidstr, *agentsocket = NULL; 1021 char *shell, *format, *pidstr, *agentsocket = NULL;
1214 fd_set *readsetp = NULL, *writesetp = NULL;
1215#ifdef HAVE_SETRLIMIT 1022#ifdef HAVE_SETRLIMIT
1216 struct rlimit rlim; 1023 struct rlimit rlim;
1217#endif 1024#endif
@@ -1219,9 +1026,11 @@ main(int ac, char **av)
1219 extern char *optarg; 1026 extern char *optarg;
1220 pid_t pid; 1027 pid_t pid;
1221 char pidstrbuf[1 + 3 * sizeof pid]; 1028 char pidstrbuf[1 + 3 * sizeof pid];
1222 struct timeval *tvp = NULL;
1223 size_t len; 1029 size_t len;
1224 mode_t prev_mask; 1030 mode_t prev_mask;
1031 int timeout = -1; /* INFTIM */
1032 struct pollfd *pfd = NULL;
1033 size_t npfd = 0;
1225 1034
1226 ssh_malloc_init(); /* must be called before any mallocs */ 1035 ssh_malloc_init(); /* must be called before any mallocs */
1227 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1036 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
@@ -1442,15 +1251,14 @@ skip:
1442 signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN); 1251 signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN);
1443 signal(SIGHUP, cleanup_handler); 1252 signal(SIGHUP, cleanup_handler);
1444 signal(SIGTERM, cleanup_handler); 1253 signal(SIGTERM, cleanup_handler);
1445 nalloc = 0;
1446 1254
1447 if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) 1255 if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1)
1448 fatal("%s: pledge: %s", __progname, strerror(errno)); 1256 fatal("%s: pledge: %s", __progname, strerror(errno));
1449 platform_pledge_agent(); 1257 platform_pledge_agent();
1450 1258
1451 while (1) { 1259 while (1) {
1452 prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp); 1260 prepare_poll(&pfd, &npfd, &timeout);
1453 result = select(max_fd + 1, readsetp, writesetp, NULL, tvp); 1261 result = poll(pfd, npfd, timeout);
1454 saved_errno = errno; 1262 saved_errno = errno;
1455 if (parent_alive_interval != 0) 1263 if (parent_alive_interval != 0)
1456 check_parent_exists(); 1264 check_parent_exists();
@@ -1458,9 +1266,9 @@ skip:
1458 if (result < 0) { 1266 if (result < 0) {
1459 if (saved_errno == EINTR) 1267 if (saved_errno == EINTR)
1460 continue; 1268 continue;
1461 fatal("select: %s", strerror(saved_errno)); 1269 fatal("poll: %s", strerror(saved_errno));
1462 } else if (result > 0) 1270 } else if (result > 0)
1463 after_select(readsetp, writesetp); 1271 after_poll(pfd, npfd);
1464 } 1272 }
1465 /* NOTREACHED */ 1273 /* NOTREACHED */
1466} 1274}
diff --git a/ssh-gss.h b/ssh-gss.h
index a99d7f08b..6593e422d 100644
--- a/ssh-gss.h
+++ b/ssh-gss.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-gss.h,v 1.11 2014/02/26 20:28:44 djm Exp $ */ 1/* $OpenBSD: ssh-gss.h,v 1.12 2017/06/24 06:34:38 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 3 * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
4 * 4 *
@@ -128,6 +128,7 @@ OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
128void ssh_gssapi_do_child(char ***, u_int *); 128void ssh_gssapi_do_child(char ***, u_int *);
129void ssh_gssapi_cleanup_creds(void); 129void ssh_gssapi_cleanup_creds(void);
130void ssh_gssapi_storecreds(void); 130void ssh_gssapi_storecreds(void);
131const char *ssh_gssapi_displayname(void);
131 132
132#endif /* GSSAPI */ 133#endif /* GSSAPI */
133 134
diff --git a/ssh-keygen.0 b/ssh-keygen.0
index 569297da4..fb2c02fe7 100644
--- a/ssh-keygen.0
+++ b/ssh-keygen.0
@@ -4,7 +4,7 @@ NAME
4 ssh-keygen M-bM-^@M-^S authentication key generation, management and conversion 4 ssh-keygen M-bM-^@M-^S authentication key generation, management and conversion
5 5
6SYNOPSIS 6SYNOPSIS
7 ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1] 7 ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa]
8 [-N new_passphrase] [-C comment] [-f output_keyfile] 8 [-N new_passphrase] [-C comment] [-f output_keyfile]
9 ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile] 9 ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]
10 ssh-keygen -i [-m key_format] [-f input_keyfile] 10 ssh-keygen -i [-m key_format] [-f input_keyfile]
@@ -21,24 +21,21 @@ SYNOPSIS
21 ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point] 21 ssh-keygen -G output_file [-v] [-b bits] [-M memory] [-S start_point]
22 ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines] 22 ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]
23 [-j start_line] [-K checkpt] [-W generator] 23 [-j start_line] [-K checkpt] [-W generator]
24 ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals] 24 ssh-keygen -s ca_key -I certificate_identity [-h] [-U]
25 [-O option] [-V validity_interval] [-z serial_number] file ... 25 [-D pkcs11_provider] [-n principals] [-O option]
26 [-V validity_interval] [-z serial_number] file ...
26 ssh-keygen -L [-f input_keyfile] 27 ssh-keygen -L [-f input_keyfile]
27 ssh-keygen -A 28 ssh-keygen -A [-f prefix_path]
28 ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number] 29 ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]
29 file ... 30 file ...
30 ssh-keygen -Q -f krl_file file ... 31 ssh-keygen -Q -f krl_file file ...
31 32
32DESCRIPTION 33DESCRIPTION
33 ssh-keygen generates, manages and converts authentication keys for 34 ssh-keygen generates, manages and converts authentication keys for
34 ssh(1). ssh-keygen can create keys for use by SSH protocol versions 1 35 ssh(1). ssh-keygen can create keys for use by SSH protocol version 2.
35 and 2. Protocol 1 should not be used and is only offered to support
36 legacy devices. It suffers from a number of cryptographic weaknesses and
37 doesn't support many of the advanced features available for protocol 2.
38 36
39 The type of key to be generated is specified with the -t option. If 37 The type of key to be generated is specified with the -t option. If
40 invoked without any arguments, ssh-keygen will generate an RSA key for 38 invoked without any arguments, ssh-keygen will generate an RSA key.
41 use in SSH protocol 2 connections.
42 39
43 ssh-keygen is also used to generate groups for use in Diffie-Hellman 40 ssh-keygen is also used to generate groups for use in Diffie-Hellman
44 group exchange (DH-GEX). See the MODULI GENERATION section for details. 41 group exchange (DH-GEX). See the MODULI GENERATION section for details.
@@ -48,10 +45,10 @@ DESCRIPTION
48 KEY REVOCATION LISTS section for details. 45 KEY REVOCATION LISTS section for details.
49 46
50 Normally each user wishing to use SSH with public key authentication runs 47 Normally each user wishing to use SSH with public key authentication runs
51 this once to create the authentication key in ~/.ssh/identity, 48 this once to create the authentication key in ~/.ssh/id_dsa,
52 ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 or ~/.ssh/id_rsa. 49 ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 or ~/.ssh/id_rsa. Additionally, the
53 Additionally, the system administrator may use this to generate host 50 system administrator may use this to generate host keys, as seen in
54 keys, as seen in /etc/rc. 51 /etc/rc.
55 52
56 Normally this program generates the key and asks for a file in which to 53 Normally this program generates the key and asks for a file in which to
57 store the private key. The public key is stored in a file with the same 54 store the private key. The public key is stored in a file with the same
@@ -71,32 +68,33 @@ DESCRIPTION
71 or forgotten, a new key must be generated and the corresponding public 68 or forgotten, a new key must be generated and the corresponding public
72 key copied to other machines. 69 key copied to other machines.
73 70
74 For RSA1 keys and keys stored in the newer OpenSSH format, there is also 71 For keys stored in the newer OpenSSH format, there is also a comment
75 a comment field in the key file that is only for convenience to the user 72 field in the key file that is only for convenience to the user to help
76 to help identify the key. The comment can tell what the key is for, or 73 identify the key. The comment can tell what the key is for, or whatever
77 whatever is useful. The comment is initialized to M-bM-^@M-^\user@hostM-bM-^@M-^] when the 74 is useful. The comment is initialized to M-bM-^@M-^\user@hostM-bM-^@M-^] when the key is
78 key is created, but can be changed using the -c option. 75 created, but can be changed using the -c option.
79 76
80 After a key is generated, instructions below detail where the keys should 77 After a key is generated, instructions below detail where the keys should
81 be placed to be activated. 78 be placed to be activated.
82 79
83 The options are as follows: 80 The options are as follows:
84 81
85 -A For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) for 82 -A For each of the key types (rsa, dsa, ecdsa and ed25519) for which
86 which host keys do not exist, generate the host keys with the 83 host keys do not exist, generate the host keys with the default
87 default key file path, an empty passphrase, default bits for the 84 key file path, an empty passphrase, default bits for the key
88 key type, and default comment. This is used by /etc/rc to 85 type, and default comment. If -f has also been specified, its
89 generate new host keys. 86 argument is used as a prefix to the default path for the
87 resulting host key files. This is used by /etc/rc to generate
88 new host keys.
90 89
91 -a rounds 90 -a rounds
92 When saving a new-format private key (i.e. an ed25519 key or any 91 When saving a new-format private key (i.e. an ed25519 key or when
93 SSH protocol 2 key when the -o flag is set), this option 92 the -o flag is set), this option specifies the number of KDF (key
94 specifies the number of KDF (key derivation function) rounds 93 derivation function) rounds used. Higher numbers result in
95 used. Higher numbers result in slower passphrase verification 94 slower passphrase verification and increased resistance to brute-
96 and increased resistance to brute-force password cracking (should 95 force password cracking (should the keys be stolen).
97 the keys be stolen). 96
98 97 When screening DH-GEX candidates (using the -T command). This
99 When screening DH-GEX candidates ( using the -T command). This
100 option specifies the number of primality tests to perform. 98 option specifies the number of primality tests to perform.
101 99
102 -B Show the bubblebabble digest of specified private or public key 100 -B Show the bubblebabble digest of specified private or public key
@@ -117,10 +115,10 @@ DESCRIPTION
117 Provides a new comment. 115 Provides a new comment.
118 116
119 -c Requests changing the comment in the private and public key 117 -c Requests changing the comment in the private and public key
120 files. This operation is only supported for RSA1 keys and keys 118 files. This operation is only supported for keys stored in the
121 stored in the newer OpenSSH format. The program will prompt for 119 newer OpenSSH format. The program will prompt for the file
122 the file containing the private keys, for the passphrase if the 120 containing the private keys, for the passphrase if the key has
123 key has one, and for the new comment. 121 one, and for the new comment.
124 122
125 -D pkcs11 123 -D pkcs11
126 Download the RSA public keys provided by the PKCS#11 shared 124 Download the RSA public keys provided by the PKCS#11 shared
@@ -200,11 +198,10 @@ DESCRIPTION
200 198
201 -L Prints the contents of one or more certificates. 199 -L Prints the contents of one or more certificates.
202 200
203 -l Show fingerprint of specified public key file. Private RSA1 keys 201 -l Show fingerprint of specified public key file. For RSA and DSA
204 are also supported. For RSA and DSA keys ssh-keygen tries to 202 keys ssh-keygen tries to find the matching public key file and
205 find the matching public key file and prints its fingerprint. If 203 prints its fingerprint. If combined with -v, a visual ASCII art
206 combined with -v, a visual ASCII art representation of the key is 204 representation of the key is supplied with the fingerprint.
207 supplied with the fingerprint.
208 205
209 -M memory 206 -M memory
210 Specify the amount of memory to use (in megabytes) when 207 Specify the amount of memory to use (in megabytes) when
@@ -228,14 +225,29 @@ DESCRIPTION
228 225
229 -O option 226 -O option
230 Specify a certificate option when signing a key. This option may 227 Specify a certificate option when signing a key. This option may
231 be specified multiple times. Please see the CERTIFICATES section 228 be specified multiple times. See also the CERTIFICATES section
232 for details. The options that are valid for user certificates 229 for further details. The options that are valid for user
233 are: 230 certificates are:
234 231
235 clear Clear all enabled permissions. This is useful for 232 clear Clear all enabled permissions. This is useful for
236 clearing the default set of permissions so permissions 233 clearing the default set of permissions so permissions
237 may be added individually. 234 may be added individually.
238 235
236 critical:name[=contents]
237 extension:name[=contents]
238 Includes an arbitrary certificate critical option or
239 extension. The specified name should include a domain
240 suffix, e.g. M-bM-^@M-^\name@example.comM-bM-^@M-^]. If contents is
241 specified then it is included as the contents of the
242 extension/option encoded as a string, otherwise the
243 extension/option is created with no contents (usually
244 indicating a flag). Extensions may be ignored by a
245 client or server that does not recognise them, whereas
246 unknown critical options will cause the certificate to be
247 refused.
248
249 At present, no standard options are valid for host keys.
250
239 force-command=command 251 force-command=command
240 Forces the execution of command instead of any shell or 252 Forces the execution of command instead of any shell or
241 command specified by the user when the certificate is 253 command specified by the user when the certificate is
@@ -277,8 +289,6 @@ DESCRIPTION
277 separated list of one or more address/netmask pairs in 289 separated list of one or more address/netmask pairs in
278 CIDR format. 290 CIDR format.
279 291
280 At present, no options are valid for host keys.
281
282 -o Causes ssh-keygen to save private keys using the new OpenSSH 292 -o Causes ssh-keygen to save private keys using the new OpenSSH
283 format rather than the more compatible PEM format. The new 293 format rather than the more compatible PEM format. The new
284 format has increased resistance to brute-force password cracking 294 format has increased resistance to brute-force password cracking
@@ -322,10 +332,13 @@ DESCRIPTION
322 Test DH group exchange candidate primes (generated using the -G 332 Test DH group exchange candidate primes (generated using the -G
323 option) for safety. 333 option) for safety.
324 334
325 -t dsa | ecdsa | ed25519 | rsa | rsa1 335 -t dsa | ecdsa | ed25519 | rsa
326 Specifies the type of key to create. The possible values are 336 Specifies the type of key to create. The possible values are
327 M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or 337 M-bM-^@M-^\dsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or M-bM-^@M-^\rsaM-bM-^@M-^].
328 M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2. 338
339 -U When used in combination with -s, this option indicates that a CA
340 key resides in a ssh-agent(1). See the CERTIFICATES section for
341 more information.
329 342
330 -u Update a KRL. When specified with -k, keys listed via the 343 -u Update a KRL. When specified with -k, keys listed via the
331 command line are added to the existing KRL rather than a new KRL 344 command line are added to the existing KRL rather than a new KRL
@@ -432,6 +445,12 @@ CERTIFICATES
432 445
433 $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub 446 $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub
434 447
448 Similarly, it is possible for the CA key to be hosted in a ssh-agent(1).
449 This is indicated by the -U flag and, again, the CA key must be
450 identified by its public half.
451
452 $ ssh-keygen -Us ca_key.pub -I key_id user_key.pub
453
435 In all cases, key_id is a "key identifier" that is logged by the server 454 In all cases, key_id is a "key identifier" that is logged by the server
436 when the certificate is used for authentication. 455 when the certificate is used for authentication.
437 456
@@ -512,44 +531,28 @@ KEY REVOCATION LISTS
512 was revoked. 531 was revoked.
513 532
514FILES 533FILES
515 ~/.ssh/identity
516 Contains the protocol version 1 RSA authentication identity of
517 the user. This file should not be readable by anyone but the
518 user. It is possible to specify a passphrase when generating the
519 key; that passphrase will be used to encrypt the private part of
520 this file using 3DES. This file is not automatically accessed by
521 ssh-keygen but it is offered as the default file for the private
522 key. ssh(1) will read this file when a login attempt is made.
523
524 ~/.ssh/identity.pub
525 Contains the protocol version 1 RSA public key for
526 authentication. The contents of this file should be added to
527 ~/.ssh/authorized_keys on all machines where the user wishes to
528 log in using RSA authentication. There is no need to keep the
529 contents of this file secret.
530
531 ~/.ssh/id_dsa 534 ~/.ssh/id_dsa
532 ~/.ssh/id_ecdsa 535 ~/.ssh/id_ecdsa
533 ~/.ssh/id_ed25519 536 ~/.ssh/id_ed25519
534 ~/.ssh/id_rsa 537 ~/.ssh/id_rsa
535 Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA 538 Contains the DSA, ECDSA, Ed25519 or RSA authentication identity
536 authentication identity of the user. This file should not be 539 of the user. This file should not be readable by anyone but the
537 readable by anyone but the user. It is possible to specify a 540 user. It is possible to specify a passphrase when generating the
538 passphrase when generating the key; that passphrase will be used 541 key; that passphrase will be used to encrypt the private part of
539 to encrypt the private part of this file using 128-bit AES. This 542 this file using 128-bit AES. This file is not automatically
540 file is not automatically accessed by ssh-keygen but it is 543 accessed by ssh-keygen but it is offered as the default file for
541 offered as the default file for the private key. ssh(1) will 544 the private key. ssh(1) will read this file when a login attempt
542 read this file when a login attempt is made. 545 is made.
543 546
544 ~/.ssh/id_dsa.pub 547 ~/.ssh/id_dsa.pub
545 ~/.ssh/id_ecdsa.pub 548 ~/.ssh/id_ecdsa.pub
546 ~/.ssh/id_ed25519.pub 549 ~/.ssh/id_ed25519.pub
547 ~/.ssh/id_rsa.pub 550 ~/.ssh/id_rsa.pub
548 Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA public 551 Contains the DSA, ECDSA, Ed25519 or RSA public key for
549 key for authentication. The contents of this file should be 552 authentication. The contents of this file should be added to
550 added to ~/.ssh/authorized_keys on all machines where the user 553 ~/.ssh/authorized_keys on all machines where the user wishes to
551 wishes to log in using public key authentication. There is no 554 log in using public key authentication. There is no need to keep
552 need to keep the contents of this file secret. 555 the contents of this file secret.
553 556
554 /etc/moduli 557 /etc/moduli
555 Contains Diffie-Hellman groups used for DH-GEX. The file format 558 Contains Diffie-Hellman groups used for DH-GEX. The file format
@@ -567,4 +570,4 @@ AUTHORS
567 created OpenSSH. Markus Friedl contributed the support for SSH protocol 570 created OpenSSH. Markus Friedl contributed the support for SSH protocol
568 versions 1.5 and 2.0. 571 versions 1.5 and 2.0.
569 572
570OpenBSD 6.0 June 16, 2016 OpenBSD 6.0 573OpenBSD 6.2 July 8, 2017 OpenBSD 6.2
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index ce2213c78..5f1ec09b0 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keygen.1,v 1.133 2016/06/16 06:10:45 jmc Exp $ 1.\" $OpenBSD: ssh-keygen.1,v 1.144 2017/07/08 18:32:54 jmc Exp $
2.\" 2.\"
3.\" Author: Tatu Ylonen <ylo@cs.hut.fi> 3.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,7 +35,7 @@
35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37.\" 37.\"
38.Dd $Mdocdate: June 16 2016 $ 38.Dd $Mdocdate: July 8 2017 $
39.Dt SSH-KEYGEN 1 39.Dt SSH-KEYGEN 1
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -46,7 +46,7 @@
46.Nm ssh-keygen 46.Nm ssh-keygen
47.Op Fl q 47.Op Fl q
48.Op Fl b Ar bits 48.Op Fl b Ar bits
49.Op Fl t Cm dsa | ecdsa | ed25519 | rsa | rsa1 49.Op Fl t Cm dsa | ecdsa | ed25519 | rsa
50.Op Fl N Ar new_passphrase 50.Op Fl N Ar new_passphrase
51.Op Fl C Ar comment 51.Op Fl C Ar comment
52.Op Fl f Ar output_keyfile 52.Op Fl f Ar output_keyfile
@@ -114,6 +114,8 @@
114.Fl s Ar ca_key 114.Fl s Ar ca_key
115.Fl I Ar certificate_identity 115.Fl I Ar certificate_identity
116.Op Fl h 116.Op Fl h
117.Op Fl U
118.Op Fl D Ar pkcs11_provider
117.Op Fl n Ar principals 119.Op Fl n Ar principals
118.Op Fl O Ar option 120.Op Fl O Ar option
119.Op Fl V Ar validity_interval 121.Op Fl V Ar validity_interval
@@ -124,6 +126,7 @@
124.Op Fl f Ar input_keyfile 126.Op Fl f Ar input_keyfile
125.Nm ssh-keygen 127.Nm ssh-keygen
126.Fl A 128.Fl A
129.Op Fl f Ar prefix_path
127.Nm ssh-keygen 130.Nm ssh-keygen
128.Fl k 131.Fl k
129.Fl f Ar krl_file 132.Fl f Ar krl_file
@@ -141,18 +144,14 @@
141generates, manages and converts authentication keys for 144generates, manages and converts authentication keys for
142.Xr ssh 1 . 145.Xr ssh 1 .
143.Nm 146.Nm
144can create keys for use by SSH protocol versions 1 and 2. 147can create keys for use by SSH protocol version 2.
145Protocol 1 should not be used
146and is only offered to support legacy devices.
147It suffers from a number of cryptographic weaknesses
148and doesn't support many of the advanced features available for protocol 2.
149.Pp 148.Pp
150The type of key to be generated is specified with the 149The type of key to be generated is specified with the
151.Fl t 150.Fl t
152option. 151option.
153If invoked without any arguments, 152If invoked without any arguments,
154.Nm 153.Nm
155will generate an RSA key for use in SSH protocol 2 connections. 154will generate an RSA key.
156.Pp 155.Pp
157.Nm 156.Nm
158is also used to generate groups for use in Diffie-Hellman group 157is also used to generate groups for use in Diffie-Hellman group
@@ -172,7 +171,6 @@ section for details.
172Normally each user wishing to use SSH 171Normally each user wishing to use SSH
173with public key authentication runs this once to create the authentication 172with public key authentication runs this once to create the authentication
174key in 173key in
175.Pa ~/.ssh/identity ,
176.Pa ~/.ssh/id_dsa , 174.Pa ~/.ssh/id_dsa ,
177.Pa ~/.ssh/id_ecdsa , 175.Pa ~/.ssh/id_ecdsa ,
178.Pa ~/.ssh/id_ed25519 176.Pa ~/.ssh/id_ed25519
@@ -207,7 +205,7 @@ There is no way to recover a lost passphrase.
207If the passphrase is lost or forgotten, a new key must be generated 205If the passphrase is lost or forgotten, a new key must be generated
208and the corresponding public key copied to other machines. 206and the corresponding public key copied to other machines.
209.Pp 207.Pp
210For RSA1 keys and keys stored in the newer OpenSSH format, 208For keys stored in the newer OpenSSH format,
211there is also a comment field in the key file that is only for 209there is also a comment field in the key file that is only for
212convenience to the user to help identify the key. 210convenience to the user to help identify the key.
213The comment can tell what the key is for, or whatever is useful. 211The comment can tell what the key is for, or whatever is useful.
@@ -223,24 +221,26 @@ should be placed to be activated.
223The options are as follows: 221The options are as follows:
224.Bl -tag -width Ds 222.Bl -tag -width Ds
225.It Fl A 223.It Fl A
226For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) 224For each of the key types (rsa, dsa, ecdsa and ed25519)
227for which host keys 225for which host keys
228do not exist, generate the host keys with the default key file path, 226do not exist, generate the host keys with the default key file path,
229an empty passphrase, default bits for the key type, and default comment. 227an empty passphrase, default bits for the key type, and default comment.
228If
229.Fl f
230has also been specified, its argument is used as a prefix to the
231default path for the resulting host key files.
230This is used by 232This is used by
231.Pa /etc/rc 233.Pa /etc/rc
232to generate new host keys. 234to generate new host keys.
233.It Fl a Ar rounds 235.It Fl a Ar rounds
234When saving a new-format private key (i.e. an ed25519 key or any SSH protocol 236When saving a new-format private key (i.e. an ed25519 key or when the
2352 key when the
236.Fl o 237.Fl o
237flag is set), this option specifies the number of KDF (key derivation function) 238flag is set), this option specifies the number of KDF (key derivation function)
238rounds used. 239rounds used.
239Higher numbers result in slower passphrase verification and increased 240Higher numbers result in slower passphrase verification and increased
240resistance to brute-force password cracking (should the keys be stolen). 241resistance to brute-force password cracking (should the keys be stolen).
241.Pp 242.Pp
242When screening DH-GEX candidates ( 243When screening DH-GEX candidates (using the
243using the
244.Fl T 244.Fl T
245command). 245command).
246This option specifies the number of primality tests to perform. 246This option specifies the number of primality tests to perform.
@@ -264,7 +264,7 @@ flag will be ignored.
264Provides a new comment. 264Provides a new comment.
265.It Fl c 265.It Fl c
266Requests changing the comment in the private and public key files. 266Requests changing the comment in the private and public key files.
267This operation is only supported for RSA1 keys and keys stored in the 267This operation is only supported for keys stored in the
268newer OpenSSH format. 268newer OpenSSH format.
269The program will prompt for the file containing the private keys, for 269The program will prompt for the file containing the private keys, for
270the passphrase if the key has one, and for the new comment. 270the passphrase if the key has one, and for the new comment.
@@ -384,7 +384,6 @@ section.
384Prints the contents of one or more certificates. 384Prints the contents of one or more certificates.
385.It Fl l 385.It Fl l
386Show fingerprint of specified public key file. 386Show fingerprint of specified public key file.
387Private RSA1 keys are also supported.
388For RSA and DSA keys 387For RSA and DSA keys
389.Nm 388.Nm
390tries to find the matching public key file and prints its fingerprint. 389tries to find the matching public key file and prints its fingerprint.
@@ -423,51 +422,81 @@ section for details.
423.It Fl O Ar option 422.It Fl O Ar option
424Specify a certificate option when signing a key. 423Specify a certificate option when signing a key.
425This option may be specified multiple times. 424This option may be specified multiple times.
426Please see the 425See also the
427.Sx CERTIFICATES 426.Sx CERTIFICATES
428section for details. 427section for further details.
429The options that are valid for user certificates are: 428The options that are valid for user certificates are:
430.Bl -tag -width Ds 429.Pp
430.Bl -tag -width Ds -compact
431.It Ic clear 431.It Ic clear
432Clear all enabled permissions. 432Clear all enabled permissions.
433This is useful for clearing the default set of permissions so permissions may 433This is useful for clearing the default set of permissions so permissions may
434be added individually. 434be added individually.
435.Pp
436.It Ic critical : Ns Ar name Ns Op Ns = Ns Ar contents
437.It Ic extension : Ns Ar name Ns Op Ns = Ns Ar contents
438Includes an arbitrary certificate critical option or extension.
439The specified
440.Ar name
441should include a domain suffix, e.g.\&
442.Dq name@example.com .
443If
444.Ar contents
445is specified then it is included as the contents of the extension/option
446encoded as a string, otherwise the extension/option is created with no
447contents (usually indicating a flag).
448Extensions may be ignored by a client or server that does not recognise them,
449whereas unknown critical options will cause the certificate to be refused.
450.Pp
451At present, no standard options are valid for host keys.
452.Pp
435.It Ic force-command Ns = Ns Ar command 453.It Ic force-command Ns = Ns Ar command
436Forces the execution of 454Forces the execution of
437.Ar command 455.Ar command
438instead of any shell or command specified by the user when 456instead of any shell or command specified by the user when
439the certificate is used for authentication. 457the certificate is used for authentication.
458.Pp
440.It Ic no-agent-forwarding 459.It Ic no-agent-forwarding
441Disable 460Disable
442.Xr ssh-agent 1 461.Xr ssh-agent 1
443forwarding (permitted by default). 462forwarding (permitted by default).
463.Pp
444.It Ic no-port-forwarding 464.It Ic no-port-forwarding
445Disable port forwarding (permitted by default). 465Disable port forwarding (permitted by default).
466.Pp
446.It Ic no-pty 467.It Ic no-pty
447Disable PTY allocation (permitted by default). 468Disable PTY allocation (permitted by default).
469.Pp
448.It Ic no-user-rc 470.It Ic no-user-rc
449Disable execution of 471Disable execution of
450.Pa ~/.ssh/rc 472.Pa ~/.ssh/rc
451by 473by
452.Xr sshd 8 474.Xr sshd 8
453(permitted by default). 475(permitted by default).
476.Pp
454.It Ic no-x11-forwarding 477.It Ic no-x11-forwarding
455Disable X11 forwarding (permitted by default). 478Disable X11 forwarding (permitted by default).
479.Pp
456.It Ic permit-agent-forwarding 480.It Ic permit-agent-forwarding
457Allows 481Allows
458.Xr ssh-agent 1 482.Xr ssh-agent 1
459forwarding. 483forwarding.
484.Pp
460.It Ic permit-port-forwarding 485.It Ic permit-port-forwarding
461Allows port forwarding. 486Allows port forwarding.
487.Pp
462.It Ic permit-pty 488.It Ic permit-pty
463Allows PTY allocation. 489Allows PTY allocation.
490.Pp
464.It Ic permit-user-rc 491.It Ic permit-user-rc
465Allows execution of 492Allows execution of
466.Pa ~/.ssh/rc 493.Pa ~/.ssh/rc
467by 494by
468.Xr sshd 8 . 495.Xr sshd 8 .
496.Pp
469.It Ic permit-x11-forwarding 497.It Ic permit-x11-forwarding
470Allows X11 forwarding. 498Allows X11 forwarding.
499.Pp
471.It Ic source-address Ns = Ns Ar address_list 500.It Ic source-address Ns = Ns Ar address_list
472Restrict the source addresses from which the certificate is considered valid. 501Restrict the source addresses from which the certificate is considered valid.
473The 502The
@@ -475,8 +504,6 @@ The
475is a comma-separated list of one or more address/netmask pairs in CIDR 504is a comma-separated list of one or more address/netmask pairs in CIDR
476format. 505format.
477.El 506.El
478.Pp
479At present, no options are valid for host keys.
480.It Fl o 507.It Fl o
481Causes 508Causes
482.Nm 509.Nm
@@ -530,17 +557,22 @@ section for details.
530Test DH group exchange candidate primes (generated using the 557Test DH group exchange candidate primes (generated using the
531.Fl G 558.Fl G
532option) for safety. 559option) for safety.
533.It Fl t Cm dsa | ecdsa | ed25519 | rsa | rsa1 560.It Fl t Cm dsa | ecdsa | ed25519 | rsa
534Specifies the type of key to create. 561Specifies the type of key to create.
535The possible values are 562The possible values are
536.Dq rsa1
537for protocol version 1 and
538.Dq dsa , 563.Dq dsa ,
539.Dq ecdsa , 564.Dq ecdsa ,
540.Dq ed25519 , 565.Dq ed25519 ,
541or 566or
542.Dq rsa 567.Dq rsa .
543for protocol version 2. 568.It Fl U
569When used in combination with
570.Fl s ,
571this option indicates that a CA key resides in a
572.Xr ssh-agent 1 .
573See the
574.Sx CERTIFICATES
575section for more information.
544.It Fl u 576.It Fl u
545Update a KRL. 577Update a KRL.
546When specified with 578When specified with
@@ -688,6 +720,14 @@ to
688.Pp 720.Pp
689.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub 721.Dl $ ssh-keygen -s ca_key.pub -D libpkcs11.so -I key_id user_key.pub
690.Pp 722.Pp
723Similarly, it is possible for the CA key to be hosted in a
724.Xr ssh-agent 1 .
725This is indicated by the
726.Fl U
727flag and, again, the CA key must be identified by its public half.
728.Pp
729.Dl $ ssh-keygen -Us ca_key.pub -I key_id user_key.pub
730.Pp
691In all cases, 731In all cases,
692.Ar key_id 732.Ar key_id
693is a "key identifier" that is logged by the server when the certificate 733is a "key identifier" that is logged by the server when the certificate
@@ -795,31 +835,11 @@ will exit with a non-zero exit status.
795A zero exit status will only be returned if no key was revoked. 835A zero exit status will only be returned if no key was revoked.
796.Sh FILES 836.Sh FILES
797.Bl -tag -width Ds -compact 837.Bl -tag -width Ds -compact
798.It Pa ~/.ssh/identity
799Contains the protocol version 1 RSA authentication identity of the user.
800This file should not be readable by anyone but the user.
801It is possible to
802specify a passphrase when generating the key; that passphrase will be
803used to encrypt the private part of this file using 3DES.
804This file is not automatically accessed by
805.Nm
806but it is offered as the default file for the private key.
807.Xr ssh 1
808will read this file when a login attempt is made.
809.Pp
810.It Pa ~/.ssh/identity.pub
811Contains the protocol version 1 RSA public key for authentication.
812The contents of this file should be added to
813.Pa ~/.ssh/authorized_keys
814on all machines
815where the user wishes to log in using RSA authentication.
816There is no need to keep the contents of this file secret.
817.Pp
818.It Pa ~/.ssh/id_dsa 838.It Pa ~/.ssh/id_dsa
819.It Pa ~/.ssh/id_ecdsa 839.It Pa ~/.ssh/id_ecdsa
820.It Pa ~/.ssh/id_ed25519 840.It Pa ~/.ssh/id_ed25519
821.It Pa ~/.ssh/id_rsa 841.It Pa ~/.ssh/id_rsa
822Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA 842Contains the DSA, ECDSA, Ed25519 or RSA
823authentication identity of the user. 843authentication identity of the user.
824This file should not be readable by anyone but the user. 844This file should not be readable by anyone but the user.
825It is possible to 845It is possible to
@@ -835,7 +855,7 @@ will read this file when a login attempt is made.
835.It Pa ~/.ssh/id_ecdsa.pub 855.It Pa ~/.ssh/id_ecdsa.pub
836.It Pa ~/.ssh/id_ed25519.pub 856.It Pa ~/.ssh/id_ed25519.pub
837.It Pa ~/.ssh/id_rsa.pub 857.It Pa ~/.ssh/id_rsa.pub
838Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA 858Contains the DSA, ECDSA, Ed25519 or RSA
839public key for authentication. 859public key for authentication.
840The contents of this file should be added to 860The contents of this file should be added to
841.Pa ~/.ssh/authorized_keys 861.Pa ~/.ssh/authorized_keys
diff --git a/ssh-keygen.c b/ssh-keygen.c
index f17af036b..835f7d016 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.299 2017/03/10 04:26:06 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.307 2017/07/07 03:53:12 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -41,7 +41,6 @@
41 41
42#include "xmalloc.h" 42#include "xmalloc.h"
43#include "sshkey.h" 43#include "sshkey.h"
44#include "rsa.h"
45#include "authfile.h" 44#include "authfile.h"
46#include "uuencode.h" 45#include "uuencode.h"
47#include "sshbuf.h" 46#include "sshbuf.h"
@@ -59,6 +58,7 @@
59#include "krl.h" 58#include "krl.h"
60#include "digest.h" 59#include "digest.h"
61#include "utf8.h" 60#include "utf8.h"
61#include "authfd.h"
62 62
63#ifdef WITH_OPENSSL 63#ifdef WITH_OPENSSL
64# define DEFAULT_KEY_TYPE_NAME "rsa" 64# define DEFAULT_KEY_TYPE_NAME "rsa"
@@ -121,6 +121,9 @@ char *identity_comment = NULL;
121/* Path to CA key when certifying keys. */ 121/* Path to CA key when certifying keys. */
122char *ca_key_path = NULL; 122char *ca_key_path = NULL;
123 123
124/* Prefer to use agent keys for CA signing */
125int prefer_agent = 0;
126
124/* Certificate serial number */ 127/* Certificate serial number */
125unsigned long long cert_serial = 0; 128unsigned long long cert_serial = 0;
126 129
@@ -149,6 +152,15 @@ u_int32_t certflags_flags = CERTOPT_DEFAULT;
149char *certflags_command = NULL; 152char *certflags_command = NULL;
150char *certflags_src_addr = NULL; 153char *certflags_src_addr = NULL;
151 154
155/* Arbitrary extensions specified by user */
156struct cert_userext {
157 char *key;
158 char *val;
159 int crit;
160};
161struct cert_userext *cert_userext;
162size_t ncert_userext;
163
152/* Conversion to/from various formats */ 164/* Conversion to/from various formats */
153int convert_to = 0; 165int convert_to = 0;
154int convert_from = 0; 166int convert_from = 0;
@@ -217,13 +229,21 @@ type_bits_valid(int type, const char *name, u_int32_t *bitsp)
217 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; 229 OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
218 if (*bitsp > maxbits) 230 if (*bitsp > maxbits)
219 fatal("key bits exceeds maximum %d", maxbits); 231 fatal("key bits exceeds maximum %d", maxbits);
220 if (type == KEY_DSA && *bitsp != 1024) 232 switch (type) {
221 fatal("DSA keys must be 1024 bits"); 233 case KEY_DSA:
222 else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 1024) 234 if (*bitsp != 1024)
223 fatal("Key must at least be 1024 bits"); 235 fatal("Invalid DSA key length: must be 1024 bits");
224 else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1) 236 break;
225 fatal("Invalid ECDSA key length - valid lengths are " 237 case KEY_RSA:
226 "256, 384 or 521 bits"); 238 if (*bitsp < SSH_RSA_MINIMUM_MODULUS_SIZE)
239 fatal("Invalid RSA key length: minimum is %d bits",
240 SSH_RSA_MINIMUM_MODULUS_SIZE);
241 break;
242 case KEY_ECDSA:
243 if (sshkey_ecdsa_bits_to_nid(*bitsp) == -1)
244 fatal("Invalid ECDSA key length: valid lengths are "
245 "256, 384 or 521 bits");
246 }
227#endif 247#endif
228} 248}
229 249
@@ -237,9 +257,6 @@ ask_filename(struct passwd *pw, const char *prompt)
237 name = _PATH_SSH_CLIENT_ID_RSA; 257 name = _PATH_SSH_CLIENT_ID_RSA;
238 else { 258 else {
239 switch (sshkey_type_from_name(key_type_name)) { 259 switch (sshkey_type_from_name(key_type_name)) {
240 case KEY_RSA1:
241 name = _PATH_SSH_CLIENT_IDENTITY;
242 break;
243 case KEY_DSA_CERT: 260 case KEY_DSA_CERT:
244 case KEY_DSA: 261 case KEY_DSA:
245 name = _PATH_SSH_CLIENT_ID_DSA; 262 name = _PATH_SSH_CLIENT_ID_DSA;
@@ -311,8 +328,6 @@ do_convert_to_ssh2(struct passwd *pw, struct sshkey *k)
311 char comment[61]; 328 char comment[61];
312 int r; 329 int r;
313 330
314 if (k->type == KEY_RSA1)
315 fatal("version 1 keys are not supported");
316 if ((r = sshkey_to_blob(k, &blob, &len)) != 0) 331 if ((r = sshkey_to_blob(k, &blob, &len)) != 0)
317 fatal("key_to_blob failed: %s", ssh_err(r)); 332 fatal("key_to_blob failed: %s", ssh_err(r));
318 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ 333 /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */
@@ -334,7 +349,6 @@ static void
334do_convert_to_pkcs8(struct sshkey *k) 349do_convert_to_pkcs8(struct sshkey *k)
335{ 350{
336 switch (sshkey_type_plain(k->type)) { 351 switch (sshkey_type_plain(k->type)) {
337 case KEY_RSA1:
338 case KEY_RSA: 352 case KEY_RSA:
339 if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) 353 if (!PEM_write_RSA_PUBKEY(stdout, k->rsa))
340 fatal("PEM_write_RSA_PUBKEY failed"); 354 fatal("PEM_write_RSA_PUBKEY failed");
@@ -359,7 +373,6 @@ static void
359do_convert_to_pem(struct sshkey *k) 373do_convert_to_pem(struct sshkey *k)
360{ 374{
361 switch (sshkey_type_plain(k->type)) { 375 switch (sshkey_type_plain(k->type)) {
362 case KEY_RSA1:
363 case KEY_RSA: 376 case KEY_RSA:
364 if (!PEM_write_RSAPublicKey(stdout, k->rsa)) 377 if (!PEM_write_RSAPublicKey(stdout, k->rsa))
365 fatal("PEM_write_RSAPublicKey failed"); 378 fatal("PEM_write_RSAPublicKey failed");
@@ -478,7 +491,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
478 return NULL; 491 return NULL;
479 } 492 }
480 if ((key = sshkey_new_private(ktype)) == NULL) 493 if ((key = sshkey_new_private(ktype)) == NULL)
481 fatal("key_new_private failed"); 494 fatal("sshkey_new_private failed");
482 free(type); 495 free(type);
483 496
484 switch (key->type) { 497 switch (key->type) {
@@ -514,7 +527,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
514 buffer_get_bignum_bits(b, key->rsa->iqmp); 527 buffer_get_bignum_bits(b, key->rsa->iqmp);
515 buffer_get_bignum_bits(b, key->rsa->q); 528 buffer_get_bignum_bits(b, key->rsa->q);
516 buffer_get_bignum_bits(b, key->rsa->p); 529 buffer_get_bignum_bits(b, key->rsa->p);
517 if ((r = rsa_generate_additional_parameters(key->rsa)) != 0) 530 if ((r = ssh_rsa_generate_additional_parameters(key)) != 0)
518 fatal("generate RSA parameters failed: %s", ssh_err(r)); 531 fatal("generate RSA parameters failed: %s", ssh_err(r));
519 break; 532 break;
520 } 533 }
@@ -760,7 +773,7 @@ do_print_public(struct passwd *pw)
760 fatal("%s: %s", identity_file, strerror(errno)); 773 fatal("%s: %s", identity_file, strerror(errno));
761 prv = load_identity(identity_file); 774 prv = load_identity(identity_file);
762 if ((r = sshkey_write(prv, stdout)) != 0) 775 if ((r = sshkey_write(prv, stdout)) != 0)
763 error("key_write failed: %s", ssh_err(r)); 776 error("sshkey_write failed: %s", ssh_err(r));
764 sshkey_free(prv); 777 sshkey_free(prv);
765 fprintf(stdout, "\n"); 778 fprintf(stdout, "\n");
766 exit(0); 779 exit(0);
@@ -816,13 +829,6 @@ try_read_key(char **cpp)
816 struct sshkey *ret; 829 struct sshkey *ret;
817 int r; 830 int r;
818 831
819 if ((ret = sshkey_new(KEY_RSA1)) == NULL)
820 fatal("sshkey_new failed");
821 /* Try RSA1 */
822 if ((r = sshkey_read(ret, cpp)) == 0)
823 return ret;
824 /* Try modern */
825 sshkey_free(ret);
826 if ((ret = sshkey_new(KEY_UNSPEC)) == NULL) 832 if ((ret = sshkey_new(KEY_UNSPEC)) == NULL)
827 fatal("sshkey_new failed"); 833 fatal("sshkey_new failed");
828 if ((r = sshkey_read(ret, cpp)) == 0) 834 if ((r = sshkey_read(ret, cpp)) == 0)
@@ -978,9 +984,6 @@ do_gen_all_hostkeys(struct passwd *pw)
978 char *path; 984 char *path;
979 } key_types[] = { 985 } key_types[] = {
980#ifdef WITH_OPENSSL 986#ifdef WITH_OPENSSL
981#ifdef WITH_SSH1
982 { "rsa1", "RSA1", _PATH_HOST_KEY_FILE },
983#endif /* WITH_SSH1 */
984 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE }, 987 { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
985 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE }, 988 { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE },
986#ifdef OPENSSL_HAS_ECC 989#ifdef OPENSSL_HAS_ECC
@@ -994,20 +997,38 @@ do_gen_all_hostkeys(struct passwd *pw)
994 int first = 0; 997 int first = 0;
995 struct stat st; 998 struct stat st;
996 struct sshkey *private, *public; 999 struct sshkey *private, *public;
997 char comment[1024]; 1000 char comment[1024], *prv_tmp, *pub_tmp, *prv_file, *pub_file;
998 int i, type, fd, r; 1001 int i, type, fd, r;
999 FILE *f; 1002 FILE *f;
1000 1003
1001 for (i = 0; key_types[i].key_type; i++) { 1004 for (i = 0; key_types[i].key_type; i++) {
1002 if (stat(key_types[i].path, &st) == 0) 1005 public = private = NULL;
1003 continue; 1006 prv_tmp = pub_tmp = prv_file = pub_file = NULL;
1004 if (errno != ENOENT) { 1007
1008 xasprintf(&prv_file, "%s%s",
1009 identity_file, key_types[i].path);
1010
1011 /* Check whether private key exists and is not zero-length */
1012 if (stat(prv_file, &st) == 0) {
1013 if (st.st_size != 0)
1014 goto next;
1015 } else if (errno != ENOENT) {
1005 error("Could not stat %s: %s", key_types[i].path, 1016 error("Could not stat %s: %s", key_types[i].path,
1006 strerror(errno)); 1017 strerror(errno));
1007 first = 0; 1018 goto failnext;
1008 continue;
1009 } 1019 }
1010 1020
1021 /*
1022 * Private key doesn't exist or is invalid; proceed with
1023 * key generation.
1024 */
1025 xasprintf(&prv_tmp, "%s%s.XXXXXXXXXX",
1026 identity_file, key_types[i].path);
1027 xasprintf(&pub_tmp, "%s%s.pub.XXXXXXXXXX",
1028 identity_file, key_types[i].path);
1029 xasprintf(&pub_file, "%s%s.pub",
1030 identity_file, key_types[i].path);
1031
1011 if (first == 0) { 1032 if (first == 0) {
1012 first = 1; 1033 first = 1;
1013 printf("%s: generating new host keys: ", __progname); 1034 printf("%s: generating new host keys: ", __progname);
@@ -1015,56 +1036,76 @@ do_gen_all_hostkeys(struct passwd *pw)
1015 printf("%s ", key_types[i].key_type_display); 1036 printf("%s ", key_types[i].key_type_display);
1016 fflush(stdout); 1037 fflush(stdout);
1017 type = sshkey_type_from_name(key_types[i].key_type); 1038 type = sshkey_type_from_name(key_types[i].key_type);
1018 strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); 1039 if ((fd = mkstemp(prv_tmp)) == -1) {
1040 error("Could not save your public key in %s: %s",
1041 prv_tmp, strerror(errno));
1042 goto failnext;
1043 }
1044 close(fd); /* just using mkstemp() to generate/reserve a name */
1019 bits = 0; 1045 bits = 0;
1020 type_bits_valid(type, NULL, &bits); 1046 type_bits_valid(type, NULL, &bits);
1021 if ((r = sshkey_generate(type, bits, &private)) != 0) { 1047 if ((r = sshkey_generate(type, bits, &private)) != 0) {
1022 error("key_generate failed: %s", ssh_err(r)); 1048 error("sshkey_generate failed: %s", ssh_err(r));
1023 first = 0; 1049 goto failnext;
1024 continue;
1025 } 1050 }
1026 if ((r = sshkey_from_private(private, &public)) != 0) 1051 if ((r = sshkey_from_private(private, &public)) != 0)
1027 fatal("sshkey_from_private failed: %s", ssh_err(r)); 1052 fatal("sshkey_from_private failed: %s", ssh_err(r));
1028 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, 1053 snprintf(comment, sizeof comment, "%s@%s", pw->pw_name,
1029 hostname); 1054 hostname);
1030 if ((r = sshkey_save_private(private, identity_file, "", 1055 if ((r = sshkey_save_private(private, prv_tmp, "",
1031 comment, use_new_format, new_format_cipher, rounds)) != 0) { 1056 comment, use_new_format, new_format_cipher, rounds)) != 0) {
1032 error("Saving key \"%s\" failed: %s", 1057 error("Saving key \"%s\" failed: %s",
1033 identity_file, ssh_err(r)); 1058 prv_tmp, ssh_err(r));
1034 sshkey_free(private); 1059 goto failnext;
1035 sshkey_free(public);
1036 first = 0;
1037 continue;
1038 } 1060 }
1039 sshkey_free(private); 1061 if ((fd = mkstemp(pub_tmp)) == -1) {
1040 strlcat(identity_file, ".pub", sizeof(identity_file)); 1062 error("Could not save your public key in %s: %s",
1041 fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); 1063 pub_tmp, strerror(errno));
1042 if (fd == -1) { 1064 goto failnext;
1043 error("Could not save your public key in %s",
1044 identity_file);
1045 sshkey_free(public);
1046 first = 0;
1047 continue;
1048 } 1065 }
1066 (void)fchmod(fd, 0644);
1049 f = fdopen(fd, "w"); 1067 f = fdopen(fd, "w");
1050 if (f == NULL) { 1068 if (f == NULL) {
1051 error("fdopen %s failed", identity_file); 1069 error("fdopen %s failed: %s", pub_tmp, strerror(errno));
1052 close(fd); 1070 close(fd);
1053 sshkey_free(public); 1071 goto failnext;
1054 first = 0;
1055 continue;
1056 } 1072 }
1057 if ((r = sshkey_write(public, f)) != 0) { 1073 if ((r = sshkey_write(public, f)) != 0) {
1058 error("write key failed: %s", ssh_err(r)); 1074 error("write key failed: %s", ssh_err(r));
1059 fclose(f); 1075 fclose(f);
1060 sshkey_free(public); 1076 goto failnext;
1061 first = 0;
1062 continue;
1063 } 1077 }
1064 fprintf(f, " %s\n", comment); 1078 fprintf(f, " %s\n", comment);
1065 fclose(f); 1079 if (ferror(f) != 0) {
1066 sshkey_free(public); 1080 error("write key failed: %s", strerror(errno));
1081 fclose(f);
1082 goto failnext;
1083 }
1084 if (fclose(f) != 0) {
1085 error("key close failed: %s", strerror(errno));
1086 goto failnext;
1087 }
1067 1088
1089 /* Rename temporary files to their permanent locations. */
1090 if (rename(pub_tmp, pub_file) != 0) {
1091 error("Unable to move %s into position: %s",
1092 pub_file, strerror(errno));
1093 goto failnext;
1094 }
1095 if (rename(prv_tmp, prv_file) != 0) {
1096 error("Unable to move %s into position: %s",
1097 key_types[i].path, strerror(errno));
1098 failnext:
1099 first = 0;
1100 goto next;
1101 }
1102 next:
1103 sshkey_free(private);
1104 sshkey_free(public);
1105 free(prv_tmp);
1106 free(pub_tmp);
1107 free(prv_file);
1108 free(pub_file);
1068 } 1109 }
1069 if (first != 0) 1110 if (first != 0)
1070 printf("\n"); 1111 printf("\n");
@@ -1436,9 +1477,8 @@ do_change_comment(struct passwd *pw)
1436 } 1477 }
1437 } 1478 }
1438 1479
1439 if (private->type != KEY_RSA1 && private->type != KEY_ED25519 && 1480 if (private->type != KEY_ED25519 && !use_new_format) {
1440 !use_new_format) { 1481 error("Comments are only supported for keys stored in "
1441 error("Comments are only supported for RSA1 or keys stored in "
1442 "the new format (-o)."); 1482 "the new format (-o).");
1443 explicit_bzero(passphrase, strlen(passphrase)); 1483 explicit_bzero(passphrase, strlen(passphrase));
1444 sshkey_free(private); 1484 sshkey_free(private);
@@ -1476,7 +1516,7 @@ do_change_comment(struct passwd *pw)
1476 explicit_bzero(passphrase, strlen(passphrase)); 1516 explicit_bzero(passphrase, strlen(passphrase));
1477 free(passphrase); 1517 free(passphrase);
1478 if ((r = sshkey_from_private(private, &public)) != 0) 1518 if ((r = sshkey_from_private(private, &public)) != 0)
1479 fatal("key_from_private failed: %s", ssh_err(r)); 1519 fatal("sshkey_from_private failed: %s", ssh_err(r));
1480 sshkey_free(private); 1520 sshkey_free(private);
1481 1521
1482 strlcat(identity_file, ".pub", sizeof(identity_file)); 1522 strlcat(identity_file, ".pub", sizeof(identity_file));
@@ -1531,6 +1571,8 @@ add_string_option(struct sshbuf *c, const char *name, const char *value)
1531static void 1571static void
1532prepare_options_buf(struct sshbuf *c, int which) 1572prepare_options_buf(struct sshbuf *c, int which)
1533{ 1573{
1574 size_t i;
1575
1534 sshbuf_reset(c); 1576 sshbuf_reset(c);
1535 if ((which & OPTIONS_CRITICAL) != 0 && 1577 if ((which & OPTIONS_CRITICAL) != 0 &&
1536 certflags_command != NULL) 1578 certflags_command != NULL)
@@ -1553,6 +1595,17 @@ prepare_options_buf(struct sshbuf *c, int which)
1553 if ((which & OPTIONS_CRITICAL) != 0 && 1595 if ((which & OPTIONS_CRITICAL) != 0 &&
1554 certflags_src_addr != NULL) 1596 certflags_src_addr != NULL)
1555 add_string_option(c, "source-address", certflags_src_addr); 1597 add_string_option(c, "source-address", certflags_src_addr);
1598 for (i = 0; i < ncert_userext; i++) {
1599 if ((cert_userext[i].crit && (which & OPTIONS_EXTENSIONS)) ||
1600 (!cert_userext[i].crit && (which & OPTIONS_CRITICAL)))
1601 continue;
1602 if (cert_userext[i].val == NULL)
1603 add_flag_option(c, cert_userext[i].key);
1604 else {
1605 add_string_option(c, cert_userext[i].key,
1606 cert_userext[i].val);
1607 }
1608 }
1556} 1609}
1557 1610
1558static struct sshkey * 1611static struct sshkey *
@@ -1585,24 +1638,66 @@ load_pkcs11_key(char *path)
1585#endif /* ENABLE_PKCS11 */ 1638#endif /* ENABLE_PKCS11 */
1586} 1639}
1587 1640
1641/* Signer for sshkey_certify_custom that uses the agent */
1642static int
1643agent_signer(const struct sshkey *key, u_char **sigp, size_t *lenp,
1644 const u_char *data, size_t datalen,
1645 const char *alg, u_int compat, void *ctx)
1646{
1647 int *agent_fdp = (int *)ctx;
1648
1649 return ssh_agent_sign(*agent_fdp, key, sigp, lenp,
1650 data, datalen, alg, compat);
1651}
1652
1588static void 1653static void
1589do_ca_sign(struct passwd *pw, int argc, char **argv) 1654do_ca_sign(struct passwd *pw, int argc, char **argv)
1590{ 1655{
1591 int r, i, fd; 1656 int r, i, fd, found, agent_fd = -1;
1592 u_int n; 1657 u_int n;
1593 struct sshkey *ca, *public; 1658 struct sshkey *ca, *public;
1594 char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL; 1659 char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL;
1595 FILE *f; 1660 FILE *f;
1661 struct ssh_identitylist *agent_ids;
1662 size_t j;
1596 1663
1597#ifdef ENABLE_PKCS11 1664#ifdef ENABLE_PKCS11
1598 pkcs11_init(1); 1665 pkcs11_init(1);
1599#endif 1666#endif
1600 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); 1667 tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
1601 if (pkcs11provider != NULL) { 1668 if (pkcs11provider != NULL) {
1669 /* If a PKCS#11 token was specified then try to use it */
1602 if ((ca = load_pkcs11_key(tmp)) == NULL) 1670 if ((ca = load_pkcs11_key(tmp)) == NULL)
1603 fatal("No PKCS#11 key matching %s found", ca_key_path); 1671 fatal("No PKCS#11 key matching %s found", ca_key_path);
1604 } else 1672 } else if (prefer_agent) {
1673 /*
1674 * Agent signature requested. Try to use agent after making
1675 * sure the public key specified is actually present in the
1676 * agent.
1677 */
1678 if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0)
1679 fatal("Cannot load CA public key %s: %s",
1680 tmp, ssh_err(r));
1681 if ((r = ssh_get_authentication_socket(&agent_fd)) != 0)
1682 fatal("Cannot use public key for CA signature: %s",
1683 ssh_err(r));
1684 if ((r = ssh_fetch_identitylist(agent_fd, &agent_ids)) != 0)
1685 fatal("Retrieve agent key list: %s", ssh_err(r));
1686 found = 0;
1687 for (j = 0; j < agent_ids->nkeys; j++) {
1688 if (sshkey_equal(ca, agent_ids->keys[j])) {
1689 found = 1;
1690 break;
1691 }
1692 }
1693 if (!found)
1694 fatal("CA key %s not found in agent", tmp);
1695 ssh_free_identitylist(agent_ids);
1696 ca->flags |= SSHKEY_FLAG_EXT;
1697 } else {
1698 /* CA key is assumed to be a private key on the filesystem */
1605 ca = load_identity(tmp); 1699 ca = load_identity(tmp);
1700 }
1606 free(tmp); 1701 free(tmp);
1607 1702
1608 if (key_type_name != NULL && 1703 if (key_type_name != NULL &&
@@ -1650,10 +1745,18 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1650 OPTIONS_EXTENSIONS); 1745 OPTIONS_EXTENSIONS);
1651 if ((r = sshkey_from_private(ca, 1746 if ((r = sshkey_from_private(ca,
1652 &public->cert->signature_key)) != 0) 1747 &public->cert->signature_key)) != 0)
1653 fatal("key_from_private (ca key): %s", ssh_err(r)); 1748 fatal("sshkey_from_private (ca key): %s", ssh_err(r));
1654 1749
1655 if ((r = sshkey_certify(public, ca, key_type_name)) != 0) 1750 if (agent_fd != -1 && (ca->flags & SSHKEY_FLAG_EXT) != 0) {
1656 fatal("Couldn't certify key %s: %s", tmp, ssh_err(r)); 1751 if ((r = sshkey_certify_custom(public, ca,
1752 key_type_name, agent_signer, &agent_fd)) != 0)
1753 fatal("Couldn't certify key %s via agent: %s",
1754 tmp, ssh_err(r));
1755 } else {
1756 if ((sshkey_certify(public, ca, key_type_name)) != 0)
1757 fatal("Couldn't certify key %s: %s",
1758 tmp, ssh_err(r));
1759 }
1657 1760
1658 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) 1761 if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0)
1659 *cp = '\0'; 1762 *cp = '\0';
@@ -1789,7 +1892,8 @@ parse_cert_times(char *timespec)
1789static void 1892static void
1790add_cert_option(char *opt) 1893add_cert_option(char *opt)
1791{ 1894{
1792 char *val; 1895 char *val, *cp;
1896 int iscrit = 0;
1793 1897
1794 if (strcasecmp(opt, "clear") == 0) 1898 if (strcasecmp(opt, "clear") == 0)
1795 certflags_flags = 0; 1899 certflags_flags = 0;
@@ -1829,6 +1933,18 @@ add_cert_option(char *opt)
1829 if (addr_match_cidr_list(NULL, val) != 0) 1933 if (addr_match_cidr_list(NULL, val) != 0)
1830 fatal("Invalid source-address list"); 1934 fatal("Invalid source-address list");
1831 certflags_src_addr = xstrdup(val); 1935 certflags_src_addr = xstrdup(val);
1936 } else if (strncasecmp(opt, "extension:", 10) == 0 ||
1937 (iscrit = (strncasecmp(opt, "critical:", 9) == 0))) {
1938 val = xstrdup(strchr(opt, ':') + 1);
1939 if ((cp = strchr(val, '=')) != NULL)
1940 *cp++ = '\0';
1941 cert_userext = xreallocarray(cert_userext, ncert_userext + 1,
1942 sizeof(*cert_userext));
1943 cert_userext[ncert_userext].key = val;
1944 cert_userext[ncert_userext].val = cp == NULL ?
1945 NULL : xstrdup(cp);
1946 cert_userext[ncert_userext].crit = iscrit;
1947 ncert_userext++;
1832 } else 1948 } else
1833 fatal("Unsupported certificate option \"%s\"", opt); 1949 fatal("Unsupported certificate option \"%s\"", opt);
1834} 1950}
@@ -1955,7 +2071,7 @@ do_show_cert(struct passwd *pw)
1955 if (*cp == '#' || *cp == '\0') 2071 if (*cp == '#' || *cp == '\0')
1956 continue; 2072 continue;
1957 if ((key = sshkey_new(KEY_UNSPEC)) == NULL) 2073 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
1958 fatal("key_new"); 2074 fatal("sshkey_new");
1959 if ((r = sshkey_read(key, &cp)) != 0) { 2075 if ((r = sshkey_read(key, &cp)) != 0) {
1960 error("%s:%lu: invalid key: %s", path, 2076 error("%s:%lu: invalid key: %s", path,
1961 lnum, ssh_err(r)); 2077 lnum, ssh_err(r));
@@ -2101,7 +2217,7 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
2101 */ 2217 */
2102 } 2218 }
2103 if ((key = sshkey_new(KEY_UNSPEC)) == NULL) 2219 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
2104 fatal("key_new"); 2220 fatal("sshkey_new");
2105 if ((r = sshkey_read(key, &cp)) != 0) 2221 if ((r = sshkey_read(key, &cp)) != 0)
2106 fatal("%s:%lu: invalid key: %s", 2222 fatal("%s:%lu: invalid key: %s",
2107 path, lnum, ssh_err(r)); 2223 path, lnum, ssh_err(r));
@@ -2209,17 +2325,11 @@ do_check_krl(struct passwd *pw, int argc, char **argv)
2209 exit(ret); 2325 exit(ret);
2210} 2326}
2211 2327
2212#ifdef WITH_SSH1
2213# define RSA1_USAGE " | rsa1"
2214#else
2215# define RSA1_USAGE ""
2216#endif
2217
2218static void 2328static void
2219usage(void) 2329usage(void)
2220{ 2330{
2221 fprintf(stderr, 2331 fprintf(stderr,
2222 "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa%s]\n" 2332 "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa]\n"
2223 " [-N new_passphrase] [-C comment] [-f output_keyfile]\n" 2333 " [-N new_passphrase] [-C comment] [-f output_keyfile]\n"
2224 " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n" 2334 " ssh-keygen -p [-P old_passphrase] [-N new_passphrase] [-f keyfile]\n"
2225 " ssh-keygen -i [-m key_format] [-f input_keyfile]\n" 2335 " ssh-keygen -i [-m key_format] [-f input_keyfile]\n"
@@ -2227,7 +2337,7 @@ usage(void)
2227 " ssh-keygen -y [-f input_keyfile]\n" 2337 " ssh-keygen -y [-f input_keyfile]\n"
2228 " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" 2338 " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n"
2229 " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n" 2339 " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n"
2230 " ssh-keygen -B [-f input_keyfile]\n", RSA1_USAGE); 2340 " ssh-keygen -B [-f input_keyfile]\n");
2231#ifdef ENABLE_PKCS11 2341#ifdef ENABLE_PKCS11
2232 fprintf(stderr, 2342 fprintf(stderr,
2233 " ssh-keygen -D pkcs11\n"); 2343 " ssh-keygen -D pkcs11\n");
@@ -2242,8 +2352,9 @@ usage(void)
2242 " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n" 2352 " ssh-keygen -T output_file -f input_file [-v] [-a rounds] [-J num_lines]\n"
2243 " [-j start_line] [-K checkpt] [-W generator]\n" 2353 " [-j start_line] [-K checkpt] [-W generator]\n"
2244#endif 2354#endif
2245 " ssh-keygen -s ca_key -I certificate_identity [-h] [-n principals]\n" 2355 " ssh-keygen -s ca_key -I certificate_identity [-h] [-U]\n"
2246 " [-O option] [-V validity_interval] [-z serial_number] file ...\n" 2356 " [-D pkcs11_provider] [-n principals] [-O option]\n"
2357 " [-V validity_interval] [-z serial_number] file ...\n"
2247 " ssh-keygen -L [-f input_keyfile]\n" 2358 " ssh-keygen -L [-f input_keyfile]\n"
2248 " ssh-keygen -A\n" 2359 " ssh-keygen -A\n"
2249 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n" 2360 " ssh-keygen -k -f krl_file [-u] [-s ca_public] [-z version_number]\n"
@@ -2301,8 +2412,8 @@ main(int argc, char **argv)
2301 if (gethostname(hostname, sizeof(hostname)) < 0) 2412 if (gethostname(hostname, sizeof(hostname)) < 0)
2302 fatal("gethostname: %s", strerror(errno)); 2413 fatal("gethostname: %s", strerror(errno));
2303 2414
2304 /* Remaining characters: UYdw */ 2415 /* Remaining characters: Ydw */
2305 while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" 2416 while ((opt = getopt(argc, argv, "ABHLQUXceghiklopquvxy"
2306 "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:" 2417 "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:"
2307 "a:b:f:g:j:m:n:r:s:t:z:")) != -1) { 2418 "a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
2308 switch (opt) { 2419 switch (opt) {
@@ -2429,6 +2540,9 @@ main(int argc, char **argv)
2429 case 'D': 2540 case 'D':
2430 pkcs11provider = optarg; 2541 pkcs11provider = optarg;
2431 break; 2542 break;
2543 case 'U':
2544 prefer_agent = 1;
2545 break;
2432 case 'u': 2546 case 'u':
2433 update_krl = 1; 2547 update_krl = 1;
2434 break; 2548 break;
@@ -2648,9 +2762,9 @@ main(int argc, char **argv)
2648 printf("Generating public/private %s key pair.\n", 2762 printf("Generating public/private %s key pair.\n",
2649 key_type_name); 2763 key_type_name);
2650 if ((r = sshkey_generate(type, bits, &private)) != 0) 2764 if ((r = sshkey_generate(type, bits, &private)) != 0)
2651 fatal("key_generate failed"); 2765 fatal("sshkey_generate failed");
2652 if ((r = sshkey_from_private(private, &public)) != 0) 2766 if ((r = sshkey_from_private(private, &public)) != 0)
2653 fatal("key_from_private failed: %s\n", ssh_err(r)); 2767 fatal("sshkey_from_private failed: %s\n", ssh_err(r));
2654 2768
2655 if (!have_identity) 2769 if (!have_identity)
2656 ask_filename(pw, "Enter file in which to save the key"); 2770 ask_filename(pw, "Enter file in which to save the key");
diff --git a/ssh-keyscan.0 b/ssh-keyscan.0
index e9d9f0d8b..1a9751ef1 100644
--- a/ssh-keyscan.0
+++ b/ssh-keyscan.0
@@ -49,10 +49,9 @@ DESCRIPTION
49 49
50 -t type 50 -t type
51 Specifies the type of the key to fetch from the scanned hosts. 51 Specifies the type of the key to fetch from the scanned hosts.
52 The possible values are M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], 52 The possible values are M-bM-^@M-^\dsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or M-bM-^@M-^\rsaM-bM-^@M-^].
53 M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2. Multiple 53 Multiple values may be specified by separating them with commas.
54 values may be specified by separating them with commas. The 54 The default is to fetch M-bM-^@M-^\rsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], and M-bM-^@M-^\ed25519M-bM-^@M-^] keys.
55 default is to fetch M-bM-^@M-^\rsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], and M-bM-^@M-^\ed25519M-bM-^@M-^] keys.
56 55
57 -v Verbose mode. Causes ssh-keyscan to print debugging messages 56 -v Verbose mode. Causes ssh-keyscan to print debugging messages
58 about its progress. 57 about its progress.
@@ -70,10 +69,6 @@ FILES
70 69
71 1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 70 1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4
72 71
73 Output format for RSA1 keys:
74
75 host-or-namelist bits exponent modulus
76
77 Output format for RSA, DSA, ECDSA, and Ed25519 keys: 72 Output format for RSA, DSA, ECDSA, and Ed25519 keys:
78 73
79 host-or-namelist keytype base64-encoded-key 74 host-or-namelist keytype base64-encoded-key
@@ -108,4 +103,4 @@ BUGS
108 This is because it opens a connection to the ssh port, reads the public 103 This is because it opens a connection to the ssh port, reads the public
109 key, and drops the connection as soon as it gets the key. 104 key, and drops the connection as soon as it gets the key.
110 105
111OpenBSD 6.0 November 8, 2015 OpenBSD 6.0 106OpenBSD 6.2 May 2, 2017 OpenBSD 6.2
diff --git a/ssh-keyscan.1 b/ssh-keyscan.1
index d29d9d906..aa4a2ae83 100644
--- a/ssh-keyscan.1
+++ b/ssh-keyscan.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keyscan.1,v 1.38 2015/11/08 23:24:03 jmc Exp $ 1.\" $OpenBSD: ssh-keyscan.1,v 1.40 2017/05/02 17:04:09 jmc Exp $
2.\" 2.\"
3.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. 3.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
4.\" 4.\"
@@ -6,7 +6,7 @@
6.\" permitted provided that due credit is given to the author and the 6.\" permitted provided that due credit is given to the author and the
7.\" OpenBSD project by leaving this copyright notice intact. 7.\" OpenBSD project by leaving this copyright notice intact.
8.\" 8.\"
9.Dd $Mdocdate: November 8 2015 $ 9.Dd $Mdocdate: May 2 2017 $
10.Dt SSH-KEYSCAN 1 10.Dt SSH-KEYSCAN 1
11.Os 11.Os
12.Sh NAME 12.Sh NAME
@@ -90,14 +90,11 @@ Default is 5 seconds.
90.It Fl t Ar type 90.It Fl t Ar type
91Specifies the type of the key to fetch from the scanned hosts. 91Specifies the type of the key to fetch from the scanned hosts.
92The possible values are 92The possible values are
93.Dq rsa1
94for protocol version 1 and
95.Dq dsa , 93.Dq dsa ,
96.Dq ecdsa , 94.Dq ecdsa ,
97.Dq ed25519 , 95.Dq ed25519 ,
98or 96or
99.Dq rsa 97.Dq rsa .
100for protocol version 2.
101Multiple values may be specified by separating them with commas. 98Multiple values may be specified by separating them with commas.
102The default is to fetch 99The default is to fetch
103.Dq rsa , 100.Dq rsa ,
@@ -127,11 +124,6 @@ Input format:
1271.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 1241.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4
128.Ed 125.Ed
129.Pp 126.Pp
130Output format for RSA1 keys:
131.Bd -literal
132host-or-namelist bits exponent modulus
133.Ed
134.Pp
135Output format for RSA, DSA, ECDSA, and Ed25519 keys: 127Output format for RSA, DSA, ECDSA, and Ed25519 keys:
136.Bd -literal 128.Bd -literal
137host-or-namelist keytype base64-encoded-key 129host-or-namelist keytype base64-encoded-key
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index 1f95239a3..258123ae8 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keyscan.c,v 1.109 2017/03/10 04:26:06 djm Exp $ */ 1/* $OpenBSD: ssh-keyscan.c,v 1.115 2017/06/30 04:17:23 dtucker Exp $ */
2/* 2/*
3 * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. 3 * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
4 * 4 *
@@ -32,7 +32,6 @@
32 32
33#include "xmalloc.h" 33#include "xmalloc.h"
34#include "ssh.h" 34#include "ssh.h"
35#include "ssh1.h"
36#include "sshbuf.h" 35#include "sshbuf.h"
37#include "sshkey.h" 36#include "sshkey.h"
38#include "cipher.h" 37#include "cipher.h"
@@ -54,11 +53,13 @@ int IPv4or6 = AF_UNSPEC;
54 53
55int ssh_port = SSH_DEFAULT_PORT; 54int ssh_port = SSH_DEFAULT_PORT;
56 55
57#define KT_RSA1 1 56#define KT_DSA (1)
58#define KT_DSA 2 57#define KT_RSA (1<<1)
59#define KT_RSA 4 58#define KT_ECDSA (1<<2)
60#define KT_ECDSA 8 59#define KT_ED25519 (1<<3)
61#define KT_ED25519 16 60
61#define KT_MIN KT_DSA
62#define KT_MAX KT_ED25519
62 63
63int get_cert = 0; 64int get_cert = 0;
64int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519; 65int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519;
@@ -94,7 +95,7 @@ typedef struct Connection {
94 int c_plen; /* Packet length field for ssh packet */ 95 int c_plen; /* Packet length field for ssh packet */
95 int c_len; /* Total bytes which must be read. */ 96 int c_len; /* Total bytes which must be read. */
96 int c_off; /* Length of data read so far. */ 97 int c_off; /* Length of data read so far. */
97 int c_keytype; /* Only one of KT_RSA1, KT_DSA, or KT_RSA */ 98 int c_keytype; /* Only one of KT_* */
98 sig_atomic_t c_done; /* SSH2 done */ 99 sig_atomic_t c_done; /* SSH2 done */
99 char *c_namebase; /* Address to free for c_name and c_namelist */ 100 char *c_namebase; /* Address to free for c_name and c_namelist */
100 char *c_name; /* Hostname of connection for errors */ 101 char *c_name; /* Hostname of connection for errors */
@@ -187,52 +188,6 @@ strnnsep(char **stringp, char *delim)
187 return (tok); 188 return (tok);
188} 189}
189 190
190#ifdef WITH_SSH1
191static struct sshkey *
192keygrab_ssh1(con *c)
193{
194 static struct sshkey *rsa;
195 static struct sshbuf *msg;
196 int r;
197 u_char type;
198
199 if (rsa == NULL) {
200 if ((rsa = sshkey_new(KEY_RSA1)) == NULL) {
201 error("%s: sshkey_new failed", __func__);
202 return NULL;
203 }
204 if ((msg = sshbuf_new()) == NULL)
205 fatal("%s: sshbuf_new failed", __func__);
206 }
207 if ((r = sshbuf_put(msg, c->c_data, c->c_plen)) != 0 ||
208 (r = sshbuf_consume(msg, 8 - (c->c_plen & 7))) != 0 || /* padding */
209 (r = sshbuf_get_u8(msg, &type)) != 0)
210 goto buf_err;
211 if (type != (int) SSH_SMSG_PUBLIC_KEY) {
212 error("%s: invalid packet type", c->c_name);
213 sshbuf_reset(msg);
214 return NULL;
215 }
216 if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */
217 /* server key */
218 (r = sshbuf_get_u32(msg, NULL)) != 0 ||
219 (r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
220 (r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
221 /* host key */
222 (r = sshbuf_get_u32(msg, NULL)) != 0 ||
223 (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 ||
224 (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) {
225 buf_err:
226 error("%s: buffer error: %s", __func__, ssh_err(r));
227 sshbuf_reset(msg);
228 return NULL;
229 }
230
231 sshbuf_reset(msg);
232
233 return (rsa);
234}
235#endif
236 191
237static int 192static int
238key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh) 193key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh)
@@ -267,7 +222,6 @@ keygrab_ssh2(con *c)
267 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; 222 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
268 int r; 223 int r;
269 224
270 enable_compat20();
271 switch (c->c_keytype) { 225 switch (c->c_keytype) {
272 case KT_DSA: 226 case KT_DSA:
273 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? 227 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ?
@@ -317,7 +271,7 @@ keygrab_ssh2(con *c)
317 * do the key-exchange until an error occurs or until 271 * do the key-exchange until an error occurs or until
318 * the key_print_wrapper() callback sets c_done. 272 * the key_print_wrapper() callback sets c_done.
319 */ 273 */
320 ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done, c->c_ssh); 274 ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done);
321} 275}
322 276
323static void 277static void
@@ -436,7 +390,6 @@ confree(int s)
436{ 390{
437 if (s >= maxfd || fdcon[s].c_status == CS_UNUSED) 391 if (s >= maxfd || fdcon[s].c_status == CS_UNUSED)
438 fatal("confree: attempt to free bad fdno %d", s); 392 fatal("confree: attempt to free bad fdno %d", s);
439 close(s);
440 free(fdcon[s].c_namebase); 393 free(fdcon[s].c_namebase);
441 free(fdcon[s].c_output_name); 394 free(fdcon[s].c_output_name);
442 if (fdcon[s].c_status == CS_KEYS) 395 if (fdcon[s].c_status == CS_KEYS)
@@ -447,7 +400,8 @@ confree(int s)
447 ssh_packet_close(fdcon[s].c_ssh); 400 ssh_packet_close(fdcon[s].c_ssh);
448 free(fdcon[s].c_ssh); 401 free(fdcon[s].c_ssh);
449 fdcon[s].c_ssh = NULL; 402 fdcon[s].c_ssh = NULL;
450 } 403 } else
404 close(s);
451 TAILQ_REMOVE(&tq, &fdcon[s], c_link); 405 TAILQ_REMOVE(&tq, &fdcon[s], c_link);
452 FD_CLR(s, read_wait); 406 FD_CLR(s, read_wait);
453 ncon--; 407 ncon--;
@@ -482,6 +436,20 @@ congreet(int s)
482 size_t bufsiz; 436 size_t bufsiz;
483 con *c = &fdcon[s]; 437 con *c = &fdcon[s];
484 438
439 /* send client banner */
440 n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
441 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2);
442 if (n < 0 || (size_t)n >= sizeof(buf)) {
443 error("snprintf: buffer too small");
444 confree(s);
445 return;
446 }
447 if (atomicio(vwrite, s, buf, n) != (size_t)n) {
448 error("write (%s): %s", c->c_name, strerror(errno));
449 confree(s);
450 return;
451 }
452
485 for (;;) { 453 for (;;) {
486 memset(buf, '\0', sizeof(buf)); 454 memset(buf, '\0', sizeof(buf));
487 bufsiz = sizeof(buf); 455 bufsiz = sizeof(buf);
@@ -524,38 +492,14 @@ congreet(int s)
524 c->c_ssh->compat = compat_datafellows(remote_version); 492 c->c_ssh->compat = compat_datafellows(remote_version);
525 else 493 else
526 c->c_ssh->compat = 0; 494 c->c_ssh->compat = 0;
527 if (c->c_keytype != KT_RSA1) { 495 if (!ssh2_capable(remote_major, remote_minor)) {
528 if (!ssh2_capable(remote_major, remote_minor)) { 496 debug("%s doesn't support ssh2", c->c_name);
529 debug("%s doesn't support ssh2", c->c_name);
530 confree(s);
531 return;
532 }
533 } else if (remote_major != 1) {
534 debug("%s doesn't support ssh1", c->c_name);
535 confree(s); 497 confree(s);
536 return; 498 return;
537 } 499 }
538 fprintf(stderr, "# %s:%d %s\n", c->c_name, ssh_port, chop(buf)); 500 fprintf(stderr, "# %s:%d %s\n", c->c_name, ssh_port, chop(buf));
539 n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n", 501 keygrab_ssh2(c);
540 c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2, 502 confree(s);
541 c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2);
542 if (n < 0 || (size_t)n >= sizeof(buf)) {
543 error("snprintf: buffer too small");
544 confree(s);
545 return;
546 }
547 if (atomicio(vwrite, s, buf, n) != (size_t)n) {
548 error("write (%s): %s", c->c_name, strerror(errno));
549 confree(s);
550 return;
551 }
552 if (c->c_keytype != KT_RSA1) {
553 keygrab_ssh2(c);
554 confree(s);
555 return;
556 }
557 c->c_status = CS_SIZE;
558 contouch(s);
559} 503}
560 504
561static void 505static void
@@ -585,12 +529,6 @@ conread(int s)
585 c->c_data = xmalloc(c->c_len); 529 c->c_data = xmalloc(c->c_len);
586 c->c_status = CS_KEYS; 530 c->c_status = CS_KEYS;
587 break; 531 break;
588#ifdef WITH_SSH1
589 case CS_KEYS:
590 keyprint(c, keygrab_ssh1(c));
591 confree(s);
592 return;
593#endif
594 default: 532 default:
595 fatal("conread: invalid status %d", c->c_status); 533 fatal("conread: invalid status %d", c->c_status);
596 break; 534 break;
@@ -659,7 +597,7 @@ do_host(char *host)
659 597
660 if (name == NULL) 598 if (name == NULL)
661 return; 599 return;
662 for (j = KT_RSA1; j <= KT_ED25519; j *= 2) { 600 for (j = KT_MIN; j <= KT_MAX; j *= 2) {
663 if (get_keytypes & j) { 601 if (get_keytypes & j) {
664 while (ncon >= MAXCON) 602 while (ncon >= MAXCON)
665 conloop(); 603 conloop();
@@ -756,11 +694,6 @@ main(int argc, char **argv)
756 int type = sshkey_type_from_name(tname); 694 int type = sshkey_type_from_name(tname);
757 695
758 switch (type) { 696 switch (type) {
759#ifdef WITH_SSH1
760 case KEY_RSA1:
761 get_keytypes |= KT_RSA1;
762 break;
763#endif
764 case KEY_DSA: 697 case KEY_DSA:
765 get_keytypes |= KT_DSA; 698 get_keytypes |= KT_DSA;
766 break; 699 break;
diff --git a/ssh-keysign.0 b/ssh-keysign.0
index 34a451d62..d855ad07a 100644
--- a/ssh-keysign.0
+++ b/ssh-keysign.0
@@ -49,4 +49,4 @@ HISTORY
49AUTHORS 49AUTHORS
50 Markus Friedl <markus@openbsd.org> 50 Markus Friedl <markus@openbsd.org>
51 51
52OpenBSD 6.0 February 17, 2016 OpenBSD 6.0 52OpenBSD 6.2 February 17, 2016 OpenBSD 6.2
diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
index fac0167e6..a79c87210 100644
--- a/ssh-pkcs11-client.c
+++ b/ssh-pkcs11-client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-pkcs11-client.c,v 1.6 2015/12/11 00:20:04 mmcc Exp $ */ 1/* $OpenBSD: ssh-pkcs11-client.c,v 1.7 2017/05/30 08:52:19 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2010 Markus Friedl. All rights reserved. 3 * Copyright (c) 2010 Markus Friedl. All rights reserved.
4 * 4 *
@@ -106,7 +106,7 @@ static int
106pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, 106pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
107 int padding) 107 int padding)
108{ 108{
109 Key key; 109 struct sshkey key; /* XXX */
110 u_char *blob, *signature = NULL; 110 u_char *blob, *signature = NULL;
111 u_int blen, slen = 0; 111 u_int blen, slen = 0;
112 int ret = -1; 112 int ret = -1;
@@ -186,7 +186,7 @@ pkcs11_start_helper(void)
186int 186int
187pkcs11_add_provider(char *name, char *pin, Key ***keysp) 187pkcs11_add_provider(char *name, char *pin, Key ***keysp)
188{ 188{
189 Key *k; 189 struct sshkey *k;
190 int i, nkeys; 190 int i, nkeys;
191 u_char *blob; 191 u_char *blob;
192 u_int blen; 192 u_int blen;
diff --git a/ssh-pkcs11-helper.0 b/ssh-pkcs11-helper.0
index 1b58361a6..93e5565b7 100644
--- a/ssh-pkcs11-helper.0
+++ b/ssh-pkcs11-helper.0
@@ -22,4 +22,4 @@ HISTORY
22AUTHORS 22AUTHORS
23 Markus Friedl <markus@openbsd.org> 23 Markus Friedl <markus@openbsd.org>
24 24
25OpenBSD 6.0 July 16, 2013 OpenBSD 6.0 25OpenBSD 6.2 July 16, 2013 OpenBSD 6.2
diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c
index 53f41c555..fd3039c14 100644
--- a/ssh-pkcs11-helper.c
+++ b/ssh-pkcs11-helper.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-pkcs11-helper.c,v 1.12 2016/02/15 09:47:49 dtucker Exp $ */ 1/* $OpenBSD: ssh-pkcs11-helper.c,v 1.13 2017/05/30 08:52:19 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2010 Markus Friedl. All rights reserved. 3 * Copyright (c) 2010 Markus Friedl. All rights reserved.
4 * 4 *
@@ -42,7 +42,7 @@
42/* borrows code from sftp-server and ssh-agent */ 42/* borrows code from sftp-server and ssh-agent */
43 43
44struct pkcs11_keyinfo { 44struct pkcs11_keyinfo {
45 Key *key; 45 struct sshkey *key;
46 char *providername; 46 char *providername;
47 TAILQ_ENTRY(pkcs11_keyinfo) next; 47 TAILQ_ENTRY(pkcs11_keyinfo) next;
48}; 48};
@@ -60,7 +60,7 @@ Buffer iqueue;
60Buffer oqueue; 60Buffer oqueue;
61 61
62static void 62static void
63add_key(Key *k, char *name) 63add_key(struct sshkey *k, char *name)
64{ 64{
65 struct pkcs11_keyinfo *ki; 65 struct pkcs11_keyinfo *ki;
66 66
@@ -87,8 +87,8 @@ del_keys_by_name(char *name)
87} 87}
88 88
89/* lookup matching 'private' key */ 89/* lookup matching 'private' key */
90static Key * 90static struct sshkey *
91lookup_key(Key *k) 91lookup_key(struct sshkey *k)
92{ 92{
93 struct pkcs11_keyinfo *ki; 93 struct pkcs11_keyinfo *ki;
94 94
@@ -114,7 +114,7 @@ static void
114process_add(void) 114process_add(void)
115{ 115{
116 char *name, *pin; 116 char *name, *pin;
117 Key **keys; 117 struct sshkey **keys;
118 int i, nkeys; 118 int i, nkeys;
119 u_char *blob; 119 u_char *blob;
120 u_int blen; 120 u_int blen;
@@ -170,7 +170,7 @@ process_sign(void)
170 u_char *blob, *data, *signature = NULL; 170 u_char *blob, *data, *signature = NULL;
171 u_int blen, dlen, slen = 0; 171 u_int blen, dlen, slen = 0;
172 int ok = -1; 172 int ok = -1;
173 Key *key, *found; 173 struct sshkey *key, *found;
174 Buffer msg; 174 Buffer msg;
175 175
176 blob = get_string(&blen); 176 blob = get_string(&blen);
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
index aaf712d9a..b37491c5d 100644
--- a/ssh-pkcs11.c
+++ b/ssh-pkcs11.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-pkcs11.c,v 1.23 2016/10/28 03:33:52 djm Exp $ */ 1/* $OpenBSD: ssh-pkcs11.c,v 1.25 2017/05/31 09:15:42 deraadt Exp $ */
2/* 2/*
3 * Copyright (c) 2010 Markus Friedl. All rights reserved. 3 * Copyright (c) 2010 Markus Friedl. All rights reserved.
4 * 4 *
@@ -537,7 +537,8 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
537 } 537 }
538 if (rsa && rsa->n && rsa->e && 538 if (rsa && rsa->n && rsa->e &&
539 pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { 539 pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
540 key = sshkey_new(KEY_UNSPEC); 540 if ((key = sshkey_new(KEY_UNSPEC)) == NULL)
541 fatal("sshkey_new failed");
541 key->rsa = rsa; 542 key->rsa = rsa;
542 key->type = KEY_RSA; 543 key->type = KEY_RSA;
543 key->flags |= SSHKEY_FLAG_EXT; 544 key->flags |= SSHKEY_FLAG_EXT;
@@ -545,8 +546,8 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
545 sshkey_free(key); 546 sshkey_free(key);
546 } else { 547 } else {
547 /* expand key array and add key */ 548 /* expand key array and add key */
548 *keysp = xreallocarray(*keysp, *nkeys + 1, 549 *keysp = xrecallocarray(*keysp, *nkeys,
549 sizeof(struct sshkey *)); 550 *nkeys + 1, sizeof(struct sshkey *));
550 (*keysp)[*nkeys] = key; 551 (*keysp)[*nkeys] = key;
551 *nkeys = *nkeys + 1; 552 *nkeys = *nkeys + 1;
552 debug("have %d keys", *nkeys); 553 debug("have %d keys", *nkeys);
diff --git a/ssh-rsa.c b/ssh-rsa.c
index cde05df10..f570ae6d4 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-rsa.c,v 1.60 2016/09/12 23:39:34 djm Exp $ */ 1/* $OpenBSD: ssh-rsa.c,v 1.62 2017/07/01 13:50:45 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> 3 * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org>
4 * 4 *
@@ -78,6 +78,41 @@ rsa_hash_alg_nid(int type)
78 } 78 }
79} 79}
80 80
81/* calculate p-1 and q-1 */
82int
83ssh_rsa_generate_additional_parameters(struct sshkey *key)
84{
85 RSA *rsa;
86 BIGNUM *aux = NULL;
87 BN_CTX *ctx = NULL;
88 int r;
89
90 if (key == NULL || key->rsa == NULL ||
91 sshkey_type_plain(key->type) != KEY_RSA)
92 return SSH_ERR_INVALID_ARGUMENT;
93
94 if ((ctx = BN_CTX_new()) == NULL)
95 return SSH_ERR_ALLOC_FAIL;
96 if ((aux = BN_new()) == NULL) {
97 r = SSH_ERR_ALLOC_FAIL;
98 goto out;
99 }
100 rsa = key->rsa;
101
102 if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
103 (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
104 (BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
105 (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) {
106 r = SSH_ERR_LIBCRYPTO_ERROR;
107 goto out;
108 }
109 r = 0;
110 out:
111 BN_clear_free(aux);
112 BN_CTX_free(ctx);
113 return r;
114}
115
81/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */ 116/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
82int 117int
83ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, 118ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
@@ -99,9 +134,10 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
99 else 134 else
100 hash_alg = rsa_hash_alg_from_ident(alg_ident); 135 hash_alg = rsa_hash_alg_from_ident(alg_ident);
101 if (key == NULL || key->rsa == NULL || hash_alg == -1 || 136 if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
102 sshkey_type_plain(key->type) != KEY_RSA || 137 sshkey_type_plain(key->type) != KEY_RSA)
103 BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
104 return SSH_ERR_INVALID_ARGUMENT; 138 return SSH_ERR_INVALID_ARGUMENT;
139 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
140 return SSH_ERR_KEY_LENGTH;
105 slen = RSA_size(key->rsa); 141 slen = RSA_size(key->rsa);
106 if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) 142 if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
107 return SSH_ERR_INVALID_ARGUMENT; 143 return SSH_ERR_INVALID_ARGUMENT;
@@ -172,9 +208,10 @@ ssh_rsa_verify(const struct sshkey *key,
172 208
173 if (key == NULL || key->rsa == NULL || 209 if (key == NULL || key->rsa == NULL ||
174 sshkey_type_plain(key->type) != KEY_RSA || 210 sshkey_type_plain(key->type) != KEY_RSA ||
175 BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE ||
176 sig == NULL || siglen == 0) 211 sig == NULL || siglen == 0)
177 return SSH_ERR_INVALID_ARGUMENT; 212 return SSH_ERR_INVALID_ARGUMENT;
213 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
214 return SSH_ERR_KEY_LENGTH;
178 215
179 if ((b = sshbuf_from(sig, siglen)) == NULL) 216 if ((b = sshbuf_from(sig, siglen)) == NULL)
180 return SSH_ERR_ALLOC_FAIL; 217 return SSH_ERR_ALLOC_FAIL;
diff --git a/ssh.0 b/ssh.0
index 67ce809bb..f920dd97e 100644
--- a/ssh.0
+++ b/ssh.0
@@ -4,7 +4,7 @@ NAME
4 ssh M-bM-^@M-^S OpenSSH SSH client (remote login program) 4 ssh M-bM-^@M-^S OpenSSH SSH client (remote login program)
5 5
6SYNOPSIS 6SYNOPSIS
7 ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] 7 ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
8 [-D [bind_address:]port] [-E log_file] [-e escape_char] 8 [-D [bind_address:]port] [-E log_file] [-e escape_char]
9 [-F configfile] [-I pkcs11] [-i identity_file] 9 [-F configfile] [-I pkcs11] [-i identity_file]
10 [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec] 10 [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]
@@ -28,10 +28,6 @@ DESCRIPTION
28 28
29 The options are as follows: 29 The options are as follows:
30 30
31 -1 Forces ssh to try protocol version 1 only.
32
33 -2 Forces ssh to try protocol version 2 only.
34
35 -4 Forces ssh to use IPv4 addresses only. 31 -4 Forces ssh to use IPv4 addresses only.
36 32
37 -6 Forces ssh to use IPv6 addresses only. 33 -6 Forces ssh to use IPv6 addresses only.
@@ -58,21 +54,16 @@ DESCRIPTION
58 -C Requests compression of all data (including stdin, stdout, 54 -C Requests compression of all data (including stdin, stdout,
59 stderr, and data for forwarded X11, TCP and UNIX-domain 55 stderr, and data for forwarded X11, TCP and UNIX-domain
60 connections). The compression algorithm is the same used by 56 connections). The compression algorithm is the same used by
61 gzip(1), and the M-bM-^@M-^\levelM-bM-^@M-^] can be controlled by the 57 gzip(1). Compression is desirable on modem lines and other slow
62 CompressionLevel option for protocol version 1. Compression is 58 connections, but will only slow down things on fast networks.
63 desirable on modem lines and other slow connections, but will 59 The default value can be set on a host-by-host basis in the
64 only slow down things on fast networks. The default value can be 60 configuration files; see the Compression option.
65 set on a host-by-host basis in the configuration files; see the
66 Compression option.
67 61
68 -c cipher_spec 62 -c cipher_spec
69 Selects the cipher specification for encrypting the session. 63 Selects the cipher specification for encrypting the session.
70 64 cipher_spec is a comma-separated list of ciphers listed in order
71 Protocol version 1 allows specification of a single cipher. The 65 of preference. See the Ciphers keyword in ssh_config(5) for more
72 supported values are M-bM-^@M-^\3desM-bM-^@M-^], M-bM-^@M-^\blowfishM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^]. For protocol 66 information.
73 version 2, cipher_spec is a comma-separated list of ciphers
74 listed in order of preference. See the Ciphers keyword in
75 ssh_config(5) for more information.
76 67
77 -D [bind_address:]port 68 -D [bind_address:]port
78 Specifies a local M-bM-^@M-^\dynamicM-bM-^@M-^] application-level port forwarding. 69 Specifies a local M-bM-^@M-^\dynamicM-bM-^@M-^] application-level port forwarding.
@@ -137,10 +128,9 @@ DESCRIPTION
137 128
138 -i identity_file 129 -i identity_file
139 Selects a file from which the identity (private key) for public 130 Selects a file from which the identity (private key) for public
140 key authentication is read. The default is ~/.ssh/identity for 131 key authentication is read. The default is ~/.ssh/id_dsa,
141 protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, 132 ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and ~/.ssh/id_rsa. Identity
142 ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. 133 files may also be specified on a per-host basis in the
143 Identity files may also be specified on a per-host basis in the
144 configuration file. It is possible to have multiple -i options 134 configuration file. It is possible to have multiple -i options
145 (and multiple identities specified in configuration files). If 135 (and multiple identities specified in configuration files). If
146 no certificates have been explicitly specified by the 136 no certificates have been explicitly specified by the
@@ -243,11 +233,9 @@ DESCRIPTION
243 CertificateFile 233 CertificateFile
244 ChallengeResponseAuthentication 234 ChallengeResponseAuthentication
245 CheckHostIP 235 CheckHostIP
246 Cipher
247 Ciphers 236 Ciphers
248 ClearAllForwardings 237 ClearAllForwardings
249 Compression 238 Compression
250 CompressionLevel
251 ConnectionAttempts 239 ConnectionAttempts
252 ConnectTimeout 240 ConnectTimeout
253 ControlMaster 241 ControlMaster
@@ -292,17 +280,15 @@ DESCRIPTION
292 PKCS11Provider 280 PKCS11Provider
293 Port 281 Port
294 PreferredAuthentications 282 PreferredAuthentications
295 Protocol
296 ProxyCommand 283 ProxyCommand
297 ProxyJump 284 ProxyJump
298 ProxyUseFdpass 285 ProxyUseFdpass
299 PubkeyAcceptedKeyTypes 286 PubkeyAcceptedKeyTypes
300 PubkeyAuthentication 287 PubkeyAuthentication
301 RekeyLimit 288 RekeyLimit
289 RemoteCommand
302 RemoteForward 290 RemoteForward
303 RequestTTY 291 RequestTTY
304 RhostsRSAAuthentication
305 RSAAuthentication
306 SendEnv 292 SendEnv
307 ServerAliveInterval 293 ServerAliveInterval
308 ServerAliveCountMax 294 ServerAliveCountMax
@@ -340,14 +326,20 @@ DESCRIPTION
340 -R [bind_address:]port:local_socket 326 -R [bind_address:]port:local_socket
341 -R remote_socket:host:hostport 327 -R remote_socket:host:hostport
342 -R remote_socket:local_socket 328 -R remote_socket:local_socket
329 -R [bind_address:]port
343 Specifies that connections to the given TCP port or Unix socket 330 Specifies that connections to the given TCP port or Unix socket
344 on the remote (server) host are to be forwarded to the given host 331 on the remote (server) host are to be forwarded to the local
345 and port, or Unix socket, on the local side. This works by 332 side.
346 allocating a socket to listen to either a TCP port or to a Unix 333
347 socket on the remote side. Whenever a connection is made to this 334 This works by allocating a socket to listen to either a TCP port
348 port or Unix socket, the connection is forwarded over the secure 335 or to a Unix socket on the remote side. Whenever a connection is
349 channel, and a connection is made to either host port hostport, 336 made to this port or Unix socket, the connection is forwarded
350 or local_socket, from the local machine. 337 over the secure channel, and a connection is made from the local
338 machine to either an explicit destination specified by host port
339 hostport, or local_socket, or, if no explicit destination was
340 specified, ssh will act as a SOCKS 4/5 proxy and forward
341 connections to the destinations requested by the remote SOCKS
342 client.
351 343
352 Port forwardings can also be specified in the configuration file. 344 Port forwardings can also be specified in the configuration file.
353 Privileged ports can be forwarded only when logging in as root on 345 Privileged ports can be forwarded only when logging in as root on
@@ -438,12 +430,7 @@ DESCRIPTION
438 and configuration options are described in ssh_config(5). 430 and configuration options are described in ssh_config(5).
439 431
440AUTHENTICATION 432AUTHENTICATION
441 The OpenSSH SSH client supports SSH protocols 1 and 2. The default is to 433 The OpenSSH SSH client supports SSH protocol 2.
442 use protocol 2 only, though this can be changed via the Protocol option
443 in ssh_config(5) or the -1 and -2 options (see above). Protocol 1 should
444 not be used and is only offered to support legacy devices. It suffers
445 from a number of cryptographic weaknesses and doesn't support many of the
446 advanced features available for protocol 2.
447 434
448 The methods available for authentication are: GSSAPI-based 435 The methods available for authentication are: GSSAPI-based
449 authentication, host-based authentication, public key authentication, 436 authentication, host-based authentication, public key authentication,
@@ -481,11 +468,15 @@ AUTHENTICATION
481 proves that it has access to the private key and the server checks that 468 proves that it has access to the private key and the server checks that
482 the corresponding public key is authorized to accept the account. 469 the corresponding public key is authorized to accept the account.
483 470
471 The server may inform the client of errors that prevented public key
472 authentication from succeeding after authentication completes using a
473 different method. These may be viewed by increasing the LogLevel to
474 DEBUG or higher (e.g. by using the -v flag).
475
484 The user creates his/her key pair by running ssh-keygen(1). This stores 476 The user creates his/her key pair by running ssh-keygen(1). This stores
485 the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (DSA), 477 the private key in ~/.ssh/id_dsa (DSA), ~/.ssh/id_ecdsa (ECDSA),
486 ~/.ssh/id_ecdsa (ECDSA), ~/.ssh/id_ed25519 (Ed25519), or ~/.ssh/id_rsa 478 ~/.ssh/id_ed25519 (Ed25519), or ~/.ssh/id_rsa (RSA) and stores the public
487 (RSA) and stores the public key in ~/.ssh/identity.pub (protocol 1), 479 key in ~/.ssh/id_dsa.pub (DSA), ~/.ssh/id_ecdsa.pub (ECDSA),
488 ~/.ssh/id_dsa.pub (DSA), ~/.ssh/id_ecdsa.pub (ECDSA),
489 ~/.ssh/id_ed25519.pub (Ed25519), or ~/.ssh/id_rsa.pub (RSA) in the user's 480 ~/.ssh/id_ed25519.pub (Ed25519), or ~/.ssh/id_rsa.pub (RSA) in the user's
490 home directory. The user should then copy the public key to 481 home directory. The user should then copy the public key to
491 ~/.ssh/authorized_keys in his/her home directory on the remote machine. 482 ~/.ssh/authorized_keys in his/her home directory on the remote machine.
@@ -845,7 +836,6 @@ FILES
845 Contains additional definitions for environment variables; see 836 Contains additional definitions for environment variables; see
846 ENVIRONMENT, above. 837 ENVIRONMENT, above.
847 838
848 ~/.ssh/identity
849 ~/.ssh/id_dsa 839 ~/.ssh/id_dsa
850 ~/.ssh/id_ecdsa 840 ~/.ssh/id_ecdsa
851 ~/.ssh/id_ed25519 841 ~/.ssh/id_ed25519
@@ -858,7 +848,6 @@ FILES
858 will be used to encrypt the sensitive part of this file using 848 will be used to encrypt the sensitive part of this file using
859 3DES. 849 3DES.
860 850
861 ~/.ssh/identity.pub
862 ~/.ssh/id_dsa.pub 851 ~/.ssh/id_dsa.pub
863 ~/.ssh/id_ecdsa.pub 852 ~/.ssh/id_ecdsa.pub
864 ~/.ssh/id_ed25519.pub 853 ~/.ssh/id_ed25519.pub
@@ -968,4 +957,4 @@ AUTHORS
968 created OpenSSH. Markus Friedl contributed the support for SSH protocol 957 created OpenSSH. Markus Friedl contributed the support for SSH protocol
969 versions 1.5 and 2.0. 958 versions 1.5 and 2.0.
970 959
971OpenBSD 6.0 July 16, 2016 OpenBSD 6.0 960OpenBSD 6.2 September 21, 2017 OpenBSD 6.2
diff --git a/ssh.1 b/ssh.1
index 4011c65aa..2ab1697f9 100644
--- a/ssh.1
+++ b/ssh.1
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh.1,v 1.376 2016/07/16 06:57:55 jmc Exp $ 36.\" $OpenBSD: ssh.1,v 1.384 2017/09/21 19:16:53 markus Exp $
37.Dd $Mdocdate: July 16 2016 $ 37.Dd $Mdocdate: September 21 2017 $
38.Dt SSH 1 38.Dt SSH 1
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -43,7 +43,7 @@
43.Sh SYNOPSIS 43.Sh SYNOPSIS
44.Nm ssh 44.Nm ssh
45.Bk -words 45.Bk -words
46.Op Fl 1246AaCfGgKkMNnqsTtVvXxYy 46.Op Fl 46AaCfGgKkMNnqsTtVvXxYy
47.Op Fl b Ar bind_address 47.Op Fl b Ar bind_address
48.Op Fl c Ar cipher_spec 48.Op Fl c Ar cipher_spec
49.Op Fl D Oo Ar bind_address : Oc Ns Ar port 49.Op Fl D Oo Ar bind_address : Oc Ns Ar port
@@ -95,16 +95,6 @@ it is executed on the remote host instead of a login shell.
95The options are as follows: 95The options are as follows:
96.Pp 96.Pp
97.Bl -tag -width Ds -compact 97.Bl -tag -width Ds -compact
98.It Fl 1
99Forces
100.Nm
101to try protocol version 1 only.
102.Pp
103.It Fl 2
104Forces
105.Nm
106to try protocol version 2 only.
107.Pp
108.It Fl 4 98.It Fl 4
109Forces 99Forces
110.Nm 100.Nm
@@ -144,12 +134,7 @@ data for forwarded X11, TCP and
144.Ux Ns -domain 134.Ux Ns -domain
145connections). 135connections).
146The compression algorithm is the same used by 136The compression algorithm is the same used by
147.Xr gzip 1 , 137.Xr gzip 1 .
148and the
149.Dq level
150can be controlled by the
151.Cm CompressionLevel
152option for protocol version 1.
153Compression is desirable on modem lines and other 138Compression is desirable on modem lines and other
154slow connections, but will only slow down things on fast networks. 139slow connections, but will only slow down things on fast networks.
155The default value can be set on a host-by-host basis in the 140The default value can be set on a host-by-host basis in the
@@ -159,14 +144,6 @@ option.
159.Pp 144.Pp
160.It Fl c Ar cipher_spec 145.It Fl c Ar cipher_spec
161Selects the cipher specification for encrypting the session. 146Selects the cipher specification for encrypting the session.
162.Pp
163Protocol version 1 allows specification of a single cipher.
164The supported values are
165.Dq 3des ,
166.Dq blowfish ,
167and
168.Dq des .
169For protocol version 2,
170.Ar cipher_spec 147.Ar cipher_spec
171is a comma-separated list of ciphers 148is a comma-separated list of ciphers
172listed in order of preference. 149listed in order of preference.
@@ -290,14 +267,11 @@ private RSA key.
290Selects a file from which the identity (private key) for 267Selects a file from which the identity (private key) for
291public key authentication is read. 268public key authentication is read.
292The default is 269The default is
293.Pa ~/.ssh/identity
294for protocol version 1, and
295.Pa ~/.ssh/id_dsa , 270.Pa ~/.ssh/id_dsa ,
296.Pa ~/.ssh/id_ecdsa , 271.Pa ~/.ssh/id_ecdsa ,
297.Pa ~/.ssh/id_ed25519 272.Pa ~/.ssh/id_ed25519
298and 273and
299.Pa ~/.ssh/id_rsa 274.Pa ~/.ssh/id_rsa .
300for protocol version 2.
301Identity files may also be specified on 275Identity files may also be specified on
302a per-host basis in the configuration file. 276a per-host basis in the configuration file.
303It is possible to have multiple 277It is possible to have multiple
@@ -491,11 +465,9 @@ For full details of the options listed below, and their possible values, see
491.It CertificateFile 465.It CertificateFile
492.It ChallengeResponseAuthentication 466.It ChallengeResponseAuthentication
493.It CheckHostIP 467.It CheckHostIP
494.It Cipher
495.It Ciphers 468.It Ciphers
496.It ClearAllForwardings 469.It ClearAllForwardings
497.It Compression 470.It Compression
498.It CompressionLevel
499.It ConnectionAttempts 471.It ConnectionAttempts
500.It ConnectTimeout 472.It ConnectTimeout
501.It ControlMaster 473.It ControlMaster
@@ -540,17 +512,15 @@ For full details of the options listed below, and their possible values, see
540.It PKCS11Provider 512.It PKCS11Provider
541.It Port 513.It Port
542.It PreferredAuthentications 514.It PreferredAuthentications
543.It Protocol
544.It ProxyCommand 515.It ProxyCommand
545.It ProxyJump 516.It ProxyJump
546.It ProxyUseFdpass 517.It ProxyUseFdpass
547.It PubkeyAcceptedKeyTypes 518.It PubkeyAcceptedKeyTypes
548.It PubkeyAuthentication 519.It PubkeyAuthentication
549.It RekeyLimit 520.It RekeyLimit
521.It RemoteCommand
550.It RemoteForward 522.It RemoteForward
551.It RequestTTY 523.It RequestTTY
552.It RhostsRSAAuthentication
553.It RSAAuthentication
554.It SendEnv 524.It SendEnv
555.It ServerAliveInterval 525.It ServerAliveInterval
556.It ServerAliveCountMax 526.It ServerAliveCountMax
@@ -622,21 +592,30 @@ Causes most warning and diagnostic messages to be suppressed.
622.Ar remote_socket : local_socket 592.Ar remote_socket : local_socket
623.Sm on 593.Sm on
624.Xc 594.Xc
595.It Fl R Xo
596.Sm off
597.Oo Ar bind_address : Oc
598.Ar port
599.Sm on
600.Xc
625Specifies that connections to the given TCP port or Unix socket on the remote 601Specifies that connections to the given TCP port or Unix socket on the remote
626(server) host are to be forwarded to the given host and port, or Unix socket, 602(server) host are to be forwarded to the local side.
627on the local side. 603.Pp
628This works by allocating a socket to listen to either a TCP 604This works by allocating a socket to listen to either a TCP
629.Ar port 605.Ar port
630or to a Unix socket on the remote side. 606or to a Unix socket on the remote side.
631Whenever a connection is made to this port or Unix socket, the 607Whenever a connection is made to this port or Unix socket, the
632connection is forwarded over the secure channel, and a connection 608connection is forwarded over the secure channel, and a connection
633is made to either 609is made from the local machine to either an explicit destination specified by
634.Ar host 610.Ar host
635port 611port
636.Ar hostport , 612.Ar hostport ,
637or 613or
638.Ar local_socket , 614.Ar local_socket ,
639from the local machine. 615or, if no explicit destination was specified,
616.Nm
617will act as a SOCKS 4/5 proxy and forward connections to the destinations
618requested by the remote SOCKS client.
640.Pp 619.Pp
641Port forwardings can also be specified in the configuration file. 620Port forwardings can also be specified in the configuration file.
642Privileged ports can be forwarded only when 621Privileged ports can be forwarded only when
@@ -806,21 +785,7 @@ a per-user configuration file and a system-wide configuration file.
806The file format and configuration options are described in 785The file format and configuration options are described in
807.Xr ssh_config 5 . 786.Xr ssh_config 5 .
808.Sh AUTHENTICATION 787.Sh AUTHENTICATION
809The OpenSSH SSH client supports SSH protocols 1 and 2. 788The OpenSSH SSH client supports SSH protocol 2.
810The default is to use protocol 2 only,
811though this can be changed via the
812.Cm Protocol
813option in
814.Xr ssh_config 5
815or the
816.Fl 1
817and
818.Fl 2
819options (see above).
820Protocol 1 should not be used
821and is only offered to support legacy devices.
822It suffers from a number of cryptographic weaknesses
823and doesn't support many of the advanced features available for protocol 2.
824.Pp 789.Pp
825The methods available for authentication are: 790The methods available for authentication are:
826GSSAPI-based authentication, 791GSSAPI-based authentication,
@@ -890,11 +855,20 @@ The client proves that it has access to the private key
890and the server checks that the corresponding public key 855and the server checks that the corresponding public key
891is authorized to accept the account. 856is authorized to accept the account.
892.Pp 857.Pp
858The server may inform the client of errors that prevented public key
859authentication from succeeding after authentication completes using a
860different method.
861These may be viewed by increasing the
862.Cm LogLevel
863to
864.Cm DEBUG
865or higher (e.g. by using the
866.Fl v
867flag).
868.Pp
893The user creates his/her key pair by running 869The user creates his/her key pair by running
894.Xr ssh-keygen 1 . 870.Xr ssh-keygen 1 .
895This stores the private key in 871This stores the private key in
896.Pa ~/.ssh/identity
897(protocol 1),
898.Pa ~/.ssh/id_dsa 872.Pa ~/.ssh/id_dsa
899(DSA), 873(DSA),
900.Pa ~/.ssh/id_ecdsa 874.Pa ~/.ssh/id_ecdsa
@@ -905,8 +879,6 @@ or
905.Pa ~/.ssh/id_rsa 879.Pa ~/.ssh/id_rsa
906(RSA) 880(RSA)
907and stores the public key in 881and stores the public key in
908.Pa ~/.ssh/identity.pub
909(protocol 1),
910.Pa ~/.ssh/id_dsa.pub 882.Pa ~/.ssh/id_dsa.pub
911(DSA), 883(DSA),
912.Pa ~/.ssh/id_ecdsa.pub 884.Pa ~/.ssh/id_ecdsa.pub
@@ -1490,7 +1462,6 @@ Contains additional definitions for environment variables; see
1490.Sx ENVIRONMENT , 1462.Sx ENVIRONMENT ,
1491above. 1463above.
1492.Pp 1464.Pp
1493.It Pa ~/.ssh/identity
1494.It Pa ~/.ssh/id_dsa 1465.It Pa ~/.ssh/id_dsa
1495.It Pa ~/.ssh/id_ecdsa 1466.It Pa ~/.ssh/id_ecdsa
1496.It Pa ~/.ssh/id_ed25519 1467.It Pa ~/.ssh/id_ed25519
@@ -1505,7 +1476,6 @@ It is possible to specify a passphrase when
1505generating the key which will be used to encrypt the 1476generating the key which will be used to encrypt the
1506sensitive part of this file using 3DES. 1477sensitive part of this file using 3DES.
1507.Pp 1478.Pp
1508.It Pa ~/.ssh/identity.pub
1509.It Pa ~/.ssh/id_dsa.pub 1479.It Pa ~/.ssh/id_dsa.pub
1510.It Pa ~/.ssh/id_ecdsa.pub 1480.It Pa ~/.ssh/id_ecdsa.pub
1511.It Pa ~/.ssh/id_ed25519.pub 1481.It Pa ~/.ssh/id_ed25519.pub
diff --git a/ssh.c b/ssh.c
index 32b27bbc2..ae37432bd 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.451 2017/03/10 04:07:20 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.464 2017/09/21 19:16:53 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -81,7 +81,6 @@
81 81
82#include "xmalloc.h" 82#include "xmalloc.h"
83#include "ssh.h" 83#include "ssh.h"
84#include "ssh1.h"
85#include "ssh2.h" 84#include "ssh2.h"
86#include "canohost.h" 85#include "canohost.h"
87#include "compat.h" 86#include "compat.h"
@@ -198,7 +197,7 @@ static void
198usage(void) 197usage(void)
199{ 198{
200 fprintf(stderr, 199 fprintf(stderr,
201"usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" 200"usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n"
202" [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" 201" [-D [bind_address:]port] [-E log_file] [-e escape_char]\n"
203" [-F configfile] [-I pkcs11] [-i identity_file]\n" 202" [-F configfile] [-I pkcs11] [-i identity_file]\n"
204" [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n" 203" [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n"
@@ -209,8 +208,7 @@ usage(void)
209 exit(255); 208 exit(255);
210} 209}
211 210
212static int ssh_session(void); 211static int ssh_session2(struct ssh *);
213static int ssh_session2(void);
214static void load_public_identity_files(void); 212static void load_public_identity_files(void);
215static void main_sigchld_handler(int); 213static void main_sigchld_handler(int);
216 214
@@ -511,13 +509,13 @@ int
511main(int ac, char **av) 509main(int ac, char **av)
512{ 510{
513 struct ssh *ssh = NULL; 511 struct ssh *ssh = NULL;
514 int i, r, opt, exit_status, use_syslog, direct, config_test = 0; 512 int i, r, opt, exit_status, use_syslog, direct, timeout_ms;
513 int config_test = 0, opt_terminated = 0;
515 char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; 514 char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile;
516 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; 515 char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
517 char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex; 516 char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex;
518 struct stat st; 517 struct stat st;
519 struct passwd *pw; 518 struct passwd *pw;
520 int timeout_ms;
521 extern int optind, optreset; 519 extern int optind, optreset;
522 extern char *optarg; 520 extern char *optarg;
523 struct Forward fwd; 521 struct Forward fwd;
@@ -598,6 +596,14 @@ main(int ac, char **av)
598 */ 596 */
599 initialize_options(&options); 597 initialize_options(&options);
600 598
599 /*
600 * Prepare main ssh transport/connection structures
601 */
602 if ((ssh = ssh_alloc_session_state()) == NULL)
603 fatal("Couldn't allocate session state");
604 channel_init_channels(ssh);
605 active_state = ssh; /* XXX legacy API compat */
606
601 /* Parse command-line arguments. */ 607 /* Parse command-line arguments. */
602 host = NULL; 608 host = NULL;
603 use_syslog = 0; 609 use_syslog = 0;
@@ -609,10 +615,10 @@ main(int ac, char **av)
609 "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { 615 "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
610 switch (opt) { 616 switch (opt) {
611 case '1': 617 case '1':
612 options.protocol = SSH_PROTO_1; 618 fatal("SSH protocol v.1 is no longer supported");
613 break; 619 break;
614 case '2': 620 case '2':
615 options.protocol = SSH_PROTO_2; 621 /* Ignored */
616 break; 622 break;
617 case '4': 623 case '4':
618 options.address_family = AF_INET; 624 options.address_family = AF_INET;
@@ -690,11 +696,7 @@ main(int ac, char **av)
690 else if (strcmp(optarg, "key-plain") == 0) 696 else if (strcmp(optarg, "key-plain") == 0)
691 cp = sshkey_alg_list(0, 1, 0, '\n'); 697 cp = sshkey_alg_list(0, 1, 0, '\n');
692 else if (strcmp(optarg, "protocol-version") == 0) { 698 else if (strcmp(optarg, "protocol-version") == 0) {
693#ifdef WITH_SSH1
694 cp = xstrdup("1\n2");
695#else
696 cp = xstrdup("2"); 699 cp = xstrdup("2");
697#endif
698 } 700 }
699 if (cp == NULL) 701 if (cp == NULL)
700 fatal("Unsupported query \"%s\"", optarg); 702 fatal("Unsupported query \"%s\"", optarg);
@@ -818,27 +820,14 @@ main(int ac, char **av)
818 } 820 }
819 break; 821 break;
820 case 'c': 822 case 'c':
821 if (ciphers_valid(*optarg == '+' ? 823 if (!ciphers_valid(*optarg == '+' ?
822 optarg + 1 : optarg)) { 824 optarg + 1 : optarg)) {
823 /* SSH2 only */
824 free(options.ciphers);
825 options.ciphers = xstrdup(optarg);
826 options.cipher = SSH_CIPHER_INVALID;
827 break;
828 }
829 /* SSH1 only */
830 options.cipher = cipher_number(optarg);
831 if (options.cipher == -1) {
832 fprintf(stderr, "Unknown cipher type '%s'\n", 825 fprintf(stderr, "Unknown cipher type '%s'\n",
833 optarg); 826 optarg);
834 exit(255); 827 exit(255);
835 } 828 }
836 if (options.cipher == SSH_CIPHER_3DES) 829 free(options.ciphers);
837 options.ciphers = xstrdup("3des-cbc"); 830 options.ciphers = xstrdup(optarg);
838 else if (options.cipher == SSH_CIPHER_BLOWFISH)
839 options.ciphers = xstrdup("blowfish-cbc");
840 else
841 options.ciphers = xstrdup(KEX_CLIENT_ENCRYPT);
842 break; 831 break;
843 case 'm': 832 case 'm':
844 if (mac_valid(optarg)) { 833 if (mac_valid(optarg)) {
@@ -879,7 +868,8 @@ main(int ac, char **av)
879 break; 868 break;
880 869
881 case 'R': 870 case 'R':
882 if (parse_forward(&fwd, optarg, 0, 1)) { 871 if (parse_forward(&fwd, optarg, 0, 1) ||
872 parse_forward(&fwd, optarg, 1, 1)) {
883 add_remote_forward(&options, &fwd); 873 add_remote_forward(&options, &fwd);
884 } else { 874 } else {
885 fprintf(stderr, 875 fprintf(stderr,
@@ -936,6 +926,9 @@ main(int ac, char **av)
936 } 926 }
937 } 927 }
938 928
929 if (optind > 1 && strcmp(av[optind - 1], "--") == 0)
930 opt_terminated = 1;
931
939 ac -= optind; 932 ac -= optind;
940 av += optind; 933 av += optind;
941 934
@@ -950,7 +943,7 @@ main(int ac, char **av)
950 host = xstrdup(++cp); 943 host = xstrdup(++cp);
951 } else 944 } else
952 host = xstrdup(*av); 945 host = xstrdup(*av);
953 if (ac > 1) { 946 if (ac > 1 && !opt_terminated) {
954 optind = optreset = 1; 947 optind = optreset = 1;
955 goto again; 948 goto again;
956 } 949 }
@@ -992,12 +985,6 @@ main(int ac, char **av)
992 } 985 }
993 } 986 }
994 987
995 /* Cannot fork to background if no command. */
996 if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
997 !no_shell_flag)
998 fatal("Cannot fork into background without a command "
999 "to execute.");
1000
1001 /* 988 /*
1002 * Initialize "log" output. Since we are the client all output 989 * Initialize "log" output. Since we are the client all output
1003 * goes to stderr unless otherwise specified by -y or -E. 990 * goes to stderr unless otherwise specified by -y or -E.
@@ -1007,8 +994,11 @@ main(int ac, char **av)
1007 if (logfile != NULL) 994 if (logfile != NULL)
1008 log_redirect_stderr_to(logfile); 995 log_redirect_stderr_to(logfile);
1009 log_init(argv0, 996 log_init(argv0,
1010 options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, 997 options.log_level == SYSLOG_LEVEL_NOT_SET ?
1011 SYSLOG_FACILITY_USER, !use_syslog); 998 SYSLOG_LEVEL_INFO : options.log_level,
999 options.log_facility == SYSLOG_FACILITY_NOT_SET ?
1000 SYSLOG_FACILITY_USER : options.log_facility,
1001 !use_syslog);
1012 1002
1013 if (debug_flag) 1003 if (debug_flag)
1014 logit("%s, %s", SSH_RELEASE, 1004 logit("%s, %s", SSH_RELEASE,
@@ -1127,7 +1117,7 @@ main(int ac, char **av)
1127 1117
1128 if (options.port == 0) 1118 if (options.port == 0)
1129 options.port = default_ssh_port(); 1119 options.port = default_ssh_port();
1130 channel_set_af(options.address_family); 1120 channel_set_af(ssh, options.address_family);
1131 1121
1132 /* Tidy and check options */ 1122 /* Tidy and check options */
1133 if (options.host_key_alias != NULL) 1123 if (options.host_key_alias != NULL)
@@ -1149,15 +1139,24 @@ main(int ac, char **av)
1149 options.use_privileged_port = 0; 1139 options.use_privileged_port = 0;
1150#endif 1140#endif
1151 1141
1142 if (buffer_len(&command) != 0 && options.remote_command != NULL)
1143 fatal("Cannot execute command-line and remote command.");
1144
1145 /* Cannot fork to background if no command. */
1146 if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
1147 options.remote_command == NULL && !no_shell_flag)
1148 fatal("Cannot fork into background without a command "
1149 "to execute.");
1150
1152 /* reinit */ 1151 /* reinit */
1153 log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog); 1152 log_init(argv0, options.log_level, options.log_facility, !use_syslog);
1154 1153
1155 if (options.request_tty == REQUEST_TTY_YES || 1154 if (options.request_tty == REQUEST_TTY_YES ||
1156 options.request_tty == REQUEST_TTY_FORCE) 1155 options.request_tty == REQUEST_TTY_FORCE)
1157 tty_flag = 1; 1156 tty_flag = 1;
1158 1157
1159 /* Allocate a tty by default if no command specified. */ 1158 /* Allocate a tty by default if no command specified. */
1160 if (buffer_len(&command) == 0) 1159 if (buffer_len(&command) == 0 && options.remote_command == NULL)
1161 tty_flag = options.request_tty != REQUEST_TTY_NO; 1160 tty_flag = options.request_tty != REQUEST_TTY_NO;
1162 1161
1163 /* Force no tty */ 1162 /* Force no tty */
@@ -1213,6 +1212,27 @@ main(int ac, char **av)
1213 free(cp); 1212 free(cp);
1214 } 1213 }
1215 1214
1215 if (options.remote_command != NULL) {
1216 debug3("expanding RemoteCommand: %s", options.remote_command);
1217 cp = options.remote_command;
1218 options.remote_command = percent_expand(cp,
1219 "C", conn_hash_hex,
1220 "L", shorthost,
1221 "d", pw->pw_dir,
1222 "h", host,
1223 "l", thishost,
1224 "n", host_arg,
1225 "p", portstr,
1226 "r", options.user,
1227 "u", pw->pw_name,
1228 (char *)NULL);
1229 debug3("expanded RemoteCommand: %s", options.remote_command);
1230 free(cp);
1231 buffer_append(&command, options.remote_command,
1232 strlen(options.remote_command));
1233
1234 }
1235
1216 if (options.control_path != NULL) { 1236 if (options.control_path != NULL) {
1217 cp = tilde_expand_filename(options.control_path, 1237 cp = tilde_expand_filename(options.control_path,
1218 original_real_uid); 1238 original_real_uid);
@@ -1242,9 +1262,7 @@ main(int ac, char **av)
1242 if (options.control_path != NULL) { 1262 if (options.control_path != NULL) {
1243 int sock; 1263 int sock;
1244 if ((sock = muxclient(options.control_path)) >= 0) { 1264 if ((sock = muxclient(options.control_path)) >= 0) {
1245 packet_set_connection(sock, sock); 1265 ssh_packet_set_connection(ssh, sock, sock);
1246 ssh = active_state; /* XXX */
1247 enable_compat20(); /* XXX */
1248 packet_set_mux(); 1266 packet_set_mux();
1249 goto skip_connect; 1267 goto skip_connect;
1250 } 1268 }
@@ -1264,7 +1282,7 @@ main(int ac, char **av)
1264 timeout_ms = options.connection_timeout * 1000; 1282 timeout_ms = options.connection_timeout * 1000;
1265 1283
1266 /* Open a connection to the remote host. */ 1284 /* Open a connection to the remote host. */
1267 if (ssh_connect(host, addrs, &hostaddr, options.port, 1285 if (ssh_connect(ssh, host, addrs, &hostaddr, options.port,
1268 options.address_family, options.connection_attempts, 1286 options.address_family, options.connection_attempts,
1269 &timeout_ms, options.tcp_keep_alive, 1287 &timeout_ms, options.tcp_keep_alive,
1270 options.use_privileged_port) != 0) 1288 options.use_privileged_port) != 0)
@@ -1292,19 +1310,14 @@ main(int ac, char **av)
1292 sensitive_data.nkeys = 0; 1310 sensitive_data.nkeys = 0;
1293 sensitive_data.keys = NULL; 1311 sensitive_data.keys = NULL;
1294 sensitive_data.external_keysign = 0; 1312 sensitive_data.external_keysign = 0;
1295 if (options.rhosts_rsa_authentication || 1313 if (options.hostbased_authentication) {
1296 options.hostbased_authentication) {
1297 sensitive_data.nkeys = 9; 1314 sensitive_data.nkeys = 9;
1298 sensitive_data.keys = xcalloc(sensitive_data.nkeys, 1315 sensitive_data.keys = xcalloc(sensitive_data.nkeys,
1299 sizeof(Key)); 1316 sizeof(struct sshkey)); /* XXX */
1300 for (i = 0; i < sensitive_data.nkeys; i++) 1317 for (i = 0; i < sensitive_data.nkeys; i++)
1301 sensitive_data.keys[i] = NULL; 1318 sensitive_data.keys[i] = NULL;
1302 1319
1303 PRIV_START; 1320 PRIV_START;
1304#if WITH_SSH1
1305 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
1306 _PATH_HOST_KEY_FILE, "", NULL, NULL);
1307#endif
1308#ifdef OPENSSL_HAS_ECC 1321#ifdef OPENSSL_HAS_ECC
1309 sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA, 1322 sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA,
1310 _PATH_HOST_ECDSA_KEY_FILE, "", NULL); 1323 _PATH_HOST_ECDSA_KEY_FILE, "", NULL);
@@ -1452,7 +1465,7 @@ main(int ac, char **av)
1452 } 1465 }
1453 1466
1454 skip_connect: 1467 skip_connect:
1455 exit_status = compat20 ? ssh_session2() : ssh_session(); 1468 exit_status = ssh_session2(ssh);
1456 packet_close(); 1469 packet_close();
1457 1470
1458 if (options.control_path != NULL && muxserver_sock != -1) 1471 if (options.control_path != NULL && muxserver_sock != -1)
@@ -1525,7 +1538,7 @@ fork_postauth(void)
1525 1538
1526/* Callback for remote forward global requests */ 1539/* Callback for remote forward global requests */
1527static void 1540static void
1528ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) 1541ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
1529{ 1542{
1530 struct Forward *rfwd = (struct Forward *)ctxt; 1543 struct Forward *rfwd = (struct Forward *)ctxt;
1531 1544
@@ -1543,10 +1556,10 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1543 logit("Allocated port %u for remote forward to %s:%d", 1556 logit("Allocated port %u for remote forward to %s:%d",
1544 rfwd->allocated_port, 1557 rfwd->allocated_port,
1545 rfwd->connect_host, rfwd->connect_port); 1558 rfwd->connect_host, rfwd->connect_port);
1546 channel_update_permitted_opens(rfwd->handle, 1559 channel_update_permitted_opens(ssh,
1547 rfwd->allocated_port); 1560 rfwd->handle, rfwd->allocated_port);
1548 } else { 1561 } else {
1549 channel_update_permitted_opens(rfwd->handle, -1); 1562 channel_update_permitted_opens(ssh, rfwd->handle, -1);
1550 } 1563 }
1551 } 1564 }
1552 1565
@@ -1575,29 +1588,27 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
1575} 1588}
1576 1589
1577static void 1590static void
1578client_cleanup_stdio_fwd(int id, void *arg) 1591client_cleanup_stdio_fwd(struct ssh *ssh, int id, void *arg)
1579{ 1592{
1580 debug("stdio forwarding: done"); 1593 debug("stdio forwarding: done");
1581 cleanup_exit(0); 1594 cleanup_exit(0);
1582} 1595}
1583 1596
1584static void 1597static void
1585ssh_stdio_confirm(int id, int success, void *arg) 1598ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
1586{ 1599{
1587 if (!success) 1600 if (!success)
1588 fatal("stdio forwarding failed"); 1601 fatal("stdio forwarding failed");
1589} 1602}
1590 1603
1591static void 1604static void
1592ssh_init_stdio_forwarding(void) 1605ssh_init_stdio_forwarding(struct ssh *ssh)
1593{ 1606{
1594 Channel *c; 1607 Channel *c;
1595 int in, out; 1608 int in, out;
1596 1609
1597 if (options.stdio_forward_host == NULL) 1610 if (options.stdio_forward_host == NULL)
1598 return; 1611 return;
1599 if (!compat20)
1600 fatal("stdio forwarding require Protocol 2");
1601 1612
1602 debug3("%s: %s:%d", __func__, options.stdio_forward_host, 1613 debug3("%s: %s:%d", __func__, options.stdio_forward_host,
1603 options.stdio_forward_port); 1614 options.stdio_forward_port);
@@ -1605,15 +1616,15 @@ ssh_init_stdio_forwarding(void)
1605 if ((in = dup(STDIN_FILENO)) < 0 || 1616 if ((in = dup(STDIN_FILENO)) < 0 ||
1606 (out = dup(STDOUT_FILENO)) < 0) 1617 (out = dup(STDOUT_FILENO)) < 0)
1607 fatal("channel_connect_stdio_fwd: dup() in/out failed"); 1618 fatal("channel_connect_stdio_fwd: dup() in/out failed");
1608 if ((c = channel_connect_stdio_fwd(options.stdio_forward_host, 1619 if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host,
1609 options.stdio_forward_port, in, out)) == NULL) 1620 options.stdio_forward_port, in, out)) == NULL)
1610 fatal("%s: channel_connect_stdio_fwd failed", __func__); 1621 fatal("%s: channel_connect_stdio_fwd failed", __func__);
1611 channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0); 1622 channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0);
1612 channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL); 1623 channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL);
1613} 1624}
1614 1625
1615static void 1626static void
1616ssh_init_forwarding(void) 1627ssh_init_forwarding(struct ssh *ssh)
1617{ 1628{
1618 int success = 0; 1629 int success = 0;
1619 int i; 1630 int i;
@@ -1632,7 +1643,7 @@ ssh_init_forwarding(void)
1632 options.local_forwards[i].connect_path : 1643 options.local_forwards[i].connect_path :
1633 options.local_forwards[i].connect_host, 1644 options.local_forwards[i].connect_host,
1634 options.local_forwards[i].connect_port); 1645 options.local_forwards[i].connect_port);
1635 success += channel_setup_local_fwd_listener( 1646 success += channel_setup_local_fwd_listener(ssh,
1636 &options.local_forwards[i], &options.fwd_opts); 1647 &options.local_forwards[i], &options.fwd_opts);
1637 } 1648 }
1638 if (i > 0 && success != i && options.exit_on_forward_failure) 1649 if (i > 0 && success != i && options.exit_on_forward_failure)
@@ -1654,7 +1665,7 @@ ssh_init_forwarding(void)
1654 options.remote_forwards[i].connect_host, 1665 options.remote_forwards[i].connect_host,
1655 options.remote_forwards[i].connect_port); 1666 options.remote_forwards[i].connect_port);
1656 options.remote_forwards[i].handle = 1667 options.remote_forwards[i].handle =
1657 channel_request_remote_forwarding( 1668 channel_request_remote_forwarding(ssh,
1658 &options.remote_forwards[i]); 1669 &options.remote_forwards[i]);
1659 if (options.remote_forwards[i].handle < 0) { 1670 if (options.remote_forwards[i].handle < 0) {
1660 if (options.exit_on_forward_failure) 1671 if (options.exit_on_forward_failure)
@@ -1663,14 +1674,15 @@ ssh_init_forwarding(void)
1663 logit("Warning: Could not request remote " 1674 logit("Warning: Could not request remote "
1664 "forwarding."); 1675 "forwarding.");
1665 } else { 1676 } else {
1666 client_register_global_confirm(ssh_confirm_remote_forward, 1677 client_register_global_confirm(
1678 ssh_confirm_remote_forward,
1667 &options.remote_forwards[i]); 1679 &options.remote_forwards[i]);
1668 } 1680 }
1669 } 1681 }
1670 1682
1671 /* Initiate tunnel forwarding. */ 1683 /* Initiate tunnel forwarding. */
1672 if (options.tun_open != SSH_TUNMODE_NO) { 1684 if (options.tun_open != SSH_TUNMODE_NO) {
1673 if (client_request_tun_fwd(options.tun_open, 1685 if (client_request_tun_fwd(ssh, options.tun_open,
1674 options.tun_local, options.tun_remote) == -1) { 1686 options.tun_local, options.tun_remote) == -1) {
1675 if (options.exit_on_forward_failure) 1687 if (options.exit_on_forward_failure)
1676 fatal("Could not request tunnel forwarding."); 1688 fatal("Could not request tunnel forwarding.");
@@ -1696,174 +1708,8 @@ check_agent_present(void)
1696 } 1708 }
1697} 1709}
1698 1710
1699static int
1700ssh_session(void)
1701{
1702 int type;
1703 int interactive = 0;
1704 int have_tty = 0;
1705 struct winsize ws;
1706 char *cp;
1707 const char *display;
1708 char *proto = NULL, *data = NULL;
1709
1710 /* Enable compression if requested. */
1711 if (options.compression) {
1712 debug("Requesting compression at level %d.",
1713 options.compression_level);
1714
1715 if (options.compression_level < 1 ||
1716 options.compression_level > 9)
1717 fatal("Compression level must be from 1 (fast) to "
1718 "9 (slow, best).");
1719
1720 /* Send the request. */
1721 packet_start(SSH_CMSG_REQUEST_COMPRESSION);
1722 packet_put_int(options.compression_level);
1723 packet_send();
1724 packet_write_wait();
1725 type = packet_read();
1726 if (type == SSH_SMSG_SUCCESS)
1727 packet_start_compression(options.compression_level);
1728 else if (type == SSH_SMSG_FAILURE)
1729 logit("Warning: Remote host refused compression.");
1730 else
1731 packet_disconnect("Protocol error waiting for "
1732 "compression response.");
1733 }
1734 /* Allocate a pseudo tty if appropriate. */
1735 if (tty_flag) {
1736 debug("Requesting pty.");
1737
1738 /* Start the packet. */
1739 packet_start(SSH_CMSG_REQUEST_PTY);
1740
1741 /* Store TERM in the packet. There is no limit on the
1742 length of the string. */
1743 cp = getenv("TERM");
1744 if (!cp)
1745 cp = "";
1746 packet_put_cstring(cp);
1747
1748 /* Store window size in the packet. */
1749 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
1750 memset(&ws, 0, sizeof(ws));
1751 packet_put_int((u_int)ws.ws_row);
1752 packet_put_int((u_int)ws.ws_col);
1753 packet_put_int((u_int)ws.ws_xpixel);
1754 packet_put_int((u_int)ws.ws_ypixel);
1755
1756 /* Store tty modes in the packet. */
1757 tty_make_modes(fileno(stdin), NULL);
1758
1759 /* Send the packet, and wait for it to leave. */
1760 packet_send();
1761 packet_write_wait();
1762
1763 /* Read response from the server. */
1764 type = packet_read();
1765 if (type == SSH_SMSG_SUCCESS) {
1766 interactive = 1;
1767 have_tty = 1;
1768 } else if (type == SSH_SMSG_FAILURE)
1769 logit("Warning: Remote host failed or refused to "
1770 "allocate a pseudo tty.");
1771 else
1772 packet_disconnect("Protocol error waiting for pty "
1773 "request response.");
1774 }
1775 /* Request X11 forwarding if enabled and DISPLAY is set. */
1776 display = getenv("DISPLAY");
1777 if (display == NULL && options.forward_x11)
1778 debug("X11 forwarding requested but DISPLAY not set");
1779 if (options.forward_x11 && client_x11_get_proto(display,
1780 options.xauth_location, options.forward_x11_trusted,
1781 options.forward_x11_timeout, &proto, &data) == 0) {
1782 /* Request forwarding with authentication spoofing. */
1783 debug("Requesting X11 forwarding with authentication "
1784 "spoofing.");
1785 x11_request_forwarding_with_spoofing(0, display, proto,
1786 data, 0);
1787 /* Read response from the server. */
1788 type = packet_read();
1789 if (type == SSH_SMSG_SUCCESS) {
1790 interactive = 1;
1791 } else if (type == SSH_SMSG_FAILURE) {
1792 logit("Warning: Remote host denied X11 forwarding.");
1793 } else {
1794 packet_disconnect("Protocol error waiting for X11 "
1795 "forwarding");
1796 }
1797 }
1798 /* Tell the packet module whether this is an interactive session. */
1799 packet_set_interactive(interactive,
1800 options.ip_qos_interactive, options.ip_qos_bulk);
1801
1802 /* Request authentication agent forwarding if appropriate. */
1803 check_agent_present();
1804
1805 if (options.forward_agent) {
1806 debug("Requesting authentication agent forwarding.");
1807 auth_request_forwarding();
1808
1809 /* Read response from the server. */
1810 type = packet_read();
1811 packet_check_eom();
1812 if (type != SSH_SMSG_SUCCESS)
1813 logit("Warning: Remote host denied authentication agent forwarding.");
1814 }
1815
1816 /* Initiate port forwardings. */
1817 ssh_init_stdio_forwarding();
1818 ssh_init_forwarding();
1819
1820 /* Execute a local command */
1821 if (options.local_command != NULL &&
1822 options.permit_local_command)
1823 ssh_local_cmd(options.local_command);
1824
1825 /*
1826 * If requested and we are not interested in replies to remote
1827 * forwarding requests, then let ssh continue in the background.
1828 */
1829 if (fork_after_authentication_flag) {
1830 if (options.exit_on_forward_failure &&
1831 options.num_remote_forwards > 0) {
1832 debug("deferring postauth fork until remote forward "
1833 "confirmation received");
1834 } else
1835 fork_postauth();
1836 }
1837
1838 /*
1839 * If a command was specified on the command line, execute the
1840 * command now. Otherwise request the server to start a shell.
1841 */
1842 if (buffer_len(&command) > 0) {
1843 int len = buffer_len(&command);
1844 if (len > 900)
1845 len = 900;
1846 debug("Sending command: %.*s", len,
1847 (u_char *)buffer_ptr(&command));
1848 packet_start(SSH_CMSG_EXEC_CMD);
1849 packet_put_string(buffer_ptr(&command), buffer_len(&command));
1850 packet_send();
1851 packet_write_wait();
1852 } else {
1853 debug("Requesting shell.");
1854 packet_start(SSH_CMSG_EXEC_SHELL);
1855 packet_send();
1856 packet_write_wait();
1857 }
1858
1859 /* Enter the interactive session. */
1860 return client_loop(have_tty, tty_flag ?
1861 options.escape_char : SSH_ESCAPECHAR_NONE, 0);
1862}
1863
1864/* request pty/x11/agent/tcpfwd/shell for channel */
1865static void 1711static void
1866ssh_session2_setup(int id, int success, void *arg) 1712ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
1867{ 1713{
1868 extern char **environ; 1714 extern char **environ;
1869 const char *display; 1715 const char *display;
@@ -1876,15 +1722,15 @@ ssh_session2_setup(int id, int success, void *arg)
1876 display = getenv("DISPLAY"); 1722 display = getenv("DISPLAY");
1877 if (display == NULL && options.forward_x11) 1723 if (display == NULL && options.forward_x11)
1878 debug("X11 forwarding requested but DISPLAY not set"); 1724 debug("X11 forwarding requested but DISPLAY not set");
1879 if (options.forward_x11 && client_x11_get_proto(display, 1725 if (options.forward_x11 && client_x11_get_proto(ssh, display,
1880 options.xauth_location, options.forward_x11_trusted, 1726 options.xauth_location, options.forward_x11_trusted,
1881 options.forward_x11_timeout, &proto, &data) == 0) { 1727 options.forward_x11_timeout, &proto, &data) == 0) {
1882 /* Request forwarding with authentication spoofing. */ 1728 /* Request forwarding with authentication spoofing. */
1883 debug("Requesting X11 forwarding with authentication " 1729 debug("Requesting X11 forwarding with authentication "
1884 "spoofing."); 1730 "spoofing.");
1885 x11_request_forwarding_with_spoofing(id, display, proto, 1731 x11_request_forwarding_with_spoofing(ssh, id, display, proto,
1886 data, 1); 1732 data, 1);
1887 client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); 1733 client_expect_confirm(ssh, id, "X11 forwarding", CONFIRM_WARN);
1888 /* XXX exit_on_forward_failure */ 1734 /* XXX exit_on_forward_failure */
1889 interactive = 1; 1735 interactive = 1;
1890 } 1736 }
@@ -1892,7 +1738,7 @@ ssh_session2_setup(int id, int success, void *arg)
1892 check_agent_present(); 1738 check_agent_present();
1893 if (options.forward_agent) { 1739 if (options.forward_agent) {
1894 debug("Requesting authentication agent forwarding."); 1740 debug("Requesting authentication agent forwarding.");
1895 channel_request_start(id, "auth-agent-req@openssh.com", 0); 1741 channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
1896 packet_send(); 1742 packet_send();
1897 } 1743 }
1898 1744
@@ -1900,13 +1746,13 @@ ssh_session2_setup(int id, int success, void *arg)
1900 packet_set_interactive(interactive, 1746 packet_set_interactive(interactive,
1901 options.ip_qos_interactive, options.ip_qos_bulk); 1747 options.ip_qos_interactive, options.ip_qos_bulk);
1902 1748
1903 client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), 1749 client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"),
1904 NULL, fileno(stdin), &command, environ); 1750 NULL, fileno(stdin), &command, environ);
1905} 1751}
1906 1752
1907/* open new channel for a session */ 1753/* open new channel for a session */
1908static int 1754static int
1909ssh_session2_open(void) 1755ssh_session2_open(struct ssh *ssh)
1910{ 1756{
1911 Channel *c; 1757 Channel *c;
1912 int window, packetmax, in, out, err; 1758 int window, packetmax, in, out, err;
@@ -1936,34 +1782,34 @@ ssh_session2_open(void)
1936 window >>= 1; 1782 window >>= 1;
1937 packetmax >>= 1; 1783 packetmax >>= 1;
1938 } 1784 }
1939 c = channel_new( 1785 c = channel_new(ssh,
1940 "session", SSH_CHANNEL_OPENING, in, out, err, 1786 "session", SSH_CHANNEL_OPENING, in, out, err,
1941 window, packetmax, CHAN_EXTENDED_WRITE, 1787 window, packetmax, CHAN_EXTENDED_WRITE,
1942 "client-session", /*nonblock*/0); 1788 "client-session", /*nonblock*/0);
1943 1789
1944 debug3("ssh_session2_open: channel_new: %d", c->self); 1790 debug3("%s: channel_new: %d", __func__, c->self);
1945 1791
1946 channel_send_open(c->self); 1792 channel_send_open(ssh, c->self);
1947 if (!no_shell_flag) 1793 if (!no_shell_flag)
1948 channel_register_open_confirm(c->self, 1794 channel_register_open_confirm(ssh, c->self,
1949 ssh_session2_setup, NULL); 1795 ssh_session2_setup, NULL);
1950 1796
1951 return c->self; 1797 return c->self;
1952} 1798}
1953 1799
1954static int 1800static int
1955ssh_session2(void) 1801ssh_session2(struct ssh *ssh)
1956{ 1802{
1957 int id = -1; 1803 int id = -1;
1958 1804
1959 /* XXX should be pre-session */ 1805 /* XXX should be pre-session */
1960 if (!options.control_persist) 1806 if (!options.control_persist)
1961 ssh_init_stdio_forwarding(); 1807 ssh_init_stdio_forwarding(ssh);
1962 ssh_init_forwarding(); 1808 ssh_init_forwarding(ssh);
1963 1809
1964 /* Start listening for multiplex clients */ 1810 /* Start listening for multiplex clients */
1965 if (!packet_get_mux()) 1811 if (!packet_get_mux())
1966 muxserver_listen(); 1812 muxserver_listen(ssh);
1967 1813
1968 /* 1814 /*
1969 * If we are in control persist mode and have a working mux listen 1815 * If we are in control persist mode and have a working mux listen
@@ -1991,10 +1837,10 @@ ssh_session2(void)
1991 * stdio forward setup that we skipped earlier. 1837 * stdio forward setup that we skipped earlier.
1992 */ 1838 */
1993 if (options.control_persist && muxserver_sock == -1) 1839 if (options.control_persist && muxserver_sock == -1)
1994 ssh_init_stdio_forwarding(); 1840 ssh_init_stdio_forwarding(ssh);
1995 1841
1996 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) 1842 if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
1997 id = ssh_session2_open(); 1843 id = ssh_session2_open(ssh);
1998 else { 1844 else {
1999 packet_set_interactive( 1845 packet_set_interactive(
2000 options.control_master == SSHCTL_MASTER_NO, 1846 options.control_master == SSHCTL_MASTER_NO,
@@ -2029,7 +1875,7 @@ ssh_session2(void)
2029 fork_postauth(); 1875 fork_postauth();
2030 } 1876 }
2031 1877
2032 return client_loop(tty_flag, tty_flag ? 1878 return client_loop(ssh, tty_flag, tty_flag ?
2033 options.escape_char : SSH_ESCAPECHAR_NONE, id); 1879 options.escape_char : SSH_ESCAPECHAR_NONE, id);
2034} 1880}
2035 1881
@@ -2039,16 +1885,16 @@ load_public_identity_files(void)
2039{ 1885{
2040 char *filename, *cp, thishost[NI_MAXHOST]; 1886 char *filename, *cp, thishost[NI_MAXHOST];
2041 char *pwdir = NULL, *pwname = NULL; 1887 char *pwdir = NULL, *pwname = NULL;
2042 Key *public; 1888 struct sshkey *public;
2043 struct passwd *pw; 1889 struct passwd *pw;
2044 int i; 1890 int i;
2045 u_int n_ids, n_certs; 1891 u_int n_ids, n_certs;
2046 char *identity_files[SSH_MAX_IDENTITY_FILES]; 1892 char *identity_files[SSH_MAX_IDENTITY_FILES];
2047 Key *identity_keys[SSH_MAX_IDENTITY_FILES]; 1893 struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES];
2048 char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; 1894 char *certificate_files[SSH_MAX_CERTIFICATE_FILES];
2049 struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; 1895 struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
2050#ifdef ENABLE_PKCS11 1896#ifdef ENABLE_PKCS11
2051 Key **keys; 1897 struct sshkey **keys;
2052 int nkeys; 1898 int nkeys;
2053#endif /* PKCS11 */ 1899#endif /* PKCS11 */
2054 1900
diff --git a/ssh.h b/ssh.h
index 50467a792..12d800922 100644
--- a/ssh.h
+++ b/ssh.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.h,v 1.83 2015/12/11 03:19:09 djm Exp $ */ 1/* $OpenBSD: ssh.h,v 1.87 2017/05/07 23:15:59 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -32,7 +32,7 @@
32 32
33/* 33/*
34 * Maximum length of lines in authorized_keys file. 34 * Maximum length of lines in authorized_keys file.
35 * Current value permits 16kbit RSA and RSA1 keys and 8kbit DSA keys, with 35 * Current value permits 16kbit RSA keys and 8kbit DSA keys, with
36 * some room for options and comments. 36 * some room for options and comments.
37 */ 37 */
38#define SSH_MAX_PUBKEY_BYTES 16384 38#define SSH_MAX_PUBKEY_BYTES 16384
@@ -47,7 +47,7 @@
47#define PROTOCOL_MAJOR_1 1 47#define PROTOCOL_MAJOR_1 1
48#define PROTOCOL_MINOR_1 5 48#define PROTOCOL_MINOR_1 5
49 49
50/* We support both SSH1 and SSH2 */ 50/* We support only SSH2 */
51#define PROTOCOL_MAJOR_2 2 51#define PROTOCOL_MAJOR_2 2
52#define PROTOCOL_MINOR_2 0 52#define PROTOCOL_MINOR_2 0
53 53
@@ -98,8 +98,5 @@
98#define SSH_PRIVSEP_USER "sshd" 98#define SSH_PRIVSEP_USER "sshd"
99#endif 99#endif
100 100
101/* Minimum modulus size (n) for RSA keys. */
102#define SSH_RSA_MINIMUM_MODULUS_SIZE 768
103
104/* Listen backlog for sshd, ssh-agent and forwarding sockets */ 101/* Listen backlog for sshd, ssh-agent and forwarding sockets */
105#define SSH_LISTEN_BACKLOG 128 102#define SSH_LISTEN_BACKLOG 128
diff --git a/ssh1.h b/ssh1.h
deleted file mode 100644
index 6a05c4724..000000000
--- a/ssh1.h
+++ /dev/null
@@ -1,91 +0,0 @@
1/* $OpenBSD: ssh1.h,v 1.7 2016/05/04 14:22:33 markus Exp $ */
2
3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 * All rights reserved
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
13 */
14
15/*
16 * Definition of message types. New values can be added, but old values
17 * should not be removed or without careful consideration of the consequences
18 * for compatibility. The maximum value is 254; value 255 is reserved for
19 * future extension.
20 */
21/* Ranges */
22#define SSH_MSG_MIN 1
23#define SSH_MSG_MAX 254
24/* Message name */ /* msg code */ /* arguments */
25#define SSH_MSG_DISCONNECT 1 /* cause (string) */
26#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */
27#define SSH_CMSG_SESSION_KEY 3 /* key (BIGNUM) */
28#define SSH_CMSG_USER 4 /* user (string) */
29#define SSH_CMSG_AUTH_RHOSTS 5 /* user (string) */
30#define SSH_CMSG_AUTH_RSA 6 /* modulus (BIGNUM) */
31#define SSH_SMSG_AUTH_RSA_CHALLENGE 7 /* int (BIGNUM) */
32#define SSH_CMSG_AUTH_RSA_RESPONSE 8 /* int (BIGNUM) */
33#define SSH_CMSG_AUTH_PASSWORD 9 /* pass (string) */
34#define SSH_CMSG_REQUEST_PTY 10 /* TERM, tty modes */
35#define SSH_CMSG_WINDOW_SIZE 11 /* row,col,xpix,ypix */
36#define SSH_CMSG_EXEC_SHELL 12 /* */
37#define SSH_CMSG_EXEC_CMD 13 /* cmd (string) */
38#define SSH_SMSG_SUCCESS 14 /* */
39#define SSH_SMSG_FAILURE 15 /* */
40#define SSH_CMSG_STDIN_DATA 16 /* data (string) */
41#define SSH_SMSG_STDOUT_DATA 17 /* data (string) */
42#define SSH_SMSG_STDERR_DATA 18 /* data (string) */
43#define SSH_CMSG_EOF 19 /* */
44#define SSH_SMSG_EXITSTATUS 20 /* status (int) */
45#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 /* channel (int) */
46#define SSH_MSG_CHANNEL_OPEN_FAILURE 22 /* channel (int) */
47#define SSH_MSG_CHANNEL_DATA 23 /* ch,data (int,str) */
48#define SSH_MSG_CHANNEL_CLOSE 24 /* channel (int) */
49#define SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25 /* channel (int) */
50/* SSH_CMSG_X11_REQUEST_FORWARDING 26 OBSOLETE */
51#define SSH_SMSG_X11_OPEN 27 /* channel (int) */
52#define SSH_CMSG_PORT_FORWARD_REQUEST 28 /* p,host,hp (i,s,i) */
53#define SSH_MSG_PORT_OPEN 29 /* ch,h,p (i,s,i) */
54#define SSH_CMSG_AGENT_REQUEST_FORWARDING 30 /* */
55#define SSH_SMSG_AGENT_OPEN 31 /* port (int) */
56#define SSH_MSG_IGNORE 32 /* string */
57#define SSH_CMSG_EXIT_CONFIRMATION 33 /* */
58#define SSH_CMSG_X11_REQUEST_FORWARDING 34 /* proto,data (s,s) */
59#define SSH_CMSG_AUTH_RHOSTS_RSA 35 /* user,mod (s,mpi) */
60#define SSH_MSG_DEBUG 36 /* string */
61#define SSH_CMSG_REQUEST_COMPRESSION 37 /* level 1-9 (int) */
62#define SSH_CMSG_MAX_PACKET_SIZE 38 /* size 4k-1024k (int) */
63#define SSH_CMSG_AUTH_TIS 39 /* we use this for s/key */
64#define SSH_SMSG_AUTH_TIS_CHALLENGE 40 /* challenge (string) */
65#define SSH_CMSG_AUTH_TIS_RESPONSE 41 /* response (string) */
66#define SSH_CMSG_AUTH_KERBEROS 42 /* (KTEXT) */
67#define SSH_SMSG_AUTH_KERBEROS_RESPONSE 43 /* (KTEXT) */
68#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */
69#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */
70
71/* protocol version 1.5 overloads some version 1.3 message types */
72#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE
73#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION
74
75/*
76 * Authentication methods. New types can be added, but old types should not
77 * be removed for compatibility. The maximum allowed value is 31.
78 */
79#define SSH_AUTH_RHOSTS 1
80#define SSH_AUTH_RSA 2
81#define SSH_AUTH_PASSWORD 3
82#define SSH_AUTH_RHOSTS_RSA 4
83#define SSH_AUTH_TIS 5
84#define SSH_AUTH_KERBEROS 6
85#define SSH_PASS_KERBEROS_TGT 7
86 /* 8 to 15 are reserved */
87#define SSH_PASS_AFS_TOKEN 21
88
89/* Protocol flags. These are bit masks. */
90#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */
91#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */
diff --git a/ssh_api.c b/ssh_api.c
index 2a9f1497c..c84b4e713 100644
--- a/ssh_api.c
+++ b/ssh_api.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh_api.c,v 1.7 2016/05/04 14:22:33 markus Exp $ */ 1/* $OpenBSD: ssh_api.c,v 1.8 2017/04/30 23:13:25 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2012 Markus Friedl. All rights reserved. 3 * Copyright (c) 2012 Markus Friedl. All rights reserved.
4 * 4 *
@@ -371,7 +371,6 @@ _ssh_read_banner(struct ssh *ssh, char **bannerp)
371 } 371 }
372 if (remote_major != 2) 372 if (remote_major != 2)
373 return SSH_ERR_PROTOCOL_MISMATCH; 373 return SSH_ERR_PROTOCOL_MISMATCH;
374 enable_compat20();
375 chop(buf); 374 chop(buf);
376 debug("Remote version string %.100s", buf); 375 debug("Remote version string %.100s", buf);
377 if ((*bannerp = strdup(buf)) == NULL) 376 if ((*bannerp = strdup(buf)) == NULL)
diff --git a/ssh_config b/ssh_config
index 90fb63f0b..c12f5ef52 100644
--- a/ssh_config
+++ b/ssh_config
@@ -1,4 +1,4 @@
1# $OpenBSD: ssh_config,v 1.30 2016/02/20 23:06:23 sobrado Exp $ 1# $OpenBSD: ssh_config,v 1.33 2017/05/07 23:12:57 djm Exp $
2 2
3# This is the ssh client system-wide configuration file. See 3# This is the ssh client system-wide configuration file. See
4# ssh_config(5) for more information. This file provides defaults for 4# ssh_config(5) for more information. This file provides defaults for
@@ -20,8 +20,6 @@
20# Host * 20# Host *
21# ForwardAgent no 21# ForwardAgent no
22# ForwardX11 no 22# ForwardX11 no
23# RhostsRSAAuthentication no
24# RSAAuthentication yes
25# PasswordAuthentication yes 23# PasswordAuthentication yes
26# HostbasedAuthentication no 24# HostbasedAuthentication no
27# GSSAPIAuthentication no 25# GSSAPIAuthentication no
@@ -31,16 +29,14 @@
31# AddressFamily any 29# AddressFamily any
32# ConnectTimeout 0 30# ConnectTimeout 0
33# StrictHostKeyChecking ask 31# StrictHostKeyChecking ask
34# IdentityFile ~/.ssh/identity
35# IdentityFile ~/.ssh/id_rsa 32# IdentityFile ~/.ssh/id_rsa
36# IdentityFile ~/.ssh/id_dsa 33# IdentityFile ~/.ssh/id_dsa
37# IdentityFile ~/.ssh/id_ecdsa 34# IdentityFile ~/.ssh/id_ecdsa
38# IdentityFile ~/.ssh/id_ed25519 35# IdentityFile ~/.ssh/id_ed25519
39# Port 22 36# Port 22
40# Protocol 2 37# Protocol 2
41# Cipher 3des 38# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc
42# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc 39# MACs hmac-md5,hmac-sha1,umac-64@openssh.com
43# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
44# EscapeChar ~ 40# EscapeChar ~
45# Tunnel no 41# Tunnel no
46# TunnelDevice any:any 42# TunnelDevice any:any
diff --git a/ssh_config.0 b/ssh_config.0
index ade8e6562..9493953ab 100644
--- a/ssh_config.0
+++ b/ssh_config.0
@@ -3,10 +3,6 @@ SSH_CONFIG(5) File Formats Manual SSH_CONFIG(5)
3NAME 3NAME
4 ssh_config M-bM-^@M-^S OpenSSH SSH client configuration files 4 ssh_config M-bM-^@M-^S OpenSSH SSH client configuration files
5 5
6SYNOPSIS
7 ~/.ssh/config
8 /etc/ssh/ssh_config
9
10DESCRIPTION 6DESCRIPTION
11 ssh(1) obtains configuration data from the following sources in the 7 ssh(1) obtains configuration data from the following sources in the
12 following order: 8 following order:
@@ -189,21 +185,14 @@ DESCRIPTION
189 process, regardless of the setting of StrictHostKeyChecking. If 185 process, regardless of the setting of StrictHostKeyChecking. If
190 the option is set to no, the check will not be executed. 186 the option is set to no, the check will not be executed.
191 187
192 Cipher Specifies the cipher to use for encrypting the session in
193 protocol version 1. Currently, blowfish, 3des (the default), and
194 des are supported, though des is only supported in the ssh(1)
195 client for interoperability with legacy protocol 1
196 implementations; its use is strongly discouraged due to
197 cryptographic weaknesses.
198
199 Ciphers 188 Ciphers
200 Specifies the ciphers allowed for protocol version 2 in order of 189 Specifies the ciphers allowed and their order of preference.
201 preference. Multiple ciphers must be comma-separated. If the 190 Multiple ciphers must be comma-separated. If the specified value
202 specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified 191 begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified ciphers will be
203 ciphers will be appended to the default set instead of replacing 192 appended to the default set instead of replacing them. If the
204 them. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then 193 specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified
205 the specified ciphers (including wildcards) will be removed from 194 ciphers (including wildcards) will be removed from the default
206 the default set instead of replacing them. 195 set instead of replacing them.
207 196
208 The supported ciphers are: 197 The supported ciphers are:
209 198
@@ -216,11 +205,6 @@ DESCRIPTION
216 aes256-ctr 205 aes256-ctr
217 aes128-gcm@openssh.com 206 aes128-gcm@openssh.com
218 aes256-gcm@openssh.com 207 aes256-gcm@openssh.com
219 arcfour
220 arcfour128
221 arcfour256
222 blowfish-cbc
223 cast128-cbc
224 chacha20-poly1305@openssh.com 208 chacha20-poly1305@openssh.com
225 209
226 The default is: 210 The default is:
@@ -245,13 +229,6 @@ DESCRIPTION
245 Specifies whether to use compression. The argument must be yes 229 Specifies whether to use compression. The argument must be yes
246 or no (the default). 230 or no (the default).
247 231
248 CompressionLevel
249 Specifies the compression level to use if compression is enabled.
250 The argument must be an integer from 1 (fast) to 9 (slow, best).
251 The default level is 6, which is good for most applications. The
252 meaning of the values is the same as in gzip(1). Note that this
253 option applies to protocol version 1 only.
254
255 ConnectionAttempts 232 ConnectionAttempts
256 Specifies the number of tries (one per second) to make before 233 Specifies the number of tries (one per second) to make before
257 exiting. The argument must be an integer. This may be useful in 234 exiting. The argument must be an integer. This may be useful in
@@ -491,8 +468,9 @@ DESCRIPTION
491 HostKeyAlias 468 HostKeyAlias
492 Specifies an alias that should be used instead of the real host 469 Specifies an alias that should be used instead of the real host
493 name when looking up or saving the host key in the host key 470 name when looking up or saving the host key in the host key
494 database files. This option is useful for tunneling SSH 471 database files and when validating host certificates. This
495 connections or for multiple servers running on a single host. 472 option is useful for tunneling SSH connections or for multiple
473 servers running on a single host.
496 474
497 HostName 475 HostName
498 Specifies the real host name to log into. This can be used to 476 Specifies the real host name to log into. This can be used to
@@ -526,9 +504,8 @@ DESCRIPTION
526 504
527 IdentityFile 505 IdentityFile
528 Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA 506 Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA
529 authentication identity is read. The default is ~/.ssh/identity 507 authentication identity is read. The default is ~/.ssh/id_dsa,
530 for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, 508 ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and ~/.ssh/id_rsa.
531 ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2.
532 Additionally, any identities represented by the authentication 509 Additionally, any identities represented by the authentication
533 agent will be used for authentication unless IdentitiesOnly is 510 agent will be used for authentication unless IdentitiesOnly is
534 set. If no certificates have been explicitly specified by 511 set. If no certificates have been explicitly specified by
@@ -573,13 +550,14 @@ DESCRIPTION
573 IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. 550 IPQoS Specifies the IPv4 type-of-service or DSCP class for connections.
574 Accepted values are af11, af12, af13, af21, af22, af23, af31, 551 Accepted values are af11, af12, af13, af21, af22, af23, af31,
575 af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, cs4, cs5, cs6, 552 af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, cs4, cs5, cs6,
576 cs7, ef, lowdelay, throughput, reliability, or a numeric value. 553 cs7, ef, lowdelay, throughput, reliability, a numeric value, or
577 This option may take one or two arguments, separated by 554 none to use the operating system default. This option may take
578 whitespace. If one argument is specified, it is used as the 555 one or two arguments, separated by whitespace. If one argument
579 packet class unconditionally. If two values are specified, the 556 is specified, it is used as the packet class unconditionally. If
580 first is automatically selected for interactive sessions and the 557 two values are specified, the first is automatically selected for
581 second for non-interactive sessions. The default is lowdelay for 558 interactive sessions and the second for non-interactive sessions.
582 interactive sessions and throughput for non-interactive sessions. 559 The default is lowdelay for interactive sessions and throughput
560 for non-interactive sessions.
583 561
584 KbdInteractiveAuthentication 562 KbdInteractiveAuthentication
585 Specifies whether to use keyboard-interactive authentication. 563 Specifies whether to use keyboard-interactive authentication.
@@ -712,15 +690,6 @@ DESCRIPTION
712 gssapi-with-mic,hostbased,publickey, 690 gssapi-with-mic,hostbased,publickey,
713 keyboard-interactive,password 691 keyboard-interactive,password
714 692
715 Protocol
716 Specifies the protocol versions ssh(1) should support in order of
717 preference. The possible values are 1 and 2. Multiple versions
718 must be comma-separated. When this option is set to 2,1 ssh will
719 try version 2 and fall back to version 1 if version 2 is not
720 available. The default is version 2. Protocol 1 suffers from a
721 number of cryptographic weaknesses and should not be used. It is
722 only offered to support legacy devices.
723
724 ProxyCommand 693 ProxyCommand
725 Specifies the command to use to connect to the server. The 694 Specifies the command to use to connect to the server. The
726 command string extends to the end of the line, and is executed 695 command string extends to the end of the line, and is executed
@@ -799,15 +768,29 @@ DESCRIPTION
799 rekeying is performed after the cipher's default amount of data 768 rekeying is performed after the cipher's default amount of data
800 has been sent or received and no time based rekeying is done. 769 has been sent or received and no time based rekeying is done.
801 770
771 RemoteCommand
772 Specifies a command to execute on the remote machine after
773 successfully connecting to the server. The command string
774 extends to the end of the line, and is executed with the user's
775 shell. Arguments to RemoteCommand accept the tokens described in
776 the TOKENS section.
777
802 RemoteForward 778 RemoteForward
803 Specifies that a TCP port on the remote machine be forwarded over 779 Specifies that a TCP port on the remote machine be forwarded over
804 the secure channel to the specified host and port from the local 780 the secure channel. The remote port may either be fowarded to a
805 machine. The first argument must be [bind_address:]port and the 781 specified host and port from the local machine, or may act as a
806 second argument must be host:hostport. IPv6 addresses can be 782 SOCKS 4/5 proxy that allows a remote client to connect to
807 specified by enclosing addresses in square brackets. Multiple 783 arbitrary destinations from the local machine. The first
808 forwardings may be specified, and additional forwardings can be 784 argument must be [bind_address:]port If forwarding to a specific
809 given on the command line. Privileged ports can be forwarded 785 destination then the second argument must be host:hostport,
810 only when logging in as root on the remote machine. 786 otherwise if no destination argument is specified then the remote
787 forwarding will be established as a SOCKS proxy.
788
789 IPv6 addresses can be specified by enclosing addresses in square
790 brackets. Multiple forwardings may be specified, and additional
791 forwardings can be given on the command line. Privileged ports
792 can be forwarded only when logging in as root on the remote
793 machine.
811 794
812 If the port argument is 0, the listen port will be dynamically 795 If the port argument is 0, the listen port will be dynamically
813 allocated on the server and reported to the client at run time. 796 allocated on the server and reported to the client at run time.
@@ -835,19 +818,6 @@ DESCRIPTION
835 List (KRL) as generated by ssh-keygen(1). For more information 818 List (KRL) as generated by ssh-keygen(1). For more information
836 on KRLs, see the KEY REVOCATION LISTS section in ssh-keygen(1). 819 on KRLs, see the KEY REVOCATION LISTS section in ssh-keygen(1).
837 820
838 RhostsRSAAuthentication
839 Specifies whether to try rhosts based authentication with RSA
840 host authentication. The argument must be yes or no (the
841 default). This option applies to protocol version 1 only and
842 requires ssh(1) to be setuid root.
843
844 RSAAuthentication
845 Specifies whether to try RSA authentication. The argument to
846 this keyword must be yes (the default) or no. RSA authentication
847 will only be attempted if the identity file exists, or an
848 authentication agent is running. Note that this option applies
849 to protocol version 1 only.
850
851 SendEnv 821 SendEnv
852 Specifies what variables from the local environ(7) should be sent 822 Specifies what variables from the local environ(7) should be sent
853 to the server. The server must also support it, and the server 823 to the server. The server must also support it, and the server
@@ -916,14 +886,25 @@ DESCRIPTION
916 protection against trojan horse attacks, though it can be 886 protection against trojan horse attacks, though it can be
917 annoying when the /etc/ssh/ssh_known_hosts file is poorly 887 annoying when the /etc/ssh/ssh_known_hosts file is poorly
918 maintained or when connections to new hosts are frequently made. 888 maintained or when connections to new hosts are frequently made.
919 This option forces the user to manually add all new hosts. If 889 This option forces the user to manually add all new hosts.
920 this flag is set to no, ssh will automatically add new host keys 890
921 to the user known hosts files. If this flag is set to ask (the 891 If this flag is set to M-bM-^@M-^\accept-newM-bM-^@M-^] then ssh will automatically
922 default), new host keys will be added to the user known host 892 add new host keys to the user known hosts files, but will not
923 files only after the user has confirmed that is what they really 893 permit connections to hosts with changed host keys. If this flag
924 want to do, and ssh will refuse to connect to hosts whose host 894 is set to M-bM-^@M-^\noM-bM-^@M-^] or M-bM-^@M-^\offM-bM-^@M-^], ssh will automatically add new host keys
925 key has changed. The host keys of known hosts will be verified 895 to the user known hosts files and allow connections to hosts with
926 automatically in all cases. 896 changed hostkeys to proceed, subject to some restrictions. If
897 this flag is set to ask (the default), new host keys will be
898 added to the user known host files only after the user has
899 confirmed that is what they really want to do, and ssh will
900 refuse to connect to hosts whose host key has changed. The host
901 keys of known hosts will be verified automatically in all cases.
902
903 SyslogFacility
904 Gives the facility code that is used when logging messages from
905 ssh(1). The possible values are: DAEMON, USER, AUTH, LOCAL0,
906 LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The
907 default is USER.
927 908
928 TCPKeepAlive 909 TCPKeepAlive
929 Specifies whether the system should send TCP keepalive messages 910 Specifies whether the system should send TCP keepalive messages
@@ -973,9 +954,7 @@ DESCRIPTION
973 UsePrivilegedPort 954 UsePrivilegedPort
974 Specifies whether to use a privileged port for outgoing 955 Specifies whether to use a privileged port for outgoing
975 connections. The argument must be yes or no (the default). If 956 connections. The argument must be yes or no (the default). If
976 set to yes, ssh(1) must be setuid root. Note that this option 957 set to yes, ssh(1) must be setuid root.
977 must be set to yes for RhostsRSAAuthentication with older
978 servers.
979 958
980 User Specifies the user to log in as. This can be useful when a 959 User Specifies the user to log in as. This can be useful when a
981 different user name is used on different machines. This saves 960 different user name is used on different machines. This saves
@@ -1065,6 +1044,8 @@ TOKENS
1065 1044
1066 ProxyCommand accepts the tokens %%, %h, %p, and %r. 1045 ProxyCommand accepts the tokens %%, %h, %p, and %r.
1067 1046
1047 RemoteCommand accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u.
1048
1068FILES 1049FILES
1069 ~/.ssh/config 1050 ~/.ssh/config
1070 This is the per-user configuration file. The format of this file 1051 This is the per-user configuration file. The format of this file
@@ -1089,4 +1070,4 @@ AUTHORS
1089 created OpenSSH. Markus Friedl contributed the support for SSH protocol 1070 created OpenSSH. Markus Friedl contributed the support for SSH protocol
1090 versions 1.5 and 2.0. 1071 versions 1.5 and 2.0.
1091 1072
1092OpenBSD 6.0 February 27, 2017 OpenBSD 6.0 1073OpenBSD 6.2 September 21, 2017 OpenBSD 6.2
diff --git a/ssh_config.5 b/ssh_config.5
index 532745b2f..eab8dd01c 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,16 +33,13 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh_config.5,v 1.242 2017/02/27 14:30:33 jmc Exp $ 36.\" $OpenBSD: ssh_config.5,v 1.256 2017/09/21 19:16:53 markus Exp $
37.Dd $Mdocdate: February 27 2017 $ 37.Dd $Mdocdate: September 21 2017 $
38.Dt SSH_CONFIG 5 38.Dt SSH_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
41.Nm ssh_config 41.Nm ssh_config
42.Nd OpenSSH SSH client configuration files 42.Nd OpenSSH SSH client configuration files
43.Sh SYNOPSIS
44.Nm ~/.ssh/config
45.Nm /etc/ssh/ssh_config
46.Sh DESCRIPTION 43.Sh DESCRIPTION
47.Xr ssh 1 44.Xr ssh 1
48obtains configuration data from the following sources in 45obtains configuration data from the following sources in
@@ -391,25 +388,8 @@ in the process, regardless of the setting of
391If the option is set to 388If the option is set to
392.Cm no , 389.Cm no ,
393the check will not be executed. 390the check will not be executed.
394.It Cm Cipher
395Specifies the cipher to use for encrypting the session
396in protocol version 1.
397Currently,
398.Cm blowfish ,
399.Cm 3des
400(the default),
401and
402.Cm des
403are supported,
404though
405.Cm des
406is only supported in the
407.Xr ssh 1
408client for interoperability with legacy protocol 1 implementations;
409its use is strongly discouraged due to cryptographic weaknesses.
410.It Cm Ciphers 391.It Cm Ciphers
411Specifies the ciphers allowed for protocol version 2 392Specifies the ciphers allowed and their order of preference.
412in order of preference.
413Multiple ciphers must be comma-separated. 393Multiple ciphers must be comma-separated.
414If the specified value begins with a 394If the specified value begins with a
415.Sq + 395.Sq +
@@ -431,11 +411,6 @@ aes192-ctr
431aes256-ctr 411aes256-ctr
432aes128-gcm@openssh.com 412aes128-gcm@openssh.com
433aes256-gcm@openssh.com 413aes256-gcm@openssh.com
434arcfour
435arcfour128
436arcfour256
437blowfish-cbc
438cast128-cbc
439chacha20-poly1305@openssh.com 414chacha20-poly1305@openssh.com
440.Ed 415.Ed
441.Pp 416.Pp
@@ -472,13 +447,6 @@ The argument must be
472or 447or
473.Cm no 448.Cm no
474(the default). 449(the default).
475.It Cm CompressionLevel
476Specifies the compression level to use if compression is enabled.
477The argument must be an integer from 1 (fast) to 9 (slow, best).
478The default level is 6, which is good for most applications.
479The meaning of the values is the same as in
480.Xr gzip 1 .
481Note that this option applies to protocol version 1 only.
482.It Cm ConnectionAttempts 450.It Cm ConnectionAttempts
483Specifies the number of tries (one per second) to make before exiting. 451Specifies the number of tries (one per second) to make before exiting.
484The argument must be an integer. 452The argument must be an integer.
@@ -838,7 +806,7 @@ The list of available key types may also be obtained using
838.It Cm HostKeyAlias 806.It Cm HostKeyAlias
839Specifies an alias that should be used instead of the 807Specifies an alias that should be used instead of the
840real host name when looking up or saving the host key 808real host name when looking up or saving the host key
841in the host key database files. 809in the host key database files and when validating host certificates.
842This option is useful for tunneling SSH connections 810This option is useful for tunneling SSH connections
843or for multiple servers running on a single host. 811or for multiple servers running on a single host.
844.It Cm HostName 812.It Cm HostName
@@ -902,14 +870,11 @@ section.
902Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA authentication 870Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA authentication
903identity is read. 871identity is read.
904The default is 872The default is
905.Pa ~/.ssh/identity
906for protocol version 1, and
907.Pa ~/.ssh/id_dsa , 873.Pa ~/.ssh/id_dsa ,
908.Pa ~/.ssh/id_ecdsa , 874.Pa ~/.ssh/id_ecdsa ,
909.Pa ~/.ssh/id_ed25519 875.Pa ~/.ssh/id_ed25519
910and 876and
911.Pa ~/.ssh/id_rsa 877.Pa ~/.ssh/id_rsa .
912for protocol version 2.
913Additionally, any identities represented by the authentication agent 878Additionally, any identities represented by the authentication agent
914will be used for authentication unless 879will be used for authentication unless
915.Cm IdentitiesOnly 880.Cm IdentitiesOnly
@@ -1004,7 +969,9 @@ Accepted values are
1004.Cm lowdelay , 969.Cm lowdelay ,
1005.Cm throughput , 970.Cm throughput ,
1006.Cm reliability , 971.Cm reliability ,
1007or a numeric value. 972a numeric value, or
973.Cm none
974to use the operating system default.
1008This option may take one or two arguments, separated by whitespace. 975This option may take one or two arguments, separated by whitespace.
1009If one argument is specified, it is used as the packet class unconditionally. 976If one argument is specified, it is used as the packet class unconditionally.
1010If two values are specified, the first is automatically selected for 977If two values are specified, the first is automatically selected for
@@ -1192,21 +1159,6 @@ The default is:
1192gssapi-with-mic,hostbased,publickey, 1159gssapi-with-mic,hostbased,publickey,
1193keyboard-interactive,password 1160keyboard-interactive,password
1194.Ed 1161.Ed
1195.It Cm Protocol
1196Specifies the protocol versions
1197.Xr ssh 1
1198should support in order of preference.
1199The possible values are 1 and 2.
1200Multiple versions must be comma-separated.
1201When this option is set to
1202.Cm 2,1
1203.Nm ssh
1204will try version 2 and fall back to version 1
1205if version 2 is not available.
1206The default is version 2.
1207Protocol 1 suffers from a number of cryptographic weaknesses and should
1208not be used.
1209It is only offered to support legacy devices.
1210.It Cm ProxyCommand 1162.It Cm ProxyCommand
1211Specifies the command to use to connect to the server. 1163Specifies the command to use to connect to the server.
1212The command 1164The command
@@ -1334,15 +1286,31 @@ is
1334.Cm default none , 1286.Cm default none ,
1335which means that rekeying is performed after the cipher's default amount 1287which means that rekeying is performed after the cipher's default amount
1336of data has been sent or received and no time based rekeying is done. 1288of data has been sent or received and no time based rekeying is done.
1289.It Cm RemoteCommand
1290Specifies a command to execute on the remote machine after successfully
1291connecting to the server.
1292The command string extends to the end of the line, and is executed with
1293the user's shell.
1294Arguments to
1295.Cm RemoteCommand
1296accept the tokens described in the
1297.Sx TOKENS
1298section.
1337.It Cm RemoteForward 1299.It Cm RemoteForward
1338Specifies that a TCP port on the remote machine be forwarded over 1300Specifies that a TCP port on the remote machine be forwarded over
1339the secure channel to the specified host and port from the local machine. 1301the secure channel.
1302The remote port may either be fowarded to a specified host and port
1303from the local machine, or may act as a SOCKS 4/5 proxy that allows a remote
1304client to connect to arbitrary destinations from the local machine.
1340The first argument must be 1305The first argument must be
1341.Sm off 1306.Sm off
1342.Oo Ar bind_address : Oc Ar port 1307.Oo Ar bind_address : Oc Ar port
1343.Sm on 1308.Sm on
1344and the second argument must be 1309If forwarding to a specific destination then the second argument must be
1345.Ar host : Ns Ar hostport . 1310.Ar host : Ns Ar hostport ,
1311otherwise if no destination argument is specified then the remote forwarding
1312will be established as a SOCKS proxy.
1313.Pp
1346IPv6 addresses can be specified by enclosing addresses in square brackets. 1314IPv6 addresses can be specified by enclosing addresses in square brackets.
1347Multiple forwardings may be specified, and additional 1315Multiple forwardings may be specified, and additional
1348forwardings can be given on the command line. 1316forwardings can be given on the command line.
@@ -1397,28 +1365,6 @@ an OpenSSH Key Revocation List (KRL) as generated by
1397.Xr ssh-keygen 1 . 1365.Xr ssh-keygen 1 .
1398For more information on KRLs, see the KEY REVOCATION LISTS section in 1366For more information on KRLs, see the KEY REVOCATION LISTS section in
1399.Xr ssh-keygen 1 . 1367.Xr ssh-keygen 1 .
1400.It Cm RhostsRSAAuthentication
1401Specifies whether to try rhosts based authentication with RSA host
1402authentication.
1403The argument must be
1404.Cm yes
1405or
1406.Cm no
1407(the default).
1408This option applies to protocol version 1 only and requires
1409.Xr ssh 1
1410to be setuid root.
1411.It Cm RSAAuthentication
1412Specifies whether to try RSA authentication.
1413The argument to this keyword must be
1414.Cm yes
1415(the default)
1416or
1417.Cm no .
1418RSA authentication will only be
1419attempted if the identity file exists, or an authentication agent is
1420running.
1421Note that this option applies to protocol version 1 only.
1422.It Cm SendEnv 1368.It Cm SendEnv
1423Specifies what variables from the local 1369Specifies what variables from the local
1424.Xr environ 7 1370.Xr environ 7
@@ -1518,10 +1464,19 @@ file is poorly maintained or when connections to new hosts are
1518frequently made. 1464frequently made.
1519This option forces the user to manually 1465This option forces the user to manually
1520add all new hosts. 1466add all new hosts.
1467.Pp
1521If this flag is set to 1468If this flag is set to
1522.Cm no , 1469.Dq accept-new
1523ssh will automatically add new host keys to the 1470then ssh will automatically add new host keys to the user
1524user known hosts files. 1471known hosts files, but will not permit connections to hosts with
1472changed host keys.
1473If this flag is set to
1474.Dq no
1475or
1476.Dq off ,
1477ssh will automatically add new host keys to the user known hosts files
1478and allow connections to hosts with changed hostkeys to proceed,
1479subject to some restrictions.
1525If this flag is set to 1480If this flag is set to
1526.Cm ask 1481.Cm ask
1527(the default), 1482(the default),
@@ -1531,6 +1486,12 @@ has confirmed that is what they really want to do, and
1531ssh will refuse to connect to hosts whose host key has changed. 1486ssh will refuse to connect to hosts whose host key has changed.
1532The host keys of 1487The host keys of
1533known hosts will be verified automatically in all cases. 1488known hosts will be verified automatically in all cases.
1489.It Cm SyslogFacility
1490Gives the facility code that is used when logging messages from
1491.Xr ssh 1 .
1492The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
1493LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
1494The default is USER.
1534.It Cm TCPKeepAlive 1495.It Cm TCPKeepAlive
1535Specifies whether the system should send TCP keepalive messages to the 1496Specifies whether the system should send TCP keepalive messages to the
1536other side. 1497other side.
@@ -1627,11 +1588,6 @@ If set to
1627.Cm yes , 1588.Cm yes ,
1628.Xr ssh 1 1589.Xr ssh 1
1629must be setuid root. 1590must be setuid root.
1630Note that this option must be set to
1631.Cm yes
1632for
1633.Cm RhostsRSAAuthentication
1634with older servers.
1635.It Cm User 1591.It Cm User
1636Specifies the user to log in as. 1592Specifies the user to log in as.
1637This can be useful when a different user name is used on different machines. 1593This can be useful when a different user name is used on different machines.
@@ -1770,6 +1726,9 @@ accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u.
1770.Pp 1726.Pp
1771.Cm ProxyCommand 1727.Cm ProxyCommand
1772accepts the tokens %%, %h, %p, and %r. 1728accepts the tokens %%, %h, %p, and %r.
1729.Pp
1730.Cm RemoteCommand
1731accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u.
1773.Sh FILES 1732.Sh FILES
1774.Bl -tag -width Ds 1733.Bl -tag -width Ds
1775.It Pa ~/.ssh/config 1734.It Pa ~/.ssh/config
diff --git a/sshbuf-getput-basic.c b/sshbuf-getput-basic.c
index 74c49be7c..50648258f 100644
--- a/sshbuf-getput-basic.c
+++ b/sshbuf-getput-basic.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf-getput-basic.c,v 1.6 2016/06/16 11:00:17 dtucker Exp $ */ 1/* $OpenBSD: sshbuf-getput-basic.c,v 1.7 2017/06/01 04:51:58 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -365,7 +365,7 @@ sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len)
365int 365int
366sshbuf_put_cstring(struct sshbuf *buf, const char *v) 366sshbuf_put_cstring(struct sshbuf *buf, const char *v)
367{ 367{
368 return sshbuf_put_string(buf, (u_char *)v, v == NULL ? 0 : strlen(v)); 368 return sshbuf_put_string(buf, v, v == NULL ? 0 : strlen(v));
369} 369}
370 370
371int 371int
diff --git a/sshbuf.c b/sshbuf.c
index cbf7ed4a4..de783a363 100644
--- a/sshbuf.c
+++ b/sshbuf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf.c,v 1.8 2016/11/25 23:22:04 djm Exp $ */ 1/* $OpenBSD: sshbuf.c,v 1.11 2017/06/01 06:58:25 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -193,15 +193,16 @@ sshbuf_reset(struct sshbuf *buf)
193 buf->off = buf->size; 193 buf->off = buf->size;
194 return; 194 return;
195 } 195 }
196 if (sshbuf_check_sanity(buf) == 0) 196 (void) sshbuf_check_sanity(buf);
197 explicit_bzero(buf->d, buf->alloc);
198 buf->off = buf->size = 0; 197 buf->off = buf->size = 0;
199 if (buf->alloc != SSHBUF_SIZE_INIT) { 198 if (buf->alloc != SSHBUF_SIZE_INIT) {
200 if ((d = realloc(buf->d, SSHBUF_SIZE_INIT)) != NULL) { 199 if ((d = recallocarray(buf->d, buf->alloc, SSHBUF_SIZE_INIT,
200 1)) != NULL) {
201 buf->cd = buf->d = d; 201 buf->cd = buf->d = d;
202 buf->alloc = SSHBUF_SIZE_INIT; 202 buf->alloc = SSHBUF_SIZE_INIT;
203 } 203 }
204 } 204 }
205 explicit_bzero(buf->d, SSHBUF_SIZE_INIT);
205} 206}
206 207
207size_t 208size_t
@@ -253,9 +254,8 @@ sshbuf_set_max_size(struct sshbuf *buf, size_t max_size)
253 rlen = ROUNDUP(buf->size, SSHBUF_SIZE_INC); 254 rlen = ROUNDUP(buf->size, SSHBUF_SIZE_INC);
254 if (rlen > max_size) 255 if (rlen > max_size)
255 rlen = max_size; 256 rlen = max_size;
256 explicit_bzero(buf->d + buf->size, buf->alloc - buf->size);
257 SSHBUF_DBG(("new alloc = %zu", rlen)); 257 SSHBUF_DBG(("new alloc = %zu", rlen));
258 if ((dp = realloc(buf->d, rlen)) == NULL) 258 if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL)
259 return SSH_ERR_ALLOC_FAIL; 259 return SSH_ERR_ALLOC_FAIL;
260 buf->cd = buf->d = dp; 260 buf->cd = buf->d = dp;
261 buf->alloc = rlen; 261 buf->alloc = rlen;
@@ -344,7 +344,7 @@ sshbuf_allocate(struct sshbuf *buf, size_t len)
344 if (rlen > buf->max_size) 344 if (rlen > buf->max_size)
345 rlen = buf->alloc + need; 345 rlen = buf->alloc + need;
346 SSHBUF_DBG(("adjusted rlen %zu", rlen)); 346 SSHBUF_DBG(("adjusted rlen %zu", rlen));
347 if ((dp = realloc(buf->d, rlen)) == NULL) { 347 if ((dp = recallocarray(buf->d, buf->alloc, rlen, 1)) == NULL) {
348 SSHBUF_DBG(("realloc fail")); 348 SSHBUF_DBG(("realloc fail"));
349 return SSH_ERR_ALLOC_FAIL; 349 return SSH_ERR_ALLOC_FAIL;
350 } 350 }
@@ -391,6 +391,9 @@ sshbuf_consume(struct sshbuf *buf, size_t len)
391 if (len > sshbuf_len(buf)) 391 if (len > sshbuf_len(buf))
392 return SSH_ERR_MESSAGE_INCOMPLETE; 392 return SSH_ERR_MESSAGE_INCOMPLETE;
393 buf->off += len; 393 buf->off += len;
394 /* deal with empty buffer */
395 if (buf->off == buf->size)
396 buf->off = buf->size = 0;
394 SSHBUF_TELL("done"); 397 SSHBUF_TELL("done");
395 return 0; 398 return 0;
396} 399}
diff --git a/sshbuf.h b/sshbuf.h
index 1ac4b8c0a..77f1e9e6d 100644
--- a/sshbuf.h
+++ b/sshbuf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf.h,v 1.8 2016/11/25 23:22:04 djm Exp $ */ 1/* $OpenBSD: sshbuf.h,v 1.9 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -211,6 +211,7 @@ int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
211/* Another variant: "peeks" into the buffer without modifying it */ 211/* Another variant: "peeks" into the buffer without modifying it */
212int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, 212int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
213 size_t *lenp); 213 size_t *lenp);
214/* XXX peek_u8 / peek_u32 */
214 215
215/* 216/*
216 * Functions to extract or store SSH wire encoded bignums and elliptic 217 * Functions to extract or store SSH wire encoded bignums and elliptic
diff --git a/sshconnect.c b/sshconnect.c
index 948b638ad..dc7a704d2 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.273 2017/03/10 03:22:40 dtucker Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.287 2017/09/14 04:32:21 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -34,6 +34,9 @@
34#include <paths.h> 34#include <paths.h>
35#endif 35#endif
36#include <pwd.h> 36#include <pwd.h>
37#ifdef HAVE_POLL_H
38#include <poll.h>
39#endif
37#include <signal.h> 40#include <signal.h>
38#include <stdarg.h> 41#include <stdarg.h>
39#include <stdio.h> 42#include <stdio.h>
@@ -45,7 +48,6 @@
45#include "key.h" 48#include "key.h"
46#include "hostfile.h" 49#include "hostfile.h"
47#include "ssh.h" 50#include "ssh.h"
48#include "rsa.h"
49#include "buffer.h" 51#include "buffer.h"
50#include "packet.h" 52#include "packet.h"
51#include "uidswap.h" 53#include "uidswap.h"
@@ -67,7 +69,7 @@
67 69
68char *client_version_string = NULL; 70char *client_version_string = NULL;
69char *server_version_string = NULL; 71char *server_version_string = NULL;
70Key *previous_host_key = NULL; 72struct sshkey *previous_host_key = NULL;
71 73
72static int matching_host_key_dns = 0; 74static int matching_host_key_dns = 0;
73 75
@@ -79,8 +81,8 @@ extern char *__progname;
79extern uid_t original_real_uid; 81extern uid_t original_real_uid;
80extern uid_t original_effective_uid; 82extern uid_t original_effective_uid;
81 83
82static int show_other_keys(struct hostkeys *, Key *); 84static int show_other_keys(struct hostkeys *, struct sshkey *);
83static void warn_changed_key(Key *); 85static void warn_changed_key(struct sshkey *);
84 86
85/* Expand a proxy command */ 87/* Expand a proxy command */
86static char * 88static char *
@@ -102,7 +104,7 @@ expand_proxy_command(const char *proxy_command, const char *user,
102 * a connected fd back to us. 104 * a connected fd back to us.
103 */ 105 */
104static int 106static int
105ssh_proxy_fdpass_connect(const char *host, u_short port, 107ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
106 const char *proxy_command) 108 const char *proxy_command)
107{ 109{
108 char *command_string; 110 char *command_string;
@@ -173,7 +175,8 @@ ssh_proxy_fdpass_connect(const char *host, u_short port,
173 fatal("Couldn't wait for child: %s", strerror(errno)); 175 fatal("Couldn't wait for child: %s", strerror(errno));
174 176
175 /* Set the connection file descriptors. */ 177 /* Set the connection file descriptors. */
176 packet_set_connection(sock, sock); 178 if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
179 return -1; /* ssh_packet_set_connection logs error */
177 180
178 return 0; 181 return 0;
179} 182}
@@ -182,7 +185,8 @@ ssh_proxy_fdpass_connect(const char *host, u_short port,
182 * Connect to the given ssh server using a proxy command. 185 * Connect to the given ssh server using a proxy command.
183 */ 186 */
184static int 187static int
185ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) 188ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
189 const char *proxy_command)
186{ 190{
187 char *command_string; 191 char *command_string;
188 int pin[2], pout[2]; 192 int pin[2], pout[2];
@@ -249,9 +253,9 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
249 free(command_string); 253 free(command_string);
250 254
251 /* Set the connection file descriptors. */ 255 /* Set the connection file descriptors. */
252 packet_set_connection(pout[0], pin[1]); 256 if (ssh_packet_set_connection(ssh, pout[0], pin[1]) == NULL)
257 return -1; /* ssh_packet_set_connection logs error */
253 258
254 /* Indicate OK return */
255 return 0; 259 return 0;
256} 260}
257 261
@@ -328,87 +332,71 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
328 return sock; 332 return sock;
329} 333}
330 334
335/*
336 * Wait up to *timeoutp milliseconds for fd to be readable. Updates
337 * *timeoutp with time remaining.
338 * Returns 0 if fd ready or -1 on timeout or error (see errno).
339 */
331static int 340static int
332timeout_connect(int sockfd, const struct sockaddr *serv_addr, 341waitrfd(int fd, int *timeoutp)
333 socklen_t addrlen, int *timeoutp)
334{ 342{
335 fd_set *fdset; 343 struct pollfd pfd;
336 struct timeval tv, t_start; 344 struct timeval t_start;
337 socklen_t optlen; 345 int oerrno, r;
338 int optval, rc, result = -1;
339 346
340 gettimeofday(&t_start, NULL); 347 gettimeofday(&t_start, NULL);
341 348 pfd.fd = fd;
342 if (*timeoutp <= 0) { 349 pfd.events = POLLIN;
343 result = connect(sockfd, serv_addr, addrlen); 350 for (; *timeoutp >= 0;) {
344 goto done; 351 r = poll(&pfd, 1, *timeoutp);
345 } 352 oerrno = errno;
346 353 ms_subtract_diff(&t_start, timeoutp);
347 set_nonblock(sockfd); 354 errno = oerrno;
348 rc = connect(sockfd, serv_addr, addrlen); 355 if (r > 0)
349 if (rc == 0) { 356 return 0;
350 unset_nonblock(sockfd); 357 else if (r == -1 && errno != EAGAIN)
351 result = 0; 358 return -1;
352 goto done; 359 else if (r == 0)
353 } 360 break;
354 if (errno != EINPROGRESS) {
355 result = -1;
356 goto done;
357 } 361 }
362 /* timeout */
363 errno = ETIMEDOUT;
364 return -1;
365}
358 366
359 fdset = xcalloc(howmany(sockfd + 1, NFDBITS), 367static int
360 sizeof(fd_mask)); 368timeout_connect(int sockfd, const struct sockaddr *serv_addr,
361 FD_SET(sockfd, fdset); 369 socklen_t addrlen, int *timeoutp)
362 ms_to_timeval(&tv, *timeoutp); 370{
371 int optval = 0;
372 socklen_t optlen = sizeof(optval);
363 373
364 for (;;) { 374 /* No timeout: just do a blocking connect() */
365 rc = select(sockfd + 1, NULL, fdset, NULL, &tv); 375 if (*timeoutp <= 0)
366 if (rc != -1 || errno != EINTR) 376 return connect(sockfd, serv_addr, addrlen);
367 break;
368 }
369 377
370 switch (rc) { 378 set_nonblock(sockfd);
371 case 0: 379 if (connect(sockfd, serv_addr, addrlen) == 0) {
372 /* Timed out */ 380 /* Succeeded already? */
373 errno = ETIMEDOUT;
374 break;
375 case -1:
376 /* Select error */
377 debug("select: %s", strerror(errno));
378 break;
379 case 1:
380 /* Completed or failed */
381 optval = 0;
382 optlen = sizeof(optval);
383 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,
384 &optlen) == -1) {
385 debug("getsockopt: %s", strerror(errno));
386 break;
387 }
388 if (optval != 0) {
389 errno = optval;
390 break;
391 }
392 result = 0;
393 unset_nonblock(sockfd); 381 unset_nonblock(sockfd);
394 break; 382 return 0;
395 default: 383 } else if (errno != EINPROGRESS)
396 /* Should not occur */ 384 return -1;
397 fatal("Bogus return (%d) from select()", rc);
398 }
399 385
400 free(fdset); 386 if (waitrfd(sockfd, timeoutp) == -1)
387 return -1;
401 388
402 done: 389 /* Completed or failed */
403 if (result == 0 && *timeoutp > 0) { 390 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) {
404 ms_subtract_diff(&t_start, timeoutp); 391 debug("getsockopt: %s", strerror(errno));
405 if (*timeoutp <= 0) { 392 return -1;
406 errno = ETIMEDOUT;
407 result = -1;
408 }
409 } 393 }
410 394 if (optval != 0) {
411 return (result); 395 errno = optval;
396 return -1;
397 }
398 unset_nonblock(sockfd);
399 return 0;
412} 400}
413 401
414/* 402/*
@@ -423,7 +411,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
423 * the daemon. 411 * the daemon.
424 */ 412 */
425static int 413static int
426ssh_connect_direct(const char *host, struct addrinfo *aitop, 414ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
427 struct sockaddr_storage *hostaddr, u_short port, int family, 415 struct sockaddr_storage *hostaddr, u_short port, int family,
428 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) 416 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)
429{ 417{
@@ -497,40 +485,39 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop,
497 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 485 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
498 486
499 /* Set the connection. */ 487 /* Set the connection. */
500 packet_set_connection(sock, sock); 488 if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
489 return -1; /* ssh_packet_set_connection logs error */
501 490
502 return 0; 491 return 0;
503} 492}
504 493
505int 494int
506ssh_connect(const char *host, struct addrinfo *addrs, 495ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs,
507 struct sockaddr_storage *hostaddr, u_short port, int family, 496 struct sockaddr_storage *hostaddr, u_short port, int family,
508 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv) 497 int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)
509{ 498{
510 if (options.proxy_command == NULL) { 499 if (options.proxy_command == NULL) {
511 return ssh_connect_direct(host, addrs, hostaddr, port, family, 500 return ssh_connect_direct(ssh, host, addrs, hostaddr, port,
512 connection_attempts, timeout_ms, want_keepalive, needpriv); 501 family, connection_attempts, timeout_ms, want_keepalive,
502 needpriv);
513 } else if (strcmp(options.proxy_command, "-") == 0) { 503 } else if (strcmp(options.proxy_command, "-") == 0) {
514 packet_set_connection(STDIN_FILENO, STDOUT_FILENO); 504 if ((ssh_packet_set_connection(ssh,
515 return 0; /* Always succeeds */ 505 STDIN_FILENO, STDOUT_FILENO)) == NULL)
506 return -1; /* ssh_packet_set_connection logs error */
507 return 0;
516 } else if (options.proxy_use_fdpass) { 508 } else if (options.proxy_use_fdpass) {
517 return ssh_proxy_fdpass_connect(host, port, 509 return ssh_proxy_fdpass_connect(ssh, host, port,
518 options.proxy_command); 510 options.proxy_command);
519 } 511 }
520 return ssh_proxy_connect(host, port, options.proxy_command); 512 return ssh_proxy_connect(ssh, host, port, options.proxy_command);
521} 513}
522 514
523static void 515static void
524send_client_banner(int connection_out, int minor1) 516send_client_banner(int connection_out, int minor1)
525{ 517{
526 /* Send our own protocol version identification. */ 518 /* Send our own protocol version identification. */
527 if (compat20) { 519 xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n",
528 xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", 520 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);
529 PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION);
530 } else {
531 xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n",
532 PROTOCOL_MAJOR_1, minor1, SSH_VERSION);
533 }
534 if (atomicio(vwrite, connection_out, client_version_string, 521 if (atomicio(vwrite, connection_out, client_version_string,
535 strlen(client_version_string)) != strlen(client_version_string)) 522 strlen(client_version_string)) != strlen(client_version_string))
536 fatal("write: %.100s", strerror(errno)); 523 fatal("write: %.100s", strerror(errno));
@@ -549,50 +536,27 @@ ssh_exchange_identification(int timeout_ms)
549 int remote_major, remote_minor, mismatch; 536 int remote_major, remote_minor, mismatch;
550 int connection_in = packet_get_connection_in(); 537 int connection_in = packet_get_connection_in();
551 int connection_out = packet_get_connection_out(); 538 int connection_out = packet_get_connection_out();
552 int minor1 = PROTOCOL_MINOR_1, client_banner_sent = 0;
553 u_int i, n; 539 u_int i, n;
554 size_t len; 540 size_t len;
555 int fdsetsz, remaining, rc; 541 int rc;
556 struct timeval t_start, t_remaining;
557 fd_set *fdset;
558
559 fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
560 fdset = xcalloc(1, fdsetsz);
561 542
562 /* 543 send_client_banner(connection_out, 0);
563 * If we are SSH2-only then we can send the banner immediately and
564 * save a round-trip.
565 */
566 if (options.protocol == SSH_PROTO_2) {
567 enable_compat20();
568 send_client_banner(connection_out, 0);
569 client_banner_sent = 1;
570 }
571 544
572 /* Read other side's version identification. */ 545 /* Read other side's version identification. */
573 remaining = timeout_ms;
574 for (n = 0;;) { 546 for (n = 0;;) {
575 for (i = 0; i < sizeof(buf) - 1; i++) { 547 for (i = 0; i < sizeof(buf) - 1; i++) {
576 if (timeout_ms > 0) { 548 if (timeout_ms > 0) {
577 gettimeofday(&t_start, NULL); 549 rc = waitrfd(connection_in, &timeout_ms);
578 ms_to_timeval(&t_remaining, remaining); 550 if (rc == -1 && errno == ETIMEDOUT) {
579 FD_SET(connection_in, fdset);
580 rc = select(connection_in + 1, fdset, NULL,
581 fdset, &t_remaining);
582 ms_subtract_diff(&t_start, &remaining);
583 if (rc == 0 || remaining <= 0)
584 fatal("Connection timed out during " 551 fatal("Connection timed out during "
585 "banner exchange"); 552 "banner exchange");
586 if (rc == -1) { 553 } else if (rc == -1) {
587 if (errno == EINTR) 554 fatal("%s: %s",
588 continue; 555 __func__, strerror(errno));
589 fatal("ssh_exchange_identification: "
590 "select: %s", strerror(errno));
591 } 556 }
592 } 557 }
593 558
594 len = atomicio(read, connection_in, &buf[i], 1); 559 len = atomicio(read, connection_in, &buf[i], 1);
595
596 if (len != 1 && errno == EPIPE) 560 if (len != 1 && errno == EPIPE)
597 fatal("ssh_exchange_identification: " 561 fatal("ssh_exchange_identification: "
598 "Connection closed by remote host"); 562 "Connection closed by remote host");
@@ -618,7 +582,6 @@ ssh_exchange_identification(int timeout_ms)
618 debug("ssh_exchange_identification: %s", buf); 582 debug("ssh_exchange_identification: %s", buf);
619 } 583 }
620 server_version_string = xstrdup(buf); 584 server_version_string = xstrdup(buf);
621 free(fdset);
622 585
623 /* 586 /*
624 * Check that the versions match. In future this might accept 587 * Check that the versions match. In future this might accept
@@ -634,51 +597,25 @@ ssh_exchange_identification(int timeout_ms)
634 mismatch = 0; 597 mismatch = 0;
635 598
636 switch (remote_major) { 599 switch (remote_major) {
600 case 2:
601 break;
637 case 1: 602 case 1:
638 if (remote_minor == 99 && 603 if (remote_minor != 99)
639 (options.protocol & SSH_PROTO_2) &&
640 !(options.protocol & SSH_PROTO_1_PREFERRED)) {
641 enable_compat20();
642 break;
643 }
644 if (!(options.protocol & SSH_PROTO_1)) {
645 mismatch = 1; 604 mismatch = 1;
646 break;
647 }
648 if (remote_minor < 3) {
649 fatal("Remote machine has too old SSH software version.");
650 } else if (remote_minor == 3 || remote_minor == 4) {
651 /* We speak 1.3, too. */
652 enable_compat13();
653 minor1 = 3;
654 if (options.forward_agent) {
655 logit("Agent forwarding disabled for protocol 1.3");
656 options.forward_agent = 0;
657 }
658 }
659 break; 605 break;
660 case 2:
661 if (options.protocol & SSH_PROTO_2) {
662 enable_compat20();
663 break;
664 }
665 /* FALLTHROUGH */
666 default: 606 default:
667 mismatch = 1; 607 mismatch = 1;
668 break; 608 break;
669 } 609 }
670 if (mismatch) 610 if (mismatch)
671 fatal("Protocol major versions differ: %d vs. %d", 611 fatal("Protocol major versions differ: %d vs. %d",
672 (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, 612 PROTOCOL_MAJOR_2, remote_major);
673 remote_major);
674 if ((datafellows & SSH_BUG_DERIVEKEY) != 0) 613 if ((datafellows & SSH_BUG_DERIVEKEY) != 0)
675 fatal("Server version \"%.100s\" uses unsafe key agreement; " 614 fatal("Server version \"%.100s\" uses unsafe key agreement; "
676 "refusing connection", remote_version); 615 "refusing connection", remote_version);
677 if ((datafellows & SSH_BUG_RSASIGMD5) != 0) 616 if ((datafellows & SSH_BUG_RSASIGMD5) != 0)
678 logit("Server version \"%.100s\" uses unsafe RSA signature " 617 logit("Server version \"%.100s\" uses unsafe RSA signature "
679 "scheme; disabling use of RSA keys", remote_version); 618 "scheme; disabling use of RSA keys", remote_version);
680 if (!client_banner_sent)
681 send_client_banner(connection_out, minor1);
682 chop(server_version_string); 619 chop(server_version_string);
683} 620}
684 621
@@ -707,7 +644,7 @@ confirm(const char *prompt)
707} 644}
708 645
709static int 646static int
710check_host_cert(const char *host, const Key *host_key) 647check_host_cert(const char *host, const struct sshkey *host_key)
711{ 648{
712 const char *reason; 649 const char *reason;
713 650
@@ -805,13 +742,13 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
805#define ROQUIET 2 742#define ROQUIET 2
806static int 743static int
807check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, 744check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
808 Key *host_key, int readonly, 745 struct sshkey *host_key, int readonly,
809 char **user_hostfiles, u_int num_user_hostfiles, 746 char **user_hostfiles, u_int num_user_hostfiles,
810 char **system_hostfiles, u_int num_system_hostfiles) 747 char **system_hostfiles, u_int num_system_hostfiles)
811{ 748{
812 HostStatus host_status; 749 HostStatus host_status;
813 HostStatus ip_status; 750 HostStatus ip_status;
814 Key *raw_key = NULL; 751 struct sshkey *raw_key = NULL;
815 char *ip = NULL, *host = NULL; 752 char *ip = NULL, *host = NULL;
816 char hostline[1000], *hostp, *fp, *ra; 753 char hostline[1000], *hostp, *fp, *ra;
817 char msg[1024]; 754 char msg[1024];
@@ -819,7 +756,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
819 const struct hostkey_entry *host_found, *ip_found; 756 const struct hostkey_entry *host_found, *ip_found;
820 int len, cancelled_forwarding = 0; 757 int len, cancelled_forwarding = 0;
821 int local = sockaddr_is_local(hostaddr); 758 int local = sockaddr_is_local(hostaddr);
822 int r, want_cert = key_is_cert(host_key), host_ip_differ = 0; 759 int r, want_cert = sshkey_is_cert(host_key), host_ip_differ = 0;
823 int hostkey_trusted = 0; /* Known or explicitly accepted by user */ 760 int hostkey_trusted = 0; /* Known or explicitly accepted by user */
824 struct hostkeys *host_hostkeys, *ip_hostkeys; 761 struct hostkeys *host_hostkeys, *ip_hostkeys;
825 u_int i; 762 u_int i;
@@ -870,8 +807,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
870 807
871 retry: 808 retry:
872 /* Reload these as they may have changed on cert->key downgrade */ 809 /* Reload these as they may have changed on cert->key downgrade */
873 want_cert = key_is_cert(host_key); 810 want_cert = sshkey_is_cert(host_key);
874 type = key_type(host_key); 811 type = sshkey_type(host_key);
875 812
876 /* 813 /*
877 * Check if the host key is present in the user's list of known 814 * Check if the host key is present in the user's list of known
@@ -891,7 +828,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
891 if (host_status == HOST_CHANGED && 828 if (host_status == HOST_CHANGED &&
892 (ip_status != HOST_CHANGED || 829 (ip_status != HOST_CHANGED ||
893 (ip_found != NULL && 830 (ip_found != NULL &&
894 !key_equal(ip_found->key, host_found->key)))) 831 !sshkey_equal(ip_found->key, host_found->key))))
895 host_ip_differ = 1; 832 host_ip_differ = 1;
896 } else 833 } else
897 ip_status = host_status; 834 ip_status = host_status;
@@ -903,7 +840,9 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
903 host, type, want_cert ? "certificate" : "key"); 840 host, type, want_cert ? "certificate" : "key");
904 debug("Found %s in %s:%lu", want_cert ? "CA key" : "key", 841 debug("Found %s in %s:%lu", want_cert ? "CA key" : "key",
905 host_found->file, host_found->line); 842 host_found->file, host_found->line);
906 if (want_cert && !check_host_cert(hostname, host_key)) 843 if (want_cert &&
844 !check_host_cert(options.host_key_alias == NULL ?
845 hostname : options.host_key_alias, host_key))
907 goto fail; 846 goto fail;
908 if (options.check_host_ip && ip_status == HOST_NEW) { 847 if (options.check_host_ip && ip_status == HOST_NEW) {
909 if (readonly || want_cert) 848 if (readonly || want_cert)
@@ -947,7 +886,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
947 if (readonly || want_cert) 886 if (readonly || want_cert)
948 goto fail; 887 goto fail;
949 /* The host is new. */ 888 /* The host is new. */
950 if (options.strict_host_key_checking == 1) { 889 if (options.strict_host_key_checking ==
890 SSH_STRICT_HOSTKEY_YES) {
951 /* 891 /*
952 * User has requested strict host key checking. We 892 * User has requested strict host key checking. We
953 * will not add the host key automatically. The only 893 * will not add the host key automatically. The only
@@ -956,7 +896,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
956 error("No %s host key is known for %.200s and you " 896 error("No %s host key is known for %.200s and you "
957 "have requested strict checking.", type, host); 897 "have requested strict checking.", type, host);
958 goto fail; 898 goto fail;
959 } else if (options.strict_host_key_checking == 2) { 899 } else if (options.strict_host_key_checking ==
900 SSH_STRICT_HOSTKEY_ASK) {
960 char msg1[1024], msg2[1024]; 901 char msg1[1024], msg2[1024];
961 902
962 if (show_other_keys(host_hostkeys, host_key)) 903 if (show_other_keys(host_hostkeys, host_key))
@@ -1000,8 +941,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
1000 hostkey_trusted = 1; /* user explicitly confirmed */ 941 hostkey_trusted = 1; /* user explicitly confirmed */
1001 } 942 }
1002 /* 943 /*
1003 * If not in strict mode, add the key automatically to the 944 * If in "new" or "off" strict mode, add the key automatically
1004 * local known_hosts file. 945 * to the local known_hosts file.
1005 */ 946 */
1006 if (options.check_host_ip && ip_status == HOST_NEW) { 947 if (options.check_host_ip && ip_status == HOST_NEW) {
1007 snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); 948 snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
@@ -1043,7 +984,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
1043 * If strict host key checking is in use, the user will have 984 * If strict host key checking is in use, the user will have
1044 * to edit the key manually and we can only abort. 985 * to edit the key manually and we can only abort.
1045 */ 986 */
1046 if (options.strict_host_key_checking) { 987 if (options.strict_host_key_checking !=
988 SSH_STRICT_HOSTKEY_OFF) {
1047 error("%s host key for %.200s was revoked and you have " 989 error("%s host key for %.200s was revoked and you have "
1048 "requested strict checking.", type, host); 990 "requested strict checking.", type, host);
1049 goto fail; 991 goto fail;
@@ -1088,14 +1030,16 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
1088 warn_changed_key(host_key); 1030 warn_changed_key(host_key);
1089 error("Add correct host key in %.100s to get rid of this message.", 1031 error("Add correct host key in %.100s to get rid of this message.",
1090 user_hostfiles[0]); 1032 user_hostfiles[0]);
1091 error("Offending %s key in %s:%lu", key_type(host_found->key), 1033 error("Offending %s key in %s:%lu",
1034 sshkey_type(host_found->key),
1092 host_found->file, host_found->line); 1035 host_found->file, host_found->line);
1093 1036
1094 /* 1037 /*
1095 * If strict host key checking is in use, the user will have 1038 * If strict host key checking is in use, the user will have
1096 * to edit the key manually and we can only abort. 1039 * to edit the key manually and we can only abort.
1097 */ 1040 */
1098 if (options.strict_host_key_checking) { 1041 if (options.strict_host_key_checking !=
1042 SSH_STRICT_HOSTKEY_OFF) {
1099 error("%s host key for %.200s has changed and you have " 1043 error("%s host key for %.200s has changed and you have "
1100 "requested strict checking.", type, host); 1044 "requested strict checking.", type, host);
1101 goto fail; 1045 goto fail;
@@ -1182,15 +1126,17 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
1182 "\nMatching host key in %s:%lu", 1126 "\nMatching host key in %s:%lu",
1183 host_found->file, host_found->line); 1127 host_found->file, host_found->line);
1184 } 1128 }
1185 if (options.strict_host_key_checking == 1) { 1129 if (options.strict_host_key_checking ==
1186 logit("%s", msg); 1130 SSH_STRICT_HOSTKEY_ASK) {
1187 error("Exiting, you have requested strict checking.");
1188 goto fail;
1189 } else if (options.strict_host_key_checking == 2) {
1190 strlcat(msg, "\nAre you sure you want " 1131 strlcat(msg, "\nAre you sure you want "
1191 "to continue connecting (yes/no)? ", sizeof(msg)); 1132 "to continue connecting (yes/no)? ", sizeof(msg));
1192 if (!confirm(msg)) 1133 if (!confirm(msg))
1193 goto fail; 1134 goto fail;
1135 } else if (options.strict_host_key_checking !=
1136 SSH_STRICT_HOSTKEY_OFF) {
1137 logit("%s", msg);
1138 error("Exiting, you have requested strict checking.");
1139 goto fail;
1194 } else { 1140 } else {
1195 logit("%s", msg); 1141 logit("%s", msg);
1196 } 1142 }
@@ -1217,14 +1163,16 @@ fail:
1217 * search normally. 1163 * search normally.
1218 */ 1164 */
1219 debug("No matching CA found. Retry with plain key"); 1165 debug("No matching CA found. Retry with plain key");
1220 raw_key = key_from_private(host_key); 1166 if ((r = sshkey_from_private(host_key, &raw_key)) != 0)
1221 if (key_drop_cert(raw_key) != 0) 1167 fatal("%s: sshkey_from_private: %s",
1222 fatal("Couldn't drop certificate"); 1168 __func__, ssh_err(r));
1169 if ((r = sshkey_drop_cert(raw_key)) != 0)
1170 fatal("Couldn't drop certificate: %s", ssh_err(r));
1223 host_key = raw_key; 1171 host_key = raw_key;
1224 goto retry; 1172 goto retry;
1225 } 1173 }
1226 if (raw_key != NULL) 1174 if (raw_key != NULL)
1227 key_free(raw_key); 1175 sshkey_free(raw_key);
1228 free(ip); 1176 free(ip);
1229 free(host); 1177 free(host);
1230 if (host_hostkeys != NULL) 1178 if (host_hostkeys != NULL)
@@ -1236,7 +1184,7 @@ fail:
1236 1184
1237/* returns 0 if key verifies or -1 if key does NOT verify */ 1185/* returns 0 if key verifies or -1 if key does NOT verify */
1238int 1186int
1239verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) 1187verify_host_key(char *host, struct sockaddr *hostaddr, struct sshkey *host_key)
1240{ 1188{
1241 u_int i; 1189 u_int i;
1242 int r = -1, flags = 0; 1190 int r = -1, flags = 0;
@@ -1272,8 +1220,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
1272 host_key->cert->principals[i]); 1220 host_key->cert->principals[i]);
1273 } 1221 }
1274 } else { 1222 } else {
1275 debug("Server host key: %s %s", compat20 ? 1223 debug("Server host key: %s %s", sshkey_ssh_name(host_key), fp);
1276 sshkey_ssh_name(host_key) : sshkey_type(host_key), fp);
1277 } 1224 }
1278 1225
1279 if (sshkey_equal(previous_host_key, host_key)) { 1226 if (sshkey_equal(previous_host_key, host_key)) {
@@ -1341,8 +1288,8 @@ out:
1341 free(fp); 1288 free(fp);
1342 free(cafp); 1289 free(cafp);
1343 if (r == 0 && host_key != NULL) { 1290 if (r == 0 && host_key != NULL) {
1344 key_free(previous_host_key); 1291 sshkey_free(previous_host_key);
1345 previous_host_key = key_from_private(host_key); 1292 r = sshkey_from_private(host_key, &previous_host_key);
1346 } 1293 }
1347 1294
1348 return r; 1295 return r;
@@ -1378,17 +1325,8 @@ ssh_login(Sensitive *sensitive, const char *orighost,
1378 /* key exchange */ 1325 /* key exchange */
1379 /* authenticate user */ 1326 /* authenticate user */
1380 debug("Authenticating to %s:%d as '%s'", host, port, server_user); 1327 debug("Authenticating to %s:%d as '%s'", host, port, server_user);
1381 if (compat20) { 1328 ssh_kex2(host, hostaddr, port);
1382 ssh_kex2(host, hostaddr, port); 1329 ssh_userauth2(local_user, server_user, host, sensitive);
1383 ssh_userauth2(local_user, server_user, host, sensitive);
1384 } else {
1385#ifdef WITH_SSH1
1386 ssh_kex(host, hostaddr);
1387 ssh_userauth1(local_user, server_user, host, sensitive);
1388#else
1389 fatal("ssh1 is not supported");
1390#endif
1391 }
1392 free(local_user); 1330 free(local_user);
1393} 1331}
1394 1332
@@ -1412,10 +1350,9 @@ ssh_put_password(char *password)
1412 1350
1413/* print all known host keys for a given host, but skip keys of given type */ 1351/* print all known host keys for a given host, but skip keys of given type */
1414static int 1352static int
1415show_other_keys(struct hostkeys *hostkeys, Key *key) 1353show_other_keys(struct hostkeys *hostkeys, struct sshkey *key)
1416{ 1354{
1417 int type[] = { 1355 int type[] = {
1418 KEY_RSA1,
1419 KEY_RSA, 1356 KEY_RSA,
1420 KEY_DSA, 1357 KEY_DSA,
1421 KEY_ECDSA, 1358 KEY_ECDSA,
@@ -1453,7 +1390,7 @@ show_other_keys(struct hostkeys *hostkeys, Key *key)
1453} 1390}
1454 1391
1455static void 1392static void
1456warn_changed_key(Key *host_key) 1393warn_changed_key(struct sshkey *host_key)
1457{ 1394{
1458 char *fp; 1395 char *fp;
1459 1396
@@ -1516,7 +1453,7 @@ ssh_local_cmd(const char *args)
1516} 1453}
1517 1454
1518void 1455void
1519maybe_add_key_to_agent(char *authfile, Key *private, char *comment, 1456maybe_add_key_to_agent(char *authfile, struct sshkey *private, char *comment,
1520 char *passphrase) 1457 char *passphrase)
1521{ 1458{
1522 int auth_sock = -1, r; 1459 int auth_sock = -1, r;
diff --git a/sshconnect.h b/sshconnect.h
index cf1851a95..b5029e234 100644
--- a/sshconnect.h
+++ b/sshconnect.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.h,v 1.29 2015/11/15 22:26:49 jcs Exp $ */ 1/* $OpenBSD: sshconnect.h,v 1.31 2017/09/12 06:32:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -26,14 +26,16 @@
26 26
27typedef struct Sensitive Sensitive; 27typedef struct Sensitive Sensitive;
28struct Sensitive { 28struct Sensitive {
29 Key **keys; 29 struct sshkey **keys;
30 int nkeys; 30 int nkeys;
31 int external_keysign; 31 int external_keysign;
32}; 32};
33 33
34struct addrinfo; 34struct addrinfo;
35int ssh_connect(const char *, struct addrinfo *, struct sockaddr_storage *, 35struct ssh;
36 u_short, int, int, int *, int, int); 36
37int ssh_connect(struct ssh *, const char *, struct addrinfo *,
38 struct sockaddr_storage *, u_short, int, int, int *, int, int);
37void ssh_kill_proxy_command(void); 39void ssh_kill_proxy_command(void);
38 40
39void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short, 41void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short,
@@ -41,7 +43,7 @@ void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short,
41 43
42void ssh_exchange_identification(int); 44void ssh_exchange_identification(int);
43 45
44int verify_host_key(char *, struct sockaddr *, Key *); 46int verify_host_key(char *, struct sockaddr *, struct sshkey *);
45 47
46void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short, 48void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short,
47 char **, char **); 49 char **, char **);
@@ -55,7 +57,7 @@ void ssh_userauth2(const char *, const char *, char *, Sensitive *);
55void ssh_put_password(char *); 57void ssh_put_password(char *);
56int ssh_local_cmd(const char *); 58int ssh_local_cmd(const char *);
57 59
58void maybe_add_key_to_agent(char *, Key *, char *, char *); 60void maybe_add_key_to_agent(char *, struct sshkey *, char *, char *);
59 61
60/* 62/*
61 * Macros to raise/lower permissions. 63 * Macros to raise/lower permissions.
diff --git a/sshconnect1.c b/sshconnect1.c
deleted file mode 100644
index dc00b4cd0..000000000
--- a/sshconnect1.c
+++ /dev/null
@@ -1,774 +0,0 @@
1/* $OpenBSD: sshconnect1.c,v 1.80 2017/03/10 03:53:11 dtucker Exp $ */
2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 * Code to connect to a remote host, and to perform the client side of the
7 * login (authentication) dialog.
8 *
9 * As far as I am concerned, the code I have written for this software
10 * can be used freely for any purpose. Any derived versions of this
11 * software must be clearly marked as such, and if the derived work is
12 * incompatible with the protocol description in the RFC file, it must be
13 * called by a name other than "ssh" or "Secure Shell".
14 */
15
16#include "includes.h"
17
18#ifdef WITH_SSH1
19
20#include <sys/types.h>
21#include <sys/socket.h>
22
23#include <openssl/bn.h>
24
25#include <errno.h>
26#include <stdarg.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <signal.h>
31#include <pwd.h>
32
33#include "xmalloc.h"
34#include "ssh.h"
35#include "ssh1.h"
36#include "rsa.h"
37#include "buffer.h"
38#include "packet.h"
39#include "key.h"
40#include "cipher.h"
41#include "kex.h"
42#include "uidswap.h"
43#include "log.h"
44#include "misc.h"
45#include "readconf.h"
46#include "authfd.h"
47#include "sshconnect.h"
48#include "authfile.h"
49#include "canohost.h"
50#include "hostfile.h"
51#include "auth.h"
52#include "digest.h"
53#include "ssherr.h"
54
55/* Session id for the current session. */
56u_char session_id[16];
57u_int supported_authentications = 0;
58
59extern Options options;
60extern char *__progname;
61
62/*
63 * Checks if the user has an authentication agent, and if so, tries to
64 * authenticate using the agent.
65 */
66static int
67try_agent_authentication(void)
68{
69 int r, type, agent_fd, ret = 0;
70 u_char response[16];
71 size_t i;
72 BIGNUM *challenge;
73 struct ssh_identitylist *idlist = NULL;
74
75 /* Get connection to the agent. */
76 if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
77 if (r != SSH_ERR_AGENT_NOT_PRESENT)
78 debug("%s: ssh_get_authentication_socket: %s",
79 __func__, ssh_err(r));
80 return 0;
81 }
82
83 if ((challenge = BN_new()) == NULL)
84 fatal("try_agent_authentication: BN_new failed");
85
86 /* Loop through identities served by the agent. */
87 if ((r = ssh_fetch_identitylist(agent_fd, 1, &idlist)) != 0) {
88 if (r != SSH_ERR_AGENT_NO_IDENTITIES)
89 debug("%s: ssh_fetch_identitylist: %s",
90 __func__, ssh_err(r));
91 goto out;
92 }
93 for (i = 0; i < idlist->nkeys; i++) {
94 /* Try this identity. */
95 debug("Trying RSA authentication via agent with '%.100s'",
96 idlist->comments[i]);
97
98 /* Tell the server that we are willing to authenticate using this key. */
99 packet_start(SSH_CMSG_AUTH_RSA);
100 packet_put_bignum(idlist->keys[i]->rsa->n);
101 packet_send();
102 packet_write_wait();
103
104 /* Wait for server's response. */
105 type = packet_read();
106
107 /* The server sends failure if it doesn't like our key or
108 does not support RSA authentication. */
109 if (type == SSH_SMSG_FAILURE) {
110 debug("Server refused our key.");
111 continue;
112 }
113 /* Otherwise it should have sent a challenge. */
114 if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
115 packet_disconnect("Protocol error during RSA authentication: %d",
116 type);
117
118 packet_get_bignum(challenge);
119 packet_check_eom();
120
121 debug("Received RSA challenge from server.");
122
123 /* Ask the agent to decrypt the challenge. */
124 if ((r = ssh_decrypt_challenge(agent_fd, idlist->keys[i],
125 challenge, session_id, response)) != 0) {
126 /*
127 * The agent failed to authenticate this identifier
128 * although it advertised it supports this. Just
129 * return a wrong value.
130 */
131 logit("Authentication agent failed to decrypt "
132 "challenge: %s", ssh_err(r));
133 explicit_bzero(response, sizeof(response));
134 }
135 debug("Sending response to RSA challenge.");
136
137 /* Send the decrypted challenge back to the server. */
138 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
139 for (i = 0; i < 16; i++)
140 packet_put_char(response[i]);
141 packet_send();
142 packet_write_wait();
143
144 /* Wait for response from the server. */
145 type = packet_read();
146
147 /*
148 * The server returns success if it accepted the
149 * authentication.
150 */
151 if (type == SSH_SMSG_SUCCESS) {
152 debug("RSA authentication accepted by server.");
153 ret = 1;
154 break;
155 } else if (type != SSH_SMSG_FAILURE)
156 packet_disconnect("Protocol error waiting RSA auth "
157 "response: %d", type);
158 }
159 if (ret != 1)
160 debug("RSA authentication using agent refused.");
161 out:
162 ssh_free_identitylist(idlist);
163 ssh_close_authentication_socket(agent_fd);
164 BN_clear_free(challenge);
165 return ret;
166}
167
168/*
169 * Computes the proper response to a RSA challenge, and sends the response to
170 * the server.
171 */
172static void
173respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
174{
175 u_char buf[32], response[16];
176 struct ssh_digest_ctx *md;
177 int i, len;
178
179 /* Decrypt the challenge using the private key. */
180 /* XXX think about Bleichenbacher, too */
181 if (rsa_private_decrypt(challenge, challenge, prv) != 0)
182 packet_disconnect(
183 "respond_to_rsa_challenge: rsa_private_decrypt failed");
184
185 /* Compute the response. */
186 /* The response is MD5 of decrypted challenge plus session id. */
187 len = BN_num_bytes(challenge);
188 if (len <= 0 || (u_int)len > sizeof(buf))
189 packet_disconnect(
190 "respond_to_rsa_challenge: bad challenge length %d", len);
191
192 memset(buf, 0, sizeof(buf));
193 BN_bn2bin(challenge, buf + sizeof(buf) - len);
194 if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
195 ssh_digest_update(md, buf, 32) < 0 ||
196 ssh_digest_update(md, session_id, 16) < 0 ||
197 ssh_digest_final(md, response, sizeof(response)) < 0)
198 fatal("%s: md5 failed", __func__);
199 ssh_digest_free(md);
200
201 debug("Sending response to host key RSA challenge.");
202
203 /* Send the response back to the server. */
204 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
205 for (i = 0; i < 16; i++)
206 packet_put_char(response[i]);
207 packet_send();
208 packet_write_wait();
209
210 explicit_bzero(buf, sizeof(buf));
211 explicit_bzero(response, sizeof(response));
212 explicit_bzero(&md, sizeof(md));
213}
214
215/*
216 * Checks if the user has authentication file, and if so, tries to authenticate
217 * the user using it.
218 */
219static int
220try_rsa_authentication(int idx)
221{
222 BIGNUM *challenge;
223 Key *public, *private;
224 char buf[300], *passphrase = NULL, *comment, *authfile;
225 int i, perm_ok = 1, type, quit;
226
227 public = options.identity_keys[idx];
228 authfile = options.identity_files[idx];
229 comment = xstrdup(authfile);
230
231 debug("Trying RSA authentication with key '%.100s'", comment);
232
233 /* Tell the server that we are willing to authenticate using this key. */
234 packet_start(SSH_CMSG_AUTH_RSA);
235 packet_put_bignum(public->rsa->n);
236 packet_send();
237 packet_write_wait();
238
239 /* Wait for server's response. */
240 type = packet_read();
241
242 /*
243 * The server responds with failure if it doesn't like our key or
244 * doesn't support RSA authentication.
245 */
246 if (type == SSH_SMSG_FAILURE) {
247 debug("Server refused our key.");
248 free(comment);
249 return 0;
250 }
251 /* Otherwise, the server should respond with a challenge. */
252 if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
253 packet_disconnect("Protocol error during RSA authentication: %d", type);
254
255 /* Get the challenge from the packet. */
256 if ((challenge = BN_new()) == NULL)
257 fatal("try_rsa_authentication: BN_new failed");
258 packet_get_bignum(challenge);
259 packet_check_eom();
260
261 debug("Received RSA challenge from server.");
262
263 /*
264 * If the key is not stored in external hardware, we have to
265 * load the private key. Try first with empty passphrase; if it
266 * fails, ask for a passphrase.
267 */
268 if (public->flags & SSHKEY_FLAG_EXT)
269 private = public;
270 else
271 private = key_load_private_type(KEY_RSA1, authfile, "", NULL,
272 &perm_ok);
273 if (private == NULL && !options.batch_mode && perm_ok) {
274 snprintf(buf, sizeof(buf),
275 "Enter passphrase for RSA key '%.100s': ", comment);
276 for (i = 0; i < options.number_of_password_prompts; i++) {
277 passphrase = read_passphrase(buf, 0);
278 if (strcmp(passphrase, "") != 0) {
279 private = key_load_private_type(KEY_RSA1,
280 authfile, passphrase, NULL, NULL);
281 quit = 0;
282 } else {
283 debug2("no passphrase given, try next key");
284 quit = 1;
285 }
286 if (private != NULL || quit)
287 break;
288 debug2("bad passphrase given, try again...");
289 }
290 }
291
292 if (private != NULL)
293 maybe_add_key_to_agent(authfile, private, comment, passphrase);
294
295 if (passphrase != NULL) {
296 explicit_bzero(passphrase, strlen(passphrase));
297 free(passphrase);
298 }
299
300 /* We no longer need the comment. */
301 free(comment);
302
303 if (private == NULL) {
304 if (!options.batch_mode && perm_ok)
305 error("Bad passphrase.");
306
307 /* Send a dummy response packet to avoid protocol error. */
308 packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
309 for (i = 0; i < 16; i++)
310 packet_put_char(0);
311 packet_send();
312 packet_write_wait();
313
314 /* Expect the server to reject it... */
315 packet_read_expect(SSH_SMSG_FAILURE);
316 BN_clear_free(challenge);
317 return 0;
318 }
319
320 /* Compute and send a response to the challenge. */
321 respond_to_rsa_challenge(challenge, private->rsa);
322
323 /* Destroy the private key unless it in external hardware. */
324 if (!(private->flags & SSHKEY_FLAG_EXT))
325 key_free(private);
326
327 /* We no longer need the challenge. */
328 BN_clear_free(challenge);
329
330 /* Wait for response from the server. */
331 type = packet_read();
332 if (type == SSH_SMSG_SUCCESS) {
333 debug("RSA authentication accepted by server.");
334 return 1;
335 }
336 if (type != SSH_SMSG_FAILURE)
337 packet_disconnect("Protocol error waiting RSA auth response: %d", type);
338 debug("RSA authentication refused.");
339 return 0;
340}
341
342/*
343 * Tries to authenticate the user using combined rhosts or /etc/hosts.equiv
344 * authentication and RSA host authentication.
345 */
346static int
347try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
348{
349 int type;
350 BIGNUM *challenge;
351
352 debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
353
354 /* Tell the server that we are willing to authenticate using this key. */
355 packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
356 packet_put_cstring(local_user);
357 packet_put_int(BN_num_bits(host_key->rsa->n));
358 packet_put_bignum(host_key->rsa->e);
359 packet_put_bignum(host_key->rsa->n);
360 packet_send();
361 packet_write_wait();
362
363 /* Wait for server's response. */
364 type = packet_read();
365
366 /* The server responds with failure if it doesn't admit our
367 .rhosts authentication or doesn't know our host key. */
368 if (type == SSH_SMSG_FAILURE) {
369 debug("Server refused our rhosts authentication or host key.");
370 return 0;
371 }
372 /* Otherwise, the server should respond with a challenge. */
373 if (type != SSH_SMSG_AUTH_RSA_CHALLENGE)
374 packet_disconnect("Protocol error during RSA authentication: %d", type);
375
376 /* Get the challenge from the packet. */
377 if ((challenge = BN_new()) == NULL)
378 fatal("try_rhosts_rsa_authentication: BN_new failed");
379 packet_get_bignum(challenge);
380 packet_check_eom();
381
382 debug("Received RSA challenge for host key from server.");
383
384 /* Compute a response to the challenge. */
385 respond_to_rsa_challenge(challenge, host_key->rsa);
386
387 /* We no longer need the challenge. */
388 BN_clear_free(challenge);
389
390 /* Wait for response from the server. */
391 type = packet_read();
392 if (type == SSH_SMSG_SUCCESS) {
393 debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
394 return 1;
395 }
396 if (type != SSH_SMSG_FAILURE)
397 packet_disconnect("Protocol error waiting RSA auth response: %d", type);
398 debug("Rhosts or /etc/hosts.equiv with RSA host authentication refused.");
399 return 0;
400}
401
402/*
403 * Tries to authenticate with any string-based challenge/response system.
404 * Note that the client code is not tied to s/key or TIS.
405 */
406static int
407try_challenge_response_authentication(void)
408{
409 int type, i;
410 u_int clen;
411 char prompt[1024];
412 char *challenge, *response;
413
414 debug("Doing challenge response authentication.");
415
416 for (i = 0; i < options.number_of_password_prompts; i++) {
417 /* request a challenge */
418 packet_start(SSH_CMSG_AUTH_TIS);
419 packet_send();
420 packet_write_wait();
421
422 type = packet_read();
423 if (type != SSH_SMSG_FAILURE &&
424 type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
425 packet_disconnect("Protocol error: got %d in response "
426 "to SSH_CMSG_AUTH_TIS", type);
427 }
428 if (type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
429 debug("No challenge.");
430 return 0;
431 }
432 challenge = packet_get_string(&clen);
433 packet_check_eom();
434 snprintf(prompt, sizeof prompt, "%s%s", challenge,
435 strchr(challenge, '\n') ? "" : "\nResponse: ");
436 free(challenge);
437 if (i != 0)
438 error("Permission denied, please try again.");
439 if (options.cipher == SSH_CIPHER_NONE)
440 logit("WARNING: Encryption is disabled! "
441 "Response will be transmitted in clear text.");
442 response = read_passphrase(prompt, 0);
443 if (strcmp(response, "") == 0) {
444 free(response);
445 break;
446 }
447 packet_start(SSH_CMSG_AUTH_TIS_RESPONSE);
448 ssh_put_password(response);
449 explicit_bzero(response, strlen(response));
450 free(response);
451 packet_send();
452 packet_write_wait();
453 type = packet_read();
454 if (type == SSH_SMSG_SUCCESS)
455 return 1;
456 if (type != SSH_SMSG_FAILURE)
457 packet_disconnect("Protocol error: got %d in response "
458 "to SSH_CMSG_AUTH_TIS_RESPONSE", type);
459 }
460 /* failure */
461 return 0;
462}
463
464/*
465 * Tries to authenticate with plain passwd authentication.
466 */
467static int
468try_password_authentication(char *prompt)
469{
470 int type, i;
471 char *password;
472
473 debug("Doing password authentication.");
474 if (options.cipher == SSH_CIPHER_NONE)
475 logit("WARNING: Encryption is disabled! Password will be transmitted in clear text.");
476 for (i = 0; i < options.number_of_password_prompts; i++) {
477 if (i != 0)
478 error("Permission denied, please try again.");
479 password = read_passphrase(prompt, 0);
480 packet_start(SSH_CMSG_AUTH_PASSWORD);
481 ssh_put_password(password);
482 explicit_bzero(password, strlen(password));
483 free(password);
484 packet_send();
485 packet_write_wait();
486
487 type = packet_read();
488 if (type == SSH_SMSG_SUCCESS)
489 return 1;
490 if (type != SSH_SMSG_FAILURE)
491 packet_disconnect("Protocol error: got %d in response to passwd auth", type);
492 }
493 /* failure */
494 return 0;
495}
496
497/*
498 * SSH1 key exchange
499 */
500void
501ssh_kex(char *host, struct sockaddr *hostaddr)
502{
503 int i;
504 BIGNUM *key;
505 Key *host_key, *server_key;
506 int bits, rbits;
507 int ssh_cipher_default = SSH_CIPHER_3DES;
508 u_char session_key[SSH_SESSION_KEY_LENGTH];
509 u_char cookie[8];
510 u_int supported_ciphers;
511 u_int server_flags, client_flags;
512
513 debug("Waiting for server public key.");
514
515 /* Wait for a public key packet from the server. */
516 packet_read_expect(SSH_SMSG_PUBLIC_KEY);
517
518 /* Get cookie from the packet. */
519 for (i = 0; i < 8; i++)
520 cookie[i] = packet_get_char();
521
522 /* Get the public key. */
523 if ((server_key = key_new(KEY_RSA1)) == NULL)
524 fatal("%s: key_new(KEY_RSA1) failed", __func__);
525 bits = packet_get_int();
526 packet_get_bignum(server_key->rsa->e);
527 packet_get_bignum(server_key->rsa->n);
528
529 rbits = BN_num_bits(server_key->rsa->n);
530 if (bits != rbits) {
531 logit("Warning: Server lies about size of server public key: "
532 "actual size is %d bits vs. announced %d.", rbits, bits);
533 logit("Warning: This may be due to an old implementation of ssh.");
534 }
535 /* Get the host key. */
536 if ((host_key = key_new(KEY_RSA1)) == NULL)
537 fatal("%s: key_new(KEY_RSA1) failed", __func__);
538 bits = packet_get_int();
539 packet_get_bignum(host_key->rsa->e);
540 packet_get_bignum(host_key->rsa->n);
541
542 rbits = BN_num_bits(host_key->rsa->n);
543 if (bits != rbits) {
544 logit("Warning: Server lies about size of server host key: "
545 "actual size is %d bits vs. announced %d.", rbits, bits);
546 logit("Warning: This may be due to an old implementation of ssh.");
547 }
548
549 /* Get protocol flags. */
550 server_flags = packet_get_int();
551 packet_set_protocol_flags(server_flags);
552
553 supported_ciphers = packet_get_int();
554 supported_authentications = packet_get_int();
555 packet_check_eom();
556
557 debug("Received server public key (%d bits) and host key (%d bits).",
558 BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));
559
560 if (verify_host_key(host, hostaddr, host_key) == -1)
561 fatal("Host key verification failed.");
562
563 client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
564
565 derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id);
566
567 /*
568 * Generate an encryption key for the session. The key is a 256 bit
569 * random number, interpreted as a 32-byte key, with the least
570 * significant 8 bits being the first byte of the key.
571 */
572 arc4random_buf(session_key, sizeof(session_key));
573
574 /*
575 * According to the protocol spec, the first byte of the session key
576 * is the highest byte of the integer. The session key is xored with
577 * the first 16 bytes of the session id.
578 */
579 if ((key = BN_new()) == NULL)
580 fatal("ssh_kex: BN_new failed");
581 if (BN_set_word(key, 0) == 0)
582 fatal("ssh_kex: BN_set_word failed");
583 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
584 if (BN_lshift(key, key, 8) == 0)
585 fatal("ssh_kex: BN_lshift failed");
586 if (i < 16) {
587 if (BN_add_word(key, session_key[i] ^ session_id[i])
588 == 0)
589 fatal("ssh_kex: BN_add_word failed");
590 } else {
591 if (BN_add_word(key, session_key[i]) == 0)
592 fatal("ssh_kex: BN_add_word failed");
593 }
594 }
595
596 /*
597 * Encrypt the integer using the public key and host key of the
598 * server (key with smaller modulus first).
599 */
600 if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) {
601 /* Public key has smaller modulus. */
602 if (BN_num_bits(host_key->rsa->n) <
603 BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
604 fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "
605 "SSH_KEY_BITS_RESERVED %d",
606 BN_num_bits(host_key->rsa->n),
607 BN_num_bits(server_key->rsa->n),
608 SSH_KEY_BITS_RESERVED);
609 }
610 if (rsa_public_encrypt(key, key, server_key->rsa) != 0 ||
611 rsa_public_encrypt(key, key, host_key->rsa) != 0)
612 fatal("%s: rsa_public_encrypt failed", __func__);
613 } else {
614 /* Host key has smaller modulus (or they are equal). */
615 if (BN_num_bits(server_key->rsa->n) <
616 BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
617 fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "
618 "SSH_KEY_BITS_RESERVED %d",
619 BN_num_bits(server_key->rsa->n),
620 BN_num_bits(host_key->rsa->n),
621 SSH_KEY_BITS_RESERVED);
622 }
623 if (rsa_public_encrypt(key, key, host_key->rsa) != 0 ||
624 rsa_public_encrypt(key, key, server_key->rsa) != 0)
625 fatal("%s: rsa_public_encrypt failed", __func__);
626 }
627
628 /* Destroy the public keys since we no longer need them. */
629 key_free(server_key);
630 key_free(host_key);
631
632 if (options.cipher == SSH_CIPHER_NOT_SET) {
633 if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default))
634 options.cipher = ssh_cipher_default;
635 } else if (options.cipher == SSH_CIPHER_INVALID ||
636 !(cipher_mask_ssh1(1) & (1 << options.cipher))) {
637 logit("No valid SSH1 cipher, using %.100s instead.",
638 cipher_name(ssh_cipher_default));
639 options.cipher = ssh_cipher_default;
640 }
641 /* Check that the selected cipher is supported. */
642 if (!(supported_ciphers & (1 << options.cipher)))
643 fatal("Selected cipher type %.100s not supported by server.",
644 cipher_name(options.cipher));
645
646 debug("Encryption type: %.100s", cipher_name(options.cipher));
647
648 /* Send the encrypted session key to the server. */
649 packet_start(SSH_CMSG_SESSION_KEY);
650 packet_put_char(options.cipher);
651
652 /* Send the cookie back to the server. */
653 for (i = 0; i < 8; i++)
654 packet_put_char(cookie[i]);
655
656 /* Send and destroy the encrypted encryption key integer. */
657 packet_put_bignum(key);
658 BN_clear_free(key);
659
660 /* Send protocol flags. */
661 packet_put_int(client_flags);
662
663 /* Send the packet now. */
664 packet_send();
665 packet_write_wait();
666
667 debug("Sent encrypted session key.");
668
669 /* Set the encryption key. */
670 packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, options.cipher);
671
672 /*
673 * We will no longer need the session key here.
674 * Destroy any extra copies.
675 */
676 explicit_bzero(session_key, sizeof(session_key));
677
678 /*
679 * Expect a success message from the server. Note that this message
680 * will be received in encrypted form.
681 */
682 packet_read_expect(SSH_SMSG_SUCCESS);
683
684 debug("Received encrypted confirmation.");
685}
686
687/*
688 * Authenticate user
689 */
690void
691ssh_userauth1(const char *local_user, const char *server_user, char *host,
692 Sensitive *sensitive)
693{
694 int i, type;
695
696 if (supported_authentications == 0)
697 fatal("ssh_userauth1: server supports no auth methods");
698
699 /* Send the name of the user to log in as on the server. */
700 packet_start(SSH_CMSG_USER);
701 packet_put_cstring(server_user);
702 packet_send();
703 packet_write_wait();
704
705 /*
706 * The server should respond with success if no authentication is
707 * needed (the user has no password). Otherwise the server responds
708 * with failure.
709 */
710 type = packet_read();
711
712 /* check whether the connection was accepted without authentication. */
713 if (type == SSH_SMSG_SUCCESS)
714 goto success;
715 if (type != SSH_SMSG_FAILURE)
716 packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type);
717
718 /*
719 * Try .rhosts or /etc/hosts.equiv authentication with RSA host
720 * authentication.
721 */
722 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
723 options.rhosts_rsa_authentication) {
724 for (i = 0; i < sensitive->nkeys; i++) {
725 if (sensitive->keys[i] != NULL &&
726 sensitive->keys[i]->type == KEY_RSA1 &&
727 try_rhosts_rsa_authentication(local_user,
728 sensitive->keys[i]))
729 goto success;
730 }
731 }
732 /* Try RSA authentication if the server supports it. */
733 if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
734 options.rsa_authentication) {
735 /*
736 * Try RSA authentication using the authentication agent. The
737 * agent is tried first because no passphrase is needed for
738 * it, whereas identity files may require passphrases.
739 */
740 if (try_agent_authentication())
741 goto success;
742
743 /* Try RSA authentication for each identity. */
744 for (i = 0; i < options.num_identity_files; i++)
745 if (options.identity_keys[i] != NULL &&
746 options.identity_keys[i]->type == KEY_RSA1 &&
747 try_rsa_authentication(i))
748 goto success;
749 }
750 /* Try challenge response authentication if the server supports it. */
751 if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
752 options.challenge_response_authentication && !options.batch_mode) {
753 if (try_challenge_response_authentication())
754 goto success;
755 }
756 /* Try password authentication if the server supports it. */
757 if ((supported_authentications & (1 << SSH_AUTH_PASSWORD)) &&
758 options.password_authentication && !options.batch_mode) {
759 char prompt[80];
760
761 snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
762 server_user, host);
763 if (try_password_authentication(prompt))
764 goto success;
765 }
766 /* All authentication methods have failed. Exit with an error message. */
767 fatal("Permission denied.");
768 /* NOTREACHED */
769
770 success:
771 return; /* need statement after label */
772}
773
774#endif /* WITH_SSH1 */
diff --git a/sshconnect2.c b/sshconnect2.c
index f8a54beea..be9397e48 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.255 2017/03/11 23:40:26 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.266 2017/08/27 00:38:41 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -93,7 +93,7 @@ char *xxx_host;
93struct sockaddr *xxx_hostaddr; 93struct sockaddr *xxx_hostaddr;
94 94
95static int 95static int
96verify_host_key_callback(Key *hostkey, struct ssh *ssh) 96verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
97{ 97{
98 if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) 98 if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
99 fatal("Host key verification failed."); 99 fatal("Host key verification failed.");
@@ -217,7 +217,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
217 kex->server_version_string=server_version_string; 217 kex->server_version_string=server_version_string;
218 kex->verify_host_key=&verify_host_key_callback; 218 kex->verify_host_key=&verify_host_key_callback;
219 219
220 dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); 220 ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done);
221 221
222 /* remove ext-info from the KEX proposals for rekeying */ 222 /* remove ext-info from the KEX proposals for rekeying */
223 myproposal[PROPOSAL_KEX_ALGS] = 223 myproposal[PROPOSAL_KEX_ALGS] =
@@ -287,16 +287,16 @@ struct cauthmethod {
287 int *batch_flag; /* flag in option struct that disables method */ 287 int *batch_flag; /* flag in option struct that disables method */
288}; 288};
289 289
290int input_userauth_service_accept(int, u_int32_t, void *); 290int input_userauth_service_accept(int, u_int32_t, struct ssh *);
291int input_userauth_ext_info(int, u_int32_t, void *); 291int input_userauth_ext_info(int, u_int32_t, struct ssh *);
292int input_userauth_success(int, u_int32_t, void *); 292int input_userauth_success(int, u_int32_t, struct ssh *);
293int input_userauth_success_unexpected(int, u_int32_t, void *); 293int input_userauth_success_unexpected(int, u_int32_t, struct ssh *);
294int input_userauth_failure(int, u_int32_t, void *); 294int input_userauth_failure(int, u_int32_t, struct ssh *);
295int input_userauth_banner(int, u_int32_t, void *); 295int input_userauth_banner(int, u_int32_t, struct ssh *);
296int input_userauth_error(int, u_int32_t, void *); 296int input_userauth_error(int, u_int32_t, struct ssh *);
297int input_userauth_info_req(int, u_int32_t, void *); 297int input_userauth_info_req(int, u_int32_t, struct ssh *);
298int input_userauth_pk_ok(int, u_int32_t, void *); 298int input_userauth_pk_ok(int, u_int32_t, struct ssh *);
299int input_userauth_passwd_changereq(int, u_int32_t, void *); 299int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *);
300 300
301int userauth_none(Authctxt *); 301int userauth_none(Authctxt *);
302int userauth_pubkey(Authctxt *); 302int userauth_pubkey(Authctxt *);
@@ -306,11 +306,11 @@ int userauth_hostbased(Authctxt *);
306 306
307#ifdef GSSAPI 307#ifdef GSSAPI
308int userauth_gssapi(Authctxt *authctxt); 308int userauth_gssapi(Authctxt *authctxt);
309int input_gssapi_response(int type, u_int32_t, void *); 309int input_gssapi_response(int type, u_int32_t, struct ssh *);
310int input_gssapi_token(int type, u_int32_t, void *); 310int input_gssapi_token(int type, u_int32_t, struct ssh *);
311int input_gssapi_hash(int type, u_int32_t, void *); 311int input_gssapi_hash(int type, u_int32_t, struct ssh *);
312int input_gssapi_error(int, u_int32_t, void *); 312int input_gssapi_error(int, u_int32_t, struct ssh *);
313int input_gssapi_errtok(int, u_int32_t, void *); 313int input_gssapi_errtok(int, u_int32_t, struct ssh *);
314#endif 314#endif
315 315
316void userauth(Authctxt *, char *); 316void userauth(Authctxt *, char *);
@@ -319,7 +319,7 @@ static int sign_and_send_pubkey(Authctxt *, Identity *);
319static void pubkey_prepare(Authctxt *); 319static void pubkey_prepare(Authctxt *);
320static void pubkey_cleanup(Authctxt *); 320static void pubkey_cleanup(Authctxt *);
321static void pubkey_reset(Authctxt *); 321static void pubkey_reset(Authctxt *);
322static Key *load_identity_file(Identity *); 322static struct sshkey *load_identity_file(Identity *);
323 323
324static Authmethod *authmethod_get(char *authlist); 324static Authmethod *authmethod_get(char *authlist);
325static Authmethod *authmethod_lookup(const char *name); 325static Authmethod *authmethod_lookup(const char *name);
@@ -397,10 +397,12 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
397 (r = sshpkt_send(ssh)) != 0) 397 (r = sshpkt_send(ssh)) != 0)
398 fatal("%s: %s", __func__, ssh_err(r)); 398 fatal("%s: %s", __func__, ssh_err(r));
399 399
400 ssh->authctxt = &authctxt;
400 ssh_dispatch_init(ssh, &input_userauth_error); 401 ssh_dispatch_init(ssh, &input_userauth_error);
401 ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info); 402 ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info);
402 ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept); 403 ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept);
403 ssh_dispatch_run(ssh, DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ 404 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */
405 ssh->authctxt = NULL;
404 406
405 pubkey_cleanup(&authctxt); 407 pubkey_cleanup(&authctxt);
406 ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); 408 ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
@@ -412,10 +414,9 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
412 414
413/* ARGSUSED */ 415/* ARGSUSED */
414int 416int
415input_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt) 417input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
416{ 418{
417 Authctxt *authctxt = ctxt; 419 Authctxt *authctxt = ssh->authctxt;
418 struct ssh *ssh = active_state;
419 int r; 420 int r;
420 421
421 if (ssh_packet_remaining(ssh) > 0) { 422 if (ssh_packet_remaining(ssh) > 0) {
@@ -446,9 +447,9 @@ input_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt)
446 447
447/* ARGSUSED */ 448/* ARGSUSED */
448int 449int
449input_userauth_ext_info(int type, u_int32_t seqnr, void *ctxt) 450input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh)
450{ 451{
451 return kex_input_ext_info(type, seqnr, active_state); 452 return kex_input_ext_info(type, seqnr, ssh);
452} 453}
453 454
454void 455void
@@ -468,7 +469,8 @@ userauth(Authctxt *authctxt, char *authlist)
468 for (;;) { 469 for (;;) {
469 Authmethod *method = authmethod_get(authlist); 470 Authmethod *method = authmethod_get(authlist);
470 if (method == NULL) 471 if (method == NULL)
471 fatal("Permission denied (%s).", authlist); 472 fatal("%s@%s: Permission denied (%s).",
473 authctxt->server_user, authctxt->host, authlist);
472 authctxt->method = method; 474 authctxt->method = method;
473 475
474 /* reset the per method handler */ 476 /* reset the per method handler */
@@ -488,7 +490,7 @@ userauth(Authctxt *authctxt, char *authlist)
488 490
489/* ARGSUSED */ 491/* ARGSUSED */
490int 492int
491input_userauth_error(int type, u_int32_t seq, void *ctxt) 493input_userauth_error(int type, u_int32_t seq, struct ssh *ssh)
492{ 494{
493 fatal("input_userauth_error: bad message during authentication: " 495 fatal("input_userauth_error: bad message during authentication: "
494 "type %d", type); 496 "type %d", type);
@@ -497,7 +499,7 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt)
497 499
498/* ARGSUSED */ 500/* ARGSUSED */
499int 501int
500input_userauth_banner(int type, u_int32_t seq, void *ctxt) 502input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh)
501{ 503{
502 char *msg, *lang; 504 char *msg, *lang;
503 u_int len; 505 u_int len;
@@ -514,9 +516,9 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
514 516
515/* ARGSUSED */ 517/* ARGSUSED */
516int 518int
517input_userauth_success(int type, u_int32_t seq, void *ctxt) 519input_userauth_success(int type, u_int32_t seq, struct ssh *ssh)
518{ 520{
519 Authctxt *authctxt = ctxt; 521 Authctxt *authctxt = ssh->authctxt;
520 522
521 if (authctxt == NULL) 523 if (authctxt == NULL)
522 fatal("input_userauth_success: no authentication context"); 524 fatal("input_userauth_success: no authentication context");
@@ -531,9 +533,9 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
531} 533}
532 534
533int 535int
534input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt) 536input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh)
535{ 537{
536 Authctxt *authctxt = ctxt; 538 Authctxt *authctxt = ssh->authctxt;
537 539
538 if (authctxt == NULL) 540 if (authctxt == NULL)
539 fatal("%s: no authentication context", __func__); 541 fatal("%s: no authentication context", __func__);
@@ -545,9 +547,9 @@ input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
545 547
546/* ARGSUSED */ 548/* ARGSUSED */
547int 549int
548input_userauth_failure(int type, u_int32_t seq, void *ctxt) 550input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh)
549{ 551{
550 Authctxt *authctxt = ctxt; 552 Authctxt *authctxt = ssh->authctxt;
551 char *authlist = NULL; 553 char *authlist = NULL;
552 int partial; 554 int partial;
553 555
@@ -571,10 +573,10 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt)
571 573
572/* ARGSUSED */ 574/* ARGSUSED */
573int 575int
574input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) 576input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
575{ 577{
576 Authctxt *authctxt = ctxt; 578 Authctxt *authctxt = ssh->authctxt;
577 Key *key = NULL; 579 struct sshkey *key = NULL;
578 Identity *id = NULL; 580 Identity *id = NULL;
579 Buffer b; 581 Buffer b;
580 int pktype, sent = 0; 582 int pktype, sent = 0;
@@ -702,9 +704,9 @@ userauth_gssapi(Authctxt *authctxt)
702} 704}
703 705
704static OM_uint32 706static OM_uint32
705process_gssapi_token(void *ctxt, gss_buffer_t recv_tok) 707process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
706{ 708{
707 Authctxt *authctxt = ctxt; 709 Authctxt *authctxt = ssh->authctxt;
708 Gssctxt *gssctxt = authctxt->methoddata; 710 Gssctxt *gssctxt = authctxt->methoddata;
709 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 711 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
710 gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; 712 gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
@@ -757,9 +759,9 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
757 759
758/* ARGSUSED */ 760/* ARGSUSED */
759int 761int
760input_gssapi_response(int type, u_int32_t plen, void *ctxt) 762input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
761{ 763{
762 Authctxt *authctxt = ctxt; 764 Authctxt *authctxt = ssh->authctxt;
763 Gssctxt *gssctxt; 765 Gssctxt *gssctxt;
764 int oidlen; 766 int oidlen;
765 char *oidv; 767 char *oidv;
@@ -787,7 +789,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
787 789
788 free(oidv); 790 free(oidv);
789 791
790 if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { 792 if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) {
791 /* Start again with next method on list */ 793 /* Start again with next method on list */
792 debug("Trying to start again"); 794 debug("Trying to start again");
793 userauth(authctxt, NULL); 795 userauth(authctxt, NULL);
@@ -798,9 +800,9 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
798 800
799/* ARGSUSED */ 801/* ARGSUSED */
800int 802int
801input_gssapi_token(int type, u_int32_t plen, void *ctxt) 803input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
802{ 804{
803 Authctxt *authctxt = ctxt; 805 Authctxt *authctxt = ssh->authctxt;
804 gss_buffer_desc recv_tok; 806 gss_buffer_desc recv_tok;
805 OM_uint32 status; 807 OM_uint32 status;
806 u_int slen; 808 u_int slen;
@@ -813,7 +815,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
813 815
814 packet_check_eom(); 816 packet_check_eom();
815 817
816 status = process_gssapi_token(ctxt, &recv_tok); 818 status = process_gssapi_token(ssh, &recv_tok);
817 819
818 free(recv_tok.value); 820 free(recv_tok.value);
819 821
@@ -827,9 +829,9 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
827 829
828/* ARGSUSED */ 830/* ARGSUSED */
829int 831int
830input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) 832input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
831{ 833{
832 Authctxt *authctxt = ctxt; 834 Authctxt *authctxt = ssh->authctxt;
833 Gssctxt *gssctxt; 835 Gssctxt *gssctxt;
834 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 836 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
835 gss_buffer_desc recv_tok; 837 gss_buffer_desc recv_tok;
@@ -858,7 +860,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
858 860
859/* ARGSUSED */ 861/* ARGSUSED */
860int 862int
861input_gssapi_error(int type, u_int32_t plen, void *ctxt) 863input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
862{ 864{
863 char *msg; 865 char *msg;
864 char *lang; 866 char *lang;
@@ -893,7 +895,7 @@ int
893userauth_passwd(Authctxt *authctxt) 895userauth_passwd(Authctxt *authctxt)
894{ 896{
895 static int attempt = 0; 897 static int attempt = 0;
896 char prompt[150]; 898 char prompt[256];
897 char *password; 899 char *password;
898 const char *host = options.host_key_alias ? options.host_key_alias : 900 const char *host = options.host_key_alias ? options.host_key_alias :
899 authctxt->host; 901 authctxt->host;
@@ -929,11 +931,11 @@ userauth_passwd(Authctxt *authctxt)
929 */ 931 */
930/* ARGSUSED */ 932/* ARGSUSED */
931int 933int
932input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) 934input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
933{ 935{
934 Authctxt *authctxt = ctxt; 936 Authctxt *authctxt = ssh->authctxt;
935 char *info, *lang, *password = NULL, *retype = NULL; 937 char *info, *lang, *password = NULL, *retype = NULL;
936 char prompt[150]; 938 char prompt[256];
937 const char *host; 939 const char *host;
938 940
939 debug2("input_userauth_passwd_changereq"); 941 debug2("input_userauth_passwd_changereq");
@@ -1015,7 +1017,7 @@ static int
1015identity_sign(struct identity *id, u_char **sigp, size_t *lenp, 1017identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
1016 const u_char *data, size_t datalen, u_int compat) 1018 const u_char *data, size_t datalen, u_int compat)
1017{ 1019{
1018 Key *prv; 1020 struct sshkey *prv;
1019 int ret; 1021 int ret;
1020 1022
1021 /* the agent supports this key */ 1023 /* the agent supports this key */
@@ -1035,6 +1037,11 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
1035 /* load the private key from the file */ 1037 /* load the private key from the file */
1036 if ((prv = load_identity_file(id)) == NULL) 1038 if ((prv = load_identity_file(id)) == NULL)
1037 return SSH_ERR_KEY_NOT_FOUND; 1039 return SSH_ERR_KEY_NOT_FOUND;
1040 if (id->key != NULL && !sshkey_equal_public(prv, id->key)) {
1041 error("%s: private key %s contents do not match public",
1042 __func__, id->filename);
1043 return SSH_ERR_KEY_NOT_FOUND;
1044 }
1038 ret = sshkey_sign(prv, sigp, lenp, data, datalen, 1045 ret = sshkey_sign(prv, sigp, lenp, data, datalen,
1039 key_sign_encode(prv), compat); 1046 key_sign_encode(prv), compat);
1040 sshkey_free(prv); 1047 sshkey_free(prv);
@@ -1225,10 +1232,10 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
1225 return 1; 1232 return 1;
1226} 1233}
1227 1234
1228static Key * 1235static struct sshkey *
1229load_identity_file(Identity *id) 1236load_identity_file(Identity *id)
1230{ 1237{
1231 Key *private = NULL; 1238 struct sshkey *private = NULL;
1232 char prompt[300], *passphrase, *comment; 1239 char prompt[300], *passphrase, *comment;
1233 int r, perm_ok = 0, quit = 0, i; 1240 int r, perm_ok = 0, quit = 0, i;
1234 struct stat st; 1241 struct stat st;
@@ -1317,8 +1324,6 @@ pubkey_prepare(Authctxt *authctxt)
1317 /* list of keys stored in the filesystem and PKCS#11 */ 1324 /* list of keys stored in the filesystem and PKCS#11 */
1318 for (i = 0; i < options.num_identity_files; i++) { 1325 for (i = 0; i < options.num_identity_files; i++) {
1319 key = options.identity_keys[i]; 1326 key = options.identity_keys[i];
1320 if (key && key->type == KEY_RSA1)
1321 continue;
1322 if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER) 1327 if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER)
1323 continue; 1328 continue;
1324 options.identity_keys[i] = NULL; 1329 options.identity_keys[i] = NULL;
@@ -1347,7 +1352,7 @@ pubkey_prepare(Authctxt *authctxt)
1347 if (r != SSH_ERR_AGENT_NOT_PRESENT) 1352 if (r != SSH_ERR_AGENT_NOT_PRESENT)
1348 debug("%s: ssh_get_authentication_socket: %s", 1353 debug("%s: ssh_get_authentication_socket: %s",
1349 __func__, ssh_err(r)); 1354 __func__, ssh_err(r));
1350 } else if ((r = ssh_fetch_identitylist(agent_fd, 2, &idlist)) != 0) { 1355 } else if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) {
1351 if (r != SSH_ERR_AGENT_NO_IDENTITIES) 1356 if (r != SSH_ERR_AGENT_NO_IDENTITIES)
1352 debug("%s: ssh_fetch_identitylist: %s", 1357 debug("%s: ssh_fetch_identitylist: %s",
1353 __func__, ssh_err(r)); 1358 __func__, ssh_err(r));
@@ -1471,7 +1476,7 @@ try_identity(Identity *id)
1471 key_type(id->key), id->filename); 1476 key_type(id->key), id->filename);
1472 return (0); 1477 return (0);
1473 } 1478 }
1474 return (id->key->type != KEY_RSA1); 1479 return 1;
1475} 1480}
1476 1481
1477int 1482int
@@ -1479,6 +1484,7 @@ userauth_pubkey(Authctxt *authctxt)
1479{ 1484{
1480 Identity *id; 1485 Identity *id;
1481 int sent = 0; 1486 int sent = 0;
1487 char *fp;
1482 1488
1483 while ((id = TAILQ_FIRST(&authctxt->keys))) { 1489 while ((id = TAILQ_FIRST(&authctxt->keys))) {
1484 if (id->tried++) 1490 if (id->tried++)
@@ -1493,8 +1499,16 @@ userauth_pubkey(Authctxt *authctxt)
1493 */ 1499 */
1494 if (id->key != NULL) { 1500 if (id->key != NULL) {
1495 if (try_identity(id)) { 1501 if (try_identity(id)) {
1496 debug("Offering %s public key: %s", 1502 if ((fp = sshkey_fingerprint(id->key,
1497 key_type(id->key), id->filename); 1503 options.fingerprint_hash,
1504 SSH_FP_DEFAULT)) == NULL) {
1505 error("%s: sshkey_fingerprint failed",
1506 __func__);
1507 return 0;
1508 }
1509 debug("Offering public key: %s %s %s",
1510 sshkey_type(id->key), fp, id->filename);
1511 free(fp);
1498 sent = send_pubkey_test(authctxt, id); 1512 sent = send_pubkey_test(authctxt, id);
1499 } 1513 }
1500 } else { 1514 } else {
@@ -1552,9 +1566,9 @@ userauth_kbdint(Authctxt *authctxt)
1552 * parse INFO_REQUEST, prompt user and send INFO_RESPONSE 1566 * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
1553 */ 1567 */
1554int 1568int
1555input_userauth_info_req(int type, u_int32_t seq, void *ctxt) 1569input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
1556{ 1570{
1557 Authctxt *authctxt = ctxt; 1571 Authctxt *authctxt = ssh->authctxt;
1558 char *name, *inst, *lang, *prompt, *response; 1572 char *name, *inst, *lang, *prompt, *response;
1559 u_int num_prompts, i; 1573 u_int num_prompts, i;
1560 int echo = 0; 1574 int echo = 0;
@@ -1755,7 +1769,6 @@ userauth_hostbased(Authctxt *authctxt)
1755 private = NULL; 1769 private = NULL;
1756 for (i = 0; i < authctxt->sensitive->nkeys; i++) { 1770 for (i = 0; i < authctxt->sensitive->nkeys; i++) {
1757 if (authctxt->sensitive->keys[i] == NULL || 1771 if (authctxt->sensitive->keys[i] == NULL ||
1758 authctxt->sensitive->keys[i]->type == KEY_RSA1 ||
1759 authctxt->sensitive->keys[i]->type == KEY_UNSPEC) 1772 authctxt->sensitive->keys[i]->type == KEY_UNSPEC)
1760 continue; 1773 continue;
1761 if (match_pattern_list( 1774 if (match_pattern_list(
diff --git a/sshd.0 b/sshd.0
index 6cd5f038c..92c8ec533 100644
--- a/sshd.0
+++ b/sshd.0
@@ -134,7 +134,7 @@ AUTHENTICATION
134 client selects the encryption algorithm to use from those offered by the 134 client selects the encryption algorithm to use from those offered by the
135 server. Additionally, session integrity is provided through a 135 server. Additionally, session integrity is provided through a
136 cryptographic message authentication code (hmac-md5, hmac-sha1, umac-64, 136 cryptographic message authentication code (hmac-md5, hmac-sha1, umac-64,
137 umac-128, hmac-ripemd160, hmac-sha2-256 or hmac-sha2-512). 137 umac-128, hmac-sha2-256 or hmac-sha2-512).
138 138
139 Finally, the server and the client enter an authentication dialog. The 139 Finally, the server and the client enter an authentication dialog. The
140 client tries to authenticate itself using host-based authentication, 140 client tries to authenticate itself using host-based authentication,
@@ -412,13 +412,19 @@ SSH_KNOWN_HOSTS FILE FORMAT
412 should be used on a key line. 412 should be used on a key line.
413 413
414 Hostnames is a comma-separated list of patterns (M-bM-^@M-^X*M-bM-^@M-^Y and M-bM-^@M-^X?M-bM-^@M-^Y act as 414 Hostnames is a comma-separated list of patterns (M-bM-^@M-^X*M-bM-^@M-^Y and M-bM-^@M-^X?M-bM-^@M-^Y act as
415 wildcards); each pattern in turn is matched against the canonical host 415 wildcards); each pattern in turn is matched against the host name. When
416 name (when authenticating a client) or against the user-supplied name 416 sshd is authenticating a client, such as when using
417 (when authenticating a server). A pattern may also be preceded by M-bM-^@M-^X!M-bM-^@M-^Y to 417 HostbasedAuthentication, this will be the canonical client host name.
418 indicate negation: if the host name matches a negated pattern, it is not 418 When ssh(1) is authenticating a server, this will be the host name given
419 accepted (by that line) even if it matched another pattern on the line. 419 by the user, the value of the ssh(1) HostkeyAlias if it was specified, or
420 A hostname or address may optionally be enclosed within M-bM-^@M-^X[M-bM-^@M-^Y and M-bM-^@M-^X]M-bM-^@M-^Y 420 the canonical server hostname if the ssh(1) CanonicalizeHostname option
421 brackets then followed by M-bM-^@M-^X:M-bM-^@M-^Y and a non-standard port number. 421 was used.
422
423 A pattern may also be preceded by M-bM-^@M-^X!M-bM-^@M-^Y to indicate negation: if the host
424 name matches a negated pattern, it is not accepted (by that line) even if
425 it matched another pattern on the line. A hostname or address may
426 optionally be enclosed within M-bM-^@M-^X[M-bM-^@M-^Y and M-bM-^@M-^X]M-bM-^@M-^Y brackets then followed by M-bM-^@M-^X:M-bM-^@M-^Y
427 and a non-standard port number.
422 428
423 Alternately, hostnames may be stored in a hashed form which hides host 429 Alternately, hostnames may be stored in a hashed form which hides host
424 names and addresses should the file's contents be disclosed. Hashed 430 names and addresses should the file's contents be disclosed. Hashed
@@ -623,4 +629,4 @@ AUTHORS
623 versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support 629 versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support
624 for privilege separation. 630 for privilege separation.
625 631
626OpenBSD 6.0 January 30, 2017 OpenBSD 6.0 632OpenBSD 6.2 June 24, 2017 OpenBSD 6.2
diff --git a/sshd.8 b/sshd.8
index 7725a692c..a4201146b 100644
--- a/sshd.8
+++ b/sshd.8
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: sshd.8,v 1.288 2017/01/30 23:27:39 dtucker Exp $ 36.\" $OpenBSD: sshd.8,v 1.291 2017/06/24 06:28:50 jmc Exp $
37.Dd $Mdocdate: January 30 2017 $ 37.Dd $Mdocdate: June 24 2017 $
38.Dt SSHD 8 38.Dt SSHD 8
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -260,7 +260,7 @@ The client selects the encryption algorithm
260to use from those offered by the server. 260to use from those offered by the server.
261Additionally, session integrity is provided 261Additionally, session integrity is provided
262through a cryptographic message authentication code 262through a cryptographic message authentication code
263(hmac-md5, hmac-sha1, umac-64, umac-128, hmac-ripemd160, 263(hmac-md5, hmac-sha1, umac-64, umac-128,
264hmac-sha2-256 or hmac-sha2-512). 264hmac-sha2-256 or hmac-sha2-512).
265.Pp 265.Pp
266Finally, the server and the client enter an authentication dialog. 266Finally, the server and the client enter an authentication dialog.
@@ -652,9 +652,23 @@ Hostnames is a comma-separated list of patterns
652and 652and
653.Ql \&? 653.Ql \&?
654act as 654act as
655wildcards); each pattern in turn is matched against the canonical host 655wildcards); each pattern in turn is matched against the host name.
656name (when authenticating a client) or against the user-supplied 656When
657name (when authenticating a server). 657.Nm sshd
658is authenticating a client, such as when using
659.Cm HostbasedAuthentication ,
660this will be the canonical client host name.
661When
662.Xr ssh 1
663is authenticating a server, this will be the host name
664given by the user, the value of the
665.Xr ssh 1
666.Cm HostkeyAlias
667if it was specified, or the canonical server hostname if the
668.Xr ssh 1
669.Cm CanonicalizeHostname
670option was used.
671.Pp
658A pattern may also be preceded by 672A pattern may also be preceded by
659.Ql \&! 673.Ql \&!
660to indicate negation: if the host name matches a negated 674to indicate negation: if the host name matches a negated
diff --git a/sshd.c b/sshd.c
index 010a2c38a..51a1aaf6e 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.485 2017/03/15 03:52:30 deraadt Exp $ */ 1/* $OpenBSD: sshd.c,v 1.492 2017/09/12 06:32:07 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -88,7 +88,6 @@
88#include "xmalloc.h" 88#include "xmalloc.h"
89#include "ssh.h" 89#include "ssh.h"
90#include "ssh2.h" 90#include "ssh2.h"
91#include "rsa.h"
92#include "sshpty.h" 91#include "sshpty.h"
93#include "packet.h" 92#include "packet.h"
94#include "log.h" 93#include "log.h"
@@ -195,10 +194,10 @@ int have_agent = 0;
195 * not very useful. Currently, memory locking is not implemented. 194 * not very useful. Currently, memory locking is not implemented.
196 */ 195 */
197struct { 196struct {
198 Key **host_keys; /* all private host keys */ 197 struct sshkey **host_keys; /* all private host keys */
199 Key **host_pubkeys; /* all public host keys */ 198 struct sshkey **host_pubkeys; /* all public host keys */
200 Key **host_certificates; /* all public host certificates */ 199 struct sshkey **host_certificates; /* all public host certificates */
201 int have_ssh2_key; 200 int have_ssh2_key;
202} sensitive_data; 201} sensitive_data;
203 202
204/* This is set to true when a signal is received. */ 203/* This is set to true when a signal is received. */
@@ -223,6 +222,7 @@ int startup_pipe; /* in child */
223int use_privsep = -1; 222int use_privsep = -1;
224struct monitor *pmonitor = NULL; 223struct monitor *pmonitor = NULL;
225int privsep_is_preauth = 1; 224int privsep_is_preauth = 1;
225static int privsep_chroot = 1;
226 226
227/* global authentication context */ 227/* global authentication context */
228Authctxt *the_authctxt = NULL; 228Authctxt *the_authctxt = NULL;
@@ -449,10 +449,8 @@ sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out)
449 chop(server_version_string); 449 chop(server_version_string);
450 debug("Local version string %.200s", server_version_string); 450 debug("Local version string %.200s", server_version_string);
451 451
452 if (remote_major == 2 || 452 if (remote_major != 2 ||
453 (remote_major == 1 && remote_minor == 99)) { 453 (remote_major == 1 && remote_minor != 99)) {
454 enable_compat20();
455 } else {
456 s = "Protocol major versions differ.\n"; 454 s = "Protocol major versions differ.\n";
457 (void) atomicio(vwrite, sock_out, s, strlen(s)); 455 (void) atomicio(vwrite, sock_out, s, strlen(s));
458 close(sock_in); 456 close(sock_in);
@@ -487,7 +485,7 @@ destroy_sensitive_data(void)
487void 485void
488demote_sensitive_data(void) 486demote_sensitive_data(void)
489{ 487{
490 Key *tmp; 488 struct sshkey *tmp;
491 int i; 489 int i;
492 490
493 for (i = 0; i < options.num_host_key_files; i++) { 491 for (i = 0; i < options.num_host_key_files; i++) {
@@ -541,7 +539,7 @@ privsep_preauth_child(void)
541 demote_sensitive_data(); 539 demote_sensitive_data();
542 540
543 /* Demote the child */ 541 /* Demote the child */
544 if (getuid() == 0 || geteuid() == 0) { 542 if (privsep_chroot) {
545 /* Change our root directory */ 543 /* Change our root directory */
546 if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) 544 if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
547 fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, 545 fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
@@ -650,6 +648,7 @@ privsep_postauth(Authctxt *authctxt)
650 else if (pmonitor->m_pid != 0) { 648 else if (pmonitor->m_pid != 0) {
651 verbose("User child is on pid %ld", (long)pmonitor->m_pid); 649 verbose("User child is on pid %ld", (long)pmonitor->m_pid);
652 buffer_clear(&loginmsg); 650 buffer_clear(&loginmsg);
651 monitor_clear_keystate(pmonitor);
653 monitor_child_postauth(pmonitor); 652 monitor_child_postauth(pmonitor);
654 653
655 /* NEVERREACHED */ 654 /* NEVERREACHED */
@@ -687,7 +686,7 @@ list_hostkey_types(void)
687 const char *p; 686 const char *p;
688 char *ret; 687 char *ret;
689 int i; 688 int i;
690 Key *key; 689 struct sshkey *key;
691 690
692 buffer_init(&b); 691 buffer_init(&b);
693 for (i = 0; i < options.num_host_key_files; i++) { 692 for (i = 0; i < options.num_host_key_files; i++) {
@@ -743,11 +742,11 @@ list_hostkey_types(void)
743 return ret; 742 return ret;
744} 743}
745 744
746static Key * 745static struct sshkey *
747get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) 746get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
748{ 747{
749 int i; 748 int i;
750 Key *key; 749 struct sshkey *key;
751 750
752 for (i = 0; i < options.num_host_key_files; i++) { 751 for (i = 0; i < options.num_host_key_files; i++) {
753 switch (type) { 752 switch (type) {
@@ -771,19 +770,19 @@ get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
771 return NULL; 770 return NULL;
772} 771}
773 772
774Key * 773struct sshkey *
775get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) 774get_hostkey_public_by_type(int type, int nid, struct ssh *ssh)
776{ 775{
777 return get_hostkey_by_type(type, nid, 0, ssh); 776 return get_hostkey_by_type(type, nid, 0, ssh);
778} 777}
779 778
780Key * 779struct sshkey *
781get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) 780get_hostkey_private_by_type(int type, int nid, struct ssh *ssh)
782{ 781{
783 return get_hostkey_by_type(type, nid, 1, ssh); 782 return get_hostkey_by_type(type, nid, 1, ssh);
784} 783}
785 784
786Key * 785struct sshkey *
787get_hostkey_by_index(int ind) 786get_hostkey_by_index(int ind)
788{ 787{
789 if (ind < 0 || ind >= options.num_host_key_files) 788 if (ind < 0 || ind >= options.num_host_key_files)
@@ -791,7 +790,7 @@ get_hostkey_by_index(int ind)
791 return (sensitive_data.host_keys[ind]); 790 return (sensitive_data.host_keys[ind]);
792} 791}
793 792
794Key * 793struct sshkey *
795get_hostkey_public_by_index(int ind, struct ssh *ssh) 794get_hostkey_public_by_index(int ind, struct ssh *ssh)
796{ 795{
797 if (ind < 0 || ind >= options.num_host_key_files) 796 if (ind < 0 || ind >= options.num_host_key_files)
@@ -800,7 +799,7 @@ get_hostkey_public_by_index(int ind, struct ssh *ssh)
800} 799}
801 800
802int 801int
803get_hostkey_index(Key *key, int compare, struct ssh *ssh) 802get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh)
804{ 803{
805 int i; 804 int i;
806 805
@@ -1367,8 +1366,8 @@ main(int ac, char **av)
1367 u_int n; 1366 u_int n;
1368 u_int64_t ibytes, obytes; 1367 u_int64_t ibytes, obytes;
1369 mode_t new_umask; 1368 mode_t new_umask;
1370 Key *key; 1369 struct sshkey *key;
1371 Key *pubkey; 1370 struct sshkey *pubkey;
1372 int keytype; 1371 int keytype;
1373 Authctxt *authctxt; 1372 Authctxt *authctxt;
1374 struct connection_info *connection_info = get_connection_info(0, 0); 1373 struct connection_info *connection_info = get_connection_info(0, 0);
@@ -1622,9 +1621,6 @@ main(int ac, char **av)
1622 "enabled authentication methods"); 1621 "enabled authentication methods");
1623 } 1622 }
1624 1623
1625 /* set default channel AF */
1626 channel_set_af(options.address_family);
1627
1628 /* Check that there are no remaining arguments. */ 1624 /* Check that there are no remaining arguments. */
1629 if (optind < ac) { 1625 if (optind < ac) {
1630 fprintf(stderr, "Extra argument %s.\n", av[optind]); 1626 fprintf(stderr, "Extra argument %s.\n", av[optind]);
@@ -1640,8 +1636,9 @@ main(int ac, char **av)
1640 ); 1636 );
1641 1637
1642 /* Store privilege separation user for later use if required. */ 1638 /* Store privilege separation user for later use if required. */
1639 privsep_chroot = use_privsep && (getuid() == 0 || geteuid() == 0);
1643 if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { 1640 if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
1644 if (use_privsep || options.kerberos_authentication) 1641 if (privsep_chroot || options.kerberos_authentication)
1645 fatal("Privilege separation user %s does not exist", 1642 fatal("Privilege separation user %s does not exist",
1646 SSH_PRIVSEP_USER); 1643 SSH_PRIVSEP_USER);
1647 } else { 1644 } else {
@@ -1655,9 +1652,9 @@ main(int ac, char **av)
1655 1652
1656 /* load host keys */ 1653 /* load host keys */
1657 sensitive_data.host_keys = xcalloc(options.num_host_key_files, 1654 sensitive_data.host_keys = xcalloc(options.num_host_key_files,
1658 sizeof(Key *)); 1655 sizeof(struct sshkey *));
1659 sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, 1656 sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files,
1660 sizeof(Key *)); 1657 sizeof(struct sshkey *));
1661 1658
1662 if (options.host_key_agent) { 1659 if (options.host_key_agent) {
1663 if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) 1660 if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME))
@@ -1676,14 +1673,6 @@ main(int ac, char **av)
1676 key = key_load_private(options.host_key_files[i], "", NULL); 1673 key = key_load_private(options.host_key_files[i], "", NULL);
1677 pubkey = key_load_public(options.host_key_files[i], NULL); 1674 pubkey = key_load_public(options.host_key_files[i], NULL);
1678 1675
1679 if ((pubkey != NULL && pubkey->type == KEY_RSA1) ||
1680 (key != NULL && key->type == KEY_RSA1)) {
1681 verbose("Ignoring RSA1 key %s",
1682 options.host_key_files[i]);
1683 key_free(key);
1684 key_free(pubkey);
1685 continue;
1686 }
1687 if (pubkey == NULL && key != NULL) 1676 if (pubkey == NULL && key != NULL)
1688 pubkey = key_demote(key); 1677 pubkey = key_demote(key);
1689 sensitive_data.host_keys[i] = key; 1678 sensitive_data.host_keys[i] = key;
@@ -1729,7 +1718,7 @@ main(int ac, char **av)
1729 * indices to the public keys that they relate to. 1718 * indices to the public keys that they relate to.
1730 */ 1719 */
1731 sensitive_data.host_certificates = xcalloc(options.num_host_key_files, 1720 sensitive_data.host_certificates = xcalloc(options.num_host_key_files,
1732 sizeof(Key *)); 1721 sizeof(struct sshkey *));
1733 for (i = 0; i < options.num_host_key_files; i++) 1722 for (i = 0; i < options.num_host_key_files; i++)
1734 sensitive_data.host_certificates[i] = NULL; 1723 sensitive_data.host_certificates[i] = NULL;
1735 1724
@@ -1767,7 +1756,7 @@ main(int ac, char **av)
1767 key_type(key)); 1756 key_type(key));
1768 } 1757 }
1769 1758
1770 if (use_privsep) { 1759 if (privsep_chroot) {
1771 struct stat st; 1760 struct stat st;
1772 1761
1773 if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || 1762 if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) ||
@@ -1963,8 +1952,14 @@ main(int ac, char **av)
1963 packet_set_connection(sock_in, sock_out); 1952 packet_set_connection(sock_in, sock_out);
1964 packet_set_server(); 1953 packet_set_server();
1965 ssh = active_state; /* XXX */ 1954 ssh = active_state; /* XXX */
1955
1966 check_ip_options(ssh); 1956 check_ip_options(ssh);
1967 1957
1958 /* Prepare the channels layer */
1959 channel_init_channels(ssh);
1960 channel_set_af(ssh, options.address_family);
1961 process_permitopen(ssh, &options);
1962
1968 /* Set SO_KEEPALIVE if requested. */ 1963 /* Set SO_KEEPALIVE if requested. */
1969 if (options.tcp_keep_alive && packet_connection_is_on_socket() && 1964 if (options.tcp_keep_alive && packet_connection_is_on_socket() &&
1970 setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) 1965 setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
@@ -2040,6 +2035,7 @@ main(int ac, char **av)
2040 */ 2035 */
2041 if (use_privsep) { 2036 if (use_privsep) {
2042 mm_send_keystate(pmonitor); 2037 mm_send_keystate(pmonitor);
2038 packet_clear_keys();
2043 exit(0); 2039 exit(0);
2044 } 2040 }
2045 2041
@@ -2087,10 +2083,10 @@ main(int ac, char **av)
2087 options.client_alive_count_max); 2083 options.client_alive_count_max);
2088 2084
2089 /* Try to send all our hostkeys to the client */ 2085 /* Try to send all our hostkeys to the client */
2090 notify_hostkeys(active_state); 2086 notify_hostkeys(ssh);
2091 2087
2092 /* Start session. */ 2088 /* Start session. */
2093 do_authenticated(authctxt); 2089 do_authenticated(ssh, authctxt);
2094 2090
2095 /* The connection has been terminated. */ 2091 /* The connection has been terminated. */
2096 packet_get_bytes(&ibytes, &obytes); 2092 packet_get_bytes(&ibytes, &obytes);
@@ -2117,8 +2113,9 @@ main(int ac, char **av)
2117} 2113}
2118 2114
2119int 2115int
2120sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, 2116sshd_hostkey_sign(struct sshkey *privkey, struct sshkey *pubkey,
2121 const u_char *data, size_t dlen, const char *alg, u_int flag) 2117 u_char **signature, size_t *slen, const u_char *data, size_t dlen,
2118 const char *alg, u_int flag)
2122{ 2119{
2123 int r; 2120 int r;
2124 u_int xxx_slen, xxx_dlen = dlen; 2121 u_int xxx_slen, xxx_dlen = dlen;
@@ -2198,7 +2195,7 @@ do_ssh2_kex(void)
2198 kex->host_key_index=&get_hostkey_index; 2195 kex->host_key_index=&get_hostkey_index;
2199 kex->sign = sshd_hostkey_sign; 2196 kex->sign = sshd_hostkey_sign;
2200 2197
2201 dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); 2198 ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done);
2202 2199
2203 session_id2 = kex->session_id; 2200 session_id2 = kex->session_id;
2204 session_id2_len = kex->session_id_len; 2201 session_id2_len = kex->session_id_len;
@@ -2217,8 +2214,10 @@ do_ssh2_kex(void)
2217void 2214void
2218cleanup_exit(int i) 2215cleanup_exit(int i)
2219{ 2216{
2217 struct ssh *ssh = active_state; /* XXX */
2218
2220 if (the_authctxt) { 2219 if (the_authctxt) {
2221 do_cleanup(the_authctxt); 2220 do_cleanup(ssh, the_authctxt);
2222 if (use_privsep && privsep_is_preauth && 2221 if (use_privsep && privsep_is_preauth &&
2223 pmonitor != NULL && pmonitor->m_pid > 1) { 2222 pmonitor != NULL && pmonitor->m_pid > 1) {
2224 debug("Killing privsep child %d", pmonitor->m_pid); 2223 debug("Killing privsep child %d", pmonitor->m_pid);
diff --git a/sshd_config.0 b/sshd_config.0
index b0160aa87..678ee14b4 100644
--- a/sshd_config.0
+++ b/sshd_config.0
@@ -3,9 +3,6 @@ SSHD_CONFIG(5) File Formats Manual SSHD_CONFIG(5)
3NAME 3NAME
4 sshd_config M-bM-^@M-^S OpenSSH SSH daemon configuration file 4 sshd_config M-bM-^@M-^S OpenSSH SSH daemon configuration file
5 5
6SYNOPSIS
7 /etc/ssh/sshd_config
8
9DESCRIPTION 6DESCRIPTION
10 sshd(8) reads configuration data from /etc/ssh/sshd_config (or the file 7 sshd(8) reads configuration data from /etc/ssh/sshd_config (or the file
11 specified with -f on the command line). The file contains keyword- 8 specified with -f on the command line). The file contains keyword-
@@ -120,6 +117,11 @@ DESCRIPTION
120 Note that each authentication method listed should also be 117 Note that each authentication method listed should also be
121 explicitly enabled in the configuration. 118 explicitly enabled in the configuration.
122 119
120 The available authentication methods are: "gssapi-with-mic",
121 "hostbased", "keyboard-interactive", "none" (used for access to
122 password-less accounts when PermitEmptyPassword is enabled),
123 "password" and "publickey".
124
123 AuthorizedKeysCommand 125 AuthorizedKeysCommand
124 Specifies a program to be used to look up the user's public keys. 126 Specifies a program to be used to look up the user's public keys.
125 The program must be owned by root, not writable by group or 127 The program must be owned by root, not writable by group or
@@ -253,11 +255,6 @@ DESCRIPTION
253 aes256-ctr 255 aes256-ctr
254 aes128-gcm@openssh.com 256 aes128-gcm@openssh.com
255 aes256-gcm@openssh.com 257 aes256-gcm@openssh.com
256 arcfour
257 arcfour128
258 arcfour256
259 blowfish-cbc
260 cast128-cbc
261 chacha20-poly1305@openssh.com 258 chacha20-poly1305@openssh.com
262 259
263 The default is: 260 The default is:
@@ -329,6 +326,13 @@ DESCRIPTION
329 TCP and StreamLocal. This option overrides all other forwarding- 326 TCP and StreamLocal. This option overrides all other forwarding-
330 related options and may simplify restricted configurations. 327 related options and may simplify restricted configurations.
331 328
329 ExposeAuthInfo
330 Writes a temporary file containing a list of authentication
331 methods and public credentials (e.g. keys) used to authenticate
332 the user. The location of the file is exposed to the user
333 session through the SSH_USER_AUTH environment variable. The
334 default is no.
335
332 FingerprintHash 336 FingerprintHash
333 Specifies the hash algorithm used when logging key fingerprints. 337 Specifies the hash algorithm used when logging key fingerprints.
334 Valid options are: md5 and sha256. The default is sha256. 338 Valid options are: md5 and sha256. The default is sha256.
@@ -467,14 +471,14 @@ DESCRIPTION
467 IPQoS Specifies the IPv4 type-of-service or DSCP class for the 471 IPQoS Specifies the IPv4 type-of-service or DSCP class for the
468 connection. Accepted values are af11, af12, af13, af21, af22, 472 connection. Accepted values are af11, af12, af13, af21, af22,
469 af23, af31, af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, 473 af23, af31, af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3,
470 cs4, cs5, cs6, cs7, ef, lowdelay, throughput, reliability, or a 474 cs4, cs5, cs6, cs7, ef, lowdelay, throughput, reliability, a
471 numeric value. This option may take one or two arguments, 475 numeric value, or none to use the operating system default. This
472 separated by whitespace. If one argument is specified, it is 476 option may take one or two arguments, separated by whitespace.
473 used as the packet class unconditionally. If two values are 477 If one argument is specified, it is used as the packet class
474 specified, the first is automatically selected for interactive 478 unconditionally. If two values are specified, the first is
475 sessions and the second for non-interactive sessions. The 479 automatically selected for interactive sessions and the second
476 default is lowdelay for interactive sessions and throughput for 480 for non-interactive sessions. The default is lowdelay for
477 non-interactive sessions. 481 interactive sessions and throughput for non-interactive sessions.
478 482
479 KbdInteractiveAuthentication 483 KbdInteractiveAuthentication
480 Specifies whether to allow keyboard-interactive authentication. 484 Specifies whether to allow keyboard-interactive authentication.
@@ -573,7 +577,6 @@ DESCRIPTION
573 577
574 hmac-md5 578 hmac-md5
575 hmac-md5-96 579 hmac-md5-96
576 hmac-ripemd160
577 hmac-sha1 580 hmac-sha1
578 hmac-sha1-96 581 hmac-sha1-96
579 hmac-sha2-256 582 hmac-sha2-256
@@ -582,7 +585,6 @@ DESCRIPTION
582 umac-128@openssh.com 585 umac-128@openssh.com
583 hmac-md5-etm@openssh.com 586 hmac-md5-etm@openssh.com
584 hmac-md5-96-etm@openssh.com 587 hmac-md5-96-etm@openssh.com
585 hmac-ripemd160-etm@openssh.com
586 hmac-sha1-etm@openssh.com 588 hmac-sha1-etm@openssh.com
587 hmac-sha1-96-etm@openssh.com 589 hmac-sha1-96-etm@openssh.com
588 hmac-sha2-256-etm@openssh.com 590 hmac-sha2-256-etm@openssh.com
@@ -634,7 +636,7 @@ DESCRIPTION
634 ClientAliveInterval, DenyGroups, DenyUsers, ForceCommand, 636 ClientAliveInterval, DenyGroups, DenyUsers, ForceCommand,
635 GatewayPorts, GSSAPIAuthentication, HostbasedAcceptedKeyTypes, 637 GatewayPorts, GSSAPIAuthentication, HostbasedAcceptedKeyTypes,
636 HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, IPQoS, 638 HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, IPQoS,
637 KbdInteractiveAuthentication, KerberosAuthentication, 639 KbdInteractiveAuthentication, KerberosAuthentication, LogLevel,
638 MaxAuthTries, MaxSessions, PasswordAuthentication, 640 MaxAuthTries, MaxSessions, PasswordAuthentication,
639 PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTTY, 641 PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTTY,
640 PermitTunnel, PermitUserRC, PubkeyAcceptedKeyTypes, 642 PermitTunnel, PermitUserRC, PubkeyAcceptedKeyTypes,
@@ -1017,4 +1019,4 @@ AUTHORS
1017 versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support 1019 versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support
1018 for privilege separation. 1020 for privilege separation.
1019 1021
1020OpenBSD 6.0 March 14, 2017 OpenBSD 6.0 1022OpenBSD 6.2 September 27, 2017 OpenBSD 6.2
diff --git a/sshd_config.5 b/sshd_config.5
index ac6ccc793..251b7467f 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -33,15 +33,13 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: sshd_config.5,v 1.243 2017/03/14 07:19:07 djm Exp $ 36.\" $OpenBSD: sshd_config.5,v 1.253 2017/09/27 06:45:53 jmc Exp $
37.Dd $Mdocdate: March 14 2017 $ 37.Dd $Mdocdate: September 27 2017 $
38.Dt SSHD_CONFIG 5 38.Dt SSHD_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
41.Nm sshd_config 41.Nm sshd_config
42.Nd OpenSSH SSH daemon configuration file 42.Nd OpenSSH SSH daemon configuration file
43.Sh SYNOPSIS
44.Nm /etc/ssh/sshd_config
45.Sh DESCRIPTION 43.Sh DESCRIPTION
46.Xr sshd 8 44.Xr sshd 8
47reads configuration data from 45reads configuration data from
@@ -225,6 +223,18 @@ requires successful authentication using two different public keys.
225.Pp 223.Pp
226Note that each authentication method listed should also be explicitly enabled 224Note that each authentication method listed should also be explicitly enabled
227in the configuration. 225in the configuration.
226.Pp
227The available authentication methods are:
228.Qq gssapi-with-mic ,
229.Qq hostbased ,
230.Qq keyboard-interactive ,
231.Qq none
232(used for access to password-less accounts when
233.Cm PermitEmptyPassword
234is enabled),
235.Qq password
236and
237.Qq publickey .
228.It Cm AuthorizedKeysCommand 238.It Cm AuthorizedKeysCommand
229Specifies a program to be used to look up the user's public keys. 239Specifies a program to be used to look up the user's public keys.
230The program must be owned by root, not writable by group or others and 240The program must be owned by root, not writable by group or others and
@@ -464,16 +474,6 @@ aes128-gcm@openssh.com
464.It 474.It
465aes256-gcm@openssh.com 475aes256-gcm@openssh.com
466.It 476.It
467arcfour
468.It
469arcfour128
470.It
471arcfour256
472.It
473blowfish-cbc
474.It
475cast128-cbc
476.It
477chacha20-poly1305@openssh.com 477chacha20-poly1305@openssh.com
478.El 478.El
479.Pp 479.Pp
@@ -574,6 +574,14 @@ Disables all forwarding features, including X11,
574TCP and StreamLocal. 574TCP and StreamLocal.
575This option overrides all other forwarding-related options and may 575This option overrides all other forwarding-related options and may
576simplify restricted configurations. 576simplify restricted configurations.
577.It Cm ExposeAuthInfo
578Writes a temporary file containing a list of authentication methods and
579public credentials (e.g. keys) used to authenticate the user.
580The location of the file is exposed to the user session through the
581.Ev SSH_USER_AUTH
582environment variable.
583The default is
584.Cm no .
577.It Cm FingerprintHash 585.It Cm FingerprintHash
578Specifies the hash algorithm used when logging key fingerprints. 586Specifies the hash algorithm used when logging key fingerprints.
579Valid options are: 587Valid options are:
@@ -798,7 +806,9 @@ Accepted values are
798.Cm lowdelay , 806.Cm lowdelay ,
799.Cm throughput , 807.Cm throughput ,
800.Cm reliability , 808.Cm reliability ,
801or a numeric value. 809a numeric value, or
810.Cm none
811to use the operating system default.
802This option may take one or two arguments, separated by whitespace. 812This option may take one or two arguments, separated by whitespace.
803If one argument is specified, it is used as the packet class unconditionally. 813If one argument is specified, it is used as the packet class unconditionally.
804If two values are specified, the first is automatically selected for 814If two values are specified, the first is automatically selected for
@@ -962,8 +972,6 @@ hmac-md5
962.It 972.It
963hmac-md5-96 973hmac-md5-96
964.It 974.It
965hmac-ripemd160
966.It
967hmac-sha1 975hmac-sha1
968.It 976.It
969hmac-sha1-96 977hmac-sha1-96
@@ -980,8 +988,6 @@ hmac-md5-etm@openssh.com
980.It 988.It
981hmac-md5-96-etm@openssh.com 989hmac-md5-96-etm@openssh.com
982.It 990.It
983hmac-ripemd160-etm@openssh.com
984.It
985hmac-sha1-etm@openssh.com 991hmac-sha1-etm@openssh.com
986.It 992.It
987hmac-sha1-96-etm@openssh.com 993hmac-sha1-96-etm@openssh.com
@@ -1080,6 +1086,7 @@ Available keywords are
1080.Cm IPQoS , 1086.Cm IPQoS ,
1081.Cm KbdInteractiveAuthentication , 1087.Cm KbdInteractiveAuthentication ,
1082.Cm KerberosAuthentication , 1088.Cm KerberosAuthentication ,
1089.Cm LogLevel ,
1083.Cm MaxAuthTries , 1090.Cm MaxAuthTries ,
1084.Cm MaxSessions , 1091.Cm MaxSessions ,
1085.Cm PasswordAuthentication , 1092.Cm PasswordAuthentication ,
diff --git a/ssherr.c b/ssherr.c
index 680207063..3c0009d69 100644
--- a/ssherr.c
+++ b/ssherr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssherr.c,v 1.5 2015/09/13 14:39:16 tim Exp $ */ 1/* $OpenBSD: ssherr.c,v 1.7 2017/09/12 06:32:08 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -135,6 +135,10 @@ ssh_err(int n)
135 return "Connection corrupted"; 135 return "Connection corrupted";
136 case SSH_ERR_PROTOCOL_ERROR: 136 case SSH_ERR_PROTOCOL_ERROR:
137 return "Protocol error"; 137 return "Protocol error";
138 case SSH_ERR_KEY_LENGTH:
139 return "Invalid key length";
140 case SSH_ERR_NUMBER_TOO_LARGE:
141 return "number is too large";
138 default: 142 default:
139 return "unknown error"; 143 return "unknown error";
140 } 144 }
diff --git a/ssherr.h b/ssherr.h
index 6f771b4b7..c0b59211e 100644
--- a/ssherr.h
+++ b/ssherr.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssherr.h,v 1.3 2015/01/30 01:13:33 djm Exp $ */ 1/* $OpenBSD: ssherr.h,v 1.5 2017/09/12 06:32:08 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -77,6 +77,8 @@
77#define SSH_ERR_CONN_TIMEOUT -53 77#define SSH_ERR_CONN_TIMEOUT -53
78#define SSH_ERR_CONN_CORRUPT -54 78#define SSH_ERR_CONN_CORRUPT -54
79#define SSH_ERR_PROTOCOL_ERROR -55 79#define SSH_ERR_PROTOCOL_ERROR -55
80#define SSH_ERR_KEY_LENGTH -56
81#define SSH_ERR_NUMBER_TOO_LARGE -57
80 82
81/* Translate a numeric error code to a human-readable error string */ 83/* Translate a numeric error code to a human-readable error string */
82const char *ssh_err(int n); 84const char *ssh_err(int n);
diff --git a/sshkey.c b/sshkey.c
index 53a7674b5..e91c54f53 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.c,v 1.45 2017/03/10 04:07:20 djm Exp $ */ 1/* $OpenBSD: sshkey.c,v 1.56 2017/08/12 06:42:52 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved. 4 * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -51,7 +51,6 @@
51#include "ssherr.h" 51#include "ssherr.h"
52#include "misc.h" 52#include "misc.h"
53#include "sshbuf.h" 53#include "sshbuf.h"
54#include "rsa.h"
55#include "cipher.h" 54#include "cipher.h"
56#include "digest.h" 55#include "digest.h"
57#define SSHKEY_INTERNAL 56#define SSHKEY_INTERNAL
@@ -66,7 +65,7 @@
66#define KDFNAME "bcrypt" 65#define KDFNAME "bcrypt"
67#define AUTH_MAGIC "openssh-key-v1" 66#define AUTH_MAGIC "openssh-key-v1"
68#define SALT_LEN 16 67#define SALT_LEN 16
69#define DEFAULT_CIPHERNAME "aes256-cbc" 68#define DEFAULT_CIPHERNAME "aes256-ctr"
70#define DEFAULT_ROUNDS 16 69#define DEFAULT_ROUNDS 16
71 70
72/* Version identification string for SSH v1 identity files. */ 71/* Version identification string for SSH v1 identity files. */
@@ -89,9 +88,6 @@ static const struct keytype keytypes[] = {
89 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", 88 { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
90 KEY_ED25519_CERT, 0, 1, 0 }, 89 KEY_ED25519_CERT, 0, 1, 0 },
91#ifdef WITH_OPENSSL 90#ifdef WITH_OPENSSL
92# ifdef WITH_SSH1
93 { NULL, "RSA1", KEY_RSA1, 0, 0, 0 },
94# endif
95 { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 }, 91 { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 },
96 { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 }, 92 { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 },
97 { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 }, 93 { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 },
@@ -238,10 +234,6 @@ sshkey_names_valid2(const char *names, int allow_wildcard)
238 for ((p = strsep(&cp, ",")); p && *p != '\0'; 234 for ((p = strsep(&cp, ",")); p && *p != '\0';
239 (p = strsep(&cp, ","))) { 235 (p = strsep(&cp, ","))) {
240 type = sshkey_type_from_name(p); 236 type = sshkey_type_from_name(p);
241 if (type == KEY_RSA1) {
242 free(s);
243 return 0;
244 }
245 if (type == KEY_UNSPEC) { 237 if (type == KEY_UNSPEC) {
246 if (allow_wildcard) { 238 if (allow_wildcard) {
247 /* 239 /*
@@ -250,8 +242,6 @@ sshkey_names_valid2(const char *names, int allow_wildcard)
250 * the component is accepted. 242 * the component is accepted.
251 */ 243 */
252 for (kt = keytypes; kt->type != -1; kt++) { 244 for (kt = keytypes; kt->type != -1; kt++) {
253 if (kt->type == KEY_RSA1)
254 continue;
255 if (match_pattern_list(kt->name, 245 if (match_pattern_list(kt->name,
256 p, 0) != 0) 246 p, 0) != 0)
257 break; 247 break;
@@ -272,7 +262,6 @@ sshkey_size(const struct sshkey *k)
272{ 262{
273 switch (k->type) { 263 switch (k->type) {
274#ifdef WITH_OPENSSL 264#ifdef WITH_OPENSSL
275 case KEY_RSA1:
276 case KEY_RSA: 265 case KEY_RSA:
277 case KEY_RSA_CERT: 266 case KEY_RSA_CERT:
278 return BN_num_bits(k->rsa->n); 267 return BN_num_bits(k->rsa->n);
@@ -475,7 +464,6 @@ sshkey_new(int type)
475 k->ed25519_pk = NULL; 464 k->ed25519_pk = NULL;
476 switch (k->type) { 465 switch (k->type) {
477#ifdef WITH_OPENSSL 466#ifdef WITH_OPENSSL
478 case KEY_RSA1:
479 case KEY_RSA: 467 case KEY_RSA:
480 case KEY_RSA_CERT: 468 case KEY_RSA_CERT:
481 if ((rsa = RSA_new()) == NULL || 469 if ((rsa = RSA_new()) == NULL ||
@@ -533,7 +521,6 @@ sshkey_add_private(struct sshkey *k)
533{ 521{
534 switch (k->type) { 522 switch (k->type) {
535#ifdef WITH_OPENSSL 523#ifdef WITH_OPENSSL
536 case KEY_RSA1:
537 case KEY_RSA: 524 case KEY_RSA:
538 case KEY_RSA_CERT: 525 case KEY_RSA_CERT:
539#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL) 526#define bn_maybe_alloc_failed(p) (p == NULL && (p = BN_new()) == NULL)
@@ -589,7 +576,6 @@ sshkey_free(struct sshkey *k)
589 return; 576 return;
590 switch (k->type) { 577 switch (k->type) {
591#ifdef WITH_OPENSSL 578#ifdef WITH_OPENSSL
592 case KEY_RSA1:
593 case KEY_RSA: 579 case KEY_RSA:
594 case KEY_RSA_CERT: 580 case KEY_RSA_CERT:
595 if (k->rsa != NULL) 581 if (k->rsa != NULL)
@@ -667,7 +653,6 @@ sshkey_equal_public(const struct sshkey *a, const struct sshkey *b)
667 653
668 switch (a->type) { 654 switch (a->type) {
669#ifdef WITH_OPENSSL 655#ifdef WITH_OPENSSL
670 case KEY_RSA1:
671 case KEY_RSA_CERT: 656 case KEY_RSA_CERT:
672 case KEY_RSA: 657 case KEY_RSA:
673 return a->rsa != NULL && b->rsa != NULL && 658 return a->rsa != NULL && b->rsa != NULL &&
@@ -884,25 +869,7 @@ sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg,
884 r = SSH_ERR_INVALID_ARGUMENT; 869 r = SSH_ERR_INVALID_ARGUMENT;
885 goto out; 870 goto out;
886 } 871 }
887 872 if ((r = to_blob(k, &blob, &blob_len, 1)) != 0)
888 if (k->type == KEY_RSA1) {
889#ifdef WITH_OPENSSL
890 int nlen = BN_num_bytes(k->rsa->n);
891 int elen = BN_num_bytes(k->rsa->e);
892
893 if (nlen < 0 || elen < 0 || nlen >= INT_MAX - elen) {
894 r = SSH_ERR_INVALID_FORMAT;
895 goto out;
896 }
897 blob_len = nlen + elen;
898 if ((blob = malloc(blob_len)) == NULL) {
899 r = SSH_ERR_ALLOC_FAIL;
900 goto out;
901 }
902 BN_bn2bin(k->rsa->n, blob);
903 BN_bn2bin(k->rsa->e, blob + nlen);
904#endif /* WITH_OPENSSL */
905 } else if ((r = to_blob(k, &blob, &blob_len, 1)) != 0)
906 goto out; 873 goto out;
907 if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) { 874 if ((ret = calloc(1, SSH_DIGEST_MAX_LENGTH)) == NULL) {
908 r = SSH_ERR_ALLOC_FAIL; 875 r = SSH_ERR_ALLOC_FAIL;
@@ -1194,39 +1161,6 @@ sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
1194 return retval; 1161 return retval;
1195} 1162}
1196 1163
1197#ifdef WITH_SSH1
1198/*
1199 * Reads a multiple-precision integer in decimal from the buffer, and advances
1200 * the pointer. The integer must already be initialized. This function is
1201 * permitted to modify the buffer. This leaves *cpp to point just beyond the
1202 * last processed character.
1203 */
1204static int
1205read_decimal_bignum(char **cpp, BIGNUM *v)
1206{
1207 char *cp;
1208 size_t e;
1209 int skip = 1; /* skip white space */
1210
1211 cp = *cpp;
1212 while (*cp == ' ' || *cp == '\t')
1213 cp++;
1214 e = strspn(cp, "0123456789");
1215 if (e == 0)
1216 return SSH_ERR_INVALID_FORMAT;
1217 if (e > SSHBUF_MAX_BIGNUM * 3)
1218 return SSH_ERR_BIGNUM_TOO_LARGE;
1219 if (cp[e] == '\0')
1220 skip = 0;
1221 else if (strchr(" \t\r\n", cp[e]) == NULL)
1222 return SSH_ERR_INVALID_FORMAT;
1223 cp[e] = '\0';
1224 if (BN_dec2bn(&v, cp) <= 0)
1225 return SSH_ERR_INVALID_FORMAT;
1226 *cpp = cp + e + skip;
1227 return 0;
1228}
1229#endif /* WITH_SSH1 */
1230 1164
1231/* returns 0 ok, and < 0 error */ 1165/* returns 0 ok, and < 0 error */
1232int 1166int
@@ -1237,9 +1171,6 @@ sshkey_read(struct sshkey *ret, char **cpp)
1237 char *ep, *cp, *space; 1171 char *ep, *cp, *space;
1238 int r, type, curve_nid = -1; 1172 int r, type, curve_nid = -1;
1239 struct sshbuf *blob; 1173 struct sshbuf *blob;
1240#ifdef WITH_SSH1
1241 u_long bits;
1242#endif /* WITH_SSH1 */
1243 1174
1244 if (ret == NULL) 1175 if (ret == NULL)
1245 return SSH_ERR_INVALID_ARGUMENT; 1176 return SSH_ERR_INVALID_ARGUMENT;
@@ -1247,25 +1178,6 @@ sshkey_read(struct sshkey *ret, char **cpp)
1247 cp = *cpp; 1178 cp = *cpp;
1248 1179
1249 switch (ret->type) { 1180 switch (ret->type) {
1250 case KEY_RSA1:
1251#ifdef WITH_SSH1
1252 /* Get number of bits. */
1253 bits = strtoul(cp, &ep, 10);
1254 if (*cp == '\0' || strchr(" \t\r\n", *ep) == NULL ||
1255 bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8)
1256 return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */
1257 /* Get public exponent, public modulus. */
1258 if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0)
1259 return r;
1260 if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0)
1261 return r;
1262 /* validate the claimed number of bits */
1263 if (BN_num_bits(ret->rsa->n) != (int)bits)
1264 return SSH_ERR_KEY_BITS_MISMATCH;
1265 *cpp = ep;
1266 retval = 0;
1267#endif /* WITH_SSH1 */
1268 break;
1269 case KEY_UNSPEC: 1181 case KEY_UNSPEC:
1270 case KEY_RSA: 1182 case KEY_RSA:
1271 case KEY_DSA: 1183 case KEY_DSA:
@@ -1418,61 +1330,17 @@ sshkey_to_base64(const struct sshkey *key, char **b64p)
1418 return r; 1330 return r;
1419} 1331}
1420 1332
1421static int 1333int
1422sshkey_format_rsa1(const struct sshkey *key, struct sshbuf *b)
1423{
1424 int r = SSH_ERR_INTERNAL_ERROR;
1425#ifdef WITH_SSH1
1426 u_int bits = 0;
1427 char *dec_e = NULL, *dec_n = NULL;
1428
1429 if (key->rsa == NULL || key->rsa->e == NULL ||
1430 key->rsa->n == NULL) {
1431 r = SSH_ERR_INVALID_ARGUMENT;
1432 goto out;
1433 }
1434 if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||
1435 (dec_n = BN_bn2dec(key->rsa->n)) == NULL) {
1436 r = SSH_ERR_ALLOC_FAIL;
1437 goto out;
1438 }
1439 /* size of modulus 'n' */
1440 if ((bits = BN_num_bits(key->rsa->n)) <= 0) {
1441 r = SSH_ERR_INVALID_ARGUMENT;
1442 goto out;
1443 }
1444 if ((r = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0)
1445 goto out;
1446
1447 /* Success */
1448 r = 0;
1449 out:
1450 if (dec_e != NULL)
1451 OPENSSL_free(dec_e);
1452 if (dec_n != NULL)
1453 OPENSSL_free(dec_n);
1454#endif /* WITH_SSH1 */
1455
1456 return r;
1457}
1458
1459static int
1460sshkey_format_text(const struct sshkey *key, struct sshbuf *b) 1334sshkey_format_text(const struct sshkey *key, struct sshbuf *b)
1461{ 1335{
1462 int r = SSH_ERR_INTERNAL_ERROR; 1336 int r = SSH_ERR_INTERNAL_ERROR;
1463 char *uu = NULL; 1337 char *uu = NULL;
1464 1338
1465 if (key->type == KEY_RSA1) { 1339 if ((r = sshkey_to_base64(key, &uu)) != 0)
1466 if ((r = sshkey_format_rsa1(key, b)) != 0) 1340 goto out;
1467 goto out; 1341 if ((r = sshbuf_putf(b, "%s %s",
1468 } else { 1342 sshkey_ssh_name(key), uu)) != 0)
1469 /* Unsupported key types handled in sshkey_to_base64() */ 1343 goto out;
1470 if ((r = sshkey_to_base64(key, &uu)) != 0)
1471 goto out;
1472 if ((r = sshbuf_putf(b, "%s %s",
1473 sshkey_ssh_name(key), uu)) != 0)
1474 goto out;
1475 }
1476 r = 0; 1344 r = 0;
1477 out: 1345 out:
1478 free(uu); 1346 free(uu);
@@ -1523,10 +1391,11 @@ rsa_generate_private_key(u_int bits, RSA **rsap)
1523 BIGNUM *f4 = NULL; 1391 BIGNUM *f4 = NULL;
1524 int ret = SSH_ERR_INTERNAL_ERROR; 1392 int ret = SSH_ERR_INTERNAL_ERROR;
1525 1393
1526 if (rsap == NULL || 1394 if (rsap == NULL)
1527 bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1528 bits > SSHBUF_MAX_BIGNUM * 8)
1529 return SSH_ERR_INVALID_ARGUMENT; 1395 return SSH_ERR_INVALID_ARGUMENT;
1396 if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
1397 bits > SSHBUF_MAX_BIGNUM * 8)
1398 return SSH_ERR_KEY_LENGTH;
1530 *rsap = NULL; 1399 *rsap = NULL;
1531 if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { 1400 if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
1532 ret = SSH_ERR_ALLOC_FAIL; 1401 ret = SSH_ERR_ALLOC_FAIL;
@@ -1554,8 +1423,10 @@ dsa_generate_private_key(u_int bits, DSA **dsap)
1554 DSA *private; 1423 DSA *private;
1555 int ret = SSH_ERR_INTERNAL_ERROR; 1424 int ret = SSH_ERR_INTERNAL_ERROR;
1556 1425
1557 if (dsap == NULL || bits != 1024) 1426 if (dsap == NULL)
1558 return SSH_ERR_INVALID_ARGUMENT; 1427 return SSH_ERR_INVALID_ARGUMENT;
1428 if (bits != 1024)
1429 return SSH_ERR_KEY_LENGTH;
1559 if ((private = DSA_new()) == NULL) { 1430 if ((private = DSA_new()) == NULL) {
1560 ret = SSH_ERR_ALLOC_FAIL; 1431 ret = SSH_ERR_ALLOC_FAIL;
1561 goto out; 1432 goto out;
@@ -1632,9 +1503,10 @@ ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
1632 EC_KEY *private; 1503 EC_KEY *private;
1633 int ret = SSH_ERR_INTERNAL_ERROR; 1504 int ret = SSH_ERR_INTERNAL_ERROR;
1634 1505
1635 if (nid == NULL || ecdsap == NULL || 1506 if (nid == NULL || ecdsap == NULL)
1636 (*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
1637 return SSH_ERR_INVALID_ARGUMENT; 1507 return SSH_ERR_INVALID_ARGUMENT;
1508 if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
1509 return SSH_ERR_KEY_LENGTH;
1638 *ecdsap = NULL; 1510 *ecdsap = NULL;
1639 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) { 1511 if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
1640 ret = SSH_ERR_ALLOC_FAIL; 1512 ret = SSH_ERR_ALLOC_FAIL;
@@ -1688,7 +1560,6 @@ sshkey_generate(int type, u_int bits, struct sshkey **keyp)
1688 break; 1560 break;
1689# endif /* OPENSSL_HAS_ECC */ 1561# endif /* OPENSSL_HAS_ECC */
1690 case KEY_RSA: 1562 case KEY_RSA:
1691 case KEY_RSA1:
1692 ret = rsa_generate_private_key(bits, &k->rsa); 1563 ret = rsa_generate_private_key(bits, &k->rsa);
1693 break; 1564 break;
1694#endif /* WITH_OPENSSL */ 1565#endif /* WITH_OPENSSL */
@@ -1799,7 +1670,6 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp)
1799 break; 1670 break;
1800# endif /* OPENSSL_HAS_ECC */ 1671# endif /* OPENSSL_HAS_ECC */
1801 case KEY_RSA: 1672 case KEY_RSA:
1802 case KEY_RSA1:
1803 case KEY_RSA_CERT: 1673 case KEY_RSA_CERT:
1804 if ((n = sshkey_new(k->type)) == NULL) 1674 if ((n = sshkey_new(k->type)) == NULL)
1805 return SSH_ERR_ALLOC_FAIL; 1675 return SSH_ERR_ALLOC_FAIL;
@@ -1893,8 +1763,9 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf)
1893 goto out; 1763 goto out;
1894 } 1764 }
1895 oprincipals = key->cert->principals; 1765 oprincipals = key->cert->principals;
1896 key->cert->principals = reallocarray(key->cert->principals, 1766 key->cert->principals = recallocarray(key->cert->principals,
1897 key->cert->nprincipals + 1, sizeof(*key->cert->principals)); 1767 key->cert->nprincipals, key->cert->nprincipals + 1,
1768 sizeof(*key->cert->principals));
1898 if (key->cert->principals == NULL) { 1769 if (key->cert->principals == NULL) {
1899 free(principal); 1770 free(principal);
1900 key->cert->principals = oprincipals; 1771 key->cert->principals = oprincipals;
@@ -2009,6 +1880,10 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2009 ret = SSH_ERR_INVALID_FORMAT; 1880 ret = SSH_ERR_INVALID_FORMAT;
2010 goto out; 1881 goto out;
2011 } 1882 }
1883 if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
1884 ret = SSH_ERR_KEY_LENGTH;
1885 goto out;
1886 }
2012#ifdef DEBUG_PK 1887#ifdef DEBUG_PK
2013 RSA_print_fp(stderr, key->rsa, 8); 1888 RSA_print_fp(stderr, key->rsa, 8);
2014#endif 1889#endif
@@ -2111,11 +1986,6 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp,
2111 pk = NULL; 1986 pk = NULL;
2112 break; 1987 break;
2113 case KEY_UNSPEC: 1988 case KEY_UNSPEC:
2114 if ((key = sshkey_new(type)) == NULL) {
2115 ret = SSH_ERR_ALLOC_FAIL;
2116 goto out;
2117 }
2118 break;
2119 default: 1989 default:
2120 ret = SSH_ERR_KEY_TYPE_UNKNOWN; 1990 ret = SSH_ERR_KEY_TYPE_UNKNOWN;
2121 goto out; 1991 goto out;
@@ -2269,7 +2139,6 @@ sshkey_demote(const struct sshkey *k, struct sshkey **dkp)
2269 if ((ret = sshkey_cert_copy(k, pk)) != 0) 2139 if ((ret = sshkey_cert_copy(k, pk)) != 0)
2270 goto fail; 2140 goto fail;
2271 /* FALLTHROUGH */ 2141 /* FALLTHROUGH */
2272 case KEY_RSA1:
2273 case KEY_RSA: 2142 case KEY_RSA:
2274 if ((pk->rsa = RSA_new()) == NULL || 2143 if ((pk->rsa = RSA_new()) == NULL ||
2275 (pk->rsa->e = BN_dup(k->rsa->e)) == NULL || 2144 (pk->rsa->e = BN_dup(k->rsa->e)) == NULL ||
@@ -2378,7 +2247,8 @@ sshkey_drop_cert(struct sshkey *k)
2378 2247
2379/* Sign a certified key, (re-)generating the signed certblob. */ 2248/* Sign a certified key, (re-)generating the signed certblob. */
2380int 2249int
2381sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) 2250sshkey_certify_custom(struct sshkey *k, struct sshkey *ca, const char *alg,
2251 sshkey_certify_signer *signer, void *signer_ctx)
2382{ 2252{
2383 struct sshbuf *principals = NULL; 2253 struct sshbuf *principals = NULL;
2384 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32]; 2254 u_char *ca_blob = NULL, *sig_blob = NULL, nonce[32];
@@ -2467,8 +2337,8 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
2467 goto out; 2337 goto out;
2468 2338
2469 /* Sign the whole mess */ 2339 /* Sign the whole mess */
2470 if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), 2340 if ((ret = signer(ca, &sig_blob, &sig_len, sshbuf_ptr(cert),
2471 sshbuf_len(cert), alg, 0)) != 0) 2341 sshbuf_len(cert), alg, 0, signer_ctx)) != 0)
2472 goto out; 2342 goto out;
2473 2343
2474 /* Append signature and we are done */ 2344 /* Append signature and we are done */
@@ -2484,6 +2354,22 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
2484 return ret; 2354 return ret;
2485} 2355}
2486 2356
2357static int
2358default_key_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
2359 const u_char *data, size_t datalen,
2360 const char *alg, u_int compat, void *ctx)
2361{
2362 if (ctx != NULL)
2363 return SSH_ERR_INVALID_ARGUMENT;
2364 return sshkey_sign(key, sigp, lenp, data, datalen, alg, compat);
2365}
2366
2367int
2368sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg)
2369{
2370 return sshkey_certify_custom(k, ca, alg, default_key_sign, NULL);
2371}
2372
2487int 2373int
2488sshkey_cert_check_authority(const struct sshkey *k, 2374sshkey_cert_check_authority(const struct sshkey *k,
2489 int want_host, int require_principal, 2375 int want_host, int require_principal,
@@ -2775,8 +2661,12 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2775 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 2661 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
2776 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 2662 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
2777 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 2663 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
2778 (r = rsa_generate_additional_parameters(k->rsa)) != 0) 2664 (r = ssh_rsa_generate_additional_parameters(k)) != 0)
2779 goto out; 2665 goto out;
2666 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
2667 r = SSH_ERR_KEY_LENGTH;
2668 goto out;
2669 }
2780 break; 2670 break;
2781 case KEY_RSA_CERT: 2671 case KEY_RSA_CERT:
2782 if ((r = sshkey_froms(buf, &k)) != 0 || 2672 if ((r = sshkey_froms(buf, &k)) != 0 ||
@@ -2785,8 +2675,12 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2785 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || 2675 (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 ||
2786 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || 2676 (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 ||
2787 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || 2677 (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 ||
2788 (r = rsa_generate_additional_parameters(k->rsa)) != 0) 2678 (r = ssh_rsa_generate_additional_parameters(k)) != 0)
2789 goto out; 2679 goto out;
2680 if (BN_num_bits(k->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
2681 r = SSH_ERR_KEY_LENGTH;
2682 goto out;
2683 }
2790 break; 2684 break;
2791#endif /* WITH_OPENSSL */ 2685#endif /* WITH_OPENSSL */
2792 case KEY_ED25519: 2686 case KEY_ED25519:
@@ -2828,7 +2722,6 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp)
2828 switch (k->type) { 2722 switch (k->type) {
2829 case KEY_RSA: 2723 case KEY_RSA:
2830 case KEY_RSA_CERT: 2724 case KEY_RSA_CERT:
2831 case KEY_RSA1:
2832 if (RSA_blinding_on(k->rsa, NULL) != 1) { 2725 if (RSA_blinding_on(k->rsa, NULL) != 1) {
2833 r = SSH_ERR_LIBCRYPTO_ERROR; 2726 r = SSH_ERR_LIBCRYPTO_ERROR;
2834 goto out; 2727 goto out;
@@ -3057,12 +2950,8 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob,
3057 kdfname = "none"; 2950 kdfname = "none";
3058 } else if (ciphername == NULL) 2951 } else if (ciphername == NULL)
3059 ciphername = DEFAULT_CIPHERNAME; 2952 ciphername = DEFAULT_CIPHERNAME;
3060 else if (cipher_number(ciphername) != SSH_CIPHER_SSH2) {
3061 r = SSH_ERR_INVALID_ARGUMENT;
3062 goto out;
3063 }
3064 if ((cipher = cipher_by_name(ciphername)) == NULL) { 2953 if ((cipher = cipher_by_name(ciphername)) == NULL) {
3065 r = SSH_ERR_INTERNAL_ERROR; 2954 r = SSH_ERR_INVALID_ARGUMENT;
3066 goto out; 2955 goto out;
3067 } 2956 }
3068 2957
@@ -3404,105 +3293,6 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
3404 return r; 3293 return r;
3405} 3294}
3406 3295
3407#if WITH_SSH1
3408/*
3409 * Serialises the authentication (private) key to a blob, encrypting it with
3410 * passphrase. The identification of the blob (lowest 64 bits of n) will
3411 * precede the key to provide identification of the key without needing a
3412 * passphrase.
3413 */
3414static int
3415sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob,
3416 const char *passphrase, const char *comment)
3417{
3418 struct sshbuf *buffer = NULL, *encrypted = NULL;
3419 u_char buf[8];
3420 int r, cipher_num;
3421 struct sshcipher_ctx *ciphercontext = NULL;
3422 const struct sshcipher *cipher;
3423 u_char *cp;
3424
3425 /*
3426 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
3427 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
3428 */
3429 cipher_num = (strcmp(passphrase, "") == 0) ?
3430 SSH_CIPHER_NONE : SSH_CIPHER_3DES;
3431 if ((cipher = cipher_by_number(cipher_num)) == NULL)
3432 return SSH_ERR_INTERNAL_ERROR;
3433
3434 /* This buffer is used to build the secret part of the private key. */
3435 if ((buffer = sshbuf_new()) == NULL)
3436 return SSH_ERR_ALLOC_FAIL;
3437
3438 /* Put checkbytes for checking passphrase validity. */
3439 if ((r = sshbuf_reserve(buffer, 4, &cp)) != 0)
3440 goto out;
3441 arc4random_buf(cp, 2);
3442 memcpy(cp + 2, cp, 2);
3443
3444 /*
3445 * Store the private key (n and e will not be stored because they
3446 * will be stored in plain text, and storing them also in encrypted
3447 * format would just give known plaintext).
3448 * Note: q and p are stored in reverse order to SSL.
3449 */
3450 if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 ||
3451 (r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 ||
3452 (r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 ||
3453 (r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0)
3454 goto out;
3455
3456 /* Pad the part to be encrypted to a size that is a multiple of 8. */
3457 explicit_bzero(buf, 8);
3458 if ((r = sshbuf_put(buffer, buf, 8 - (sshbuf_len(buffer) % 8))) != 0)
3459 goto out;
3460
3461 /* This buffer will be used to contain the data in the file. */
3462 if ((encrypted = sshbuf_new()) == NULL) {
3463 r = SSH_ERR_ALLOC_FAIL;
3464 goto out;
3465 }
3466
3467 /* First store keyfile id string. */
3468 if ((r = sshbuf_put(encrypted, LEGACY_BEGIN,
3469 sizeof(LEGACY_BEGIN))) != 0)
3470 goto out;
3471
3472 /* Store cipher type and "reserved" field. */
3473 if ((r = sshbuf_put_u8(encrypted, cipher_num)) != 0 ||
3474 (r = sshbuf_put_u32(encrypted, 0)) != 0)
3475 goto out;
3476
3477 /* Store public key. This will be in plain text. */
3478 if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 ||
3479 (r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 ||
3480 (r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 ||
3481 (r = sshbuf_put_cstring(encrypted, comment)) != 0)
3482 goto out;
3483
3484 /* Allocate space for the private part of the key in the buffer. */
3485 if ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0)
3486 goto out;
3487
3488 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,
3489 CIPHER_ENCRYPT)) != 0)
3490 goto out;
3491 if ((r = cipher_crypt(ciphercontext, 0, cp,
3492 sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0)
3493 goto out;
3494
3495 r = sshbuf_putb(blob, encrypted);
3496
3497 out:
3498 cipher_free(ciphercontext);
3499 explicit_bzero(buf, sizeof(buf));
3500 sshbuf_free(buffer);
3501 sshbuf_free(encrypted);
3502
3503 return r;
3504}
3505#endif /* WITH_SSH1 */
3506 3296
3507#ifdef WITH_OPENSSL 3297#ifdef WITH_OPENSSL
3508/* convert SSH v2 key in OpenSSL PEM format */ 3298/* convert SSH v2 key in OpenSSL PEM format */
@@ -3513,11 +3303,7 @@ sshkey_private_pem_to_blob(struct sshkey *key, struct sshbuf *blob,
3513 int success, r; 3303 int success, r;
3514 int blen, len = strlen(_passphrase); 3304 int blen, len = strlen(_passphrase);
3515 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; 3305 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
3516#if (OPENSSL_VERSION_NUMBER < 0x00907000L) 3306 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
3517 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
3518#else
3519 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
3520#endif
3521 const u_char *bptr; 3307 const u_char *bptr;
3522 BIO *bio = NULL; 3308 BIO *bio = NULL;
3523 3309
@@ -3569,11 +3355,6 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
3569 int force_new_format, const char *new_format_cipher, int new_format_rounds) 3355 int force_new_format, const char *new_format_cipher, int new_format_rounds)
3570{ 3356{
3571 switch (key->type) { 3357 switch (key->type) {
3572#ifdef WITH_SSH1
3573 case KEY_RSA1:
3574 return sshkey_private_rsa1_to_blob(key, blob,
3575 passphrase, comment);
3576#endif /* WITH_SSH1 */
3577#ifdef WITH_OPENSSL 3358#ifdef WITH_OPENSSL
3578 case KEY_DSA: 3359 case KEY_DSA:
3579 case KEY_ECDSA: 3360 case KEY_ECDSA:
@@ -3593,184 +3374,66 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
3593 } 3374 }
3594} 3375}
3595 3376
3596#ifdef WITH_SSH1
3597/*
3598 * Parse the public, unencrypted portion of a RSA1 key.
3599 */
3600int
3601sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob,
3602 struct sshkey **keyp, char **commentp)
3603{
3604 int r;
3605 struct sshkey *pub = NULL;
3606 struct sshbuf *copy = NULL;
3607
3608 if (keyp != NULL)
3609 *keyp = NULL;
3610 if (commentp != NULL)
3611 *commentp = NULL;
3612
3613 /* Check that it is at least big enough to contain the ID string. */
3614 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))
3615 return SSH_ERR_INVALID_FORMAT;
3616 3377
3617 /* 3378#ifdef WITH_OPENSSL
3618 * Make sure it begins with the id string. Consume the id string 3379static int
3619 * from the buffer. 3380translate_libcrypto_error(unsigned long pem_err)
3620 */ 3381{
3621 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0) 3382 int pem_reason = ERR_GET_REASON(pem_err);
3383
3384 switch (ERR_GET_LIB(pem_err)) {
3385 case ERR_LIB_PEM:
3386 switch (pem_reason) {
3387 case PEM_R_BAD_PASSWORD_READ:
3388 case PEM_R_PROBLEMS_GETTING_PASSWORD:
3389 case PEM_R_BAD_DECRYPT:
3390 return SSH_ERR_KEY_WRONG_PASSPHRASE;
3391 default:
3392 return SSH_ERR_INVALID_FORMAT;
3393 }
3394 case ERR_LIB_EVP:
3395 switch (pem_reason) {
3396 case EVP_R_BAD_DECRYPT:
3397 return SSH_ERR_KEY_WRONG_PASSPHRASE;
3398 case EVP_R_BN_DECODE_ERROR:
3399 case EVP_R_DECODE_ERROR:
3400#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3401 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
3402#endif
3403 return SSH_ERR_INVALID_FORMAT;
3404 default:
3405 return SSH_ERR_LIBCRYPTO_ERROR;
3406 }
3407 case ERR_LIB_ASN1:
3622 return SSH_ERR_INVALID_FORMAT; 3408 return SSH_ERR_INVALID_FORMAT;
3623 /* Make a working copy of the keyblob and skip past the magic */
3624 if ((copy = sshbuf_fromb(blob)) == NULL)
3625 return SSH_ERR_ALLOC_FAIL;
3626 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)
3627 goto out;
3628
3629 /* Skip cipher type, reserved data and key bits. */
3630 if ((r = sshbuf_get_u8(copy, NULL)) != 0 || /* cipher type */
3631 (r = sshbuf_get_u32(copy, NULL)) != 0 || /* reserved */
3632 (r = sshbuf_get_u32(copy, NULL)) != 0) /* key bits */
3633 goto out;
3634
3635 /* Read the public key from the buffer. */
3636 if ((pub = sshkey_new(KEY_RSA1)) == NULL ||
3637 (r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 ||
3638 (r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0)
3639 goto out;
3640
3641 /* Finally, the comment */
3642 if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0)
3643 goto out;
3644
3645 /* The encrypted private part is not parsed by this function. */
3646
3647 r = 0;
3648 if (keyp != NULL) {
3649 *keyp = pub;
3650 pub = NULL;
3651 } 3409 }
3652 out: 3410 return SSH_ERR_LIBCRYPTO_ERROR;
3653 sshbuf_free(copy);
3654 sshkey_free(pub);
3655 return r;
3656} 3411}
3657 3412
3658static int 3413static void
3659sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, 3414clear_libcrypto_errors(void)
3660 struct sshkey **keyp, char **commentp)
3661{ 3415{
3662 int r; 3416 while (ERR_get_error() != 0)
3663 u_int16_t check1, check2; 3417 ;
3664 u_int8_t cipher_type; 3418}
3665 struct sshbuf *decrypted = NULL, *copy = NULL;
3666 u_char *cp;
3667 char *comment = NULL;
3668 struct sshcipher_ctx *ciphercontext = NULL;
3669 const struct sshcipher *cipher;
3670 struct sshkey *prv = NULL;
3671
3672 if (keyp != NULL)
3673 *keyp = NULL;
3674 if (commentp != NULL)
3675 *commentp = NULL;
3676
3677 /* Check that it is at least big enough to contain the ID string. */
3678 if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))
3679 return SSH_ERR_INVALID_FORMAT;
3680 3419
3420/*
3421 * Translate OpenSSL error codes to determine whether
3422 * passphrase is required/incorrect.
3423 */
3424static int
3425convert_libcrypto_error(void)
3426{
3681 /* 3427 /*
3682 * Make sure it begins with the id string. Consume the id string 3428 * Some password errors are reported at the beginning
3683 * from the buffer. 3429 * of the error queue.
3684 */ 3430 */
3685 if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0) 3431 if (translate_libcrypto_error(ERR_peek_error()) ==
3686 return SSH_ERR_INVALID_FORMAT; 3432 SSH_ERR_KEY_WRONG_PASSPHRASE)
3687 3433 return SSH_ERR_KEY_WRONG_PASSPHRASE;
3688 if ((prv = sshkey_new_private(KEY_RSA1)) == NULL) { 3434 return translate_libcrypto_error(ERR_peek_last_error());
3689 r = SSH_ERR_ALLOC_FAIL;
3690 goto out;
3691 }
3692 if ((copy = sshbuf_fromb(blob)) == NULL ||
3693 (decrypted = sshbuf_new()) == NULL) {
3694 r = SSH_ERR_ALLOC_FAIL;
3695 goto out;
3696 }
3697 if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)
3698 goto out;
3699
3700 /* Read cipher type. */
3701 if ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 ||
3702 (r = sshbuf_get_u32(copy, NULL)) != 0) /* reserved */
3703 goto out;
3704
3705 /* Read the public key and comment from the buffer. */
3706 if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */
3707 (r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 ||
3708 (r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 ||
3709 (r = sshbuf_get_cstring(copy, &comment, NULL)) != 0)
3710 goto out;
3711
3712 /* Check that it is a supported cipher. */
3713 cipher = cipher_by_number(cipher_type);
3714 if (cipher == NULL) {
3715 r = SSH_ERR_KEY_UNKNOWN_CIPHER;
3716 goto out;
3717 }
3718 /* Initialize space for decrypted data. */
3719 if ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0)
3720 goto out;
3721
3722 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
3723 if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,
3724 CIPHER_DECRYPT)) != 0)
3725 goto out;
3726 if ((r = cipher_crypt(ciphercontext, 0, cp,
3727 sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0)
3728 goto out;
3729
3730 if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 ||
3731 (r = sshbuf_get_u16(decrypted, &check2)) != 0)
3732 goto out;
3733 if (check1 != check2) {
3734 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3735 goto out;
3736 }
3737
3738 /* Read the rest of the private key. */
3739 if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 ||
3740 (r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 ||
3741 (r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 ||
3742 (r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0)
3743 goto out;
3744
3745 /* calculate p-1 and q-1 */
3746 if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0)
3747 goto out;
3748
3749 /* enable blinding */
3750 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
3751 r = SSH_ERR_LIBCRYPTO_ERROR;
3752 goto out;
3753 }
3754 r = 0;
3755 if (keyp != NULL) {
3756 *keyp = prv;
3757 prv = NULL;
3758 }
3759 if (commentp != NULL) {
3760 *commentp = comment;
3761 comment = NULL;
3762 }
3763 out:
3764 cipher_free(ciphercontext);
3765 free(comment);
3766 sshkey_free(prv);
3767 sshbuf_free(copy);
3768 sshbuf_free(decrypted);
3769 return r;
3770} 3435}
3771#endif /* WITH_SSH1 */
3772 3436
3773#ifdef WITH_OPENSSL
3774static int 3437static int
3775sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, 3438sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3776 const char *passphrase, struct sshkey **keyp) 3439 const char *passphrase, struct sshkey **keyp)
@@ -3791,48 +3454,10 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3791 goto out; 3454 goto out;
3792 } 3455 }
3793 3456
3457 clear_libcrypto_errors();
3794 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, 3458 if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL,
3795 (char *)passphrase)) == NULL) { 3459 (char *)passphrase)) == NULL) {
3796 unsigned long pem_err = ERR_peek_last_error(); 3460 r = convert_libcrypto_error();
3797 int pem_reason = ERR_GET_REASON(pem_err);
3798
3799 /*
3800 * Translate OpenSSL error codes to determine whether
3801 * passphrase is required/incorrect.
3802 */
3803 switch (ERR_GET_LIB(pem_err)) {
3804 case ERR_LIB_PEM:
3805 switch (pem_reason) {
3806 case PEM_R_BAD_PASSWORD_READ:
3807 case PEM_R_PROBLEMS_GETTING_PASSWORD:
3808 case PEM_R_BAD_DECRYPT:
3809 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3810 goto out;
3811 default:
3812 r = SSH_ERR_INVALID_FORMAT;
3813 goto out;
3814 }
3815 case ERR_LIB_EVP:
3816 switch (pem_reason) {
3817 case EVP_R_BAD_DECRYPT:
3818 r = SSH_ERR_KEY_WRONG_PASSPHRASE;
3819 goto out;
3820 case EVP_R_BN_DECODE_ERROR:
3821 case EVP_R_DECODE_ERROR:
3822#ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR
3823 case EVP_R_PRIVATE_KEY_DECODE_ERROR:
3824#endif
3825 r = SSH_ERR_INVALID_FORMAT;
3826 goto out;
3827 default:
3828 r = SSH_ERR_LIBCRYPTO_ERROR;
3829 goto out;
3830 }
3831 case ERR_LIB_ASN1:
3832 r = SSH_ERR_INVALID_FORMAT;
3833 goto out;
3834 }
3835 r = SSH_ERR_LIBCRYPTO_ERROR;
3836 goto out; 3461 goto out;
3837 } 3462 }
3838 if (pk->type == EVP_PKEY_RSA && 3463 if (pk->type == EVP_PKEY_RSA &&
@@ -3850,6 +3475,10 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
3850 r = SSH_ERR_LIBCRYPTO_ERROR; 3475 r = SSH_ERR_LIBCRYPTO_ERROR;
3851 goto out; 3476 goto out;
3852 } 3477 }
3478 if (BN_num_bits(prv->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
3479 r = SSH_ERR_KEY_LENGTH;
3480 goto out;
3481 }
3853 } else if (pk->type == EVP_PKEY_DSA && 3482 } else if (pk->type == EVP_PKEY_DSA &&
3854 (type == KEY_UNSPEC || type == KEY_DSA)) { 3483 (type == KEY_UNSPEC || type == KEY_DSA)) {
3855 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) { 3484 if ((prv = sshkey_new(KEY_UNSPEC)) == NULL) {
@@ -3914,11 +3543,6 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
3914 *commentp = NULL; 3543 *commentp = NULL;
3915 3544
3916 switch (type) { 3545 switch (type) {
3917#ifdef WITH_SSH1
3918 case KEY_RSA1:
3919 return sshkey_parse_private_rsa1(blob, passphrase,
3920 keyp, commentp);
3921#endif /* WITH_SSH1 */
3922#ifdef WITH_OPENSSL 3546#ifdef WITH_OPENSSL
3923 case KEY_DSA: 3547 case KEY_DSA:
3924 case KEY_ECDSA: 3548 case KEY_ECDSA:
@@ -3955,13 +3579,6 @@ sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
3955 if (commentp != NULL) 3579 if (commentp != NULL)
3956 *commentp = NULL; 3580 *commentp = NULL;
3957 3581
3958#ifdef WITH_SSH1
3959 /* it's a SSH v1 key if the public key part is readable */
3960 if (sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL) == 0) {
3961 return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1,
3962 passphrase, keyp, commentp);
3963 }
3964#endif /* WITH_SSH1 */
3965 return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, 3582 return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,
3966 passphrase, keyp, commentp); 3583 passphrase, keyp, commentp);
3967} 3584}
diff --git a/sshkey.h b/sshkey.h
index 1b9e42f45..9093eac51 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshkey.h,v 1.15 2017/03/10 04:07:20 djm Exp $ */ 1/* $OpenBSD: sshkey.h,v 1.21 2017/07/01 13:50:45 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -46,14 +46,13 @@
46# define EC_POINT void 46# define EC_POINT void
47#endif /* WITH_OPENSSL */ 47#endif /* WITH_OPENSSL */
48 48
49#define SSH_RSA_MINIMUM_MODULUS_SIZE 768 49#define SSH_RSA_MINIMUM_MODULUS_SIZE 1024
50#define SSH_KEY_MAX_SIGN_DATA_SIZE (1 << 20) 50#define SSH_KEY_MAX_SIGN_DATA_SIZE (1 << 20)
51 51
52struct sshbuf; 52struct sshbuf;
53 53
54/* Key types */ 54/* Key types */
55enum sshkey_types { 55enum sshkey_types {
56 KEY_RSA1,
57 KEY_RSA, 56 KEY_RSA,
58 KEY_DSA, 57 KEY_DSA,
59 KEY_ECDSA, 58 KEY_ECDSA,
@@ -125,6 +124,7 @@ int sshkey_fingerprint_raw(const struct sshkey *k,
125 int, u_char **retp, size_t *lenp); 124 int, u_char **retp, size_t *lenp);
126const char *sshkey_type(const struct sshkey *); 125const char *sshkey_type(const struct sshkey *);
127const char *sshkey_cert_type(const struct sshkey *); 126const char *sshkey_cert_type(const struct sshkey *);
127int sshkey_format_text(const struct sshkey *, struct sshbuf *);
128int sshkey_write(const struct sshkey *, FILE *); 128int sshkey_write(const struct sshkey *, FILE *);
129int sshkey_read(struct sshkey *, char **); 129int sshkey_read(struct sshkey *, char **);
130u_int sshkey_size(const struct sshkey *); 130u_int sshkey_size(const struct sshkey *);
@@ -137,13 +137,19 @@ int sshkey_type_is_cert(int);
137int sshkey_type_plain(int); 137int sshkey_type_plain(int);
138int sshkey_to_certified(struct sshkey *); 138int sshkey_to_certified(struct sshkey *);
139int sshkey_drop_cert(struct sshkey *); 139int sshkey_drop_cert(struct sshkey *);
140int sshkey_certify(struct sshkey *, struct sshkey *, const char *);
141int sshkey_cert_copy(const struct sshkey *, struct sshkey *); 140int sshkey_cert_copy(const struct sshkey *, struct sshkey *);
142int sshkey_cert_check_authority(const struct sshkey *, int, int, 141int sshkey_cert_check_authority(const struct sshkey *, int, int,
143 const char *, const char **); 142 const char *, const char **);
144size_t sshkey_format_cert_validity(const struct sshkey_cert *, 143size_t sshkey_format_cert_validity(const struct sshkey_cert *,
145 char *, size_t) __attribute__((__bounded__(__string__, 2, 3))); 144 char *, size_t) __attribute__((__bounded__(__string__, 2, 3)));
146 145
146int sshkey_certify(struct sshkey *, struct sshkey *, const char *);
147/* Variant allowing use of a custom signature function (e.g. for ssh-agent) */
148typedef int sshkey_certify_signer(const struct sshkey *, u_char **, size_t *,
149 const u_char *, size_t, const char *, u_int, void *);
150int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *,
151 sshkey_certify_signer *, void *);
152
147int sshkey_ecdsa_nid_from_name(const char *); 153int sshkey_ecdsa_nid_from_name(const char *);
148int sshkey_curve_name_to_nid(const char *); 154int sshkey_curve_name_to_nid(const char *);
149const char * sshkey_curve_nid_to_name(int); 155const char * sshkey_curve_nid_to_name(int);
@@ -185,13 +191,14 @@ int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp);
185int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, 191int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
186 const char *passphrase, const char *comment, 192 const char *passphrase, const char *comment,
187 int force_new_format, const char *new_format_cipher, int new_format_rounds); 193 int force_new_format, const char *new_format_cipher, int new_format_rounds);
188int sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob,
189 struct sshkey **keyp, char **commentp);
190int sshkey_parse_private_fileblob(struct sshbuf *buffer, 194int sshkey_parse_private_fileblob(struct sshbuf *buffer,
191 const char *passphrase, struct sshkey **keyp, char **commentp); 195 const char *passphrase, struct sshkey **keyp, char **commentp);
192int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, 196int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
193 const char *passphrase, struct sshkey **keyp, char **commentp); 197 const char *passphrase, struct sshkey **keyp, char **commentp);
194 198
199/* XXX should be internal, but used by ssh-keygen */
200int ssh_rsa_generate_additional_parameters(struct sshkey *);
201
195#ifdef SSHKEY_INTERNAL 202#ifdef SSHKEY_INTERNAL
196int ssh_rsa_sign(const struct sshkey *key, 203int ssh_rsa_sign(const struct sshkey *key,
197 u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, 204 u_char **sigp, size_t *lenp, const u_char *data, size_t datalen,
diff --git a/ttymodes.c b/ttymodes.c
index db772c39c..845139635 100644
--- a/ttymodes.c
+++ b/ttymodes.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ttymodes.c,v 1.30 2016/05/04 14:22:33 markus Exp $ */ 1/* $OpenBSD: ttymodes.c,v 1.32 2017/04/30 23:26:54 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -59,12 +59,10 @@
59 59
60#define TTY_OP_END 0 60#define TTY_OP_END 0
61/* 61/*
62 * uint32 (u_int) follows speed in SSH1 and SSH2 62 * uint32 (u_int) follows speed.
63 */ 63 */
64#define TTY_OP_ISPEED_PROTO1 192 64#define TTY_OP_ISPEED 128
65#define TTY_OP_OSPEED_PROTO1 193 65#define TTY_OP_OSPEED 129
66#define TTY_OP_ISPEED_PROTO2 128
67#define TTY_OP_OSPEED_PROTO2 129
68 66
69/* 67/*
70 * Converts POSIX speed_t to a baud rate. The values of the 68 * Converts POSIX speed_t to a baud rate. The values of the
@@ -282,19 +280,8 @@ tty_make_modes(int fd, struct termios *tiop)
282 struct termios tio; 280 struct termios tio;
283 int baud; 281 int baud;
284 Buffer buf; 282 Buffer buf;
285 int tty_op_ospeed, tty_op_ispeed;
286 void (*put_arg)(Buffer *, u_int);
287 283
288 buffer_init(&buf); 284 buffer_init(&buf);
289 if (compat20) {
290 tty_op_ospeed = TTY_OP_OSPEED_PROTO2;
291 tty_op_ispeed = TTY_OP_ISPEED_PROTO2;
292 put_arg = buffer_put_int;
293 } else {
294 tty_op_ospeed = TTY_OP_OSPEED_PROTO1;
295 tty_op_ispeed = TTY_OP_ISPEED_PROTO1;
296 put_arg = (void (*)(Buffer *, u_int)) buffer_put_char;
297 }
298 285
299 if (tiop == NULL) { 286 if (tiop == NULL) {
300 if (fd == -1) { 287 if (fd == -1) {
@@ -310,20 +297,20 @@ tty_make_modes(int fd, struct termios *tiop)
310 297
311 /* Store input and output baud rates. */ 298 /* Store input and output baud rates. */
312 baud = speed_to_baud(cfgetospeed(&tio)); 299 baud = speed_to_baud(cfgetospeed(&tio));
313 buffer_put_char(&buf, tty_op_ospeed); 300 buffer_put_char(&buf, TTY_OP_OSPEED);
314 buffer_put_int(&buf, baud); 301 buffer_put_int(&buf, baud);
315 baud = speed_to_baud(cfgetispeed(&tio)); 302 baud = speed_to_baud(cfgetispeed(&tio));
316 buffer_put_char(&buf, tty_op_ispeed); 303 buffer_put_char(&buf, TTY_OP_ISPEED);
317 buffer_put_int(&buf, baud); 304 buffer_put_int(&buf, baud);
318 305
319 /* Store values of mode flags. */ 306 /* Store values of mode flags. */
320#define TTYCHAR(NAME, OP) \ 307#define TTYCHAR(NAME, OP) \
321 buffer_put_char(&buf, OP); \ 308 buffer_put_char(&buf, OP); \
322 put_arg(&buf, special_char_encode(tio.c_cc[NAME])); 309 buffer_put_int(&buf, special_char_encode(tio.c_cc[NAME]));
323 310
324#define TTYMODE(NAME, FIELD, OP) \ 311#define TTYMODE(NAME, FIELD, OP) \
325 buffer_put_char(&buf, OP); \ 312 buffer_put_char(&buf, OP); \
326 put_arg(&buf, ((tio.FIELD & NAME) != 0)); 313 buffer_put_int(&buf, ((tio.FIELD & NAME) != 0));
327 314
328#include "ttymodes.h" 315#include "ttymodes.h"
329 316
@@ -333,10 +320,7 @@ tty_make_modes(int fd, struct termios *tiop)
333end: 320end:
334 /* Mark end of mode data. */ 321 /* Mark end of mode data. */
335 buffer_put_char(&buf, TTY_OP_END); 322 buffer_put_char(&buf, TTY_OP_END);
336 if (compat20) 323 packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
337 packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
338 else
339 packet_put_raw(buffer_ptr(&buf), buffer_len(&buf));
340 buffer_free(&buf); 324 buffer_free(&buf);
341} 325}
342 326
@@ -351,19 +335,10 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
351 int opcode, baud; 335 int opcode, baud;
352 int n_bytes = 0; 336 int n_bytes = 0;
353 int failure = 0; 337 int failure = 0;
354 u_int (*get_arg)(void); 338
355 int arg_size; 339 *n_bytes_ptr = packet_get_int();
356 340 if (*n_bytes_ptr == 0)
357 if (compat20) { 341 return;
358 *n_bytes_ptr = packet_get_int();
359 if (*n_bytes_ptr == 0)
360 return;
361 get_arg = packet_get_int;
362 arg_size = 4;
363 } else {
364 get_arg = packet_get_char;
365 arg_size = 1;
366 }
367 342
368 /* 343 /*
369 * Get old attributes for the terminal. We will modify these 344 * Get old attributes for the terminal. We will modify these
@@ -382,9 +357,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
382 case TTY_OP_END: 357 case TTY_OP_END:
383 goto set; 358 goto set;
384 359
385 /* XXX: future conflict possible */ 360 case TTY_OP_ISPEED:
386 case TTY_OP_ISPEED_PROTO1:
387 case TTY_OP_ISPEED_PROTO2:
388 n_bytes += 4; 361 n_bytes += 4;
389 baud = packet_get_int(); 362 baud = packet_get_int();
390 if (failure != -1 && 363 if (failure != -1 &&
@@ -392,9 +365,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
392 error("cfsetispeed failed for %d", baud); 365 error("cfsetispeed failed for %d", baud);
393 break; 366 break;
394 367
395 /* XXX: future conflict possible */ 368 case TTY_OP_OSPEED:
396 case TTY_OP_OSPEED_PROTO1:
397 case TTY_OP_OSPEED_PROTO2:
398 n_bytes += 4; 369 n_bytes += 4;
399 baud = packet_get_int(); 370 baud = packet_get_int();
400 if (failure != -1 && 371 if (failure != -1 &&
@@ -404,13 +375,13 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
404 375
405#define TTYCHAR(NAME, OP) \ 376#define TTYCHAR(NAME, OP) \
406 case OP: \ 377 case OP: \
407 n_bytes += arg_size; \ 378 n_bytes += 4; \
408 tio.c_cc[NAME] = special_char_decode(get_arg()); \ 379 tio.c_cc[NAME] = special_char_decode(packet_get_int()); \
409 break; 380 break;
410#define TTYMODE(NAME, FIELD, OP) \ 381#define TTYMODE(NAME, FIELD, OP) \
411 case OP: \ 382 case OP: \
412 n_bytes += arg_size; \ 383 n_bytes += 4; \
413 if (get_arg()) \ 384 if (packet_get_int()) \
414 tio.FIELD |= NAME; \ 385 tio.FIELD |= NAME; \
415 else \ 386 else \
416 tio.FIELD &= ~NAME; \ 387 tio.FIELD &= ~NAME; \
@@ -424,51 +395,21 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
424 default: 395 default:
425 debug("Ignoring unsupported tty mode opcode %d (0x%x)", 396 debug("Ignoring unsupported tty mode opcode %d (0x%x)",
426 opcode, opcode); 397 opcode, opcode);
427 if (!compat20) { 398 /*
428 /* 399 * SSH2:
429 * SSH1: 400 * Opcodes 1 to 159 are defined to have a uint32
430 * Opcodes 1 to 127 are defined to have 401 * argument.
431 * a one-byte argument. 402 * Opcodes 160 to 255 are undefined and cause parsing
432 * Opcodes 128 to 159 are defined to have 403 * to stop.
433 * an integer argument. 404 */
434 */ 405 if (opcode > 0 && opcode < 160) {
435 if (opcode > 0 && opcode < 128) { 406 n_bytes += 4;
436 n_bytes += 1; 407 (void) packet_get_int();
437 (void) packet_get_char(); 408 break;
438 break;
439 } else if (opcode >= 128 && opcode < 160) {
440 n_bytes += 4;
441 (void) packet_get_int();
442 break;
443 } else {
444 /*
445 * It is a truly undefined opcode (160 to 255).
446 * We have no idea about its arguments. So we
447 * must stop parsing. Note that some data
448 * may be left in the packet; hopefully there
449 * is nothing more coming after the mode data.
450 */
451 logit("parse_tty_modes: unknown opcode %d",
452 opcode);
453 goto set;
454 }
455 } else { 409 } else {
456 /* 410 logit("parse_tty_modes: unknown opcode %d",
457 * SSH2: 411 opcode);
458 * Opcodes 1 to 159 are defined to have 412 goto set;
459 * a uint32 argument.
460 * Opcodes 160 to 255 are undefined and
461 * cause parsing to stop.
462 */
463 if (opcode > 0 && opcode < 160) {
464 n_bytes += 4;
465 (void) packet_get_int();
466 break;
467 } else {
468 logit("parse_tty_modes: unknown opcode %d",
469 opcode);
470 goto set;
471 }
472 } 413 }
473 } 414 }
474 } 415 }
diff --git a/ttymodes.h b/ttymodes.h
index 14e177cef..24f07560c 100644
--- a/ttymodes.h
+++ b/ttymodes.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ttymodes.h,v 1.15 2016/05/03 09:03:49 dtucker Exp $ */ 1/* $OpenBSD: ttymodes.h,v 1.16 2017/04/30 23:26:54 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -38,22 +38,13 @@
38 */ 38 */
39 39
40/* 40/*
41 * SSH1: 41 * The tty mode description is a string, consisting of
42 * The tty mode description is a stream of bytes. The stream consists of
43 * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). 42 * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0).
44 * Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer 43 * Opcodes 1-159 have uint32 arguments.
45 * arguments. Opcodes 160-255 are not yet defined, and cause parsing to 44 * Opcodes 160-255 are not yet defined and cause parsing to stop (they
46 * stop (they should only be used after any other data). 45 * should only be used after any other data).
47 * 46 *
48 * SSH2: 47 * The client puts in the string any modes it knows about, and the
49 * Differences between SSH1 and SSH2 terminal mode encoding include:
50 * 1. Encoded terminal modes are represented as a string, and a stream
51 * of bytes within that string.
52 * 2. Opcode arguments are uint32 (1-159); 160-255 remain undefined.
53 * 3. The values for TTY_OP_ISPEED and TTY_OP_OSPEED are different;
54 * 128 and 129 vs. 192 and 193 respectively.
55 *
56 * The client puts in the stream any modes it knows about, and the
57 * server ignores any modes it does not know about. This allows some degree 48 * server ignores any modes it does not know about. This allows some degree
58 * of machine-independence, at least between systems that use a posix-like 49 * of machine-independence, at least between systems that use a posix-like
59 * tty interface. The protocol can support other systems as well, but might 50 * tty interface. The protocol can support other systems as well, but might
diff --git a/umac.c b/umac.c
index 6eb55b26e..9f2187c9a 100644
--- a/umac.c
+++ b/umac.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: umac.c,v 1.11 2014/07/22 07:13:42 guenther Exp $ */ 1/* $OpenBSD: umac.c,v 1.12 2017/05/31 08:09:45 markus Exp $ */
2/* ----------------------------------------------------------------------- 2/* -----------------------------------------------------------------------
3 * 3 *
4 * umac.c -- C Implementation UMAC Message Authentication 4 * umac.c -- C Implementation UMAC Message Authentication
@@ -203,6 +203,8 @@ static void kdf(void *bufp, aes_int_key key, UINT8 ndx, int nbytes)
203 aes_encryption(in_buf, out_buf, key); 203 aes_encryption(in_buf, out_buf, key);
204 memcpy(dst_buf,out_buf,nbytes); 204 memcpy(dst_buf,out_buf,nbytes);
205 } 205 }
206 explicit_bzero(in_buf, sizeof(in_buf));
207 explicit_bzero(out_buf, sizeof(out_buf));
206} 208}
207 209
208/* The final UHASH result is XOR'd with the output of a pseudorandom 210/* The final UHASH result is XOR'd with the output of a pseudorandom
@@ -227,6 +229,7 @@ static void pdf_init(pdf_ctx *pc, aes_int_key prf_key)
227 /* Initialize pdf and cache */ 229 /* Initialize pdf and cache */
228 memset(pc->nonce, 0, sizeof(pc->nonce)); 230 memset(pc->nonce, 0, sizeof(pc->nonce));
229 aes_encryption(pc->nonce, pc->cache, pc->prf_key); 231 aes_encryption(pc->nonce, pc->cache, pc->prf_key);
232 explicit_bzero(buf, sizeof(buf));
230} 233}
231 234
232static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8]) 235static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8])
@@ -991,6 +994,7 @@ static void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key)
991 kdf(ahc->ip_trans, prf_key, 4, STREAMS * sizeof(UINT32)); 994 kdf(ahc->ip_trans, prf_key, 4, STREAMS * sizeof(UINT32));
992 endian_convert_if_le(ahc->ip_trans, sizeof(UINT32), 995 endian_convert_if_le(ahc->ip_trans, sizeof(UINT32),
993 STREAMS * sizeof(UINT32)); 996 STREAMS * sizeof(UINT32));
997 explicit_bzero(buf, sizeof(buf));
994} 998}
995 999
996/* ---------------------------------------------------------------------- */ 1000/* ---------------------------------------------------------------------- */
@@ -1200,6 +1204,7 @@ int umac_delete(struct umac_ctx *ctx)
1200 if (ctx) { 1204 if (ctx) {
1201 if (ALLOC_BOUNDARY) 1205 if (ALLOC_BOUNDARY)
1202 ctx = (struct umac_ctx *)ctx->free_ptr; 1206 ctx = (struct umac_ctx *)ctx->free_ptr;
1207 explicit_bzero(ctx, sizeof(*ctx) + ALLOC_BOUNDARY);
1203 free(ctx); 1208 free(ctx);
1204 } 1209 }
1205 return (1); 1210 return (1);
@@ -1227,6 +1232,7 @@ struct umac_ctx *umac_new(const u_char key[])
1227 aes_key_setup(key, prf_key); 1232 aes_key_setup(key, prf_key);
1228 pdf_init(&ctx->pdf, prf_key); 1233 pdf_init(&ctx->pdf, prf_key);
1229 uhash_init(&ctx->hash, prf_key); 1234 uhash_init(&ctx->hash, prf_key);
1235 explicit_bzero(prf_key, sizeof(prf_key));
1230 } 1236 }
1231 1237
1232 return (ctx); 1238 return (ctx);
diff --git a/utf8.c b/utf8.c
index dead79b8a..bc131385f 100644
--- a/utf8.c
+++ b/utf8.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: utf8.c,v 1.5 2017/02/19 00:10:57 djm Exp $ */ 1/* $OpenBSD: utf8.c,v 1.7 2017/05/31 09:15:42 deraadt Exp $ */
2/* 2/*
3 * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org> 3 * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
4 * 4 *
@@ -61,7 +61,8 @@ dangerous_locale(void) {
61 61
62 loc = nl_langinfo(CODESET); 62 loc = nl_langinfo(CODESET);
63 return strcmp(loc, "US-ASCII") != 0 && strcmp(loc, "UTF-8") != 0 && 63 return strcmp(loc, "US-ASCII") != 0 && strcmp(loc, "UTF-8") != 0 &&
64 strcmp(loc, "ANSI_X3.4-1968") != 0 && strcmp(loc, "646") != 0; 64 strcmp(loc, "ANSI_X3.4-1968") != 0 && strcmp(loc, "646") != 0 &&
65 strcmp(loc, "") != 0;
65} 66}
66 67
67static int 68static int
@@ -75,7 +76,7 @@ grow_dst(char **dst, size_t *sz, size_t maxsz, char **dp, size_t need)
75 tsz = *sz + 128; 76 tsz = *sz + 128;
76 if (tsz > maxsz) 77 if (tsz > maxsz)
77 tsz = maxsz; 78 tsz = maxsz;
78 if ((tp = realloc(*dst, tsz)) == NULL) 79 if ((tp = recallocarray(*dst, *sz, tsz, 1)) == NULL)
79 return -1; 80 return -1;
80 *dp = tp + (*dp - *dst); 81 *dp = tp + (*dp - *dst);
81 *dst = tp; 82 *dst = tp;
diff --git a/version.h b/version.h
index c86e2097c..e093f623b 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
1/* $OpenBSD: version.h,v 1.79 2017/03/20 01:18:59 djm Exp $ */ 1/* $OpenBSD: version.h,v 1.80 2017/09/30 22:26:33 djm Exp $ */
2 2
3#define SSH_VERSION "OpenSSH_7.5" 3#define SSH_VERSION "OpenSSH_7.6"
4 4
5#define SSH_PORTABLE "p1" 5#define SSH_PORTABLE "p1"
6#define SSH_RELEASE SSH_VERSION SSH_PORTABLE 6#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
diff --git a/xmalloc.c b/xmalloc.c
index b58323677..5cc0310a4 100644
--- a/xmalloc.c
+++ b/xmalloc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: xmalloc.c,v 1.33 2016/02/15 09:47:49 dtucker Exp $ */ 1/* $OpenBSD: xmalloc.c,v 1.34 2017/05/31 09:15:42 deraadt Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -77,6 +77,18 @@ xreallocarray(void *ptr, size_t nmemb, size_t size)
77 return new_ptr; 77 return new_ptr;
78} 78}
79 79
80void *
81xrecallocarray(void *ptr, size_t onmemb, size_t nmemb, size_t size)
82{
83 void *new_ptr;
84
85 new_ptr = recallocarray(ptr, onmemb, nmemb, size);
86 if (new_ptr == NULL)
87 fatal("xrecallocarray: out of memory (%zu elements of %zu bytes)",
88 nmemb, size);
89 return new_ptr;
90}
91
80char * 92char *
81xstrdup(const char *str) 93xstrdup(const char *str)
82{ 94{
diff --git a/xmalloc.h b/xmalloc.h
index e49928932..cf38ddfa4 100644
--- a/xmalloc.h
+++ b/xmalloc.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: xmalloc.h,v 1.16 2016/02/15 09:47:49 dtucker Exp $ */ 1/* $OpenBSD: xmalloc.h,v 1.17 2017/05/31 09:15:42 deraadt Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -20,6 +20,7 @@ void ssh_malloc_init(void);
20void *xmalloc(size_t); 20void *xmalloc(size_t);
21void *xcalloc(size_t, size_t); 21void *xcalloc(size_t, size_t);
22void *xreallocarray(void *, size_t, size_t); 22void *xreallocarray(void *, size_t, size_t);
23void *xrecallocarray(void *, size_t, size_t, size_t);
23char *xstrdup(const char *); 24char *xstrdup(const char *);
24int xasprintf(char **, const char *, ...) 25int xasprintf(char **, const char *, ...)
25 __attribute__((__format__ (printf, 2, 3))) 26 __attribute__((__format__ (printf, 2, 3)))