diff options
author | Colin Watson <cjwatson@debian.org> | 2017-10-04 11:23:58 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2017-10-04 11:23:58 +0100 |
commit | 62f54f20bf351468e0124f63cc2902ee40d9b0e9 (patch) | |
tree | 3e090f2711b94ca5029d3fa3e8047b1ed1448b1f | |
parent | 6fabaf6fd9b07cc8bc6a17c9c4a5b76849cfc874 (diff) | |
parent | 66bf74a92131b7effe49fb0eefe5225151869dc5 (diff) |
Import openssh_7.6p1.orig.tar.gz
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 @@ | |||
1 | Makefile | ||
2 | buildpkg.sh | ||
3 | config.h | ||
4 | config.h.in | ||
5 | config.status | ||
6 | configure | ||
7 | openbsd-compat/Makefile | ||
8 | openbsd-compat/regress/Makefile | ||
9 | openssh.xml | ||
10 | opensshd.init | ||
11 | survey.sh | ||
12 | **/*.0 | ||
13 | **/*.o | ||
14 | **/*.out | ||
15 | **/*.a | ||
16 | autom4te.cache/ | ||
17 | scp | ||
18 | sftp | ||
19 | sftp-server | ||
20 | ssh | ||
21 | ssh-add | ||
22 | ssh-agent | ||
23 | ssh-keygen | ||
24 | ssh-keyscan | ||
25 | ssh-keysign | ||
26 | ssh-pkcs11-helper | ||
27 | sshd | ||
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. | |||
11 | 96c5054e3e1f170c6276902d5bc65bb3b87a2603 remove DEBUGLIBS from Makefile | 11 | 96c5054e3e1f170c6276902d5bc65bb3b87a2603 remove DEBUGLIBS from Makefile |
12 | 6da9a37f74aef9f9cc639004345ad893cad582d8 Update moduli file | 12 | 6da9a37f74aef9f9cc639004345ad893cad582d8 Update moduli file |
13 | 77bcb50e47b68c7209c7f0a5a020d73761e5143b unset REGRESS_FAIL_EARLY | 13 | 77bcb50e47b68c7209c7f0a5a020d73761e5143b unset REGRESS_FAIL_EARLY |
14 | 38c2133817cbcae75c88c63599ac54228f0fa384 Change COMPILER_VERSION tests | ||
15 | 30c20180c87cbc99fa1020489fe7fd8245b6420c resync integrity.sh shell | ||
16 | 1e6b51ddf767cbad0a4e63eb08026c127e654308 integrity.sh reliability | ||
17 | fe5b31f69a60d47171836911f144acff77810217 Makefile.inc bits | ||
18 | 5781670c0578fe89663c9085ed3ba477cf7e7913 Delete sshconnect1.c | ||
19 | ea80f445e819719ccdcb237022cacfac990fdc5c Makefile.inc warning flags | ||
20 | b92c93266d8234d493857bb822260dacf4366157 moduli-gen.sh tweak | ||
21 | b25bf747544265b39af74fe0716dc8d9f5b63b95 Updated moduli | ||
22 | 1bd41cba06a7752de4df304305a8153ebfb6b0ac rsa.[ch] already removed | ||
23 | e39b3902fe1d6c4a7ba6a3c58e072219f3c1e604 Makefile changes | ||
@@ -1,3 +1,2514 @@ | |||
1 | commit 66bf74a92131b7effe49fb0eefe5225151869dc5 | ||
2 | Author: djm@openbsd.org <djm@openbsd.org> | ||
3 | Date: 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 | |||
11 | commit d63b38160a59039708fd952adc75a0b3da141560 | ||
12 | Author: Damien Miller <djm@mindrot.org> | ||
13 | Date: 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 | |||
19 | commit 6f64f596430cd3576c529f07acaaf2800aa17d58 | ||
20 | Author: Damien Miller <djm@mindrot.org> | ||
21 | Date: Sun Oct 1 10:01:56 2017 +1100 | ||
22 | |||
23 | sync release notes URL | ||
24 | |||
25 | commit 35ff70a04dd71663a5ac1e73b90d16d270a06e0d | ||
26 | Author: Damien Miller <djm@mindrot.org> | ||
27 | Date: Sun Oct 1 10:01:25 2017 +1100 | ||
28 | |||
29 | sync contrib/ssh-copy-id with upstream | ||
30 | |||
31 | commit 290843b8ede85f8b30bf29cd7dceb805c3ea5b66 | ||
32 | Author: Damien Miller <djm@mindrot.org> | ||
33 | Date: Sun Oct 1 09:59:19 2017 +1100 | ||
34 | |||
35 | update version in RPM spec files | ||
36 | |||
37 | commit 4e4e0bb223c5be88d87d5798c75cc6b0d4fef31d | ||
38 | Author: Damien Miller <djm@mindrot.org> | ||
39 | Date: Sun Oct 1 09:58:24 2017 +1100 | ||
40 | |||
41 | update agent draft URL | ||
42 | |||
43 | commit e4a798f001d2ecd8bf025c1d07658079f27cc604 | ||
44 | Author: djm@openbsd.org <djm@openbsd.org> | ||
45 | Date: 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 | |||
53 | commit 5fa1407e16e7e5fda9769d53b626ce39d5588d4d | ||
54 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
55 | Date: 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 | |||
65 | commit bba69c246f0331f657fd6ec97724df99fc1ad174 | ||
66 | Author: Damien Miller <djm@mindrot.org> | ||
67 | Date: Thu Sep 28 16:06:21 2017 -0700 | ||
68 | |||
69 | don't fatal ./configure for LibreSSL | ||
70 | |||
71 | commit 04dc070e8b4507d9d829f910b29be7e3b2414913 | ||
72 | Author: Damien Miller <djm@mindrot.org> | ||
73 | Date: 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 | |||
85 | commit 74c1c3660acf996d9dc329e819179418dc115f2c | ||
86 | Author: Darren Tucker <dtucker@zip.com.au> | ||
87 | Date: 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 | |||
97 | commit 6a9481258a77b0b54b2a313d1761c87360c5f1f5 | ||
98 | Author: markus@openbsd.org <markus@openbsd.org> | ||
99 | Date: 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 | |||
107 | commit 1b9f321605733754df60fac8c1d3283c89b74455 | ||
108 | Author: Damien Miller <djm@mindrot.org> | ||
109 | Date: Tue Sep 26 16:55:55 2017 +1000 | ||
110 | |||
111 | sync missing changes in dynamic-forward.sh | ||
112 | |||
113 | commit 44fc334c7a9ebdd08addb6d5fa005369897fddeb | ||
114 | Author: Darren Tucker <dtucker@zip.com.au> | ||
115 | Date: Mon Sep 25 09:48:10 2017 +1000 | ||
116 | |||
117 | Add minimal strsignal for platforms without it. | ||
118 | |||
119 | commit 218e6f98df566fb9bd363f6aa47018cb65ede196 | ||
120 | Author: djm@openbsd.org <djm@openbsd.org> | ||
121 | Date: 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 | |||
131 | commit c704f641f7b8777497dc82e81f2ac89afec7e401 | ||
132 | Author: djm@openbsd.org <djm@openbsd.org> | ||
133 | Date: 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 | |||
143 | commit 55486f5cef117354f0c64f991895835077b7c7f7 | ||
144 | Author: djm@openbsd.org <djm@openbsd.org> | ||
145 | Date: 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 | |||
154 | commit 609d7a66ce578abf259da2d5f6f68795c2bda731 | ||
155 | Author: markus@openbsd.org <markus@openbsd.org> | ||
156 | Date: 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 | |||
175 | commit 36945fa103176c00b39731e1fc1919a0d0808b81 | ||
176 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
177 | Date: 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 | |||
187 | commit 3e8d185af326bf183b6f78597d5e3d2eeb2dc40e | ||
188 | Author: millert@openbsd.org <millert@openbsd.org> | ||
189 | Date: 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 | |||
198 | commit 5b8da1f53854c0923ec6e927e86709e4d72737b6 | ||
199 | Author: djm@openbsd.org <djm@openbsd.org> | ||
200 | Date: 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 | |||
209 | commit a3839d8d2b89ff1a80cadd4dd654336710de2c9e | ||
210 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
211 | Date: 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 | |||
220 | commit 30484e5e5f0b63d2c6ba32c6b85f06b6c6fa55fc | ||
221 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
222 | Date: 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 | |||
230 | commit b79569190b9b76dfacc6d996faa482f16e8fc026 | ||
231 | Author: Damien Miller <djm@mindrot.org> | ||
232 | Date: Tue Sep 19 12:29:23 2017 +1000 | ||
233 | |||
234 | add freezero(3) replacement | ||
235 | |||
236 | ok dtucker@ | ||
237 | |||
238 | commit 161af8f5ec0961b10cc032efb5cc1b44ced5a92e | ||
239 | Author: Damien Miller <djm@mindrot.org> | ||
240 | Date: 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 | |||
248 | commit 09eacf856e0fe1a6e3fe597ec8032b7046292914 | ||
249 | Author: bluhm@openbsd.org <bluhm@openbsd.org> | ||
250 | Date: 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 | |||
261 | commit cdede10899892f25f1ccdccd7a3fe5e5ef0aa49a | ||
262 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
263 | Date: 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 | |||
271 | commit ec218c105daa9f5b192f7aa890fdb2d4fdc4e9d8 | ||
272 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
273 | Date: 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 | |||
282 | commit 239c57d5bc2253e27e3e6ad7ac52ec8c377ee24e | ||
283 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
284 | Date: 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 | |||
295 | commit aea59a0d9f120f2a87c7f494a0d9c51eaa79b8ba | ||
296 | Author: djm@openbsd.org <djm@openbsd.org> | ||
297 | Date: 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 | |||
316 | commit 871f1e4374420b07550041b329627c474abc3010 | ||
317 | Author: Damien Miller <djm@mindrot.org> | ||
318 | Date: Tue Sep 12 18:01:35 2017 +1000 | ||
319 | |||
320 | adapt portable to channels API changes | ||
321 | |||
322 | commit 4ec0bb9f9ad7b4eb0af110fa8eddf8fa199e46bb | ||
323 | Author: djm@openbsd.org <djm@openbsd.org> | ||
324 | Date: Tue Sep 12 07:55:48 2017 +0000 | ||
325 | |||
326 | upstream commit | ||
327 | |||
328 | unused variable | ||
329 | |||
330 | Upstream-ID: 2f9ba09f2708993d35eac5aa71df910dcc52bac1 | ||
331 | |||
332 | commit 9145a73ce2ba30c82bbf91d7205bfd112529449f | ||
333 | Author: djm@openbsd.org <djm@openbsd.org> | ||
334 | Date: 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 | |||
342 | commit 9f53229c2ac97dbc6f5a03657de08a1150a9ac7e | ||
343 | Author: djm@openbsd.org <djm@openbsd.org> | ||
344 | Date: 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 | |||
361 | commit dbee4119b502e3f8b6cd3282c69c537fd01d8e16 | ||
362 | Author: djm@openbsd.org <djm@openbsd.org> | ||
363 | Date: 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 | |||
387 | commit abd59663df37a42152e37980113ccaa405b9a282 | ||
388 | Author: djm@openbsd.org <djm@openbsd.org> | ||
389 | Date: Thu Sep 7 23:48:09 2017 +0000 | ||
390 | |||
391 | upstream commit | ||
392 | |||
393 | typo in comment | ||
394 | |||
395 | Upstream-ID: a93b1e6f30f1f9b854b5b964b9fd092d0c422c47 | ||
396 | |||
397 | commit 149a8cd24ce9dd47c36f571738681df5f31a326c | ||
398 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
399 | Date: Mon Sep 4 06:34:43 2017 +0000 | ||
400 | |||
401 | upstream commit | ||
402 | |||
403 | tweak previous; | ||
404 | |||
405 | Upstream-ID: bb8cc40b61b15f6a13d81da465ac5bfc65cbfc4b | ||
406 | |||
407 | commit ec9d22cc251cc5acfe7b2bcef9cc7a1fe0e949d8 | ||
408 | Author: Damien Miller <djm@mindrot.org> | ||
409 | Date: 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 | |||
417 | commit de35c382894964a896a63ecd5607d3a3b93af75d | ||
418 | Author: Damien Miller <djm@mindrot.org> | ||
419 | Date: 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 | |||
438 | commit 22376d27a349f62c502fec3396dfe0fdcb2a40b7 | ||
439 | Author: djm@openbsd.org <djm@openbsd.org> | ||
440 | Date: 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 | |||
471 | commit ff3c42384033514e248ba5d7376aa033f4a2b99a | ||
472 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
473 | Date: Fri Sep 1 15:41:26 2017 +0000 | ||
474 | |||
475 | upstream commit | ||
476 | |||
477 | remove blank line; | ||
478 | |||
479 | Upstream-ID: 2f46b51a0ddb3730020791719e94d3e418e9f423 | ||
480 | |||
481 | commit b828605d51f57851316d7ba402b4ae06cf37c55d | ||
482 | Author: djm@openbsd.org <djm@openbsd.org> | ||
483 | Date: 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 | |||
493 | commit 8042bad97e2789a50e8f742c3bcd665ebf0add32 | ||
494 | Author: djm@openbsd.org <djm@openbsd.org> | ||
495 | Date: 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 | |||
504 | commit 71e5a536ec815d542b199f2ae6d646c0db9f1b58 | ||
505 | Author: djm@openbsd.org <djm@openbsd.org> | ||
506 | Date: 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 | |||
515 | commit 6227fe5b362239c872b91bbdee4bf63cf85aebc5 | ||
516 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
517 | Date: Tue Aug 29 13:05:58 2017 +0000 | ||
518 | |||
519 | upstream commit | ||
520 | |||
521 | sort options; | ||
522 | |||
523 | Upstream-ID: cf21d68cf54e81968bca629aaeddc87f0c684f3c | ||
524 | |||
525 | commit 530591a5795a02d01c78877d58604723918aac87 | ||
526 | Author: dlg@openbsd.org <dlg@openbsd.org> | ||
527 | Date: 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 | |||
541 | commit a54eb27dd64b5eca3ba94e15cec3535124bd5029 | ||
542 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
543 | Date: 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 | |||
553 | commit dd9d9b3381a4597b840d480b043823112039327e | ||
554 | Author: Darren Tucker <dtucker@zip.com.au> | ||
555 | Date: 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 | |||
563 | commit f5e917ab105af5dd6429348d9bc463e52b263f92 | ||
564 | Author: Darren Tucker <dtucker@zip.com.au> | ||
565 | Date: 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 | |||
571 | commit 878e029797cfc9754771d6f6ea17f8c89e11d225 | ||
572 | Author: Damien Miller <djm@mindrot.org> | ||
573 | Date: 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 | |||
581 | commit 07949bfe9133234eddd01715592aa0dde67745f0 | ||
582 | Author: Damien Miller <djm@mindrot.org> | ||
583 | Date: Wed Aug 23 20:13:18 2017 +1000 | ||
584 | |||
585 | misc.c needs functions from platform.c now | ||
586 | |||
587 | commit b074c3c3f820000a21953441cea7699c4b17d72f | ||
588 | Author: djm@openbsd.org <djm@openbsd.org> | ||
589 | Date: 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 | |||
598 | commit de4ae07f12dabf8815ecede54235fce5d22e3f63 | ||
599 | Author: djm@openbsd.org <djm@openbsd.org> | ||
600 | Date: 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 | |||
612 | commit 643c2ad82910691b2240551ea8b14472f60b5078 | ||
613 | Author: djm@openbsd.org <djm@openbsd.org> | ||
614 | Date: 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 | |||
627 | commit 0f3455356bc284d7c6f4d3c1614d31161bd5dcc2 | ||
628 | Author: djm@openbsd.org <djm@openbsd.org> | ||
629 | Date: 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 | |||
639 | commit c4972d0a9bd6f898462906b4827e09b7caea2d9b | ||
640 | Author: djm@openbsd.org <djm@openbsd.org> | ||
641 | Date: 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 | |||
650 | commit 4b3ecbb663c919132dddb3758e17a23089413519 | ||
651 | Author: djm@openbsd.org <djm@openbsd.org> | ||
652 | Date: 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 | |||
661 | commit 42a8f8bc288ef8cac504c5c73f09ed610bc74a34 | ||
662 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
663 | Date: 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 | |||
673 | commit b60ff20051ef96dfb207b6bfa45c0ad6c34a542a | ||
674 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
675 | Date: 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 | |||
689 | commit 94bc1e7ffba3cbdea8c7dcdab8376bf29283128f | ||
690 | Author: Damien Miller <djm@mindrot.org> | ||
691 | Date: 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 | |||
697 | commit c78e6eec78c88acf8d51db90ae05a3e39458603d | ||
698 | Author: Damien Miller <djm@mindrot.org> | ||
699 | Date: 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 | |||
709 | commit 2985d4062ebf4204bbd373456a810d558698f9f5 | ||
710 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
711 | Date: 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 | |||
720 | commit 9f0e44e1a0439ff4646495d5735baa61138930a9 | ||
721 | Author: djm@openbsd.org <djm@openbsd.org> | ||
722 | Date: 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 | |||
730 | commit 51676ec61491ec6d7cbd06082034e29b377b3bf6 | ||
731 | Author: djm@openbsd.org <djm@openbsd.org> | ||
732 | Date: 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 | |||
741 | commit 6c1fbd5a50d8d2415f06c920dd3b1279b741072d | ||
742 | Author: Damien Miller <djm@mindrot.org> | ||
743 | Date: Fri Jul 21 14:24:26 2017 +1000 | ||
744 | |||
745 | mention libedit | ||
746 | |||
747 | commit dc2bd308768386b02c7337120203ca477e67ba62 | ||
748 | Author: markus@openbsd.org <markus@openbsd.org> | ||
749 | Date: 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 | |||
757 | commit fd0e8fa5f89d21290b1fb5f9d110ca4f113d81d9 | ||
758 | Author: djm@openbsd.org <djm@openbsd.org> | ||
759 | Date: 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 | |||
768 | commit b1e72df2b813ecc15bd0152167bf4af5f91c36d3 | ||
769 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
770 | Date: 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 | |||
780 | commit 1f3d202770a08ee6752ed2a234b7ca6f180eb498 | ||
781 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
782 | Date: 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 | |||
797 | commit 7f13a4827fb28957161de4249bd6d71954f1f2ed | ||
798 | Author: espie@openbsd.org <espie@openbsd.org> | ||
799 | Date: 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 | |||
807 | commit dc44dd3a9e2c9795394e6a7e1e71c929cbc70ce0 | ||
808 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
809 | Date: 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 | |||
817 | commit 853edbe057a84ebd0024c8003e4da21bf2b469f7 | ||
818 | Author: djm@openbsd.org <djm@openbsd.org> | ||
819 | Date: 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 | |||
830 | commit 43616876ba68a2ffaece6a6c792def4b039f2d6e | ||
831 | Author: djm@openbsd.org <djm@openbsd.org> | ||
832 | Date: Sat Jul 1 22:55:44 2017 +0000 | ||
833 | |||
834 | upstream commit | ||
835 | |||
836 | actually remove these files | ||
837 | |||
838 | Upstream-ID: 1bd41cba06a7752de4df304305a8153ebfb6b0ac | ||
839 | |||
840 | commit 83fa3a044891887369ce8b487ce88d713a04df48 | ||
841 | Author: djm@openbsd.org <djm@openbsd.org> | ||
842 | Date: 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 | |||
851 | commit 738c73dca2c99ee78c531b4cbeefc2008fe438f0 | ||
852 | Author: Damien Miller <djm@mindrot.org> | ||
853 | Date: Fri Jul 14 14:26:36 2017 +1000 | ||
854 | |||
855 | make explicit_bzero/memset safe for sz=0 | ||
856 | |||
857 | commit 8433d51e067e0829f5521c0c646b6fd3fe17e732 | ||
858 | Author: Tim Rice <tim@multitalents.net> | ||
859 | Date: 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 | |||
865 | commit ff3507aea9c7d30cd098e7801e156c68faff7cc7 | ||
866 | Author: Damien Miller <djm@mindrot.org> | ||
867 | Date: Fri Jul 7 11:21:27 2017 +1000 | ||
868 | |||
869 | typo | ||
870 | |||
871 | commit d79bceb9311a9c137d268f5bc481705db4151810 | ||
872 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
873 | Date: 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 | |||
883 | commit 197dc9728f062e23ce374f44c95a2b5f9ffa4075 | ||
884 | Author: Darren Tucker <dtucker@zip.com.au> | ||
885 | Date: Thu Jun 29 15:40:25 2017 +1000 | ||
886 | |||
887 | Update link for my patches. | ||
888 | |||
889 | commit a98339edbc1fc21342a390f345179a9c3031bef7 | ||
890 | Author: djm@openbsd.org <djm@openbsd.org> | ||
891 | Date: 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 | |||
900 | commit c9cdef35524bd59007e17d5bd2502dade69e2dfb | ||
901 | Author: djm@openbsd.org <djm@openbsd.org> | ||
902 | Date: 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 | |||
910 | commit f17ee61cad25d210edab69d04ed447ad55fe80c1 | ||
911 | Author: djm@openbsd.org <djm@openbsd.org> | ||
912 | Date: Sat Jun 24 07:08:57 2017 +0000 | ||
913 | |||
914 | upstream commit | ||
915 | |||
916 | correct env var name | ||
917 | |||
918 | Upstream-ID: 721e761c2b1d6a4dcf700179f16fd53a1dadb313 | ||
919 | |||
920 | commit 40962198e3b132cecdb32e9350acd4294e6a1082 | ||
921 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
922 | Date: Sat Jun 24 06:57:04 2017 +0000 | ||
923 | |||
924 | upstream commit | ||
925 | |||
926 | spelling; | ||
927 | |||
928 | Upstream-ID: 606f933c8e2d0be902ea663946bc15e3eee40b25 | ||
929 | |||
930 | commit 33f86265d7e8a0e88d3a81745d746efbdd397370 | ||
931 | Author: djm@openbsd.org <djm@openbsd.org> | ||
932 | Date: 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 | |||
942 | commit 8f574959272ac7fe9239c4f5d10fd913f8920ab0 | ||
943 | Author: djm@openbsd.org <djm@openbsd.org> | ||
944 | Date: 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 | |||
957 | commit e2004d4bb7eb01c663dd3a3e7eb224f1ccdc9bba | ||
958 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
959 | Date: Sat Jun 24 06:28:50 2017 +0000 | ||
960 | |||
961 | upstream commit | ||
962 | |||
963 | word fix; | ||
964 | |||
965 | Upstream-ID: 8539bdaf2366603a34a9b2f034527ca13bb795c5 | ||
966 | |||
967 | commit 4540428cd0adf039bcf5a8a27f2d5cdf09191513 | ||
968 | Author: djm@openbsd.org <djm@openbsd.org> | ||
969 | Date: 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 | |||
978 | commit 6f8ca3b92540fa1a9b91670edc98d15448e3d765 | ||
979 | Author: djm@openbsd.org <djm@openbsd.org> | ||
980 | Date: 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 | |||
989 | commit 8904ffce057b80a7472955f1ec00d7d5c250076c | ||
990 | Author: djm@openbsd.org <djm@openbsd.org> | ||
991 | Date: 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 | |||
1001 | commit e238645d789cd7eb47541b66aea2a887ea122c9b | ||
1002 | Author: mestre@openbsd.org <mestre@openbsd.org> | ||
1003 | Date: 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 | |||
1018 | commit 5abbb31c4e7a6caa922cc1cbb14e87a77f9d19d3 | ||
1019 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
1020 | Date: Fri Jun 23 03:30:42 2017 +0000 | ||
1021 | |||
1022 | upstream commit | ||
1023 | |||
1024 | Import regenerated moduli. | ||
1025 | |||
1026 | Upstream-ID: b25bf747544265b39af74fe0716dc8d9f5b63b95 | ||
1027 | |||
1028 | commit 849c5468b6d9b4365784c5dd88e3f1fb568ba38f | ||
1029 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
1030 | Date: 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 | |||
1039 | commit 4626e39c7053c6486c1c8b708ec757e464623f5f | ||
1040 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
1041 | Date: 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 | |||
1051 | commit c948030d54911b2d3cddb96a7a8e9269e15d11cd | ||
1052 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1053 | Date: 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 | |||
1065 | commit 6026f48dfca78b713e4a7f681ffa42a0afe0929e | ||
1066 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1067 | Date: Tue Jun 13 11:22:15 2017 +0000 | ||
1068 | |||
1069 | upstream commit | ||
1070 | |||
1071 | missing prototype. | ||
1072 | |||
1073 | Upstream-ID: f443d2be9910fd2165a0667956d03343c46f66c9 | ||
1074 | |||
1075 | commit bcd1485075aa72ba9418003f5cc27af2b049c51b | ||
1076 | Author: Damien Miller <djm@mindrot.org> | ||
1077 | Date: 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 | |||
1085 | commit 072e172f1d302d2a2c6043ecbfb4004406717b96 | ||
1086 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1087 | Date: 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 | |||
1096 | commit 72be5b2f8e7dc37235e8c4b8d0bc7b5ee1301505 | ||
1097 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1098 | Date: 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 | |||
1106 | commit 5b2f34a74aa6a524cd57e856b23e1b7b25007721 | ||
1107 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1108 | Date: 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 | |||
1118 | commit 7f5637c4a67a49ef256cb4eedf14e8590ac30976 | ||
1119 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1120 | Date: 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 | |||
1130 | commit 2076e4adb986512ce8c415dd194fd4e52136c4b4 | ||
1131 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1132 | Date: 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 | |||
1142 | commit ad0531614cbe8ec424af3c0fa90c34a8e1ebee4c | ||
1143 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
1144 | Date: 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 | |||
1153 | commit ce9134260b9b1247e2385a1afed00c26112ba479 | ||
1154 | Author: Damien Miller <djm@mindrot.org> | ||
1155 | Date: 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 | |||
1162 | commit e0f609c8a2ab940374689ab8c854199c3c285a76 | ||
1163 | Author: Darren Tucker <dtucker@zip.com.au> | ||
1164 | Date: Fri Jun 9 13:36:29 2017 +1000 | ||
1165 | |||
1166 | Wrap stdint.h include in #ifdef. | ||
1167 | |||
1168 | commit 1de5e47a85850526a4fdaf77185134046c050f75 | ||
1169 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1170 | Date: 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 | |||
1178 | commit 550c053168123fcc0791f9952abad684704b5760 | ||
1179 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
1180 | Date: 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 | |||
1190 | commit 55d06c6e72a9abf1c06a7ac2749ba733134a1f39 | ||
1191 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1192 | Date: 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 | |||
1201 | commit 1527d9f61e6d50f6c2b4a3fa5b45829034b1b0b1 | ||
1202 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1203 | Date: 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 | |||
1212 | commit cc812baf39b93d5355565da98648d8c31f955990 | ||
1213 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1214 | Date: 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 | |||
1223 | commit 65eb8fae0d7ba45ef4483a3cf0ae7fd0dbc7c226 | ||
1224 | Author: Damien Miller <djm@mindrot.org> | ||
1225 | Date: Thu Jun 1 16:25:09 2017 +1000 | ||
1226 | |||
1227 | avoid compiler warning | ||
1228 | |||
1229 | commit 2d75d74272dc2a0521fce13cfe6388800c9a2406 | ||
1230 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1231 | Date: 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 | |||
1239 | commit 151c6e433a5f5af761c78de87d7b5d30a453cf5e | ||
1240 | Author: Damien Miller <djm@mindrot.org> | ||
1241 | Date: 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 | |||
1247 | commit 01e6f78924da308447e71e9a32c8a6104ef4e888 | ||
1248 | Author: Damien Miller <djm@mindrot.org> | ||
1249 | Date: Thu Jun 1 15:16:24 2017 +1000 | ||
1250 | |||
1251 | add *.0 manpage droppings | ||
1252 | |||
1253 | commit 4b2e2d3fd9dccff357e1e26ce9a5f2e103837a36 | ||
1254 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1255 | Date: Thu Jun 1 04:51:58 2017 +0000 | ||
1256 | |||
1257 | upstream commit | ||
1258 | |||
1259 | fix casts re constness | ||
1260 | |||
1261 | Upstream-ID: e38f2bac162b37dbaf784d349c8327a6626fa266 | ||
1262 | |||
1263 | commit 75b8af8de805c0694b37fcf80ce82783b2acc86f | ||
1264 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1265 | Date: 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 | |||
1274 | commit 84008608c9ee944d9f72f5100f31ccff743b10f2 | ||
1275 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1276 | Date: 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 | |||
1284 | commit 9e509d4ec97cb3d71696f1a2f1fdad254cbbce11 | ||
1285 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
1286 | Date: 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 | |||
1297 | commit dc5dc45662773c0f7745c29cf77ae2d52723e55e | ||
1298 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
1299 | Date: 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 | |||
1308 | commit 1e0cdf8efb745d0d1116e1aa22bdc99ee731695e | ||
1309 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1310 | Date: 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 | |||
1318 | commit 92e9fe633130376a95dd533df6e5e6a578c1e6b8 | ||
1319 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1320 | Date: 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 | |||
1328 | commit 17ad5b346043c5bbc5befa864d0dbeb76be39390 | ||
1329 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1330 | Date: 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 | |||
1338 | commit 39896b777320a6574dd06707aebac5fb98e666da | ||
1339 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1340 | Date: 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 | |||
1348 | commit 6116bd4ed354a71a733c8fd0f0467ce612f12911 | ||
1349 | Author: Damien Miller <djm@mindrot.org> | ||
1350 | Date: 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 | |||
1356 | commit d40dbdc85b6fb2fd78485ba02225511b8cbf20d7 | ||
1357 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1358 | Date: 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 | |||
1367 | commit 2a108277f976e8d0955c8b29d1dfde04dcbb3d5b | ||
1368 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1369 | Date: 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 | |||
1377 | commit c04e979503e97f52b750d3b98caa6fe004ab2ab9 | ||
1378 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1379 | Date: 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 | |||
1388 | commit a3bb250c93bfe556838c46ed965066afce61cffa | ||
1389 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
1390 | Date: Tue May 30 19:38:17 2017 +0000 | ||
1391 | |||
1392 | upstream commit | ||
1393 | |||
1394 | tweak previous; | ||
1395 | |||
1396 | Upstream-ID: 66987651046c42d142f7318c9695fb81a6d14031 | ||
1397 | |||
1398 | commit 1112b534a6a7a07190e497e6bf86b0d5c5fb02dc | ||
1399 | Author: bluhm@openbsd.org <bluhm@openbsd.org> | ||
1400 | Date: 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 | |||
1411 | commit eb272ea4099fd6157846f15c129ac5727933aa69 | ||
1412 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1413 | Date: 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 | |||
1421 | commit 5a146bbd4fdf5c571f9fb438e5210d28cead76d9 | ||
1422 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1423 | Date: 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 | |||
1431 | commit 60306b2d2f029f91927c6aa7c8e08068519a0fa2 | ||
1432 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1433 | Date: 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 | |||
1441 | commit eb76698b91338bd798c978d4db2d6af624d185e4 | ||
1442 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1443 | Date: 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 | |||
1451 | commit 2ae666a8fc20b3b871b2f1b90ad65cc027336ccd | ||
1452 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1453 | Date: 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 | |||
1461 | commit 94583beb24a6c5fd19cedb9104ab2d2d5cd052b6 | ||
1462 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1463 | Date: 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 | |||
1471 | commit 5f4082d886c6173b9e90b9768c9a38a3bfd92c2b | ||
1472 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1473 | Date: 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 | |||
1481 | commit 7da5df11ac788bc1133d8d598d298e33500524cc | ||
1482 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1483 | Date: 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 | |||
1491 | commit ff7371afd08ac0bbd957d90451d4dcd0da087ef5 | ||
1492 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1493 | Date: 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 | |||
1502 | commit beb965bbc5a984fa69fb1e2b45ebe766ae09d1ef | ||
1503 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1504 | Date: 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 | |||
1512 | commit 00ed75c92d1f95fe50032835106c368fa22f0f02 | ||
1513 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1514 | Date: 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 | |||
1522 | commit 54d90ace1d3535b44d92a8611952dc109a74a031 | ||
1523 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1524 | Date: 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 | |||
1532 | commit c221219b1fbee47028dcaf66613f4f8d6b7640e9 | ||
1533 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1534 | Date: 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 | |||
1542 | commit afbfa68fa18081ef05a9cd294958509a5d3cda8b | ||
1543 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1544 | Date: 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 | |||
1554 | commit 813f55336a24fdfc45e7ed655fccc7d792e8f859 | ||
1555 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1556 | Date: 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 | |||
1564 | commit 6cf711752cc2a7ffaad1fb4de18cae65715ed8bb | ||
1565 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1566 | Date: 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 | |||
1574 | commit 364f0d5edea27767fb0f915ea7fc61aded88d3e8 | ||
1575 | Author: markus@openbsd.org <markus@openbsd.org> | ||
1576 | Date: 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 | |||
1585 | commit 8ba0fd40082751dbbc23a830433488bbfb1abdca | ||
1586 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1587 | Date: 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 | |||
1596 | commit dcc714c65cfb81eb6903095b4590719e8690f3da | ||
1597 | Author: Mike Frysinger <vapier@chromium.org> | ||
1598 | Date: 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 | |||
1606 | commit 947a3e829a5b8832a4768fd764283709a4ca7955 | ||
1607 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1608 | Date: 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 | |||
1617 | commit 773224802d7cb250bb8b461546fcce10567b4b2e | ||
1618 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1619 | Date: 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 | |||
1631 | commit 54cd41a4663fad66406dd3c8fe0e4760ccd8a899 | ||
1632 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1633 | Date: 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 | |||
1642 | commit 277abcda3f1b08d2376686f0ef20320160d4c8ab | ||
1643 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1644 | Date: 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 | |||
1652 | commit adb47ce839c977fa197e770c1be8f852508d65aa | ||
1653 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1654 | Date: 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 | |||
1663 | commit 6bdf70f01e700348bb4d8c064c31a0ab90896df6 | ||
1664 | Author: Damien Miller <djm@mindrot.org> | ||
1665 | Date: Tue May 9 14:35:03 2017 +1000 | ||
1666 | |||
1667 | clean up regress files and add a .gitignore | ||
1668 | |||
1669 | commit 7bdb2eeb1d3c26acdc409bd94532eefa252e440b | ||
1670 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1671 | Date: 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 | |||
1679 | commit 5f02bb1f99f70bb422be8a5c2b77ef853f1db554 | ||
1680 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1681 | Date: 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 | |||
1690 | commit d757a4b633e8874629a1442c7c2e7b1b55d28c19 | ||
1691 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1692 | Date: 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 | |||
1700 | commit 2e58a69508ac49c02d1bb6057300fa6a76db1045 | ||
1701 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1702 | Date: 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 | |||
1711 | commit effaf526bfa57c0ac9056ca236becf52385ce8af | ||
1712 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1713 | Date: 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 | |||
1721 | commit 7461a5bc571696273252df28a1f1578968cae506 | ||
1722 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1723 | Date: 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 | |||
1732 | commit bd636f40911094a39c2920bf87d2ec340533c152 | ||
1733 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1734 | Date: 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 | |||
1743 | commit 70c1218fc45757a030285051eb4d209403f54785 | ||
1744 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1745 | Date: 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 | |||
1754 | commit acaf34fd823235d549c633c0146ee03ac5956e82 | ||
1755 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1756 | Date: 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 | |||
1765 | commit 3e371bd2124427403971db853fb2e36ce789b6fd | ||
1766 | Author: naddy@openbsd.org <naddy@openbsd.org> | ||
1767 | Date: 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 | |||
1776 | commit 2e9c324b3a7f15c092d118c2ac9490939f6228fd | ||
1777 | Author: naddy@openbsd.org <naddy@openbsd.org> | ||
1778 | Date: 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 | |||
1786 | commit 744bde79c3361e2153cb395a2ecdcee6c713585d | ||
1787 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1788 | Date: 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 | |||
1798 | commit 0c378ff6d98d80bc465a4a6a787670fb9cc701ee | ||
1799 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1800 | Date: 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 | |||
1809 | commit 9a82e24b986e3e0dc70849dbb2c19aa6c707b37f | ||
1810 | Author: naddy@openbsd.org <naddy@openbsd.org> | ||
1811 | Date: 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 | |||
1820 | commit 768405fddf64ff83aa6ef701ebb3c1f82d98a2f3 | ||
1821 | Author: naddy@openbsd.org <naddy@openbsd.org> | ||
1822 | Date: 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 | |||
1830 | commit 1a1b24f8229bf7a21f89df21987433283265527a | ||
1831 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
1832 | Date: 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 | |||
1840 | commit 2b6f799e9b230cf13a7eefc05ecead7d8569d6b5 | ||
1841 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
1842 | Date: 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 | |||
1850 | commit f10c0d32cde2084d2a0b19bc47d80cb93e85a093 | ||
1851 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
1852 | Date: 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 | |||
1860 | commit 42b690b4fd0faef78c4d68225948b6e5c46c5163 | ||
1861 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
1862 | Date: 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 | |||
1871 | commit d852603214defd93e054de2877b20cc79c19d0c6 | ||
1872 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
1873 | Date: 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 | |||
1882 | commit 8b60ce8d8111e604c711c4cdd9579ffe0edced74 | ||
1883 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
1884 | Date: 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 | |||
1892 | commit 3575f0b12afe6b561681582fd3c34067d1196231 | ||
1893 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1894 | Date: 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 | |||
1902 | commit 4f1ca823bad12e4f9614895eefe0d0073b84a28f | ||
1903 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
1904 | Date: 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 | |||
1912 | commit 6b84897f7fd39956b849eac7810319d8a9958568 | ||
1913 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
1914 | Date: 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 | |||
1922 | commit d1c6b7fdbdfe4a7a37ecd48a97f0796b061c2868 | ||
1923 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1924 | Date: 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 | |||
1933 | commit 0f163983016c2988a92e039d18a7569f9ea8e071 | ||
1934 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1935 | Date: 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 | |||
1943 | commit 21ed00a8e26fe8a772bcca782175fafc2b0890ed | ||
1944 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1945 | Date: 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 | |||
1956 | commit d29ba6f45086703fdcb894532848ada3427dfde6 | ||
1957 | Author: Darren Tucker <dtucker@zip.com.au> | ||
1958 | Date: Mon May 1 13:53:07 2017 +1000 | ||
1959 | |||
1960 | Define INT32_MAX and INT64_MAX if needed. | ||
1961 | |||
1962 | commit 329037e389f02ec95c8e16bf93ffede94d3d44ce | ||
1963 | Author: Darren Tucker <dtucker@zip.com.au> | ||
1964 | Date: Mon May 1 13:19:41 2017 +1000 | ||
1965 | |||
1966 | Wrap stdint.h in HAVE_STDINT_H | ||
1967 | |||
1968 | commit f382362e8dfb6b277f16779ab1936399d7f2af78 | ||
1969 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1970 | Date: Mon May 1 02:27:11 2017 +0000 | ||
1971 | |||
1972 | upstream commit | ||
1973 | |||
1974 | remove unused variable | ||
1975 | |||
1976 | Upstream-ID: 66011f00819d0e71b14700449a98414033284516 | ||
1977 | |||
1978 | commit dd369320d2435b630a5974ab270d686dcd92d024 | ||
1979 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1980 | Date: 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 | |||
1989 | commit 557f921aad004be15805e09fd9572969eb3d9321 | ||
1990 | Author: djm@openbsd.org <djm@openbsd.org> | ||
1991 | Date: 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 | |||
1999 | commit e77e1562716fb3da413e4c2397811017b762f5e3 | ||
2000 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2001 | Date: 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 | |||
2010 | commit f7849e6c83a4e0f602dea6c834a24091c622d68e | ||
2011 | Author: Damien Miller <djm@mindrot.org> | ||
2012 | Date: Mon May 1 09:55:56 2017 +1000 | ||
2013 | |||
2014 | remove configure --with-ssh1 | ||
2015 | |||
2016 | commit f4a6a88ddb6dba6d2f7bfb9e2c9879fcc9633043 | ||
2017 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2018 | Date: 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 | |||
2029 | commit 930e8d2827853bc2e196c20c3e000263cc87fb75 | ||
2030 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2031 | Date: 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 | |||
2041 | commit a3710d5d529a34b8f56aa62db798c70e85d576a0 | ||
2042 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2043 | Date: 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 | |||
2053 | commit aebd0abfaa8a41e75d50f9f7934267b0a2d9acb4 | ||
2054 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2055 | Date: 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 | |||
2066 | commit dfa641f758d4b8b2608ab1b00abaf88df0a8e36a | ||
2067 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2068 | Date: 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 | |||
2081 | commit e5d3bd36ef67d82092861f39b5bf422cb12b31a6 | ||
2082 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2083 | Date: 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 | |||
2092 | commit 3d6d09f2e90f4ad650ebda6520bf2da446f37f14 | ||
2093 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2094 | Date: 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 | |||
2104 | commit 05164358577c82de18ed7373196bc7dbd8a3f79c | ||
2105 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2106 | Date: 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 | |||
2114 | commit 873d3e7d9a4707d0934fb4c4299354418f91b541 | ||
2115 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2116 | Date: 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 | |||
2126 | commit 788ac799a6efa40517f2ac0d895a610394298ffc | ||
2127 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2128 | Date: 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 | |||
2138 | commit e6882463a8ae0594aacb6d6575a6318a41973d84 | ||
2139 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2140 | Date: 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 | |||
2148 | commit cdccebdf85204bf7542b7fcc1aa2ea3f36661833 | ||
2149 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2150 | Date: 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 | |||
2158 | commit 97f4d3083b036ce3e68d6346a6140a22123d5864 | ||
2159 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2160 | Date: 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 | |||
2170 | commit 99f95ba82673d33215dce17bfa1512b57f54ec09 | ||
2171 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2172 | Date: 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 | |||
2183 | commit 56912dea6ef63dae4eb1194e5d88973a7c6c5740 | ||
2184 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2185 | Date: 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 | |||
2193 | commit d4084cd230f7319056559b00db8b99296dad49d5 | ||
2194 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
2195 | Date: Sat Apr 29 06:06:01 2017 +0000 | ||
2196 | |||
2197 | upstream commit | ||
2198 | |||
2199 | tweak previous; | ||
2200 | |||
2201 | Upstream-ID: a3abc6857455299aa42a046d232b7984568bceb9 | ||
2202 | |||
2203 | commit 249516e428e8461b46340a5df5d5ed1fbad2ccce | ||
2204 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2205 | Date: 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 | |||
2214 | commit 47a287bb6ac936c26b4f3ae63279c02902ded3b9 | ||
2215 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
2216 | Date: Fri Apr 28 06:15:03 2017 +0000 | ||
2217 | |||
2218 | upstream commit | ||
2219 | |||
2220 | sort; | ||
2221 | |||
2222 | Upstream-ID: 7e6b56e52b039cf44d0418e9de9aca20a2d2d15a | ||
2223 | |||
2224 | commit 36465a76a79ad5040800711b41cf5f32249d5120 | ||
2225 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2226 | Date: Fri Apr 28 14:44:28 2017 +1000 | ||
2227 | |||
2228 | Typo. | ||
2229 | |||
2230 | Upstream-Regress-ID: 1e6b51ddf767cbad0a4e63eb08026c127e654308 | ||
2231 | |||
2232 | commit 9d18cb7bdeb00b20205fd13d412aae8c0e0457ed | ||
2233 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2234 | Date: 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 | |||
2241 | commit 9504ea6b27f9f0ece64e88582ebb9235e664a100 | ||
2242 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2243 | Date: 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 | |||
2250 | commit 06ec837a34542627e2183a412d6a9d2236f22140 | ||
2251 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2252 | Date: 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 | |||
2256 | commit e0194b471efe7d3daedc9cc66686cb1ab69d3be8 | ||
2257 | Author: jsg@openbsd.org <jsg@openbsd.org> | ||
2258 | Date: 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 | |||
2268 | commit 6830be90e71f46bcd182a9202b151eaf2b299434 | ||
2269 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2270 | Date: 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 | |||
2279 | commit 066437187e16dcafcbc19f9402ef0e6575899b1d | ||
2280 | Author: millert@openbsd.org <millert@openbsd.org> | ||
2281 | Date: 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 | |||
2291 | commit 68d3a2a059183ebd83b15e54984ffaced04d2742 | ||
2292 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
2293 | Date: 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 | |||
2303 | commit e13aad66e73a14b062d13aee4e98f1e21a3f6a14 | ||
2304 | Author: jsg@openbsd.org <jsg@openbsd.org> | ||
2305 | Date: 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 | |||
2314 | commit 91bd2181866659f00714903e78e1c3edd4c45f3d | ||
2315 | Author: millert@openbsd.org <millert@openbsd.org> | ||
2316 | Date: 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 | |||
2325 | commit 17a54a03f5a1d35e33cc24e22cd7a9d0f6865dc4 | ||
2326 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2327 | Date: Tue Apr 25 08:32:27 2017 +1000 | ||
2328 | |||
2329 | Fix typo in "socketcall". | ||
2330 | |||
2331 | Pointed out by jjelen at redhat.com. | ||
2332 | |||
2333 | commit 8b0eee148f7cf8b248c30d1bae57300f2cc5aafd | ||
2334 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2335 | Date: 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 | |||
2347 | commit f8500b2be599053daa05248a86a743232ec6a536 | ||
2348 | Author: schwarze@openbsd.org <schwarze@openbsd.org> | ||
2349 | Date: 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 | |||
2360 | commit 7480dfedf8c5c93baaabef444b3def9331e86ad5 | ||
2361 | Author: jsg@openbsd.org <jsg@openbsd.org> | ||
2362 | Date: 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 | |||
2372 | commit 4d827f0d75a53d3952288ab882efbddea7ffadfe | ||
2373 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2374 | Date: 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 | |||
2383 | commit ef47843af0a904a21c920e619c5aec97b65dd9ac | ||
2384 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
2385 | Date: 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 | |||
2393 | commit d9048861bea842c4eba9c2dbbf97064cc2a5ef02 | ||
2394 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2395 | Date: 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 | |||
2401 | commit 282cad2240c4fbc104c2f2df86d688192cbbe4bb | ||
2402 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2403 | Date: 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 | |||
2411 | commit c73a229e4edf98920f395e19fd310684fc6bb951 | ||
2412 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2413 | Date: 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 | |||
2420 | commit d427b73bf5a564f663d16546dbcbd84ba8b9d4af | ||
2421 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2422 | Date: 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 | |||
2429 | commit d13281f2964abc5f2e535e1613c77fc61b0c53e7 | ||
2430 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2431 | Date: 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 | |||
2441 | commit f2742a481fe151e493765a3fbdef200df2ea7037 | ||
2442 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2443 | Date: 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 | |||
2450 | commit 5346f271fc76549caf4a8e65b5fba319be422fe9 | ||
2451 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2452 | Date: 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 | |||
2459 | commit 8fed0a5fe7b4e78a6810b133d8e91be9742ee0a1 | ||
2460 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2461 | Date: 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 | |||
2467 | commit 608ec1f62ff22fdccc3952e51463d79c43cbd0d3 | ||
2468 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2469 | Date: 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 | |||
2476 | commit 7af27bf538cbc493d609753f9a6d43168d438f1b | ||
2477 | Author: Darren Tucker <dtucker@zip.com.au> | ||
2478 | Date: 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 | |||
2485 | commit 58b8cfa2a062b72139d7229ae8de567f55776f24 | ||
2486 | Author: Damien Miller <djm@mindrot.org> | ||
2487 | Date: Wed Mar 22 12:43:02 2017 +1100 | ||
2488 | |||
2489 | Missing header on Linux/s390 | ||
2490 | |||
2491 | Patch from Jakub Jelen | ||
2492 | |||
2493 | commit 096fb65084593f9f3c1fc91b6d9052759a272a00 | ||
2494 | Author: djm@openbsd.org <djm@openbsd.org> | ||
2495 | Date: 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 | |||
2504 | commit 6b853c6f8ba5eecc50f3b57af8e63f8184eb0fa6 | ||
2505 | Author: Damien Miller <djm@mindrot.org> | ||
2506 | Date: Tue Mar 21 08:47:55 2017 +1100 | ||
2507 | |||
2508 | Fix syntax error on Linux/X32 | ||
2509 | |||
2510 | Patch from Mike Frysinger | ||
2511 | |||
1 | commit d38f05dbdd291212bc95ea80648b72b7177e9f4e | 2512 | commit d38f05dbdd291212bc95ea80648b72b7177e9f4e |
2 | Author: Darren Tucker <dtucker@zip.com.au> | 2513 | Author: Darren Tucker <dtucker@zip.com.au> |
3 | Date: Mon Mar 20 13:38:27 2017 +1100 | 2514 | Date: 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 | |||
6842 | commit 8408218c1ca88cb17d15278174a24a94a6f65fe1 | ||
6843 | Author: djm@openbsd.org <djm@openbsd.org> | ||
6844 | Date: 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 | |||
6853 | commit 0097248f90a00865082e8c146b905a6555cc146f | ||
6854 | Author: djm@openbsd.org <djm@openbsd.org> | ||
6855 | Date: 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 | |||
6864 | commit 9c06c814aff925e11a5cc592c06929c258a014f6 | ||
6865 | Author: djm@openbsd.org <djm@openbsd.org> | ||
6866 | Date: 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 | |||
6875 | commit 3c019a936b43f3e2773f3edbde7c114d73caaa4c | ||
6876 | Author: tim@openbsd.org <tim@openbsd.org> | ||
6877 | Date: 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 | |||
6889 | commit 2681cdb6e0de7c1af549dac37a9531af202b4434 | ||
6890 | Author: tim@openbsd.org <tim@openbsd.org> | ||
6891 | Date: 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 | |||
6902 | commit 14692f7b8251cdda847e648a82735eef8a4d2a33 | ||
6903 | Author: guenther@openbsd.org <guenther@openbsd.org> | ||
6904 | Date: 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 | |||
6915 | commit 846f6fa4cfa8483a9195971dbdd162220f199d85 | ||
6916 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
6917 | Date: 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 | |||
6927 | commit 95923e0520a8647417ee6dcdff44694703dfeef0 | ||
6928 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
6929 | Date: Fri Sep 11 06:51:39 2015 +0000 | ||
6930 | |||
6931 | upstream commit | ||
6932 | |||
6933 | tweak previous; | ||
6934 | |||
6935 | Upstream-ID: f29b3cfcfd9aa31fa140c393e7bd48c1c74139d6 | ||
6936 | |||
6937 | commit 86ac462f833b05d8ed9de9c50ccb295d7faa79ff | ||
6938 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
6939 | Date: 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 | |||
6947 | commit 674b3b68c1d36b2562324927cd03857b565e05e8 | ||
6948 | Author: djm@openbsd.org <djm@openbsd.org> | ||
6949 | Date: 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 | |||
6959 | commit c0f55db7ee00c8202b05cb4b9ad4ce72cc45df41 | ||
6960 | Author: djm@openbsd.org <djm@openbsd.org> | ||
6961 | Date: 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 | |||
6970 | commit cfffbdb10fdf0f02d3f4232232eef7ec3876c383 | ||
6971 | Author: Darren Tucker <dtucker@zip.com.au> | ||
6972 | Date: 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 | |||
6980 | commit 366bada1e9e124654aac55b72b6ccf878755b0dc | ||
6981 | Author: Darren Tucker <dtucker@zip.com.au> | ||
6982 | Date: 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 | |||
6988 | commit 2bca8a43e7dd9b04d7070824ffebb823c72587b2 | ||
6989 | Author: djm@openbsd.org <djm@openbsd.org> | ||
6990 | Date: 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 | |||
6999 | commit 61942ea4a01e6db4fdf37ad61de81312ffe310e9 | ||
7000 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7001 | Date: 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 | |||
7011 | commit 4f7cc2f8cc861a21e6dbd7f6c25652afb38b9b96 | ||
7012 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
7013 | Date: 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 | |||
7022 | commit 7ad8b287c8453a3e61dbc0d34d467632b8b06fc8 | ||
7023 | Author: Darren Tucker <dtucker@zip.com.au> | ||
7024 | Date: 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 | |||
7030 | commit 26ad18247213ff72b4438abe7fc660c958810fa2 | ||
7031 | Author: Damien Miller <djm@mindrot.org> | ||
7032 | Date: Thu Sep 10 10:57:41 2015 +1000 | ||
7033 | |||
7034 | allow getrandom syscall; from Felix von Leitner | ||
7035 | |||
7036 | commit 5245bc1e6b129a10a928f73f11c3aa32656c44b4 | ||
7037 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
7038 | Date: 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 | |||
7046 | commit a85768a9321d74b41219eeb3c9be9f1702cbf6a5 | ||
7047 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7048 | Date: 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 | |||
7057 | commit 46152af8d27aa34d5d26ed1c371dc8aa142d4730 | ||
7058 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7059 | Date: 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 | |||
7067 | commit a954cdb799a4d83c2d40fbf3e7b9f187fbfd72fc | ||
7068 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7069 | Date: 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 | |||
7078 | commit f54d8ac2474b6fc3afa081cf759b48a6c89d3319 | ||
7079 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7080 | Date: 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 | |||
7089 | commit ac3451dd65f27ecf85dc045c46d49e2bbcb8dddd | ||
7090 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7091 | Date: 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 | |||
7100 | commit 9e3ed9ebb1a7e47c155c28399ddf09b306ea05df | ||
7101 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7102 | Date: 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 | |||
7110 | commit f3a3ea180afff080bab82087ee0b60db9fd84f6c | ||
7111 | Author: jsg@openbsd.org <jsg@openbsd.org> | ||
7112 | Date: 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 | |||
7123 | commit f498a98cf83feeb7ea01c15cd1c98b3111361f3a | ||
7124 | Author: Damien Miller <djm@mindrot.org> | ||
7125 | Date: Thu Sep 3 09:11:22 2015 +1000 | ||
7126 | |||
7127 | don't check for yp_match; ok tim@ | ||
7128 | |||
7129 | commit 9690b78b7848b0b376980a61d51b1613e187ddb5 | ||
7130 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7131 | Date: 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 | |||
7142 | commit 60a92470e21340e1a3fc10f9c7140d8e1519dc55 | ||
7143 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7144 | Date: 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 | |||
7153 | commit 6310f60fffca2d1e464168e7d1f7e3b6b0268897 | ||
7154 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7155 | Date: 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 | |||
7165 | commit e774e5ea56237fd626a8161f9005023dff3e76c9 | ||
7166 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
7167 | Date: 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 | |||
7176 | commit 189de02d9ad6f3645417c0ddf359b923aae5f926 | ||
7177 | Author: Damien Miller <djm@mindrot.org> | ||
7178 | Date: Fri Aug 21 15:45:02 2015 +1000 | ||
7179 | |||
7180 | expose POLLHUP and POLLNVAL for netcat.c | ||
7181 | |||
7182 | commit e91346dc2bbf460246df2ab591b7613908c1b0ad | ||
7183 | Author: Damien Miller <djm@mindrot.org> | ||
7184 | Date: Fri Aug 21 14:49:03 2015 +1000 | ||
7185 | |||
7186 | we don't use Github for issues/pull-requests | ||
7187 | |||
7188 | commit a4f5b507c708cc3dc2c8dd2d02e4416d7514dc23 | ||
7189 | Author: Damien Miller <djm@mindrot.org> | ||
7190 | Date: Fri Aug 21 14:43:55 2015 +1000 | ||
7191 | |||
7192 | fix URL for connect.c | ||
7193 | |||
7194 | commit d026a8d3da0f8186598442997c7d0a28e7275414 | ||
7195 | Author: Damien Miller <djm@mindrot.org> | ||
7196 | Date: Fri Aug 21 13:47:10 2015 +1000 | ||
7197 | |||
7198 | update version numbers for 7.1 | ||
7199 | |||
7200 | commit 78f8f589f0ca1c9f41e5a9bae3cda5ce8a6b42ed | ||
7201 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7202 | Date: Fri Aug 21 03:45:26 2015 +0000 | ||
7203 | |||
7204 | upstream commit | ||
7205 | |||
7206 | openssh-7.1 | ||
7207 | |||
7208 | Upstream-ID: ff7b1ef4b06caddfb45e08ba998128c88be3d73f | ||
7209 | |||
7210 | commit 32a181980c62fce94f7f9ffaf6a79d90f0c309cf | ||
7211 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7212 | Date: 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 | |||
7221 | commit ce445b0ed927e45bd5bdce8f836eb353998dd65c | ||
7222 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
7223 | Date: 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 | |||
7232 | commit 05291e5288704d1a98bacda269eb5a0153599146 | ||
7233 | Author: naddy@openbsd.org <naddy@openbsd.org> | ||
7234 | Date: 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 | |||
7243 | commit 8543d4ef6f2e9f98c3e6b77c894ceec30c5e4ae4 | ||
7244 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7245 | Date: 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 | |||
7254 | commit ec6eda16ebab771aa3dfc90629b41953b999cb1e | ||
7255 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7256 | Date: 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 | |||
7265 | commit 45b0eb752c94954a6de046bfaaf129e518ad4b5b | ||
7266 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7267 | Date: 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 | |||
7276 | commit c837643b93509a3ef538cb6624b678c5fe32ff79 | ||
7277 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7278 | Date: 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 | |||
7287 | commit 1f8d3d629cd553031021068eb9c646a5f1e50994 | ||
7288 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
7289 | Date: 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 | |||
7300 | commit 1dc8d93ce69d6565747eb44446ed117187621b26 | ||
7301 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
7302 | Date: 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 | |||
7313 | commit 90a95a4745a531b62b81ce3b025e892bdc434de5 | ||
7314 | Author: Damien Miller <djm@mindrot.org> | ||
7315 | Date: Tue Aug 11 13:53:41 2015 +1000 | ||
7316 | |||
7317 | update version in README | ||
7318 | |||
7319 | commit 318c37743534b58124f1bab37a8a0087a3a9bd2f | ||
7320 | Author: Damien Miller <djm@mindrot.org> | ||
7321 | Date: Tue Aug 11 13:53:09 2015 +1000 | ||
7322 | |||
7323 | update versions in *.spec | ||
7324 | |||
7325 | commit 5e75f5198769056089fb06c4d738ab0e5abc66f7 | ||
7326 | Author: Damien Miller <djm@mindrot.org> | ||
7327 | Date: 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 | |||
7334 | commit d4697fe9a28dab7255c60433e4dd23cf7fce8a8b | ||
7335 | Author: Damien Miller <djm@mindrot.org> | ||
7336 | Date: 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 | |||
7342 | commit 88763a6c893bf3dfe951ba9271bf09715e8d91ca | ||
7343 | Author: Darren Tucker <dtucker@zip.com.au> | ||
7344 | Date: Mon Jul 27 12:14:25 2015 +1000 | ||
7345 | |||
7346 | Import updated moduli file from OpenBSD. | ||
7347 | |||
7348 | commit 55b263fb7cfeacb81aaf1c2036e0394c881637da | ||
7349 | Author: Damien Miller <djm@mindrot.org> | ||
7350 | Date: Mon Aug 10 11:13:44 2015 +1000 | ||
7351 | |||
7352 | let principals-command.sh work for noexec /var/run | ||
7353 | |||
7354 | commit 2651e34cd11b1aac3a0fe23b86d8c2ff35c07897 | ||
7355 | Author: Damien Miller <djm@mindrot.org> | ||
7356 | Date: Thu Aug 6 11:43:42 2015 +1000 | ||
7357 | |||
7358 | work around echo -n / sed behaviour in tests | ||
7359 | |||
7360 | commit d85dad81778c1aa8106acd46930b25fdf0d15b2a | ||
7361 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7362 | Date: 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 | |||
7370 | commit 57e8e229bad5fe6056b5f1199665f5f7008192c6 | ||
7371 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7372 | Date: 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 | |||
7381 | commit f097d0ea1e0889ca0fa2e53a00214e43ab7fa22a | ||
7382 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7383 | Date: 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 | |||
7391 | commit 3d5728a0f6874ce4efb16913a12963595070f3a9 | ||
7392 | Author: chris@openbsd.org <chris@openbsd.org> | ||
7393 | Date: 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 | |||
7403 | commit 6f941396b6835ad18018845f515b0c4fe20be21a | ||
7404 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7405 | Date: 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 | |||
7414 | commit f4373ed1e8fbc7c8ce3fc4ea97d0ba2e0c1d7ef0 | ||
7415 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
7416 | Date: 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 | |||
7425 | commit 0c30ba91f87fcda7e975e6ff8a057f624e87ea1c | ||
7426 | Author: Damien Miller <djm@mindrot.org> | ||
7427 | Date: Thu Jul 30 12:31:39 2015 +1000 | ||
7428 | |||
7429 | downgrade OOM adjustment logging: verbose -> debug | ||
7430 | |||
7431 | commit f9eca249d4961f28ae4b09186d7dc91de74b5895 | ||
7432 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7433 | Date: 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 | |||
7445 | commit 5cefe769105a2a2e3ca7479d28d9a325d5ef0163 | ||
7446 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7447 | Date: 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 | |||
7456 | commit f319912b0d0e1675b8bb051ed8213792c788bcb2 | ||
7457 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7458 | Date: 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 | |||
7467 | commit b6ea0e573042eb85d84defb19227c89eb74cf05a | ||
7468 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7469 | Date: 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 | |||
7478 | commit 3f628c7b537291c1019ce86af90756fb4e66d0fd | ||
7479 | Author: guenther@openbsd.org <guenther@openbsd.org> | ||
7480 | Date: 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 | |||
7491 | commit ebe27ebe520098bbc0fe58945a87ce8490121edb | ||
7492 | Author: millert@openbsd.org <millert@openbsd.org> | ||
7493 | Date: 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 | |||
7502 | commit d5d91d0da819611167782c66ab629159169d94d4 | ||
7503 | Author: millert@openbsd.org <millert@openbsd.org> | ||
7504 | Date: Mon Jul 20 18:42:35 2015 +0000 | ||
7505 | |||
7506 | upstream commit | ||
7507 | |||
7508 | Sync usage with SYNOPSIS | ||
7509 | |||
7510 | Upstream-ID: 7a321a170181a54f6450deabaccb6ef60cf3f0b7 | ||
7511 | |||
7512 | commit 79ec2142fbc68dd2ed9688608da355fc0b1ed743 | ||
7513 | Author: millert@openbsd.org <millert@openbsd.org> | ||
7514 | Date: 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 | |||
7523 | commit d56fd1828074a4031b18b8faa0bf949669eb18a0 | ||
7524 | Author: Damien Miller <djm@mindrot.org> | ||
7525 | Date: Mon Jul 20 11:19:51 2015 +1000 | ||
7526 | |||
7527 | make realpath.c compile -Wsign-compare clean | ||
7528 | |||
7529 | commit c63c9a691dca26bb7648827f5a13668832948929 | ||
7530 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7531 | Date: 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 | |||
7541 | commit 63ebcd0005e9894fcd6871b7b80aeea1fec0ff76 | ||
7542 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7543 | Date: 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 | |||
7552 | commit b15fd989c8c62074397160147a8d5bc34b3f3c63 | ||
7553 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7554 | Date: 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 | |||
7563 | commit 5b64f85bb811246c59ebab70aed331f26ba37b18 | ||
7564 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7565 | Date: 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 | |||
7574 | commit cd7324d0667794eb5c236d8a4e0f236251babc2d | ||
7575 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7576 | Date: 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 | |||
7585 | commit deb8d99ecba70b67f4af7880b11ca8768df9ec3a | ||
7586 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7587 | Date: 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 | |||
7598 | commit 356b61f365405b5257f5b2ab446e5d7bd33a7b52 | ||
7599 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7600 | Date: 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 | |||
7609 | commit d3e2aee41487d55b8d7d40f538b84ff1db7989bc | ||
7610 | Author: Darren Tucker <dtucker@zip.com.au> | ||
7611 | Date: 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 | |||
7626 | commit 25b14610dab655646a109db5ef8cb4c4bf2a48a0 | ||
7627 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7628 | Date: 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 | |||
7637 | commit df56a8035d429b2184ee94aaa7e580c1ff67f73a | ||
7638 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7639 | Date: 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 | |||
7647 | commit 41e38c4d49dd60908484e6703316651333f16b93 | ||
7648 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7649 | Date: 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 | |||
7658 | commit 5bf0933184cb622ca3f96d224bf3299fd2285acc | ||
7659 | Author: markus@openbsd.org <markus@openbsd.org> | ||
7660 | Date: 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 | |||
7669 | commit 7a6e3fd7b41dbd3756b6bf9acd67954c0b1564cc | ||
7670 | Author: markus@openbsd.org <markus@openbsd.org> | ||
7671 | Date: 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 | |||
7679 | commit 7c8c174c69f681d4910fa41c37646763692b28e2 | ||
7680 | Author: markus@openbsd.org <markus@openbsd.org> | ||
7681 | Date: 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 | |||
7689 | commit 6a977a4b68747ade189e43d302f33403fd4a47ac | ||
7690 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7691 | Date: 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 | |||
7700 | commit 0c4123ad5e93fb90fee9c6635b13a6cdabaac385 | ||
7701 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7702 | Date: 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 | |||
7710 | commit 3c099845798a817cdde513c39074ec2063781f18 | ||
7711 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7712 | Date: 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 | |||
7720 | commit b1dc2b33689668c75e95f873a42d5aea1f4af1db | ||
7721 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
7722 | Date: 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 | |||
7734 | commit 3a1638dda19bbc73d0ae02b4c251ce08e564b4b9 | ||
7735 | Author: markus@openbsd.org <markus@openbsd.org> | ||
7736 | Date: 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 | |||
7746 | commit 16db0a7ee9a87945cc594d13863cfcb86038db59 | ||
7747 | Author: markus@openbsd.org <markus@openbsd.org> | ||
7748 | Date: 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 | |||
7756 | commit c355bf306ac33de6545ce9dac22b84a194601e2f | ||
7757 | Author: markus@openbsd.org <markus@openbsd.org> | ||
7758 | Date: 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 | |||
7766 | commit a3cc48cdf9853f1e832d78cb29bedfab7adce1ee | ||
7767 | Author: markus@openbsd.org <markus@openbsd.org> | ||
7768 | Date: 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 | |||
7776 | commit a635bd06b5c427a57c3ae760d3a2730bb2c863c0 | ||
7777 | Author: markus@openbsd.org <markus@openbsd.org> | ||
7778 | Date: Wed Jul 8 19:04:21 2015 +0000 | ||
7779 | |||
7780 | upstream commit | ||
7781 | |||
7782 | xmalloc.h is unused | ||
7783 | |||
7784 | Upstream-ID: afb532355b7fa7135a60d944ca1e644d1d63cb58 | ||
7785 | |||
7786 | commit 2521cf0e36c7f3f6b19f206da0af134f535e4a31 | ||
7787 | Author: markus@openbsd.org <markus@openbsd.org> | ||
7788 | Date: Wed Jul 8 19:01:15 2015 +0000 | ||
7789 | |||
7790 | upstream commit | ||
7791 | |||
7792 | compress.c is gone | ||
7793 | |||
7794 | Upstream-ID: 174fa7faa9b9643cba06164b5e498591356fbced | ||
7795 | |||
7796 | commit c65a7aa6c43aa7a308ee1ab8a96f216169ae9615 | ||
7797 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7798 | Date: 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 | |||
7807 | commit b1f383da5cd3cb921fc7776f17a14f44b8a31757 | ||
7808 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7809 | Date: 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 | |||
7818 | commit 933935ce8d093996c34d7efa4d59113163080680 | ||
7819 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7820 | Date: 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 | |||
7829 | commit bdfd29f60b74f3e678297269dc6247a5699583c1 | ||
7830 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7831 | Date: 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 | |||
7841 | commit c28fc62d789d860c75e23a9fa9fb250eb2beca57 | ||
7842 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7843 | Date: 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 | |||
7852 | commit 564d63e1b4a9637a209d42a9d49646781fc9caef | ||
7853 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7854 | Date: 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 | |||
7862 | commit 868109b650504dd9bcccdb1f51d0906f967c20ff | ||
7863 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7864 | Date: Wed Jul 1 02:39:06 2015 +0000 | ||
7865 | |||
7866 | upstream commit | ||
7867 | |||
7868 | twiddle PermitRootLogin back | ||
7869 | |||
7870 | Upstream-ID: 2bd23976305d0512e9f84d054e1fc23cd70b89f2 | ||
7871 | |||
7872 | commit 7de4b03a6e4071d454b72927ffaf52949fa34545 | ||
7873 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7874 | Date: 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 | |||
7882 | commit 1bf477d3cdf1a864646d59820878783d42357a1d | ||
7883 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7884 | Date: 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 | |||
7893 | commit 47aa7a0f8551b471fcae0447c1d78464f6dba869 | ||
7894 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7895 | Date: 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 | |||
7903 | commit 984b064fe2a23733733262f88d2e1b2a1a501662 | ||
7904 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7905 | Date: Wed Jul 1 01:55:13 2015 +0000 | ||
7906 | |||
7907 | upstream commit | ||
7908 | |||
7909 | openssh-6.9 | ||
7910 | |||
7911 | Upstream-ID: 6cfe8e1904812531080e6ab6e752d7001b5b2d45 | ||
7912 | |||
7913 | commit d921082ed670f516652eeba50705e1e9f6325346 | ||
7914 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7915 | Date: 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 | |||
7924 | commit 66295e0e1ba860e527f191b6325d2d77dec4dbce | ||
7925 | Author: Damien Miller <djm@mindrot.org> | ||
7926 | Date: Wed Jul 1 11:49:12 2015 +1000 | ||
7927 | |||
7928 | crank version numbers for release | ||
7929 | |||
7930 | commit 37035c07d4f26bb1fbe000d2acf78efdb008681d | ||
7931 | Author: Damien Miller <djm@mindrot.org> | ||
7932 | Date: Wed Jul 1 10:49:37 2015 +1000 | ||
7933 | |||
7934 | s/--with-ssh1/--without-ssh1/ | ||
7935 | |||
7936 | commit 629df770dbadc2accfbe1c81b3f31f876d0acd84 | ||
7937 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7938 | Date: 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 | |||
7947 | commit f715afebe735d61df3fd30ad72d9ac1c8bd3b5f2 | ||
7948 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7949 | Date: 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 | |||
7959 | commit 52fb6b9b034fcfd24bf88cc7be313e9c31de9889 | ||
7960 | Author: Damien Miller <djm@mindrot.org> | ||
7961 | Date: Tue Jun 30 16:05:40 2015 +1000 | ||
7962 | |||
7963 | skip IPv6-related portions on hosts without IPv6 | ||
7964 | |||
7965 | with Tim Rice | ||
7966 | |||
7967 | commit 512caddf590857af6aa12218461b5c0441028cf5 | ||
7968 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7969 | Date: 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 | |||
7979 | commit 78c2a4f883ea9aba866358e2acd9793a7f42ca93 | ||
7980 | Author: djm@openbsd.org <djm@openbsd.org> | ||
7981 | Date: 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 | |||
7992 | commit bc20205c91c9920361d12b15d253d4997dba494a | ||
7993 | Author: Damien Miller <djm@mindrot.org> | ||
7994 | Date: Thu Jun 25 09:51:39 2015 +1000 | ||
7995 | |||
7996 | add missing pselect6 | ||
7997 | |||
7998 | patch from Jakub Jelen | ||
7999 | |||
8000 | commit 9d27fb73b4a4e5e99cb880af790d5b1ce44f720a | ||
8001 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8002 | Date: 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 | |||
8010 | commit 7ed01a96a1911d8b4a9ef4f3d064e1923bfad7e3 | ||
8011 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8012 | Date: 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 | |||
8024 | commit 882f8bf94f79528caa65b0ba71c185d705bb7195 | ||
8025 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8026 | Date: 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 | |||
8038 | commit 9488538a726951e82b3a4374f3c558d72c80a89b | ||
8039 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8040 | Date: 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 | |||
8050 | commit 63b78d003bd8ca111a736e6cea6333da50f5f09b | ||
8051 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8052 | Date: 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 | |||
8062 | commit 5c15e22c691c79a47747bcf5490126656f97cecd | ||
8063 | Author: Damien Miller <djm@mindrot.org> | ||
8064 | Date: Thu Jun 18 15:07:56 2015 +1000 | ||
8065 | |||
8066 | fix syntax error | ||
8067 | |||
8068 | commit 596dbca82f3f567fb3d2d69af4b4e1d3ba1e6403 | ||
8069 | Author: jsing@openbsd.org <jsing@openbsd.org> | ||
8070 | Date: 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 | |||
8086 | commit aff3e94c0d75d0d0fa84ea392b50ab04f8c57905 | ||
8087 | Author: jsing@openbsd.org <jsing@openbsd.org> | ||
8088 | Date: 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 | |||
8102 | commit 97e2e1596c202a4693468378b16b2353fd2d6c5e | ||
8103 | Author: Damien Miller <djm@mindrot.org> | ||
8104 | Date: 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 | |||
8112 | commit 99f33d7304893bd9fa04d227cb6e870171cded19 | ||
8113 | Author: Damien Miller <djm@mindrot.org> | ||
8114 | Date: 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 | |||
8121 | commit 4ef702e1244633c1025ec7cfe044b9ab267097bf | ||
8122 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8123 | Date: 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 | |||
8131 | commit a170f22baf18af0b1acf2788b8b715605f41a1f9 | ||
8132 | Author: Tim Rice <tim@multitalents.net> | ||
8133 | Date: Tue Jun 9 22:41:13 2015 -0700 | ||
8134 | |||
8135 | Fix t12 rules for out of tree builds. | ||
8136 | |||
8137 | commit ec04dc4a5515c913121bc04ed261857e68fa5c18 | ||
8138 | Author: millert@openbsd.org <millert@openbsd.org> | ||
8139 | Date: 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 | |||
8149 | commit 732d61f417a6aea0aa5308b59cb0f563bcd6edd6 | ||
8150 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8151 | Date: 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 | |||
8159 | commit adfb24c69d1b6f5e758db200866c711e25a2ba73 | ||
8160 | Author: Darren Tucker <dtucker@zip.com.au> | ||
8161 | Date: 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 | |||
8168 | commit a1195a0fdc9eddddb04d3e9e44c4775431cb77da | ||
8169 | Merge: 6397eed d2480bc | ||
8170 | Author: Tim Rice <tim@multitalents.net> | ||
8171 | Date: Wed Jun 3 21:43:13 2015 -0700 | ||
8172 | |||
8173 | Merge branch 'master' of git.mindrot.org:/var/git/openssh | ||
8174 | |||
8175 | commit 6397eedf953b2b973d2d7cbb504ab501a07f8ddc | ||
8176 | Author: Tim Rice <tim@multitalents.net> | ||
8177 | Date: Wed Jun 3 21:41:11 2015 -0700 | ||
8178 | |||
8179 | Remove unneeded backslashes. Patch from Ángel González | ||
8180 | |||
8181 | commit d2480bcac1caf31b03068de877a47d6e1027bf6d | ||
8182 | Author: Darren Tucker <dtucker@zip.com.au> | ||
8183 | Date: Thu Jun 4 14:10:55 2015 +1000 | ||
8184 | |||
8185 | Remove redundant include of stdarg.h. bz#2410 | ||
8186 | |||
8187 | commit 5e67859a623826ccdf2df284cbb37e2d8e2787eb | ||
8188 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8189 | Date: 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 | |||
8198 | commit d7a58bbac6583e33fd5eca8e2c2cc70c57617818 | ||
8199 | Author: Darren Tucker <dtucker@zip.com.au> | ||
8200 | Date: Tue Jun 2 20:15:26 2015 +1000 | ||
8201 | |||
8202 | Replace strcpy with strlcpy. | ||
8203 | |||
8204 | ok djm, sanity check by Corinna Vinschen. | ||
8205 | |||
8206 | commit 51a1c2115265c6e80ede8a5c9dccada9aeed7143 | ||
8207 | Author: Damien Miller <djm@mindrot.org> | ||
8208 | Date: Fri May 29 18:27:21 2015 +1000 | ||
8209 | |||
8210 | skip, rather than fatal when run without SUDO set | ||
8211 | |||
8212 | commit 599f01142a376645b15cbc9349d7e8975e1cf245 | ||
8213 | Author: Damien Miller <djm@mindrot.org> | ||
8214 | Date: Fri May 29 18:03:15 2015 +1000 | ||
8215 | |||
8216 | fix merge botch that left ",," in KEX algs | ||
8217 | |||
8218 | commit 0c2a81dfc21822f2423edd30751e5ec53467b347 | ||
8219 | Author: Damien Miller <djm@mindrot.org> | ||
8220 | Date: Fri May 29 17:08:28 2015 +1000 | ||
8221 | |||
8222 | re-enable SSH protocol 1 at compile time | ||
8223 | |||
8224 | commit db438f9285d64282d3ac9e8c0944f59f037c0151 | ||
8225 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8226 | Date: 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 | |||
8234 | commit 1d9a2e2849c9864fe75daabf433436341c968e14 | ||
8235 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8236 | Date: 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 | |||
8245 | commit 496aeb25bc2d6c434171292e4714771b594bd00e | ||
8246 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8247 | Date: 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 | |||
8257 | commit dd2cfeb586c646ff8d70eb93567b2e559ace5b14 | ||
8258 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8259 | Date: Thu May 28 05:09:45 2015 +0000 | ||
8260 | |||
8261 | upstream commit | ||
8262 | |||
8263 | Fix typo (keywork->keyword) | ||
8264 | |||
8265 | Upstream-ID: 8aacd0f4089c0a244cf43417f4f9045dfaeab534 | ||
8266 | |||
8267 | commit 9cc6842493fbf23025ccc1edab064869640d3bec | ||
8268 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8269 | Date: 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 | |||
8277 | commit d1958793a0072c22be26d136dbda5ae263e717a0 | ||
8278 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8279 | Date: 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 | |||
8288 | commit 3ecde664c9fc5fb3667aedf9e6671462600f6496 | ||
8289 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8290 | Date: 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 | |||
8299 | commit 40f64292b907afd0a674fdbf3e4c2356d17a7d68 | ||
8300 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8301 | Date: 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 | |||
8311 | commit 5ab7d5fa03ad55bc438fab45dfb3aeb30a3c237a | ||
8312 | Author: Darren Tucker <dtucker@zip.com.au> | ||
8313 | Date: 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 | |||
8319 | commit a71ba58adf34e599f30cdda6e9b93ae6e3937eea | ||
8320 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8321 | Date: 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 | |||
8330 | commit b282fec1aa05246ed3482270eb70fc3ec5f39a00 | ||
8331 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8332 | Date: 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 | |||
8342 | commit 3e91b4e8b0dc2b4b7e7d42cf6e8994a32e4cb55e | ||
8343 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8344 | Date: 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 | |||
8353 | commit 64a89ec07660abba4d0da7c0095b7371c98bab62 | ||
8354 | Author: jsg@openbsd.org <jsg@openbsd.org> | ||
8355 | Date: 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 | |||
8363 | commit f948737449257d2cb83ffcfe7275eb79b677fd4a | ||
8364 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8365 | Date: 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 | |||
8374 | commit 0882332616e4f0272c31cc47bf2018f9cb258a4e | ||
8375 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8376 | Date: 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 | |||
8385 | commit d7c31da4d42c115843edee2074d7d501f8804420 | ||
8386 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8387 | Date: 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 | |||
8397 | commit aa72196a00be6e0b666215edcffbc10af234cb0e | ||
8398 | Author: Darren Tucker <dtucker@zip.com.au> | ||
8399 | Date: 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 | |||
8405 | commit 8b02481143d75e91c49d1bfae0876ac1fbf9511a | ||
8406 | Author: Darren Tucker <dtucker@zip.com.au> | ||
8407 | Date: Fri May 22 12:47:24 2015 +1000 | ||
8408 | |||
8409 | Import updated moduli file from OpenBSD. | ||
8410 | |||
8411 | commit 4739e8d5e1c0be49624082bd9f6b077e9e758db9 | ||
8412 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8413 | Date: 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 | |||
8423 | commit e97201feca10b5196da35819ae516d0b87cf3a50 | ||
8424 | Author: Damien Miller <djm@mindrot.org> | ||
8425 | Date: Thu May 21 17:55:15 2015 +1000 | ||
8426 | |||
8427 | conditionalise util.h inclusion | ||
8428 | |||
8429 | commit 13640798c7dd011ece0a7d02841fe48e94cfa0e0 | ||
8430 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8431 | Date: 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 | |||
8439 | commit 84452c5d03c21f9bfb28c234e0dc1dc67dd817b1 | ||
8440 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8441 | Date: 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 | |||
8449 | commit bcc50d816187fa9a03907ac1f3a52f04a52e10d1 | ||
8450 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8451 | Date: 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 | |||
8463 | commit 24232a3e5ab467678a86aa67968bbb915caffed4 | ||
8464 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8465 | Date: 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 | |||
8476 | commit d80fbe41a57c72420c87a628444da16d09d66ca7 | ||
8477 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8478 | Date: 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 | |||
8487 | commit 7cc44ef74133a473734bbcbd3484f24d6a7328c5 | ||
8488 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
8489 | Date: 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 | |||
8499 | commit 9173d0fbe44de7ebcad8a15618e13a8b8d78902e | ||
8500 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8501 | Date: 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 | |||
8513 | commit d028d5d3a697c71b21e4066d8672cacab3caa0a8 | ||
8514 | Author: Damien Miller <djm@mindrot.org> | ||
8515 | Date: 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 | |||
8524 | commit f6391d4e59b058984163ab28f4e317e7a72478f1 | ||
8525 | Author: Damien Miller <djm@mindrot.org> | ||
8526 | Date: 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 | |||
8534 | commit 8ac6b13cc9113eb47cd9e86c97d7b26b4b71b77f | ||
8535 | Author: Damien Miller <djm@mindrot.org> | ||
8536 | Date: 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 | |||
8544 | commit 1f792489d5cf86a4f4e3003e6e9177654033f0f2 | ||
8545 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8546 | Date: 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 | |||
8559 | commit 639d6bc57b1942393ed12fb48f00bc05d4e093e4 | ||
8560 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8561 | Date: 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 | |||
8572 | commit 9559d7de34c572d4d3fd990ca211f8ec99f62c4d | ||
8573 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8574 | Date: 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 | |||
8582 | commit 7e8528cad04b2775c3b7db08abf8fb42e47e6b2a | ||
8583 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8584 | Date: 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 | |||
8591 | commit ca430d4d9cc0f62eca3b1fb1e2928395b7ce80f7 | ||
8592 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8593 | Date: 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 | |||
8601 | commit 8312cfb8ad88657517b3e23ac8c56c8e38eb9792 | ||
8602 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8603 | Date: 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 | |||
8610 | commit 179be0f5e62f1f492462571944e45a3da660d82b | ||
8611 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8612 | Date: 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 | |||
8620 | commit a42d67be65b719a430b7fcaba2a4e4118382723a | ||
8621 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8622 | Date: 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 | |||
8633 | commit e661a86353e11592c7ed6a847e19a83609f49e77 | ||
8634 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8635 | Date: 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 | |||
8648 | commit 0ef1de742be2ee4b10381193fe90730925b7f027 | ||
8649 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8650 | Date: 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 | |||
8658 | commit 368f83c793275faa2c52f60eaa9bdac155c4254b | ||
8659 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8660 | Date: Wed Apr 22 01:38:36 2015 +0000 | ||
8661 | |||
8662 | upstream commit | ||
8663 | |||
8664 | use correct key for nested certificate test | ||
8665 | |||
8666 | commit 8d4d1bfddbbd7d21f545dc6997081d1ea1fbc99a | ||
8667 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8668 | Date: 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 | |||
8675 | commit 5ab283d0016bbc9d4d71e8e5284d011bc5a930cf | ||
8676 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8677 | Date: Fri May 8 07:29:00 2015 +0000 | ||
8678 | |||
8679 | upstream commit | ||
8680 | |||
8681 | whitespace | ||
8682 | |||
8683 | Upstream-Regress-ID: 6b708a3e709d5b7fd37890f874bafdff1f597519 | ||
8684 | |||
8685 | commit 8377d5008ad260048192e1e56ad7d15a56d103dd | ||
8686 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8687 | Date: Fri May 8 07:26:13 2015 +0000 | ||
8688 | |||
8689 | upstream commit | ||
8690 | |||
8691 | whitespace at EOL | ||
8692 | |||
8693 | Upstream-Regress-ID: 9c48911643d5b05173b36a012041bed4080b8554 | ||
8694 | |||
8695 | commit c28a3436fa8737709ea88e4437f8f23a6ab50359 | ||
8696 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8697 | Date: Fri May 8 06:45:13 2015 +0000 | ||
8698 | |||
8699 | upstream commit | ||
8700 | |||
8701 | moar whitespace at eol | ||
8702 | |||
8703 | Upstream-ID: 64eaf872a3ba52ed41e494287e80d40aaba4b515 | ||
8704 | |||
8705 | commit 2b64c490468fd4ca35ac8d5cc31c0520dc1508bb | ||
8706 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8707 | Date: Fri May 8 06:41:56 2015 +0000 | ||
8708 | |||
8709 | upstream commit | ||
8710 | |||
8711 | whitespace at EOL | ||
8712 | |||
8713 | Upstream-ID: 57bcf67d666c6fc1ad798aee448fdc3f70f7ec2c | ||
8714 | |||
8715 | commit 4e636cf201ce6e7e3b9088568218f9d4e2c51712 | ||
8716 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8717 | Date: Fri May 8 03:56:51 2015 +0000 | ||
8718 | |||
8719 | upstream commit | ||
8720 | |||
8721 | whitespace at EOL | ||
8722 | |||
8723 | commit 38b8272f823dc1dd4e29dbcee83943ed48bb12fa | ||
8724 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8725 | Date: Mon May 4 01:47:53 2015 +0000 | ||
8726 | |||
8727 | upstream commit | ||
8728 | |||
8729 | Use diff w/out -u for better portability | ||
8730 | |||
8731 | commit 297060f42d5189a4065ea1b6f0afdf6371fb0507 | ||
8732 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8733 | Date: 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 | |||
8741 | commit 63ebf019be863b2d90492a85e248cf55a6e87403 | ||
8742 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8743 | Date: 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 | |||
8750 | commit f8484dac678ab3098ae522a5f03bb2530f822987 | ||
8751 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8752 | Date: 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 | |||
8759 | commit ea139507bef8bad26e86ed99a42c7233ad115c38 | ||
8760 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8761 | Date: 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 | |||
8770 | commit b58234f00ee3872eb84f6e9e572a9a34e902e36e | ||
8771 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8772 | Date: 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 | |||
8779 | commit d5b1507a207253b39e810e91e68f9598691b7a29 | ||
8780 | Author: jsg@openbsd.org <jsg@openbsd.org> | ||
8781 | Date: 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 | |||
8792 | commit a647b9b8e616c231594b2710c925d31b1b8afea3 | ||
8793 | Author: Darren Tucker <dtucker@zip.com.au> | ||
8794 | Date: 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 | |||
8802 | commit d1680d36e17244d9af3843aeb5025cb8e40d6c07 | ||
8803 | Author: Darren Tucker <dtucker@zip.com.au> | ||
8804 | Date: Thu Apr 30 09:18:11 2015 +1000 | ||
8805 | |||
8806 | xrealloc -> xreallocarray in portable code too. | ||
8807 | |||
8808 | commit 531a57a3893f9fcd4aaaba8c312b612bbbcc021e | ||
8809 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8810 | Date: 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 | |||
8817 | commit c1d5bcf1aaf1209af02f79e48ba1cbc76a87b56f | ||
8818 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
8819 | Date: 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 | |||
8826 | commit 43beea053db191cac47c2cd8d3dc1930158aff1a | ||
8827 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8828 | Date: Tue Apr 28 10:25:15 2015 +0000 | ||
8829 | |||
8830 | upstream commit | ||
8831 | |||
8832 | Fix typo in previous | ||
8833 | |||
8834 | commit 85b96ef41374f3ddc9139581f87da09b2cd9199e | ||
8835 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8836 | Date: 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 | |||
8844 | commit 88a7c598a94ff53f76df228eeaae238d2d467565 | ||
8845 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8846 | Date: 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 | |||
8853 | commit 734226b4480a6c736096c729fcf6f391400599c7 | ||
8854 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8855 | Date: Mon Apr 27 01:52:30 2015 +0000 | ||
8856 | |||
8857 | upstream commit | ||
8858 | |||
8859 | fix compilation with OPENSSL=no; ok dtucker@ | ||
8860 | |||
8861 | commit a4b9d2ce1eb7703eaf0809b0c8a82ded8aa4f1c6 | ||
8862 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8863 | Date: 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 | |||
8870 | commit dbcc652f4ca11fe04e5930c7ef18a219318c6cda | ||
8871 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8872 | Date: 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 | |||
8879 | commit b7ca276fca316c952f0b90f5adb1448c8481eedc | ||
8880 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
8881 | Date: Fri Apr 24 06:26:49 2015 +0000 | ||
8882 | |||
8883 | upstream commit | ||
8884 | |||
8885 | combine -Dd onto one line and update usage(); | ||
8886 | |||
8887 | commit 2ea974630d7017e4c7666d14d9dc939707613e96 | ||
8888 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8889 | Date: 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 | |||
8896 | commit 8ac2ffd7aa06042f6b924c87139f2fea5c5682f7 | ||
8897 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
8898 | Date: Fri Apr 24 01:36:24 2015 +0000 | ||
8899 | |||
8900 | upstream commit | ||
8901 | |||
8902 | 2*len -> use xreallocarray() ok djm | ||
8903 | |||
8904 | commit 657a5fbc0d0aff309079ff8fb386f17e964963c2 | ||
8905 | Author: deraadt@openbsd.org <deraadt@openbsd.org> | ||
8906 | Date: 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 | |||
8913 | commit 1108ae242fdd2c304307b68ddf46aebe43ebffaa | ||
8914 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8915 | Date: 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 | |||
8924 | commit bd902b8473e1168f19378d5d0ae68d0c203525df | ||
8925 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
8926 | Date: 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 | |||
8934 | commit ca42c1758575e592239de1d5755140e054b91a0d | ||
8935 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8936 | Date: 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 | |||
8944 | commit 39bfbf7caad231cc4bda6909fb1af0705bca04d8 | ||
8945 | Author: jsg@openbsd.org <jsg@openbsd.org> | ||
8946 | Date: 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 | |||
8955 | commit 6b0d576bb87eca3efd2b309fcfe4edfefc289f9c | ||
8956 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8957 | Date: 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 | |||
8964 | commit 44a8e7ce6f3ab4c2eb1ae49115c210b98e53c4df | ||
8965 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8966 | Date: 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 | |||
8973 | commit 3038a191872d2882052306098c1810d14835e704 | ||
8974 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8975 | Date: 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 | |||
8984 | commit a58be33cb6cd24441fa7e634db0e5babdd56f07f | ||
8985 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8986 | Date: 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 | |||
8993 | commit 17d4d9d9fbc8fb80e322f94d95eecc604588a474 | ||
8994 | Author: djm@openbsd.org <djm@openbsd.org> | ||
8995 | Date: 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 | |||
9002 | commit 40132ff87b6cbc3dc05fb5df2e9d8e3afa06aafd | ||
9003 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
9004 | Date: 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 | |||
9012 | commit 6cc7cfa936afde2d829e56ee6528c7ea47a42441 | ||
9013 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
9014 | Date: 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 | |||
9021 | commit 15fdfc9b1c6808b26bc54d4d61a38b54541763ed | ||
9022 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
9023 | Date: 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 | |||
9030 | commit bb2289e2a47d465eaaaeff3dee2a6b7777b4c291 | ||
9031 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
9032 | Date: 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 | |||
9039 | commit 70860b6d07461906730632f9758ff1b7c98c695a | ||
9040 | Author: Darren Tucker <dtucker@zip.com.au> | ||
9041 | Date: 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 | |||
9047 | commit ee15d9c9f0720f5a8b0b34e4b10ecf21f9824814 | ||
9048 | Author: Darren Tucker <dtucker@zip.com.au> | ||
9049 | Date: Fri Apr 17 10:40:23 2015 +1000 | ||
9050 | |||
9051 | Wrap endian.h include inside ifdef (bz#2370). | ||
9052 | |||
9053 | commit 408f4c2ad4a4c41baa7b9b2b7423d875abbfa70b | ||
9054 | Author: Darren Tucker <dtucker@zip.com.au> | ||
9055 | Date: 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 | |||
9066 | commit 673a1c16ad078d41558247ce739fe812c960acc8 | ||
9067 | Author: Damien Miller <djm@google.com> | ||
9068 | Date: Thu Apr 16 11:40:20 2015 +1000 | ||
9069 | |||
9070 | remove dependency on arpa/telnet.h | ||
9071 | |||
9072 | commit 202d443eeda1829d336595a3cfc07827e49f45ed | ||
9073 | Author: Darren Tucker <dtucker@zip.com.au> | ||
9074 | Date: Wed Apr 15 15:59:49 2015 +1000 | ||
9075 | |||
9076 | Remove duplicate include of pwd.h. bz#2337, patch from Mordy Ovits. | ||
9077 | |||
9078 | commit 597986493412c499f2bc2209420cb195f97b3668 | ||
9079 | Author: Damien Miller <djm@google.com> | ||
9080 | Date: Thu Apr 9 10:14:48 2015 +1000 | ||
9081 | |||
9082 | platform's with openpty don't need pty_release | ||
9083 | |||
9084 | commit 318be28cda1fd9108f2e6f2f86b0b7589ba2aed0 | ||
9085 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9086 | Date: 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 | |||
9094 | commit d8f391caef62378463a0e6b36f940170dadfe605 | ||
9095 | Author: dtucker@openbsd.org <dtucker@openbsd.org> | ||
9096 | Date: 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 | |||
9105 | commit 2c2cfe1a1c97eb9a08cc9817fd0678209680c636 | ||
9106 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9107 | Date: 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 | |||
9114 | commit 4492a4f222da4cf1e8eab12689196322e27b08c4 | ||
9115 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9116 | Date: 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 | |||
9123 | commit c265e2e6e932efc6d86f6cc885dea33637a67564 | ||
9124 | Author: miod@openbsd.org <miod@openbsd.org> | ||
9125 | Date: 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 | |||
9132 | commit e7bf3a5eda6a1b02bef6096fed78527ee11e54cc | ||
9133 | Author: Darren Tucker <dtucker@zip.com.au> | ||
9134 | Date: Tue Apr 7 10:48:04 2015 +1000 | ||
9135 | |||
9136 | Use do{}while(0) for no-op functions. | ||
9137 | |||
9138 | From FreeBSD. | ||
9139 | |||
9140 | commit bb99844abae2b6447272f79e7fa84134802eb4df | ||
9141 | Author: Darren Tucker <dtucker@zip.com.au> | ||
9142 | Date: Tue Apr 7 10:47:15 2015 +1000 | ||
9143 | |||
9144 | Wrap blf.h include in ifdef. From FreeBSD. | ||
9145 | |||
9146 | commit d9b9b43656091cf0ad55c122f08fadb07dad0abd | ||
9147 | Author: Darren Tucker <dtucker@zip.com.au> | ||
9148 | Date: Tue Apr 7 09:10:00 2015 +1000 | ||
9149 | |||
9150 | Fix misspellings of regress CONFOPTS env variables. | ||
9151 | |||
9152 | Patch from Bryan Drewery. | ||
9153 | |||
9154 | commit 3f4ea3c9ab1d32d43c9222c4351f58ca11144156 | ||
9155 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9156 | Date: 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 | |||
9163 | commit 7da2be0cb9601ed25460c83aa4d44052b967ba0f | ||
9164 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9165 | Date: 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 | |||
9173 | commit 9e1777a0d1c706714b055811c12ab8cc21033e4a | ||
9174 | Author: markus@openbsd.org <markus@openbsd.org> | ||
9175 | Date: Tue Mar 24 20:19:15 2015 +0000 | ||
9176 | |||
9177 | upstream commit | ||
9178 | |||
9179 | use ${SSH} for -Q instead of installed ssh | ||
9180 | |||
9181 | commit ce1b358ea414a2cc88e4430cd5a2ea7fecd9de57 | ||
9182 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9183 | Date: Mon Mar 16 22:46:14 2015 +0000 | ||
9184 | |||
9185 | upstream commit | ||
9186 | |||
9187 | make CLEANFILES clean up more of the tests' droppings | ||
9188 | |||
9189 | commit 398f9ef192d820b67beba01ec234d66faca65775 | ||
9190 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9191 | Date: 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 | |||
9202 | commit 9a47ab80030a31f2d122b8fd95bd48c408b9fcd9 | ||
9203 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9204 | Date: 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 | |||
9210 | commit c9a0805a6280681901c270755a7cd630d7c5280e | ||
9211 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9212 | Date: 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 | |||
9219 | commit 704d8c88988cae38fb755a6243b119731d223222 | ||
9220 | Author: tobias@openbsd.org <tobias@openbsd.org> | ||
9221 | Date: 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 | |||
9231 | commit 78de1673c05ea2c33e0d4a4b64ecb5186b6ea2e9 | ||
9232 | Author: jmc@openbsd.org <jmc@openbsd.org> | ||
9233 | Date: 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 | |||
9240 | commit 26e0bcf766fadb4a44fb6199386fb1dcab65ad00 | ||
9241 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9242 | Date: 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 | |||
9250 | commit fecede00a76fbb33a349f5121c0b2f9fbc04a777 | ||
9251 | Author: markus@openbsd.org <markus@openbsd.org> | ||
9252 | Date: 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 | |||
9259 | commit 1b0ef3813244c78669e6d4d54c624f600945327d | ||
9260 | Author: naddy@openbsd.org <naddy@openbsd.org> | ||
9261 | Date: 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 | |||
9268 | commit f9b78852379b74a2d14e6fc94fe52af30b7e9c31 | ||
9269 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9270 | Date: 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 | |||
9277 | commit b8afbe2c1aaf573565e4da775261dfafc8b1ba9c | ||
9278 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9279 | Date: 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 | |||
9287 | commit 47842f71e31da130555353c1d57a1e5a8937f1c0 | ||
9288 | Author: markus@openbsd.org <markus@openbsd.org> | ||
9289 | Date: 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 | |||
9296 | commit 5f57e77f91bf2230c09eca96eb5ecec39e5f2da6 | ||
9297 | Author: markus@openbsd.org <markus@openbsd.org> | ||
9298 | Date: Wed Mar 25 19:21:48 2015 +0000 | ||
9299 | |||
9300 | upstream commit | ||
9301 | |||
9302 | unbreak ssh_agent_sign (lenp vs *lenp) | ||
9303 | |||
9304 | commit 4daeb67181054f2a377677fac919ee8f9ed3490e | ||
9305 | Author: markus@openbsd.org <markus@openbsd.org> | ||
9306 | Date: 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 | |||
9313 | commit 7d4f96f9de2a18af0d9fa75ea89a4990de0344f5 | ||
9314 | Author: markus@openbsd.org <markus@openbsd.org> | ||
9315 | Date: 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 | |||
9322 | commit df100be51354e447d9345cf1ec22e6013c0eed50 | ||
9323 | Author: markus@openbsd.org <markus@openbsd.org> | ||
9324 | Date: 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 | |||
9331 | commit a22b9ef21285e81775732436f7c84a27bd3f71e0 | ||
9332 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9333 | Date: 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 | |||
9340 | commit 2aa9da1a3b360cf7b13e96fe1521534b91501fb5 | ||
9341 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9342 | Date: 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 | |||
9350 | commit 53097b2022154edf96b4e8526af5666f979503f7 | ||
9351 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9352 | Date: 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 | |||
9359 | commit 5c27e3b6ec2db711dfcd40e6359c0bcdd0b62ea9 | ||
9360 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9361 | Date: 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 | |||
9369 | commit 725fd22a8c41db7de73a638539a5157b7e4424ae | ||
9370 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9371 | Date: 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 | |||
9378 | commit b07011c18e0b2e172c5fd09d21fb159a0bf5fcc7 | ||
9379 | Author: djm@openbsd.org <djm@openbsd.org> | ||
9380 | Date: 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 | |||
9387 | commit 1cb3016635898d287e9d58b50c430995652d5358 | ||
9388 | Author: jsg@openbsd.org <jsg@openbsd.org> | ||
9389 | Date: 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 | ||
@@ -99,7 +99,7 @@ http://www.gnu.org/software/autoconf/ | |||
99 | 99 | ||
100 | Basic Security Module (BSM): | 100 | Basic Security Module (BSM): |
101 | 101 | ||
102 | Native BSM support is know to exist in Solaris from at least 2.5.1, | 102 | Native BSM support is known to exist in Solaris from at least 2.5.1, |
103 | FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM | 103 | FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM |
104 | implementation (http://www.openbsm.org). | 104 | implementation (http://www.openbsm.org). |
105 | 105 | ||
@@ -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 | ||
78 | 2) | ||
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 | |||
99 | 3) | 78 | 3) |
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=\ | |||
78 | LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ | 78 | LIBSSH_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 | ||
97 | SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ | 97 | SSHOBJS= 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 | ||
100 | SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ | 100 | SSHDOBJS=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 | |||
228 | clean: regressclean | 228 | clean: 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 | ||
253 | distclean: regressclean | 254 | distclean: regressclean |
@@ -33,8 +33,8 @@ The method is documented in: | |||
33 | 33 | ||
34 | https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt | 34 | https://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt |
35 | 35 | ||
36 | 1.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com", | 36 | 1.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. | |||
454 | This extension is advertised in the SSH_FXP_VERSION hello with version | 454 | This 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 @@ | |||
1 | This describes the protocol used by OpenSSH's ssh-agent. | 1 | This file used to contain a description of the SSH agent protocol |
2 | implemented by OpenSSH. It has since been superseded by an Internet- | ||
3 | draft that is available from: | ||
2 | 4 | ||
3 | OpenSSH's agent supports managing keys for the standard SSH protocol | 5 | https://tools.ietf.org/html/draft-miller-ssh-agent-02 |
4 | 2 as well as the legacy SSH protocol 1. Support for these key types | ||
5 | is almost completely disjoint - in all but a few cases, operations on | ||
6 | protocol 2 keys cannot see or affect protocol 1 keys and vice-versa. | ||
7 | |||
8 | Protocol 1 and protocol 2 keys are separated because of the differing | ||
9 | cryptographic usage: protocol 1 private RSA keys are used to decrypt | ||
10 | challenges that were encrypted with the corresponding public key, | ||
11 | whereas protocol 2 RSA private keys are used to sign challenges with | ||
12 | a private key for verification with the corresponding public key. It | ||
13 | is considered unsound practice to use the same key for signing and | ||
14 | encryption. | ||
15 | |||
16 | With a couple of exceptions, the protocol message names used in this | ||
17 | document indicate which type of key the message relates to. SSH_* | ||
18 | messages refer to protocol 1 keys only. SSH2_* messages refer to | ||
19 | protocol 2 keys. Furthermore, the names also indicate whether the | ||
20 | message is a request to the agent (*_AGENTC_*) or a reply from the | ||
21 | agent (*_AGENT_*). Section 3 below contains the mapping of the | ||
22 | protocol message names to their integer values. | ||
23 | |||
24 | 1. Data types | ||
25 | |||
26 | Because of support for legacy SSH protocol 1 keys, OpenSSH's agent | ||
27 | protocol makes use of some data types not defined in RFC 4251. | ||
28 | |||
29 | 1.1 uint16 | ||
30 | |||
31 | The "uint16" data type is a simple MSB-first 16 bit unsigned integer | ||
32 | encoded in two bytes. | ||
33 | |||
34 | 1.2 mpint1 | ||
35 | |||
36 | The "mpint1" type represents an arbitrary precision integer (bignum). | ||
37 | Its 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 | ||
43 | eight bits per byte in big-endian (MSB first) format. | ||
44 | |||
45 | Note the difference between the "mpint1" encoding and the "mpint" | ||
46 | encoding defined in RFC 4251. Also note that the length of the encoded | ||
47 | integer is specified in bits, not bytes and that the byte length of | ||
48 | the integer must be calculated by rounding up the number of bits to the | ||
49 | nearest eight. | ||
50 | |||
51 | 2. Protocol Messages | ||
52 | |||
53 | All protocol messages are prefixed with their length in bytes, encoded | ||
54 | as a 32 bit unsigned integer. Specifically: | ||
55 | |||
56 | uint32 message_length | ||
57 | byte[message_length] message | ||
58 | |||
59 | The following message descriptions refer only to the content the | ||
60 | "message" field. | ||
61 | |||
62 | 2.1 Generic server responses | ||
63 | |||
64 | The following generic messages may be sent by the server in response to | ||
65 | requests from the client. On success the agent may reply either with: | ||
66 | |||
67 | byte SSH_AGENT_SUCCESS | ||
68 | |||
69 | or a request-specific success message. | ||
70 | |||
71 | On failure, the agent may reply with: | ||
72 | |||
73 | byte SSH_AGENT_FAILURE | ||
74 | |||
75 | SSH_AGENT_FAILURE messages are also sent in reply to unknown request | ||
76 | types. | ||
77 | |||
78 | 2.2 Adding keys to the agent | ||
79 | |||
80 | Keys are added to the agent using the SSH_AGENTC_ADD_RSA_IDENTITY and | ||
81 | SSH2_AGENTC_ADD_IDENTITY requests for protocol 1 and protocol 2 keys | ||
82 | respectively. | ||
83 | |||
84 | Two variants of these requests are SSH_AGENTC_ADD_RSA_ID_CONSTRAINED | ||
85 | and SSH2_AGENTC_ADD_ID_CONSTRAINED - these add keys with optional | ||
86 | "constraints" on their usage. | ||
87 | |||
88 | OpenSSH may be built with support for keys hosted on a smartcard | ||
89 | or other hardware security module. These keys may be added | ||
90 | to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and | ||
91 | SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests. | ||
92 | |||
93 | 2.2.1 Key constraints | ||
94 | |||
95 | The OpenSSH agent supports some basic optional constraints on key usage. | ||
96 | At present there are two constraints defined. | ||
97 | |||
98 | The first constraint limits the validity duration of a key. It is | ||
99 | encoded as: | ||
100 | |||
101 | byte SSH_AGENT_CONSTRAIN_LIFETIME | ||
102 | uint32 seconds | ||
103 | |||
104 | Where "seconds" contains the number of seconds that the key shall remain | ||
105 | valid measured from the moment that the agent receives it. After the | ||
106 | validity period has expired, OpenSSH's agent will erase these keys from | ||
107 | memory. | ||
108 | |||
109 | The second constraint requires the agent to seek explicit user | ||
110 | confirmation before performing private key operations with the loaded | ||
111 | key. This constraint is encoded as: | ||
112 | |||
113 | byte SSH_AGENT_CONSTRAIN_CONFIRM | ||
114 | |||
115 | Zero or more constraints may be specified when adding a key with one | ||
116 | of the *_CONSTRAINED requests. Multiple constraints are appended | ||
117 | consecutively 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 | |||
127 | Such a sequence of zero or more constraints will be referred to below | ||
128 | as "constraint[]". Agents may determine whether there are constraints | ||
129 | by checking whether additional data exists in the "add key" request | ||
130 | after the key data itself. OpenSSH will refuse to add a key if it | ||
131 | contains unknown constraints. | ||
132 | |||
133 | 2.2.2 Add protocol 1 key | ||
134 | |||
135 | A client may add a protocol 1 key to an agent with the following | ||
136 | request: | ||
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 | |||
150 | Note that there is some redundancy in the key parameters; a key could be | ||
151 | fully specified using just rsa_q, rsa_p and rsa_e at the cost of extra | ||
152 | computation. | ||
153 | |||
154 | "key_constraints" may only be present if the request type is | ||
155 | SSH_AGENTC_ADD_RSA_ID_CONSTRAINED. | ||
156 | |||
157 | The agent will reply with a SSH_AGENT_SUCCESS if the key has been | ||
158 | successfully added or a SSH_AGENT_FAILURE if an error occurred. | ||
159 | |||
160 | 2.2.3 Add protocol 2 key | ||
161 | |||
162 | The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA | ||
163 | keys 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 | |||
176 | DSA 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 | |||
185 | ECDSA 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 | |||
198 | ECDSA 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 | |||
209 | ED25519 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 | |||
218 | ED25519 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 | |||
228 | For both ssh-ed25519 and ssh-ed25519-cert-v01@openssh.com keys, the private | ||
229 | key has the public key appended (for historical reasons). | ||
230 | |||
231 | RSA 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 | |||
245 | RSA 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 | |||
258 | Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse | ||
259 | order to the protocol 1 add keys message. As with the corresponding | ||
260 | protocol 1 "add key" request, the private key is overspecified to avoid | ||
261 | redundant processing. | ||
262 | |||
263 | For DSA, ECDSA and RSA key add requests, "key_constraints" may only be | ||
264 | present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED. | ||
265 | |||
266 | The agent will reply with a SSH_AGENT_SUCCESS if the key has been | ||
267 | successfully added or a SSH_AGENT_FAILURE if an error occurred. | ||
268 | |||
269 | 2.2.4 Loading keys from a smartcard | ||
270 | |||
271 | The OpenSSH agent may have optional smartcard support built in to it. If | ||
272 | so, it supports an operation to load keys from a smartcard. Technically, | ||
273 | only the public components of the keys are loaded into the agent so | ||
274 | this operation really arranges for future private key operations to be | ||
275 | delegated 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" | ||
284 | is a PIN or passphrase used to unlock the private key(s) on the | ||
285 | device. "key_constraints" may only be present if the request type is | ||
286 | SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED. | ||
287 | |||
288 | This operation may load all SSH keys that are unlocked using the | ||
289 | "pin" on the specified reader. The type of key loaded (protocol 1 | ||
290 | or protocol 2) will be specified by the smartcard itself, it is not | ||
291 | client-specified. | ||
292 | |||
293 | The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have | ||
294 | been successfully loaded or a SSH_AGENT_FAILURE if an error occurred. | ||
295 | The agent will also return SSH_AGENT_FAILURE if it does not support | ||
296 | smartcards. | ||
297 | |||
298 | 2.3 Removing multiple keys | ||
299 | |||
300 | A client may request that an agent delete all protocol 1 keys using the | ||
301 | following request: | ||
302 | |||
303 | byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES | ||
304 | |||
305 | This message requests the deletion of all protocol 2 keys: | ||
306 | |||
307 | byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES | ||
308 | |||
309 | On success, the agent will delete all keys of the requested type and | ||
310 | reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent | ||
311 | will reply with SSH_AGENT_FAILURE. | ||
312 | |||
313 | Note that, to delete all keys (both protocol 1 and 2), a client | ||
314 | must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a | ||
315 | SSH2_AGENTC_REMOVE_ALL_IDENTITIES request. | ||
316 | |||
317 | 2.4 Removing specific keys | ||
318 | |||
319 | 2.4.1 Removing a protocol 1 key | ||
320 | |||
321 | Removal 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 | |||
328 | Note that key_bits is strictly redundant, as it may be inferred by the | ||
329 | length of rsa_n. | ||
330 | |||
331 | The agent will delete any private key matching the specified public key | ||
332 | and return SSH_AGENT_SUCCESS. If no such key was found, the agent will | ||
333 | return SSH_AGENT_FAILURE. | ||
334 | |||
335 | 2.4.2 Removing a protocol 2 key | ||
336 | |||
337 | Protocol 2 keys may be removed with the following request: | ||
338 | |||
339 | byte SSH2_AGENTC_REMOVE_IDENTITY | ||
340 | string key_blob | ||
341 | |||
342 | Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key | ||
343 | Algorithms" for any of the supported protocol 2 key types. | ||
344 | |||
345 | The agent will delete any private key matching the specified public key | ||
346 | and return SSH_AGENT_SUCCESS. If no such key was found, the agent will | ||
347 | return SSH_AGENT_FAILURE. | ||
348 | |||
349 | 2.4.3 Removing keys loaded from a smartcard | ||
350 | |||
351 | A client may request that a server remove one or more smartcard-hosted | ||
352 | keys 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 | ||
359 | or passphrase used to unlock the private key(s) on the device. | ||
360 | |||
361 | When this message is received, and if the agent supports | ||
362 | smartcard-hosted keys, it will delete all keys that are hosted on the | ||
363 | specified smartcard that may be accessed with the given "pin". | ||
364 | |||
365 | The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have | ||
366 | been successfully removed or a SSH_AGENT_FAILURE if an error occurred. | ||
367 | The agent will also return SSH_AGENT_FAILURE if it does not support | ||
368 | smartcards. | ||
369 | |||
370 | 2.5 Requesting a list of known keys | ||
371 | |||
372 | An agent may be requested to list which keys it holds. Different | ||
373 | requests exist for protocol 1 and protocol 2 keys. | ||
374 | |||
375 | 2.5.1 Requesting a list of protocol 1 keys | ||
376 | |||
377 | To request a list of protocol 1 keys that are held in the agent, a | ||
378 | client may send the following message: | ||
379 | |||
380 | byte SSH_AGENTC_REQUEST_RSA_IDENTITIES | ||
381 | |||
382 | The agent will reply with the following message: | ||
383 | |||
384 | byte SSH_AGENT_RSA_IDENTITIES_ANSWER | ||
385 | uint32 num_keys | ||
386 | |||
387 | Followed 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 | |||
394 | 2.5.2 Requesting a list of protocol 2 keys | ||
395 | |||
396 | A client may send the following message to request a list of | ||
397 | protocol 2 keys that are stored in the agent: | ||
398 | |||
399 | byte SSH2_AGENTC_REQUEST_IDENTITIES | ||
400 | |||
401 | The agent will reply with the following message header: | ||
402 | |||
403 | byte SSH2_AGENT_IDENTITIES_ANSWER | ||
404 | uint32 num_keys | ||
405 | |||
406 | Followed by zero or more consecutive keys, encoded as: | ||
407 | |||
408 | string key_blob | ||
409 | string key_comment | ||
410 | |||
411 | Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key | ||
412 | Algorithms" for any of the supported protocol 2 key types. | ||
413 | |||
414 | 2.6 Private key operations | ||
415 | |||
416 | The purpose of the agent is to perform private key operations, such as | ||
417 | signing and encryption without requiring a passphrase to unlock the | ||
418 | key and without allowing the private key itself to be exposed. There | ||
419 | are separate requests for the protocol 1 and protocol 2 private key | ||
420 | operations. | ||
421 | |||
422 | 2.6.1 Protocol 1 private key challenge | ||
423 | |||
424 | The private key operation used in version 1 of the SSH protocol is | ||
425 | decrypting a challenge that has been encrypted with a public key. | ||
426 | It 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) | ||
438 | been encrypted with the public key and must be in the range | ||
439 | 1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1 | ||
440 | session ID (computed from the server host key, the server semi-ephemeral | ||
441 | key and the session cookie). | ||
442 | |||
443 | "ignored" and "response_type" exist for compatibility with legacy | ||
444 | implementations. "response_type" must be equal to 1; other response | ||
445 | types are not supported. | ||
446 | |||
447 | On receiving this request, the server decrypts the "encrypted_challenge" | ||
448 | using the private key matching the supplied (rsa_e, rsa_n) values. For | ||
449 | the response derivation, the decrypted challenge is represented as an | ||
450 | unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values | ||
451 | smaller than 2^248 will have leading 0 bytes). | ||
452 | |||
453 | The response value is then calculated as: | ||
454 | |||
455 | response = MD5(decrypted_challenge || session_id) | ||
456 | |||
457 | and returned in the following message | ||
458 | |||
459 | byte SSH_AGENT_RSA_RESPONSE | ||
460 | byte[16] response | ||
461 | |||
462 | If the agent cannot find the key specified by the supplied (rsa_e, | ||
463 | rsa_n) then it will return SSH_AGENT_FAILURE. | ||
464 | |||
465 | 2.6.2 Protocol 2 private key signature request | ||
466 | |||
467 | A client may use the following message to request signing of data using | ||
468 | a protocol 2 key: | ||
469 | |||
470 | byte SSH2_AGENTC_SIGN_REQUEST | ||
471 | string key_blob | ||
472 | string data | ||
473 | uint32 flags | ||
474 | |||
475 | Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key | ||
476 | Algorithms" for any of the supported protocol 2 key types. "flags" is | ||
477 | a bit-mask, but at present only one possible value is defined (see below | ||
478 | for its meaning): | ||
479 | |||
480 | SSH_AGENT_OLD_SIGNATURE 1 | ||
481 | |||
482 | Upon receiving this request, the agent will look up the private key that | ||
483 | corresponds to the public key contained in key_blob. It will use this | ||
484 | private key to sign the "data" and produce a signature blob using the | ||
485 | key type-specific method described in RFC 4253 section 6.6 "Public Key | ||
486 | Algorithms". | ||
487 | |||
488 | An exception to this is for "ssh-dss" keys where the "flags" word | ||
489 | contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy | ||
490 | signature encoding is used in lieu of the standard one. In this case, | ||
491 | the DSA signature blob is encoded as: | ||
492 | |||
493 | byte[40] signature | ||
494 | |||
495 | The signature will be returned in the response message: | ||
496 | |||
497 | byte SSH2_AGENT_SIGN_RESPONSE | ||
498 | string signature_blob | ||
499 | |||
500 | If the agent cannot find the key specified by the supplied key_blob then | ||
501 | it will return SSH_AGENT_FAILURE. | ||
502 | |||
503 | 2.7 Locking or unlocking an agent | ||
504 | |||
505 | The agent supports temporary locking with a passphrase to suspend | ||
506 | processing of sensitive operations until it has been unlocked with the | ||
507 | same passphrase. To lock an agent, a client send the following request: | ||
508 | |||
509 | byte SSH_AGENTC_LOCK | ||
510 | string passphrase | ||
511 | |||
512 | Upon receipt of this message and if the agent is not already locked, | ||
513 | it will suspend processing requests and return a SSH_AGENT_SUCCESS | ||
514 | reply. If the agent is already locked, it will return SSH_AGENT_FAILURE. | ||
515 | |||
516 | While locked, the agent will refuse all requests except | ||
517 | SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and | ||
518 | SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are | ||
519 | treated specially by a locked agent: it will always return an empty list | ||
520 | of keys. | ||
521 | |||
522 | To unlock an agent, a client may request: | ||
523 | |||
524 | byte SSH_AGENTC_UNLOCK | ||
525 | string passphrase | ||
526 | |||
527 | If the passphrase matches and the agent is locked, then it will resume | ||
528 | processing all requests and return SSH_AGENT_SUCCESS. If the agent | ||
529 | is not locked or the passphrase does not match then it will return | ||
530 | SSH_AGENT_FAILURE. | ||
531 | |||
532 | Locking and unlocking affects both protocol 1 and protocol 2 keys. | ||
533 | |||
534 | 3. Protocol message numbers | ||
535 | |||
536 | 3.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 | |||
545 | 3.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 | |||
554 | 3.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 | |||
562 | 3.4 Generic replies from agent to client | ||
563 | |||
564 | SSH_AGENT_FAILURE 5 | ||
565 | SSH_AGENT_SUCCESS 6 | ||
566 | |||
567 | 3.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 | |||
572 | 3.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 | |||
577 | 3.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. | |||
192 | The reserved field is currently unused and is ignored in this version of | 192 | The reserved field is currently unused and is ignored in this version of |
193 | the protocol. | 193 | the protocol. |
194 | 194 | ||
195 | signature key contains the CA key used to sign the certificate. | 195 | The signature key field contains the CA key used to sign the |
196 | The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types | 196 | certificate. The valid key types for CA keys are ssh-rsa, |
197 | ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" | 197 | ssh-dss, ssh-ed25519 and the ECDSA types ecdsa-sha2-nistp256, |
198 | certificates, where the signature key type is a certificate type itself | 198 | ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where |
199 | are NOT supported. Note that it is possible for a RSA certificate key to | 199 | the signature key type is a certificate type itself are NOT supported. |
200 | be signed by a DSS or ECDSA CA key and vice-versa. | 200 | Note that it is possible for a RSA certificate key to be signed by a |
201 | Ed25519 or ECDSA CA key and vice-versa. | ||
201 | 202 | ||
202 | signature is computed over all preceding fields from the initial string | 203 | signature is computed over all preceding fields from the initial string |
203 | up to, and including the signature key. Signatures are computed and | 204 | up 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 |
224 | then the validating party should refuse to accept the certificate. | 225 | then the validating party should refuse to accept the certificate. |
225 | 226 | ||
227 | Custom options should append the originating author or organisation's | ||
228 | domain name to the option name, e.g. "my-option@example.com". | ||
229 | |||
226 | No critical options are defined for host certificates at present. The | 230 | No critical options are defined for host certificates at present. The |
227 | supported user certificate options and the contents and structure of | 231 | supported user certificate options and the contents and structure of |
228 | their data fields are: | 232 | their data fields are: |
@@ -254,6 +258,9 @@ as is the requirement that each name appear only once. | |||
254 | If an implementation does not recognise an extension, then it should | 258 | If an implementation does not recognise an extension, then it should |
255 | ignore it. | 259 | ignore it. |
256 | 260 | ||
261 | Custom options should append the originating author or organisation's | ||
262 | domain name to the option name, e.g. "my-option@example.com". | ||
263 | |||
257 | No extensions are defined for host certificates at present. The | 264 | No extensions are defined for host certificates at present. The |
258 | supported user certificate extensions and the contents and structure of | 265 | supported user certificate extensions and the contents and structure of |
259 | their data fields are: | 266 | their 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 $ |
@@ -1,4 +1,4 @@ | |||
1 | See https://www.openssh.com/releasenotes.html#7.5p1 for the release notes. | 1 | See https://www.openssh.com/releasenotes.html#7.6p1 for the release notes. |
2 | 2 | ||
3 | Please read https://www.openssh.com/report.html for bug reporting | 3 | Please read https://www.openssh.com/report.html for bug reporting |
4 | instructions and note that we do not use Github for bug reporting or | 4 | instructions 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 | |||
30 | commercial ssh-1.2.x. It checks "account" and "session" modules for | 30 | commercial ssh-1.2.x. It checks "account" and "session" modules for |
31 | all logins, not just when using password authentication. | 31 | all logins, not just when using password authentication. |
32 | 32 | ||
33 | OpenSSH depends on Zlib[3], OpenSSL[4] and optionally PAM[5]. | 33 | OpenSSH depends on Zlib[3], OpenSSL[4], and optionally PAM[5] and |
34 | libedit[6] | ||
34 | 35 | ||
35 | There is now several mailing lists for this port of OpenSSH. Please | 36 | There is now several mailing lists for this port of OpenSSH. Please |
36 | refer to https://www.openssh.com/list.html for details on how to join. | 37 | refer 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. | |||
38 | Please send bug reports and patches to the mailing list | 39 | Please send bug reports and patches to the mailing list |
39 | openssh-unix-dev@mindrot.org. The list is open to posting by unsubscribed | 40 | openssh-unix-dev@mindrot.org. The list is open to posting by unsubscribed |
40 | users. Code contribution are welcomed, but please follow the OpenBSD | 41 | users. Code contribution are welcomed, but please follow the OpenBSD |
41 | style guidelines[6]. | 42 | style guidelines[7]. |
42 | 43 | ||
43 | Please refer to the INSTALL document for information on how to install | 44 | Please refer to the INSTALL document for information on how to install |
44 | OpenSSH on your system. | 45 | OpenSSH 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 | ||
62 | extern ServerOptions options; | 62 | extern ServerOptions options; |
63 | 63 | ||
64 | /* XXX refactor to be stateless */ | ||
65 | |||
64 | void | 66 | void |
65 | auth_clear_options(void) | 67 | auth_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 | */ |
121 | int | 126 | int |
122 | auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) | 127 | auth_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; | |||
33 | extern int key_is_cert_authority; | 33 | extern int key_is_cert_authority; |
34 | extern char *authorized_principals; | 34 | extern char *authorized_principals; |
35 | 35 | ||
36 | int auth_parse_options(struct passwd *, char *, char *, u_long); | 36 | int auth_parse_options(struct passwd *, char *, const char *, u_long); |
37 | void auth_clear_options(void); | 37 | void auth_clear_options(void); |
38 | int auth_cert_options(struct sshkey *, struct passwd *, const char **); | 38 | int 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 | ||
107 | extern ServerOptions options; | 107 | extern ServerOptions options; |
108 | extern Buffer loginmsg; | 108 | extern Buffer loginmsg; |
109 | extern int compat20; | ||
110 | extern u_int utmp_len; | 109 | extern 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 | ||
929 | static void | ||
930 | expose_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 | |||
932 | u_int | 950 | u_int |
933 | do_pam_account(void) | 951 | do_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 | |||
1060 | do_pam_session(void) | 1080 | do_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) |
@@ -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 | ||
270 | void | 267 | /* |
271 | auth_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 | */ | ||
271 | static char * | ||
272 | format_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 | ||
287 | void | 304 | void |
@@ -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 */ |
430 | HostStatus | 453 | HostStatus |
431 | check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, | 454 | check_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 | */ | ||
488 | int | ||
489 | auth_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 | */ | ||
552 | static int | ||
553 | secure_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 | |||
567 | static FILE * | 498 | static FILE * |
568 | auth_openfile(const char *file, struct passwd *pw, int strict_modes, | 499 | auth_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 */ |
696 | int | 629 | int |
697 | auth_key_is_revoked(Key *key) | 630 | auth_key_is_revoked(struct sshkey *key) |
698 | { | 631 | { |
699 | char *fp = NULL; | 632 | char *fp = NULL; |
700 | int r; | 633 | int r; |
@@ -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 | ||
45 | struct ssh; | 45 | struct ssh; |
46 | struct sshkey; | 46 | struct sshkey; |
47 | struct sshbuf; | ||
47 | 48 | ||
48 | typedef struct Authctxt Authctxt; | 49 | typedef struct Authctxt Authctxt; |
49 | typedef struct Authmethod Authmethod; | 50 | typedef 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 | ||
92 | struct Authmethod { | 105 | struct 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 | ||
118 | int auth_password(Authctxt *, const char *); | 131 | int auth_password(Authctxt *, const char *); |
119 | 132 | ||
120 | int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); | 133 | int hostbased_key_allowed(struct passwd *, const char *, char *, |
121 | int user_key_allowed(struct passwd *, Key *, int); | 134 | struct sshkey *); |
122 | void pubkey_auth_info(Authctxt *, const Key *, const char *, ...) | 135 | int user_key_allowed(struct passwd *, struct sshkey *, int); |
123 | __attribute__((__format__ (printf, 3, 4))); | 136 | int auth2_key_already_used(Authctxt *, const struct sshkey *); |
124 | void auth2_record_userkey(Authctxt *, struct sshkey *); | ||
125 | int auth2_userkey_already_used(Authctxt *, struct sshkey *); | ||
126 | 137 | ||
127 | struct stat; | 138 | /* |
128 | int 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 | */ | ||
142 | void auth2_authctxt_reset_info(Authctxt *); | ||
143 | void auth2_record_key(Authctxt *, int, const struct sshkey *); | ||
144 | void auth2_record_info(Authctxt *authctxt, const char *, ...) | ||
145 | __attribute__((__format__ (printf, 2, 3))) | ||
146 | __attribute__((__nonnull__ (2))); | ||
147 | void auth2_update_session_info(Authctxt *, const char *, const char *); | ||
130 | 148 | ||
131 | #ifdef KRB5 | 149 | #ifdef KRB5 |
132 | int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); | 150 | int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); |
@@ -149,12 +167,9 @@ void disable_forwarding(void); | |||
149 | 167 | ||
150 | void do_authentication2(Authctxt *); | 168 | void do_authentication2(Authctxt *); |
151 | 169 | ||
152 | void auth_info(Authctxt *authctxt, const char *, ...) | ||
153 | __attribute__((__format__ (printf, 2, 3))) | ||
154 | __attribute__((__nonnull__ (2))); | ||
155 | void auth_log(Authctxt *, int, int, const char *, const char *); | 170 | void auth_log(Authctxt *, int, int, const char *, const char *); |
156 | void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn)); | 171 | void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn)); |
157 | void userauth_finish(Authctxt *, int, const char *, const char *); | 172 | void userauth_finish(struct ssh *, int, const char *, const char *); |
158 | int auth_root_allowed(const char *); | 173 | int auth_root_allowed(const char *); |
159 | 174 | ||
160 | void userauth_send_banner(const char *); | 175 | void userauth_send_banner(const char *); |
@@ -167,8 +182,8 @@ int auth2_method_allowed(Authctxt *, const char *, const char *); | |||
167 | 182 | ||
168 | void privsep_challenge_enable(void); | 183 | void privsep_challenge_enable(void); |
169 | 184 | ||
170 | int auth2_challenge(Authctxt *, char *); | 185 | int auth2_challenge(struct ssh *, char *); |
171 | void auth2_challenge_stop(Authctxt *); | 186 | void auth2_challenge_stop(struct ssh *); |
172 | int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); | 187 | int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); |
173 | int bsdauth_respond(void *, u_int, char **); | 188 | int bsdauth_respond(void *, u_int, char **); |
174 | int skey_query(void *, char **, char **, u_int *, char ***, u_int **); | 189 | int skey_query(void *, char **, char **, u_int *, char ***, u_int **); |
@@ -182,22 +197,22 @@ char *authorized_principals_file(struct passwd *); | |||
182 | 197 | ||
183 | FILE *auth_openkeyfile(const char *, struct passwd *, int); | 198 | FILE *auth_openkeyfile(const char *, struct passwd *, int); |
184 | FILE *auth_openprincipals(const char *, struct passwd *, int); | 199 | FILE *auth_openprincipals(const char *, struct passwd *, int); |
185 | int auth_key_is_revoked(Key *); | 200 | int auth_key_is_revoked(struct sshkey *); |
186 | 201 | ||
187 | const char *auth_get_canonical_hostname(struct ssh *, int); | 202 | const char *auth_get_canonical_hostname(struct ssh *, int); |
188 | 203 | ||
189 | HostStatus | 204 | HostStatus |
190 | check_key_in_hostfiles(struct passwd *, Key *, const char *, | 205 | check_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 */ |
194 | Key *get_hostkey_by_index(int); | 209 | struct sshkey *get_hostkey_by_index(int); |
195 | Key *get_hostkey_public_by_index(int, struct ssh *); | 210 | struct sshkey *get_hostkey_public_by_index(int, struct ssh *); |
196 | Key *get_hostkey_public_by_type(int, int, struct ssh *); | 211 | struct sshkey *get_hostkey_public_by_type(int, int, struct ssh *); |
197 | Key *get_hostkey_private_by_type(int, int, struct ssh *); | 212 | struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *); |
198 | int get_hostkey_index(Key *, int, struct ssh *); | 213 | int get_hostkey_index(struct sshkey *, int, struct ssh *); |
199 | int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, | 214 | int 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 */ |
203 | void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); | 218 | void 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 */ |
48 | extern ServerOptions options; | 48 | extern ServerOptions options; |
49 | 49 | ||
50 | static int auth2_challenge_start(Authctxt *); | 50 | static int auth2_challenge_start(struct ssh *); |
51 | static int send_userauth_info_request(Authctxt *); | 51 | static int send_userauth_info_request(Authctxt *); |
52 | static int input_userauth_info_response(int, u_int32_t, void *); | 52 | static int input_userauth_info_response(int, u_int32_t, struct ssh *); |
53 | 53 | ||
54 | #ifdef BSD_AUTH | 54 | #ifdef BSD_AUTH |
55 | extern KbdintDevice bsdauth_device; | 55 | extern 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 | */ |
197 | int | 197 | int |
198 | auth2_challenge(Authctxt *authctxt, char *devs) | 198 | auth2_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 */ |
212 | void | 213 | void |
213 | auth2_challenge_stop(Authctxt *authctxt) | 214 | auth2_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*/ |
224 | static int | 226 | static int |
225 | auth2_challenge_start(Authctxt *authctxt) | 227 | auth2_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 | ||
287 | static int | 290 | static int |
288 | input_userauth_info_response(int type, u_int32_t seq, void *ctxt) | 291 | input_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 | ||
49 | extern ServerOptions options; | 49 | extern ServerOptions options; |
50 | 50 | ||
51 | static int input_gssapi_token(int type, u_int32_t plen, void *ctxt); | 51 | static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); |
52 | static int input_gssapi_mic(int type, u_int32_t plen, void *ctxt); | 52 | static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); |
53 | static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); | 53 | static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh); |
54 | static int input_gssapi_errtok(int, u_int32_t, void *); | 54 | static 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 | */ |
60 | static int | 60 | static int |
61 | userauth_gssapi(Authctxt *authctxt) | 61 | userauth_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 | ||
129 | static int | 130 | static int |
130 | input_gssapi_token(int type, u_int32_t plen, void *ctxt) | 131 | input_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 | ||
184 | static int | 185 | static int |
185 | input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) | 186 | input_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 | ||
225 | static int | 226 | static int |
226 | input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) | 227 | input_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 | ||
252 | static int | 258 | static int |
253 | input_gssapi_mic(int type, u_int32_t plen, void *ctxt) | 259 | input_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; | |||
56 | extern u_int session_id2_len; | 57 | extern u_int session_id2_len; |
57 | 58 | ||
58 | static int | 59 | static int |
59 | userauth_hostbased(Authctxt *authctxt) | 60 | userauth_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); | ||
146 | done: | 152 | done: |
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 */ |
159 | int | 164 | int |
160 | hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, | 165 | hostbased_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 @@ | |||
43 | extern ServerOptions options; | 43 | extern ServerOptions options; |
44 | 44 | ||
45 | static int | 45 | static int |
46 | userauth_kbdint(Authctxt *authctxt) | 46 | userauth_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; | |||
59 | static int none_enabled = 1; | 60 | static int none_enabled = 1; |
60 | 61 | ||
61 | static int | 62 | static int |
62 | userauth_none(Authctxt *authctxt) | 63 | userauth_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 @@ | |||
48 | extern ServerOptions options; | 48 | extern ServerOptions options; |
49 | 49 | ||
50 | static int | 50 | static int |
51 | userauth_passwd(Authctxt *authctxt) | 51 | userauth_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; | |||
75 | extern u_int session_id2_len; | 74 | extern u_int session_id2_len; |
76 | 75 | ||
77 | static int | 76 | static int |
78 | userauth_pubkey(Authctxt *authctxt) | 77 | userauth_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(); |
212 | done: | 234 | done: |
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 | ||
222 | void | ||
223 | pubkey_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 | */ | ||
264 | static int | ||
265 | split_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 | */ | ||
338 | static char * | ||
339 | assemble_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 | */ | ||
394 | static pid_t | ||
395 | subprocess(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 */ | ||
520 | static int | ||
521 | exited_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 | |||
541 | static int | 244 | static int |
542 | match_principals_option(const char *principal_list, struct sshkey_cert *cert) | 245 | match_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 | ||
561 | static int | 264 | static int |
562 | process_principals(FILE *f, char *file, struct passwd *pw, | 265 | process_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 | */ |
763 | static int | 466 | static int |
764 | check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) | 467 | check_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 */ |
878 | static int | 581 | static int |
879 | user_cert_trusted_ca(struct passwd *pw, Key *key) | 582 | user_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 | */ |
944 | static int | 647 | static int |
945 | user_key_allowed2(struct passwd *pw, Key *key, char *file) | 648 | user_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 | */ |
967 | static int | 670 | static int |
968 | user_key_command_allowed2(struct passwd *user_pw, Key *key) | 671 | user_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 | */ |
1090 | int | 794 | int |
1091 | user_key_allowed(struct passwd *pw, Key *key, int auth_attempt) | 795 | user_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 */ | ||
1124 | void | ||
1125 | auth2_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 */ | ||
1139 | int | ||
1140 | auth2_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 | |||
1152 | Authmethod method_pubkey = { | 828 | Authmethod method_pubkey = { |
1153 | "publickey", | 829 | "publickey", |
1154 | userauth_pubkey, | 830 | userauth_pubkey, |
@@ -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 */ |
60 | extern ServerOptions options; | 62 | extern ServerOptions options; |
@@ -87,8 +89,8 @@ Authmethod *authmethods[] = { | |||
87 | 89 | ||
88 | /* protocol */ | 90 | /* protocol */ |
89 | 91 | ||
90 | static int input_service_request(int, u_int32_t, void *); | 92 | static int input_service_request(int, u_int32_t, struct ssh *); |
91 | static int input_userauth_request(int, u_int32_t, void *); | 93 | static int input_userauth_request(int, u_int32_t, struct ssh *); |
92 | 94 | ||
93 | /* helper */ | 95 | /* helper */ |
94 | static Authmethod *authmethod_lookup(Authctxt *, const char *); | 96 | static Authmethod *authmethod_lookup(Authctxt *, const char *); |
@@ -168,16 +170,19 @@ done: | |||
168 | void | 170 | void |
169 | do_authentication2(Authctxt *authctxt) | 171 | do_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*/ |
177 | static int | 182 | static int |
178 | input_service_request(int type, u_int32_t seq, void *ctxt) | 183 | input_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*/ |
212 | static int | 217 | static int |
213 | input_userauth_request(int type, u_int32_t seq, void *ctxt) | 218 | input_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 | ||
295 | void | 300 | void |
296 | userauth_finish(Authctxt *authctxt, int authenticated, const char *method, | 301 | userauth_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 */ | ||
635 | void 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 */ | ||
644 | void | ||
645 | auth2_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 | */ | ||
666 | void | ||
667 | auth2_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 */ | ||
695 | int | ||
696 | auth2_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 | */ | ||
719 | void | ||
720 | auth2_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 | ||
@@ -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 | ||
203 | static int | ||
204 | deserialise_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 | ||
240 | static int | 202 | static int |
241 | deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp) | 203 | deserialise_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 | */ |
266 | int | 228 | int |
267 | ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp) | 229 | ssh_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 | ||
389 | int | ||
390 | ssh_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 */ |
430 | static u_int | 327 | static u_int |
431 | agent_encode_alg(struct sshkey *key, const char *alg) | 328 | agent_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 */ |
443 | int | 340 | int |
444 | ssh_agent_sign(int sock, struct sshkey *key, | 341 | ssh_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 | ||
498 | static int | ||
499 | ssh_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 | ||
517 | static int | 395 | static int |
518 | ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key, | 396 | ssh_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 | */ |
700 | int | 562 | int |
701 | ssh_remove_all_identities(int sock, int version) | 563 | ssh_remove_all_identities(int sock, int version) |
@@ -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); | |||
27 | void ssh_close_authentication_socket(int sock); | 27 | void ssh_close_authentication_socket(int sock); |
28 | 28 | ||
29 | int ssh_lock_agent(int sock, int lock, const char *password); | 29 | int ssh_lock_agent(int sock, int lock, const char *password); |
30 | int ssh_fetch_identitylist(int sock, int version, | 30 | int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp); |
31 | struct ssh_identitylist **idlp); | ||
32 | void ssh_free_identitylist(struct ssh_identitylist *idl); | 31 | void ssh_free_identitylist(struct ssh_identitylist *idl); |
33 | int ssh_add_identity_constrained(int sock, struct sshkey *key, | 32 | int 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 | ||
40 | int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, | 39 | int 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]); |
42 | int ssh_agent_sign(int sock, struct sshkey *key, | 41 | int 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 | */ | ||
156 | static int | ||
157 | sshkey_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? */ |
181 | int | 139 | int |
@@ -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 */ |
349 | int | 307 | int |
350 | sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) | 308 | sshkey_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 | ||
@@ -53,8 +53,9 @@ void | |||
53 | bitmap_free(struct bitmap *b) | 53 | bitmap_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; |
@@ -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 | ||
32 | int | ||
33 | buffer_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 | |||
44 | void | ||
45 | buffer_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 | |||
51 | int | ||
52 | buffer_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 | |||
63 | void | ||
64 | buffer_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 | |||
71 | int | 31 | int |
72 | buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) | 32 | buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) |
73 | { | 33 | { |
@@ -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> |
52 | void buffer_put_bignum(Buffer *, const BIGNUM *); | ||
53 | void buffer_put_bignum2(Buffer *, const BIGNUM *); | 52 | void buffer_put_bignum2(Buffer *, const BIGNUM *); |
54 | void buffer_get_bignum(Buffer *, BIGNUM *); | ||
55 | void buffer_get_bignum2(Buffer *, BIGNUM *); | 53 | void buffer_get_bignum2(Buffer *, BIGNUM *); |
56 | void buffer_put_bignum2_from_string(Buffer *, const u_char *, u_int); | 54 | void 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 | ||
78 | int buffer_put_bignum_ret(Buffer *, const BIGNUM *); | ||
79 | int buffer_get_bignum_ret(Buffer *, BIGNUM *); | ||
80 | int buffer_put_bignum2_ret(Buffer *, const BIGNUM *); | 76 | int buffer_put_bignum2_ret(Buffer *, const BIGNUM *); |
81 | int buffer_get_bignum2_ret(Buffer *, BIGNUM *); | 77 | int buffer_get_bignum2_ret(Buffer *, BIGNUM *); |
82 | int buffer_get_short_ret(u_short *, Buffer *); | 78 | int 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 | */ | ||
92 | static 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 | */ | ||
98 | static 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 | */ | ||
104 | static 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. */ | 118 | typedef void chan_fn(struct ssh *, Channel *c, |
128 | static 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. */ | ||
131 | static 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 */ |
134 | static int num_permitted_opens = 0; | 122 | struct 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 | /* |
137 | static 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 | */ | ||
150 | static 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 | /* |
159 | static 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 | /* |
162 | static 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 */ |
165 | static char *x11_saved_data = NULL; | ||
166 | static u_int x11_saved_data_len = 0; | ||
167 | 179 | ||
168 | /* Deadline after which all X11 connections are refused */ | 180 | /* Saved X11 local (client) display. */ |
169 | static 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 | */ | ||
175 | static u_char *x11_fake_data = NULL; | ||
176 | static 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 */ |
184 | static int IPv4or6 = AF_UNSPEC; | 202 | int IPv4or6; |
203 | }; | ||
185 | 204 | ||
186 | /* helper */ | 205 | /* helper */ |
187 | static void port_open_helper(Channel *c, char *rtype); | 206 | static void port_open_helper(struct ssh *ssh, Channel *c, char *rtype); |
188 | static const char *channel_rfwd_bind_host(const char *listen_host); | 207 | static const char *channel_rfwd_bind_host(const char *listen_host); |
189 | 208 | ||
190 | /* non-blocking connect helpers */ | 209 | /* non-blocking connect helpers */ |
191 | static int connect_next(struct channel_connect *); | 210 | static int connect_next(struct channel_connect *); |
192 | static void channel_connect_ctx_free(struct channel_connect *); | 211 | static void channel_connect_ctx_free(struct channel_connect *); |
212 | static Channel *rdynamic_connect_prepare(struct ssh *, char *, char *); | ||
213 | static int rdynamic_connect_finish(struct ssh *, Channel *); | ||
214 | |||
215 | /* Setup helper */ | ||
216 | static void channel_handler_init(struct ssh_channels *sc); | ||
193 | 217 | ||
194 | /* -- channel core */ | 218 | /* -- channel core */ |
195 | 219 | ||
220 | void | ||
221 | channel_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 | |||
196 | Channel * | 239 | Channel * |
197 | channel_by_id(int id) | 240 | channel_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 | ||
213 | Channel * | 256 | Channel * |
214 | channel_by_remote_id(int remote_id) | 257 | channel_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 | */ |
231 | Channel * | 274 | Channel * |
232 | channel_lookup(int id) | 275 | channel_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 | */ |
260 | static void | 303 | static void |
261 | channel_register_fds(Channel *c, int rfd, int wfd, int efd, | 304 | channel_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 | */ |
304 | Channel * | 349 | Channel * |
305 | channel_new(char *ctype, int type, int rfd, int wfd, int efd, | 350 | channel_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 | ||
383 | static int | 402 | static void |
384 | channel_find_maxfd(void) | 403 | channel_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 | ||
401 | int | 420 | int |
402 | channel_close_fd(int *fdp) | 421 | channel_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. */ |
416 | static void | 436 | static void |
417 | channel_close_fds(Channel *c) | 437 | channel_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 | |||
445 | static void | ||
446 | fwd_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 | |||
454 | enum { FWDPERM_USER, FWDPERM_ADMIN }; | ||
455 | |||
456 | static int | ||
457 | fwd_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 | |||
494 | static void | ||
495 | mux_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. */ |
426 | void | 526 | void |
427 | channel_free(Channel *c) | 527 | channel_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 | ||
510 | void | 584 | void |
511 | channel_free_all(void) | 585 | channel_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 | */ |
524 | void | 598 | void |
525 | channel_close_all(void) | 599 | channel_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 | */ |
537 | void | 611 | void |
538 | channel_stop_listening(void) | 612 | channel_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 | */ |
565 | int | 639 | int |
566 | channel_not_very_much_buffered_data(void) | 640 | channel_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. */ |
594 | int | 660 | int |
595 | channel_still_open(void) | 661 | channel_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 */ |
642 | int | 703 | int |
643 | channel_find_open(void) | 704 | channel_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 | */ |
691 | char * | 749 | char * |
692 | channel_open_message(void) | 750 | channel_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 | |||
811 | static void | ||
812 | open_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 | ||
748 | void | 825 | void |
749 | channel_send_open(int id) | 826 | channel_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 | ||
766 | void | 841 | void |
767 | channel_request_start(int id, char *service, int wantconfirm) | 842 | channel_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 | ||
782 | void | 863 | void |
783 | channel_register_status_confirm(int id, channel_confirm_cb *cb, | 864 | channel_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 | ||
799 | void | 880 | void |
800 | channel_register_open_confirm(int id, channel_open_fn *fn, void *ctx) | 881 | channel_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 | ||
812 | void | 894 | void |
813 | channel_register_cleanup(int id, channel_callback_fn *fn, int do_close) | 895 | channel_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 | ||
825 | void | 908 | void |
826 | channel_cancel_cleanup(int id) | 909 | channel_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 | ||
838 | void | 921 | void |
839 | channel_register_filter(int id, channel_infilter_fn *ifn, | 922 | channel_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 | ||
854 | void | 937 | void |
855 | channel_set_fds(int id, int rfd, int wfd, int efd, | 938 | channel_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 | */ | ||
879 | typedef void chan_fn(Channel *c, fd_set *readset, fd_set *writeset); | ||
880 | chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE]; | ||
881 | chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE]; | ||
882 | 959 | ||
883 | /* ARGSUSED */ | ||
884 | static void | 960 | static void |
885 | channel_pre_listener(Channel *c, fd_set *readset, fd_set *writeset) | 961 | channel_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 */ | ||
891 | static void | 967 | static void |
892 | channel_pre_connecting(Channel *c, fd_set *readset, fd_set *writeset) | 968 | channel_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 | ||
898 | static void | 975 | static void |
899 | channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset) | 976 | channel_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 | |||
907 | static void | ||
908 | channel_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 */ | ||
945 | static void | ||
946 | channel_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 */ | ||
958 | static void | ||
959 | channel_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 | */ |
976 | static int | 1021 | static int |
977 | x11_open_helper(Buffer *b) | 1022 | x11_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 | ||
1041 | static void | 1088 | static void |
1042 | channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset) | 1089 | channel_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 | |||
1067 | static void | ||
1068 | channel_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 | ||
1093 | static void | 1112 | static void |
1094 | channel_pre_mux_client(Channel *c, fd_set *readset, fd_set *writeset) | 1113 | channel_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 */ | ||
1117 | static int | 1136 | static int |
1118 | channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) | 1137 | channel_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 */ | ||
1230 | static int | 1262 | static int |
1231 | channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) | 1263 | channel_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 | ||
1345 | Channel * | 1398 | Channel * |
1346 | channel_connect_stdio_fwd(const char *host_to_connect, u_short port_to_connect, | 1399 | channel_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 */ |
1370 | static void | 1422 | static void |
1371 | channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset) | 1423 | channel_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 */ | ||
1469 | static void | ||
1470 | rdynamic_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 */ | ||
1481 | static void | ||
1482 | channel_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 */ | ||
1414 | static void | 1544 | static void |
1415 | channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset) | 1545 | channel_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 | ||
1478 | static void | 1600 | static void |
1479 | port_open_helper(Channel *c, char *rtype) | 1601 | port_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 | ||
1560 | void | 1684 | void |
1561 | channel_set_x11_refuse_time(u_int refuse_time) | 1685 | channel_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 */ | ||
1570 | static void | 1693 | static void |
1571 | channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) | 1694 | channel_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 */ | ||
1630 | static void | 1753 | static void |
1631 | channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset) | 1754 | channel_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 */ | ||
1667 | static void | 1782 | static void |
1668 | channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) | 1783 | channel_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 */ | ||
1727 | static int | 1857 | static int |
1728 | channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset) | 1858 | channel_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 */ | ||
1776 | static int | 1908 | static int |
1777 | channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset) | 1909 | channel_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 | ||
1868 | static int | 2002 | static int |
1869 | channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset) | 2003 | channel_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 | |||
2031 | static int | ||
2032 | channel_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 | ||
1920 | static int | 2063 | static int |
1921 | channel_check_window(Channel *c) | 2064 | channel_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 | |||
2081 | static int | ||
2082 | channel_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 | ||
1942 | static void | 2112 | static void |
1943 | channel_post_open(Channel *c, fd_set *readset, fd_set *writeset) | 2113 | channel_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 | ||
1953 | static u_int | 2122 | static u_int |
1954 | read_mux(Channel *c, u_int need) | 2123 | read_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 | ||
1976 | static void | 2148 | static void |
1977 | channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset) | 2149 | channel_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) && | 2185 | static void |
2012 | buffer_len(&c->output) > 0) { | 2186 | channel_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 | |||
2208 | static void | ||
2209 | channel_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 | ||
2025 | static void | 2216 | static void |
2026 | channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset) | 2217 | channel_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 */ | ||
2078 | static void | 2268 | static void |
2079 | channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset) | 2269 | channel_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; | |
2094 | static void | 2284 | pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener; |
2095 | channel_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 | |||
2123 | static void | ||
2124 | channel_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 | |||
2145 | static void | ||
2146 | channel_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 | |||
2164 | static void | ||
2165 | channel_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 */ |
2182 | static void | 2309 | static void |
2183 | channel_garbage_collect(Channel *c) | 2310 | channel_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 | ||
2330 | enum channel_table { CHAN_PRE, CHAN_POST }; | ||
2331 | |||
2203 | static void | 2332 | static void |
2204 | channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset, | 2333 | channel_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 | */ | ||
2386 | static void | ||
2387 | channel_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 | */ |
2259 | void | 2406 | void |
2260 | channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, | 2407 | channel_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 | */ |
2292 | void | 2441 | void |
2293 | channel_after_select(fd_set *readset, fd_set *writeset) | 2442 | channel_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 | */ | ||
2450 | static void | ||
2451 | channel_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 | */ | ||
2528 | static void | ||
2529 | channel_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. */ |
2300 | void | 2563 | void |
2301 | channel_output_poll(void) | 2564 | channel_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 | */ |
2465 | int | 2639 | int |
2466 | channel_proxy_downstream(Channel *downstream) | 2640 | channel_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 | */ |
2625 | int | 2793 | int |
2626 | channel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt) | 2794 | channel_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 */ |
2876 | static int | ||
2877 | channel_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 */ | ||
2894 | static Channel * | ||
2895 | channel_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 | |||
2707 | int | 2907 | int |
2708 | channel_input_data(int type, u_int32_t seq, void *ctxt) | 2908 | channel_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 */ | ||
2770 | int | 2969 | int |
2771 | channel_input_extended_data(int type, u_int32_t seq, void *ctxt) | 2970 | channel_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 */ | ||
2820 | int | 3022 | int |
2821 | channel_input_ieof(int type, u_int32_t seq, void *ctxt) | 3023 | channel_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 */ | ||
2846 | int | ||
2847 | channel_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 */ | ||
2887 | int | 3043 | int |
2888 | channel_input_oclose(int type, u_int32_t seq, void *ctxt) | 3044 | channel_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 */ | ||
2903 | int | ||
2904 | channel_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 */ | ||
2923 | int | 3055 | int |
2924 | channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) | 3056 | channel_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 */ | ||
2977 | int | 3109 | int |
2978 | channel_input_open_failure(int type, u_int32_t seq, void *ctxt) | 3110 | channel_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 */ | ||
3018 | int | 3148 | int |
3019 | channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) | 3149 | channel_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 */ | ||
3049 | int | ||
3050 | channel_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 */ | ||
3081 | int | 3178 | int |
3082 | channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) | 3179 | channel_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 | ||
3112 | void | 3208 | void |
3113 | channel_set_af(int af) | 3209 | channel_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 | ||
3182 | static int | 3278 | static int |
3183 | channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd, | 3279 | channel_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 | ||
3330 | static int | 3433 | static int |
3331 | channel_setup_fwd_listener_streamlocal(int type, struct Forward *fwd, | 3434 | channel_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 | ||
3404 | static int | 3507 | static int |
3405 | channel_cancel_rport_listener_tcpip(const char *host, u_short port) | 3508 | channel_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 | ||
3424 | static int | 3528 | static int |
3425 | channel_cancel_rport_listener_streamlocal(const char *path) | 3529 | channel_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 | ||
3446 | int | 3550 | int |
3447 | channel_cancel_rport_listener(struct Forward *fwd) | 3551 | channel_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 | ||
3455 | static int | 3562 | static int |
3456 | channel_cancel_lport_listener_tcpip(const char *lhost, u_short lport, | 3563 | channel_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 | ||
3490 | static int | 3598 | static int |
3491 | channel_cancel_lport_listener_streamlocal(const char *path) | 3599 | channel_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 | ||
3517 | int | 3625 | int |
3518 | channel_cancel_lport_listener(struct Forward *fwd, int cport, struct ForwardOptions *fwd_opts) | 3626 | channel_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 */ |
3527 | int | 3639 | int |
3528 | channel_setup_local_fwd_listener(struct Forward *fwd, struct ForwardOptions *fwd_opts) | 3640 | channel_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 */ |
3540 | int | 3653 | int |
3541 | channel_setup_remote_fwd_listener(struct Forward *fwd, | 3654 | channel_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 | */ |
3581 | int | 3694 | int |
3582 | channel_request_remote_forwarding(struct Forward *fwd) | 3695 | channel_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 | ||
3659 | static int | 3752 | static int |
@@ -3718,36 +3811,33 @@ open_listen_match_streamlocal(ForwardPermission *allowed_open, | |||
3718 | * local side. | 3811 | * local side. |
3719 | */ | 3812 | */ |
3720 | static int | 3813 | static int |
3721 | channel_request_rforward_cancel_tcpip(const char *host, u_short port) | 3814 | channel_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 | */ |
3759 | static int | 3849 | static int |
3760 | channel_request_rforward_cancel_streamlocal(const char *path) | 3850 | channel_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 | */ |
3796 | int | 3883 | int |
3797 | channel_request_rforward_cancel(struct Forward *fwd) | 3884 | channel_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 | */ |
3813 | void | 3901 | void |
3814 | channel_permit_all_opens(void) | 3902 | channel_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 | ||
3820 | void | 3908 | void |
3821 | channel_add_permitted_opens(char *host, int port) | 3909 | channel_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 | */ |
3843 | void | 3923 | void |
3844 | channel_update_permitted_opens(int idx, int newport) | 3924 | channel_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 | ||
3871 | int | 3946 | int |
3872 | channel_add_adm_permitted_opens(char *host, int port) | 3947 | channel_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 | ||
3887 | void | 3954 | void |
3888 | channel_disable_adm_local_opens(void) | 3955 | channel_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 | ||
3896 | void | 3961 | void |
3897 | channel_clear_permitted_opens(void) | 3962 | channel_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 | ||
3911 | void | 3971 | void |
3912 | channel_clear_adm_permitted_opens(void) | 3972 | channel_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 | |||
3926 | void | ||
3927 | channel_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 | */ |
4033 | static Channel * | 4070 | static int |
4034 | connect_to_reason(const char *name, int port, char *ctype, char *rname, | 4071 | connect_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 */ |
4105 | static Channel * | 4136 | static Channel * |
4106 | connect_to(const char *name, int port, char *ctype, char *rname) | 4137 | connect_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 | */ |
4115 | Channel * | 4164 | Channel * |
4116 | channel_connect_by_listen_address(const char *listen_host, | 4165 | channel_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 | ||
4136 | Channel * | 4190 | Channel * |
4137 | channel_connect_by_listen_path(const char *path, char *ctype, char *rname) | 4191 | channel_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. */ |
4154 | Channel * | 4212 | Channel * |
4155 | channel_connect_to_port(const char *host, u_short port, char *ctype, | 4213 | channel_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. */ |
4189 | Channel * | 4271 | Channel * |
4190 | channel_connect_to_path(const char *path, char *ctype, char *rname) | 4272 | channel_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 | ||
4220 | void | 4309 | void |
4221 | channel_send_window_changes(void) | 4310 | channel_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 */ | ||
4335 | static Channel * | ||
4336 | rdynamic_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 */ | ||
4362 | static int | ||
4363 | rdynamic_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 | */ |
4248 | int | 4389 | int |
4249 | x11_create_display_inet(int x11_display_offset, int x11_use_localhost, | 4390 | x11_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 | ||
4349 | static int | 4492 | static int |
@@ -4401,7 +4544,7 @@ is_path_to_xsocket(const char *display, char *path, size_t pathlen) | |||
4401 | #endif | 4544 | #endif |
4402 | 4545 | ||
4403 | int | 4546 | int |
4404 | x11_connect_display(void) | 4547 | x11_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 */ | ||
4524 | int | ||
4525 | x11_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 */ | ||
4569 | int | ||
4570 | deny_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 | */ |
4597 | void | 4669 | void |
4598 | x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, | 4670 | x11_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 | |||
4666 | void | ||
4667 | auth_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 | ||
66 | struct ssh; | ||
66 | struct Channel; | 67 | struct Channel; |
67 | typedef struct Channel Channel; | 68 | typedef struct Channel Channel; |
69 | struct fwd_perm_list; | ||
68 | 70 | ||
69 | typedef void channel_open_fn(int, int, void *); | 71 | typedef void channel_open_fn(struct ssh *, int, int, void *); |
70 | typedef void channel_callback_fn(int, void *); | 72 | typedef void channel_callback_fn(struct ssh *, int, void *); |
71 | typedef int channel_infilter_fn(struct Channel *, char *, int); | 73 | typedef int channel_infilter_fn(struct ssh *, struct Channel *, char *, int); |
72 | typedef void channel_filter_cleanup_fn(int, void *); | 74 | typedef void channel_filter_cleanup_fn(struct ssh *, int, void *); |
73 | typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *); | 75 | typedef 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 */ |
76 | typedef void channel_confirm_cb(int, struct Channel *, void *); | 79 | typedef void channel_confirm_cb(struct ssh *, int, struct Channel *, void *); |
77 | typedef void channel_confirm_abandon_cb(struct Channel *, void *); | 80 | typedef void channel_confirm_abandon_cb(struct ssh *, struct Channel *, void *); |
78 | struct channel_confirm { | 81 | struct 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 */ |
94 | typedef int mux_callback_fn(struct Channel *); | 97 | typedef int mux_callback_fn(struct ssh *, struct Channel *); |
95 | 98 | ||
96 | struct Channel { | 99 | struct 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 */ | ||
223 | void channel_init_channels(struct ssh *ssh); | ||
210 | 224 | ||
211 | /* channel management */ | 225 | /* channel management */ |
212 | 226 | ||
213 | Channel *channel_by_id(int); | 227 | Channel *channel_by_id(struct ssh *, int); |
214 | Channel *channel_by_remote_id(int); | 228 | Channel *channel_by_remote_id(struct ssh *, u_int); |
215 | Channel *channel_lookup(int); | 229 | Channel *channel_lookup(struct ssh *, int); |
216 | Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); | 230 | Channel *channel_new(struct ssh *, char *, int, int, int, int, |
217 | void channel_set_fds(int, int, int, int, int, int, int, u_int); | 231 | u_int, u_int, int, char *, int); |
218 | void channel_free(Channel *); | 232 | void channel_set_fds(struct ssh *, int, int, int, int, int, |
219 | void channel_free_all(void); | 233 | int, int, u_int); |
220 | void channel_stop_listening(void); | 234 | void channel_free(struct ssh *, Channel *); |
221 | 235 | void channel_free_all(struct ssh *); | |
222 | void channel_send_open(int); | 236 | void channel_stop_listening(struct ssh *); |
223 | void channel_request_start(int, char *, int); | 237 | |
224 | void channel_register_cleanup(int, channel_callback_fn *, int); | 238 | void channel_send_open(struct ssh *, int); |
225 | void channel_register_open_confirm(int, channel_open_fn *, void *); | 239 | void channel_request_start(struct ssh *, int, char *, int); |
226 | void channel_register_filter(int, channel_infilter_fn *, | 240 | void channel_register_cleanup(struct ssh *, int, |
227 | channel_outfilter_fn *, channel_filter_cleanup_fn *, void *); | 241 | channel_callback_fn *, int); |
228 | void channel_register_status_confirm(int, channel_confirm_cb *, | 242 | void channel_register_open_confirm(struct ssh *, int, |
229 | channel_confirm_abandon_cb *, void *); | 243 | channel_open_fn *, void *); |
230 | void channel_cancel_cleanup(int); | 244 | void channel_register_filter(struct ssh *, int, channel_infilter_fn *, |
231 | int channel_close_fd(int *); | 245 | channel_outfilter_fn *, channel_filter_cleanup_fn *, void *); |
232 | void channel_send_window_changes(void); | 246 | void channel_register_status_confirm(struct ssh *, int, |
247 | channel_confirm_cb *, channel_confirm_abandon_cb *, void *); | ||
248 | void channel_cancel_cleanup(struct ssh *, int); | ||
249 | int channel_close_fd(struct ssh *, int *); | ||
250 | void channel_send_window_changes(struct ssh *); | ||
233 | 251 | ||
234 | /* mux proxy support */ | 252 | /* mux proxy support */ |
235 | 253 | ||
236 | int channel_proxy_downstream(Channel *mc); | 254 | int channel_proxy_downstream(struct ssh *, Channel *mc); |
237 | int channel_proxy_upstream(Channel *, int, u_int32_t, void *); | 255 | int channel_proxy_upstream(Channel *, int, u_int32_t, struct ssh *); |
238 | 256 | ||
239 | /* protocol handler */ | 257 | /* protocol handler */ |
240 | 258 | ||
241 | int channel_input_close(int, u_int32_t, void *); | 259 | int channel_input_data(int, u_int32_t, struct ssh *); |
242 | int channel_input_close_confirmation(int, u_int32_t, void *); | 260 | int channel_input_extended_data(int, u_int32_t, struct ssh *); |
243 | int channel_input_data(int, u_int32_t, void *); | 261 | int channel_input_ieof(int, u_int32_t, struct ssh *); |
244 | int channel_input_extended_data(int, u_int32_t, void *); | 262 | int channel_input_oclose(int, u_int32_t, struct ssh *); |
245 | int channel_input_ieof(int, u_int32_t, void *); | 263 | int channel_input_open_confirmation(int, u_int32_t, struct ssh *); |
246 | int channel_input_oclose(int, u_int32_t, void *); | 264 | int channel_input_open_failure(int, u_int32_t, struct ssh *); |
247 | int channel_input_open_confirmation(int, u_int32_t, void *); | 265 | int channel_input_port_open(int, u_int32_t, struct ssh *); |
248 | int channel_input_open_failure(int, u_int32_t, void *); | 266 | int channel_input_window_adjust(int, u_int32_t, struct ssh *); |
249 | int channel_input_port_open(int, u_int32_t, void *); | 267 | int channel_input_status_confirm(int, u_int32_t, struct ssh *); |
250 | int channel_input_window_adjust(int, u_int32_t, void *); | ||
251 | int 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 | ||
255 | void channel_prepare_select(fd_set **, fd_set **, int *, u_int*, | 271 | void channel_prepare_select(struct ssh *, fd_set **, fd_set **, int *, |
256 | time_t*, int); | 272 | u_int*, time_t*); |
257 | void channel_after_select(fd_set *, fd_set *); | 273 | void channel_after_select(struct ssh *, fd_set *, fd_set *); |
258 | void channel_output_poll(void); | 274 | void channel_output_poll(struct ssh *); |
259 | 275 | ||
260 | int channel_not_very_much_buffered_data(void); | 276 | int channel_not_very_much_buffered_data(struct ssh *); |
261 | void channel_close_all(void); | 277 | void channel_close_all(struct ssh *); |
262 | int channel_still_open(void); | 278 | int channel_still_open(struct ssh *); |
263 | char *channel_open_message(void); | 279 | char *channel_open_message(struct ssh *); |
264 | int channel_find_open(void); | 280 | int channel_find_open(struct ssh *); |
265 | 281 | ||
266 | /* tcp forwarding */ | 282 | /* tcp forwarding */ |
267 | struct Forward; | 283 | struct Forward; |
268 | struct ForwardOptions; | 284 | struct ForwardOptions; |
269 | void channel_set_af(int af); | 285 | void channel_set_af(struct ssh *, int af); |
270 | void channel_permit_all_opens(void); | 286 | void channel_permit_all_opens(struct ssh *); |
271 | void channel_add_permitted_opens(char *, int); | 287 | void channel_add_permitted_opens(struct ssh *, char *, int); |
272 | int channel_add_adm_permitted_opens(char *, int); | 288 | int channel_add_adm_permitted_opens(struct ssh *, char *, int); |
273 | void channel_disable_adm_local_opens(void); | 289 | void channel_copy_adm_permitted_opens(struct ssh *, |
274 | void channel_update_permitted_opens(int, int); | 290 | const struct fwd_perm_list *); |
275 | void channel_clear_permitted_opens(void); | 291 | void channel_disable_adm_local_opens(struct ssh *); |
276 | void channel_clear_adm_permitted_opens(void); | 292 | void channel_update_permitted_opens(struct ssh *, int, int); |
277 | void channel_print_adm_permitted_opens(void); | 293 | void channel_clear_permitted_opens(struct ssh *); |
278 | Channel *channel_connect_to_port(const char *, u_short, char *, char *, int *, | 294 | void channel_clear_adm_permitted_opens(struct ssh *); |
279 | const char **); | 295 | void channel_print_adm_permitted_opens(struct ssh *); |
280 | Channel *channel_connect_to_path(const char *, char *, char *); | 296 | Channel *channel_connect_to_port(struct ssh *, const char *, u_short, |
281 | Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); | 297 | char *, char *, int *, const char **); |
282 | Channel *channel_connect_by_listen_address(const char *, u_short, | 298 | Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *); |
283 | char *, char *); | 299 | Channel *channel_connect_stdio_fwd(struct ssh *, const char*, |
284 | Channel *channel_connect_by_listen_path(const char *, char *, char *); | 300 | u_short, int, int); |
285 | int channel_request_remote_forwarding(struct Forward *); | 301 | Channel *channel_connect_by_listen_address(struct ssh *, const char *, |
286 | int channel_setup_local_fwd_listener(struct Forward *, struct ForwardOptions *); | 302 | u_short, char *, char *); |
287 | int channel_request_rforward_cancel(struct Forward *); | 303 | Channel *channel_connect_by_listen_path(struct ssh *, const char *, |
288 | int channel_setup_remote_fwd_listener(struct Forward *, int *, struct ForwardOptions *); | 304 | char *, char *); |
289 | int channel_cancel_rport_listener(struct Forward *); | 305 | int channel_request_remote_forwarding(struct ssh *, struct Forward *); |
290 | int channel_cancel_lport_listener(struct Forward *, int, struct ForwardOptions *); | 306 | int channel_setup_local_fwd_listener(struct ssh *, struct Forward *, |
307 | struct ForwardOptions *); | ||
308 | int channel_request_rforward_cancel(struct ssh *, struct Forward *); | ||
309 | int channel_setup_remote_fwd_listener(struct ssh *, struct Forward *, | ||
310 | int *, struct ForwardOptions *); | ||
311 | int channel_cancel_rport_listener(struct ssh *, struct Forward *); | ||
312 | int channel_cancel_lport_listener(struct ssh *, struct Forward *, | ||
313 | int, struct ForwardOptions *); | ||
291 | int permitopen_port(const char *); | 314 | int permitopen_port(const char *); |
292 | 315 | ||
293 | /* x11 forwarding */ | 316 | /* x11 forwarding */ |
294 | 317 | ||
295 | void channel_set_x11_refuse_time(u_int); | 318 | void channel_set_x11_refuse_time(struct ssh *, u_int); |
296 | int x11_connect_display(void); | 319 | int x11_connect_display(struct ssh *); |
297 | int x11_create_display_inet(int, int, int, u_int *, int **); | 320 | int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **); |
298 | int x11_input_open(int, u_int32_t, void *); | 321 | void x11_request_forwarding_with_spoofing(struct ssh *, int, |
299 | void x11_request_forwarding_with_spoofing(int, const char *, const char *, | 322 | const char *, const char *, const char *, int); |
300 | const char *, int); | ||
301 | int deny_input_open(int, u_int32_t, void *); | ||
302 | |||
303 | /* agent forwarding */ | ||
304 | |||
305 | void auth_request_forwarding(void); | ||
306 | 323 | ||
307 | /* channel close */ | 324 | /* channel close */ |
308 | 325 | ||
309 | int chan_is_dead(Channel *, int); | 326 | int chan_is_dead(struct ssh *, Channel *, int); |
310 | void chan_mark_dead(Channel *); | 327 | void chan_mark_dead(struct ssh *, Channel *); |
311 | 328 | ||
312 | /* channel events */ | 329 | /* channel events */ |
313 | 330 | ||
314 | void chan_rcvd_oclose(Channel *); | 331 | void chan_rcvd_oclose(struct ssh *, Channel *); |
315 | void chan_rcvd_eow(Channel *); /* SSH2-only */ | 332 | void chan_rcvd_eow(struct ssh *, Channel *); |
316 | void chan_read_failed(Channel *); | 333 | void chan_read_failed(struct ssh *, Channel *); |
317 | void chan_ibuf_empty(Channel *); | 334 | void chan_ibuf_empty(struct ssh *, Channel *); |
318 | 335 | void chan_rcvd_ieof(struct ssh *, Channel *); | |
319 | void chan_rcvd_ieof(Channel *); | 336 | void chan_write_failed(struct ssh *, Channel *); |
320 | void chan_write_failed(Channel *); | 337 | void chan_obuf_empty(struct ssh *, Channel *); |
321 | void 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 | */ | ||
45 | struct ssh1_3des_ctx | ||
46 | { | ||
47 | EVP_CIPHER_CTX k1, k2, k3; | ||
48 | }; | ||
49 | |||
50 | const EVP_CIPHER * evp_ssh1_3des(void); | ||
51 | int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); | ||
52 | |||
53 | static int | ||
54 | ssh1_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 | |||
91 | static int | ||
92 | ssh1_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 | |||
105 | static int | ||
106 | ssh1_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 | |||
121 | int | ||
122 | ssh1_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 | |||
142 | const EVP_CIPHER * | ||
143 | evp_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 | |||
40 | const EVP_CIPHER * evp_ssh1_bf(void); | ||
41 | |||
42 | static void | ||
43 | swap_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 | ||
62 | static 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 | |||
74 | static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, | ||
75 | const u_char *, LIBCRYPTO_EVP_INL_TYPE) = NULL; | ||
76 | |||
77 | static int | ||
78 | bf_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 | |||
89 | const EVP_CIPHER * | ||
90 | evp_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 */ | ||
@@ -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 | ||
55 | extern const EVP_CIPHER *evp_ssh1_bf(void); | ||
56 | extern const EVP_CIPHER *evp_ssh1_3des(void); | ||
57 | extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); | ||
58 | #endif | ||
59 | 54 | ||
60 | struct sshcipher_ctx { | 55 | struct sshcipher_ctx { |
61 | int plaintext; | 56 | int plaintext; |
@@ -68,17 +63,16 @@ struct sshcipher_ctx { | |||
68 | 63 | ||
69 | struct sshcipher { | 64 | struct 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 | ||
89 | static const struct sshcipher ciphers[] = { | 83 | static 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 | ||
205 | u_int | 178 | u_int |
206 | cipher_get_number(const struct sshcipher *c) | ||
207 | { | ||
208 | return (c->number); | ||
209 | } | ||
210 | |||
211 | u_int | ||
212 | cipher_is_cbc(const struct sshcipher *c) | 179 | cipher_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 | ||
223 | u_int | ||
224 | cipher_ctx_get_number(struct sshcipher_ctx *cc) | ||
225 | { | ||
226 | return cc->cipher->number; | ||
227 | } | ||
228 | |||
229 | u_int | ||
230 | cipher_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 | |||
241 | const struct sshcipher * | 190 | const struct sshcipher * |
242 | cipher_by_name(const char *name) | 191 | cipher_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 | ||
251 | const struct sshcipher * | ||
252 | cipher_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 "," |
262 | int | 201 | int |
263 | ciphers_valid(const char *names) | 202 | ciphers_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 | |||
290 | int | ||
291 | cipher_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 | |||
302 | char * | ||
303 | cipher_name(int id) | ||
304 | { | ||
305 | const struct sshcipher *c = cipher_by_number(id); | ||
306 | return (c==NULL) ? "<unknown>" : c->name; | ||
307 | } | ||
308 | |||
309 | const char * | 224 | const char * |
310 | cipher_warning_message(const struct sshcipher_ctx *cc) | 225 | cipher_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 | */ | ||
542 | int | ||
543 | cipher_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 | |||
566 | cipher_get_keyiv_len(const struct sshcipher_ctx *cc) | 434 | cipher_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 | ||
584 | int | 449 | int |
@@ -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 | ||
@@ -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 | ||
65 | struct sshcipher; | 48 | struct sshcipher; |
66 | struct sshcipher_ctx; | 49 | struct sshcipher_ctx; |
67 | 50 | ||
68 | u_int cipher_mask_ssh1(int); | ||
69 | const struct sshcipher *cipher_by_name(const char *); | 51 | const struct sshcipher *cipher_by_name(const char *); |
70 | const struct sshcipher *cipher_by_number(int); | ||
71 | int cipher_number(const char *); | ||
72 | char *cipher_name(int); | ||
73 | const char *cipher_warning_message(const struct sshcipher_ctx *); | 52 | const char *cipher_warning_message(const struct sshcipher_ctx *); |
74 | int ciphers_valid(const char *); | 53 | int ciphers_valid(const char *); |
75 | char *cipher_alg_list(char, int); | 54 | char *cipher_alg_list(char, int); |
@@ -80,8 +59,6 @@ int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *, | |||
80 | int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int, | 59 | int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int, |
81 | const u_char *, u_int); | 60 | const u_char *, u_int); |
82 | void cipher_free(struct sshcipher_ctx *); | 61 | void cipher_free(struct sshcipher_ctx *); |
83 | int cipher_set_key_string(struct sshcipher_ctx **, | ||
84 | const struct sshcipher *, const char *, int); | ||
85 | u_int cipher_blocksize(const struct sshcipher *); | 62 | u_int cipher_blocksize(const struct sshcipher *); |
86 | u_int cipher_keylen(const struct sshcipher *); | 63 | u_int cipher_keylen(const struct sshcipher *); |
87 | u_int cipher_seclen(const struct sshcipher *); | 64 | u_int cipher_seclen(const struct sshcipher *); |
@@ -90,13 +67,9 @@ u_int cipher_ivlen(const struct sshcipher *); | |||
90 | u_int cipher_is_cbc(const struct sshcipher *); | 67 | u_int cipher_is_cbc(const struct sshcipher *); |
91 | 68 | ||
92 | u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); | 69 | u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); |
93 | u_int cipher_ctx_get_number(struct sshcipher_ctx *); | ||
94 | 70 | ||
95 | u_int cipher_get_number(const struct sshcipher *); | ||
96 | int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int); | 71 | int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int); |
97 | int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *); | 72 | int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *); |
98 | int cipher_get_keyiv_len(const struct sshcipher_ctx *); | 73 | int cipher_get_keyiv_len(const struct sshcipher_ctx *); |
99 | int cipher_get_keycontext(const struct sshcipher_ctx *, u_char *); | ||
100 | void 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. */ |
154 | volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ | 153 | volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ |
155 | static int escape_char1; /* Escape character. (proto1 only) */ | ||
156 | static int escape_pending1; /* Last character was an escape (proto1 only) */ | ||
157 | static int last_was_cr; /* Last character was a newline. */ | 154 | static int last_was_cr; /* Last character was a newline. */ |
158 | static int exit_status; /* Used to store the command exit status. */ | 155 | static int exit_status; /* Used to store the command exit status. */ |
159 | static int stdin_eof; /* EOF has been encountered on stderr. */ | 156 | static Buffer stderr_buffer; /* Used for final exit message. */ |
160 | static Buffer stdin_buffer; /* Buffer for stdin data. */ | ||
161 | static Buffer stdout_buffer; /* Buffer for stdout data. */ | ||
162 | static Buffer stderr_buffer; /* Buffer for stderr data. */ | ||
163 | static u_int buffer_high; /* Soft max buffer size. */ | ||
164 | static int connection_in; /* Connection to server (input). */ | 157 | static int connection_in; /* Connection to server (input). */ |
165 | static int connection_out; /* Connection to server (output). */ | 158 | static int connection_out; /* Connection to server (output). */ |
166 | static int need_rekeying; /* Set to non-zero if rekeying is requested. */ | 159 | static 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? */ | ||
187 | struct global_confirm { | 181 | struct 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 | |||
212 | static void | ||
213 | enter_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 | */ |
262 | static void | 247 | static void |
263 | set_control_persist_exit_time(void) | 248 | set_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 |
306 | int | 291 | int |
307 | client_x11_get_proto(const char *display, const char *xauth_path, | 292 | client_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 | |||
463 | static void | ||
464 | client_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 | |||
518 | static void | ||
519 | client_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 | ||
549 | static void | 451 | static void |
550 | client_check_window_change(void) | 452 | client_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 | ||
575 | static int | 464 | static int |
576 | client_global_request_reply(int type, u_int32_t seq, void *ctxt) | 465 | client_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 | */ |
613 | static void | 502 | static void |
614 | client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, | 503 | client_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 | ||
804 | static void | 665 | static void |
805 | client_status_confirm(int type, Channel *c, void *ctx) | 666 | client_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 | ||
865 | static void | 725 | static void |
866 | client_abandon_status_confirm(Channel *c, void *ctx) | 726 | client_abandon_status_confirm(struct ssh *ssh, Channel *c, void *ctx) |
867 | { | 727 | { |
868 | free(ctx); | 728 | free(ctx); |
869 | } | 729 | } |
870 | 730 | ||
871 | void | 731 | void |
872 | client_expect_confirm(int id, const char *request, | 732 | client_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 | ||
905 | static void | 765 | static void |
906 | process_cmdline(void) | 766 | process_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 */ | ||
1034 | struct escape_help_text { | 888 | struct 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 | ||
1054 | static void | 908 | static void |
1055 | print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client, | 909 | print_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 | */ |
1088 | static int | 941 | static int |
1089 | process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, | 942 | process_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 | ||
1328 | static void | ||
1329 | client_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 | |||
1384 | static void | ||
1385 | client_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) | |||
1449 | static void | 1164 | static void |
1450 | client_process_buffered_input_packets(void) | 1165 | client_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 */ |
1470 | void | 1185 | void |
1471 | client_filter_cleanup(int cid, void *ctx) | 1186 | client_filter_cleanup(struct ssh *ssh, int cid, void *ctx) |
1472 | { | 1187 | { |
1473 | free(ctx); | 1188 | free(ctx); |
1474 | } | 1189 | } |
1475 | 1190 | ||
1476 | int | 1191 | int |
1477 | client_simple_escape_filter(Channel *c, char *buf, int len) | 1192 | client_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 | ||
1486 | static void | 1201 | static void |
1487 | client_channel_closed(int id, void *arg) | 1202 | client_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 | |||
1501 | int | 1215 | int |
1502 | client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | 1216 | client_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 | ||
1799 | static int | ||
1800 | client_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 | } | ||
1810 | static int | ||
1811 | client_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 | } | ||
1821 | static int | ||
1822 | client_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 | |||
1839 | static int | ||
1840 | client_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 | |||
1885 | static Channel * | 1462 | static Channel * |
1886 | client_request_forwarded_tcpip(const char *request_type, int rchan, | 1463 | client_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 | ||
1938 | static Channel * | 1515 | static Channel * |
1939 | client_request_forwarded_streamlocal(const char *request_type, int rchan) | 1516 | client_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 | ||
1959 | static Channel * | 1537 | static Channel * |
1960 | client_request_x11(const char *request_type, int rchan) | 1538 | client_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 | ||
2000 | static Channel * | 1578 | static Channel * |
2001 | client_request_agent(const char *request_type, int rchan) | 1579 | client_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 | ||
2026 | int | 1604 | int |
2027 | client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) | 1605 | client_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 */ |
2071 | static int | 1645 | static int |
2072 | client_input_channel_open(int type, u_int32_t seq, void *ctxt) | 1646 | client_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 | ||
2127 | static int | 1702 | static int |
2128 | client_input_channel_req(int type, u_int32_t seq, void *ctxt) | 1703 | client_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 | ||
2325 | static void | 1900 | static void |
2326 | client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx) | 1901 | client_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 | ||
2568 | static int | 2143 | static int |
2569 | client_input_global_request(int type, u_int32_t seq, void *ctxt) | 2144 | client_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 | ||
2591 | void | 2166 | void |
2592 | client_session2_setup(int id, int want_tty, int want_subsystem, | 2167 | client_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 | ||
2689 | static void | 2265 | static void |
2690 | client_init_dispatch_20(void) | 2266 | client_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 | ||
2715 | static void | ||
2716 | client_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 | |||
2735 | static void | ||
2736 | client_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 | |||
2743 | static void | ||
2744 | client_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 | |||
2754 | void | 2291 | void |
2755 | client_stop_mux(void) | 2292 | client_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 | ||
40 | struct ssh; | ||
41 | |||
40 | /* Client side main loop for the interactive session. */ | 42 | /* Client side main loop for the interactive session. */ |
41 | int client_loop(int, int, int); | 43 | int client_loop(struct ssh *, int, int, int); |
42 | int client_x11_get_proto(const char *, const char *, u_int, u_int, | 44 | int client_x11_get_proto(struct ssh *, const char *, const char *, |
43 | char **, char **); | 45 | u_int, u_int, char **, char **); |
44 | void client_global_request_reply_fwd(int, u_int32_t, void *); | 46 | void client_global_request_reply_fwd(int, u_int32_t, void *); |
45 | void client_session2_setup(int, int, int, const char *, struct termios *, | 47 | void client_session2_setup(struct ssh *, int, int, int, |
46 | int, Buffer *, char **); | 48 | const char *, struct termios *, int, Buffer *, char **); |
47 | int client_request_tun_fwd(int, int, int); | 49 | int client_request_tun_fwd(struct ssh *, int, int, int); |
48 | void client_stop_mux(void); | 50 | void client_stop_mux(void); |
49 | 51 | ||
50 | /* Escape filter for protocol 2 sessions */ | 52 | /* Escape filter for protocol 2 sessions */ |
51 | void *client_new_escape_filter_ctx(int); | 53 | void *client_new_escape_filter_ctx(int); |
52 | void client_filter_cleanup(int, void *); | 54 | void client_filter_cleanup(struct ssh *, int, void *); |
53 | int client_simple_escape_filter(Channel *, char *, int); | 55 | int client_simple_escape_filter(struct ssh *, Channel *, char *, int); |
54 | 56 | ||
55 | /* Global request confirmation callbacks */ | 57 | /* Global request confirmation callbacks */ |
56 | typedef void global_confirm_cb(int, u_int32_t seq, void *); | 58 | typedef void global_confirm_cb(struct ssh *, int, u_int32_t, void *); |
57 | void client_register_global_confirm(global_confirm_cb *, void *); | 59 | void client_register_global_confirm(global_confirm_cb *, void *); |
58 | 60 | ||
59 | /* Channel request confirmation callbacks */ | 61 | /* Channel request confirmation callbacks */ |
60 | enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY }; | 62 | enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY }; |
61 | void client_expect_confirm(int, const char *, enum confirm_action); | 63 | void 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 | ||
76 | void muxserver_listen(void); | 79 | void muxserver_listen(struct ssh *); |
77 | int muxclient(const char *); | 80 | int muxclient(const char *); |
78 | void mux_exit_message(Channel *, int); | 81 | void mux_exit_message(struct ssh *, Channel *, int); |
79 | void mux_tty_alloc_failed(Channel *); | 82 | void mux_tty_alloc_failed(struct ssh *ssh, Channel *); |
80 | 83 | ||
@@ -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 | ||
42 | int compat13 = 0; | ||
43 | int compat20 = 0; | ||
44 | int datafellows = 0; | 42 | int datafellows = 0; |
45 | 43 | ||
46 | void | ||
47 | enable_compat20(void) | ||
48 | { | ||
49 | if (compat20) | ||
50 | return; | ||
51 | debug("Enabling compatibility mode for protocol 2.0"); | ||
52 | compat20 = 1; | ||
53 | } | ||
54 | void | ||
55 | enable_compat13(void) | ||
56 | { | ||
57 | debug("Enabling compatibility mode for protocol 1.3"); | ||
58 | compat13 = 1; | ||
59 | } | ||
60 | /* datafellows bug compatibility */ | 44 | /* datafellows bug compatibility */ |
61 | u_int | 45 | u_int |
62 | compat_datafellows(const char *version) | 46 | compat_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; |
@@ -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 | ||
66 | void enable_compat13(void); | ||
67 | void enable_compat20(void); | ||
68 | u_int compat_datafellows(const char *); | 66 | u_int compat_datafellows(const char *); |
69 | int proto_spec(const char *); | 67 | int proto_spec(const char *); |
70 | char *compat_cipher_proposal(char *); | 68 | char *compat_cipher_proposal(char *); |
71 | char *compat_pkalg_proposal(char *); | 69 | char *compat_pkalg_proposal(char *); |
72 | char *compat_kex_proposal(char *); | 70 | char *compat_kex_proposal(char *); |
73 | 71 | ||
74 | extern int compat13; | ||
75 | extern int compat20; | ||
76 | extern int datafellows; | 72 | extern 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 |
@@ -624,7 +624,6 @@ ac_includes_default="\ | |||
624 | #endif" | 624 | #endif" |
625 | 625 | ||
626 | ac_subst_vars='LTLIBOBJS | 626 | ac_subst_vars='LTLIBOBJS |
627 | LIBOBJS | ||
628 | UNSUPPORTED_ALGORITHMS | 627 | UNSUPPORTED_ALGORITHMS |
629 | TEST_MALLOC_OPTIONS | 628 | TEST_MALLOC_OPTIONS |
630 | TEST_SSH_UTF8 | 629 | TEST_SSH_UTF8 |
@@ -648,7 +647,7 @@ TEST_SSH_ECC | |||
648 | LIBEDIT | 647 | LIBEDIT |
649 | PKGCONFIG | 648 | PKGCONFIG |
650 | LDNSCONFIG | 649 | LDNSCONFIG |
651 | COMMENT_OUT_RSA1 | 650 | LIBOBJS |
652 | LD | 651 | LD |
653 | PATH_PASSWD_PROG | 652 | PATH_PASSWD_PROG |
654 | STARTUP_SCRIPT_SHELL | 653 | STARTUP_SCRIPT_SHELL |
@@ -735,13 +734,14 @@ ac_user_opts=' | |||
735 | enable_option_checking | 734 | enable_option_checking |
736 | enable_largefile | 735 | enable_largefile |
737 | with_openssl | 736 | with_openssl |
738 | with_ssh1 | ||
739 | with_stackprotect | 737 | with_stackprotect |
740 | with_hardening | 738 | with_hardening |
741 | with_rpath | 739 | with_rpath |
742 | with_cflags | 740 | with_cflags |
741 | with_cflags_after | ||
743 | with_cppflags | 742 | with_cppflags |
744 | with_ldflags | 743 | with_ldflags |
744 | with_ldflags_after | ||
745 | with_libs | 745 | with_libs |
746 | with_Werror | 746 | with_Werror |
747 | with_solaris_contracts | 747 | with_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 | ||
5636 | openssl=yes | 5637 | openssl=yes |
5637 | ssh1=no | ||
5638 | COMMENT_OUT_RSA1="#no ssh1#" | ||
5639 | 5638 | ||
5640 | # Check whether --with-openssl was given. | 5639 | # Check whether --with-openssl was given. |
5641 | if test "${with_openssl+set}" = set; then : | 5640 | if 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; } |
5663 | fi | 5661 | fi |
5664 | 5662 | ||
5665 | |||
5666 | # Check whether --with-ssh1 was given. | ||
5667 | if 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 | |||
5682 | fi | ||
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; } | ||
5686 | if test "x$ssh1" = "xyes" ; then | ||
5687 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 | ||
5688 | $as_echo "yes" >&6; } | ||
5689 | |||
5690 | cat >>confdefs.h <<_ACEOF | ||
5691 | #define WITH_SSH1 1 | ||
5692 | _ACEOF | ||
5693 | |||
5694 | |||
5695 | else | ||
5696 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
5697 | $as_echo "no" >&6; } | ||
5698 | fi | ||
5699 | |||
5700 | use_stack_protector=1 | 5663 | use_stack_protector=1 |
5701 | use_toolchain_hardening=1 | 5664 | use_toolchain_hardening=1 |
5702 | 5665 | ||
@@ -5743,6 +5706,49 @@ CFLAGS="$saved_CFLAGS" | |||
5743 | 5706 | ||
5744 | if test "$GCC" = "yes" || test "$GCC" = "egcs"; then | 5707 | if 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> | ||
5720 | int 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 | ||
5731 | if ac_fn_c_try_compile "$LINENO"; then : | ||
5732 | |||
5733 | if `grep -i "unrecognized option" conftest.err >/dev/null` | ||
5734 | then | ||
5735 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
5736 | $as_echo "no" >&6; } | ||
5737 | CFLAGS="$saved_CFLAGS" | ||
5738 | else | ||
5739 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 | ||
5740 | $as_echo "yes" >&6; } | ||
5741 | CFLAGS="$saved_CFLAGS $_define_flag" | ||
5742 | fi | ||
5743 | else | ||
5744 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 | ||
5745 | $as_echo "no" >&6; } | ||
5746 | CFLAGS="$saved_CFLAGS" | ||
5747 | |||
5748 | fi | ||
5749 | rm -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; } | |||
6215 | fi | 6221 | fi |
6216 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | 6222 | rm -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; } | |||
6258 | fi | 6265 | fi |
6259 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | 6266 | rm -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 : | |||
6620 | fi | 6626 | fi |
6621 | 6627 | ||
6622 | 6628 | ||
6629 | |||
6630 | # Check whether --with-cflags-after was given. | ||
6631 | if 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 | |||
6639 | fi | ||
6640 | |||
6641 | |||
6623 | # Check whether --with-cppflags was given. | 6642 | # Check whether --with-cppflags was given. |
6624 | if test "${with_cppflags+set}" = set; then : | 6643 | if 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 : | |||
6644 | fi | 6663 | fi |
6645 | 6664 | ||
6646 | 6665 | ||
6666 | # Check whether --with-ldflags-after was given. | ||
6667 | if 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 | |||
6675 | fi | ||
6676 | |||
6677 | |||
6647 | # Check whether --with-libs was given. | 6678 | # Check whether --with-libs was given. |
6648 | if test "${with_libs+set}" = set; then : | 6679 | if 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 | |||
6756 | done | 6786 | done |
6757 | 6787 | ||
6758 | 6788 | ||
6789 | # sys/capsicum.h requires sys/types.h | ||
6790 | for ac_header in sys/capsicum.h | ||
6791 | do : | ||
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 | " | ||
6798 | if 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 | |||
6803 | fi | ||
6804 | |||
6805 | done | ||
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 |
6760 | for ac_header in lastlog.h | 6809 | for ac_header in lastlog.h |
6761 | do : | 6810 | do : |
@@ -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 : | |||
9631 | fi | 9682 | fi |
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 | ||
9634 | for ac_func in strftime | 9687 | for ac_func in strftime |
9635 | do : | 9688 | do : |
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 | |||
9686 | fi | 9739 | fi |
9687 | done | 9740 | done |
9688 | 9741 | ||
9742 | for ac_header in stdlib.h | ||
9743 | do : | ||
9744 | ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" | ||
9745 | if test "x$ac_cv_header_stdlib_h" = xyes; then : | ||
9746 | cat >>confdefs.h <<_ACEOF | ||
9747 | #define HAVE_STDLIB_H 1 | ||
9748 | _ACEOF | ||
9749 | |||
9750 | fi | ||
9751 | |||
9752 | done | ||
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; } | ||
9756 | if ${ac_cv_func_malloc_0_nonnull+:} false; then : | ||
9757 | $as_echo_n "(cached) " >&6 | ||
9758 | else | ||
9759 | if test "$cross_compiling" = yes; then : | ||
9760 | ac_cv_func_malloc_0_nonnull=no | ||
9761 | else | ||
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 | ||
9767 | char *malloc (); | ||
9768 | #endif | ||
9769 | |||
9770 | int | ||
9771 | main () | ||
9772 | { | ||
9773 | return ! malloc (0); | ||
9774 | ; | ||
9775 | return 0; | ||
9776 | } | ||
9777 | _ACEOF | ||
9778 | if ac_fn_c_try_run "$LINENO"; then : | ||
9779 | ac_cv_func_malloc_0_nonnull=yes | ||
9780 | else | ||
9781 | ac_cv_func_malloc_0_nonnull=no | ||
9782 | fi | ||
9783 | rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ | ||
9784 | conftest.$ac_objext conftest.beam conftest.$ac_ext | ||
9785 | fi | ||
9786 | |||
9787 | fi | ||
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; } | ||
9790 | if test $ac_cv_func_malloc_0_nonnull = yes; then : | ||
9791 | |||
9792 | $as_echo "#define HAVE_MALLOC 1" >>confdefs.h | ||
9793 | |||
9794 | else | ||
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 | ;; | ||
9801 | esac | ||
9802 | |||
9803 | |||
9804 | $as_echo "#define malloc rpl_malloc" >>confdefs.h | ||
9805 | |||
9806 | fi | ||
9807 | |||
9808 | |||
9809 | for ac_header in stdlib.h | ||
9810 | do : | ||
9811 | ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" | ||
9812 | if test "x$ac_cv_header_stdlib_h" = xyes; then : | ||
9813 | cat >>confdefs.h <<_ACEOF | ||
9814 | #define HAVE_STDLIB_H 1 | ||
9815 | _ACEOF | ||
9816 | |||
9817 | fi | ||
9818 | |||
9819 | done | ||
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; } | ||
9823 | if ${ac_cv_func_realloc_0_nonnull+:} false; then : | ||
9824 | $as_echo_n "(cached) " >&6 | ||
9825 | else | ||
9826 | if test "$cross_compiling" = yes; then : | ||
9827 | ac_cv_func_realloc_0_nonnull=no | ||
9828 | else | ||
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 | ||
9834 | char *realloc (); | ||
9835 | #endif | ||
9836 | |||
9837 | int | ||
9838 | main () | ||
9839 | { | ||
9840 | return ! realloc (0, 0); | ||
9841 | ; | ||
9842 | return 0; | ||
9843 | } | ||
9844 | _ACEOF | ||
9845 | if ac_fn_c_try_run "$LINENO"; then : | ||
9846 | ac_cv_func_realloc_0_nonnull=yes | ||
9847 | else | ||
9848 | ac_cv_func_realloc_0_nonnull=no | ||
9849 | fi | ||
9850 | rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ | ||
9851 | conftest.$ac_objext conftest.beam conftest.$ac_ext | ||
9852 | fi | ||
9853 | |||
9854 | fi | ||
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; } | ||
9857 | if test $ac_cv_func_realloc_0_nonnull = yes; then : | ||
9858 | |||
9859 | $as_echo "#define HAVE_REALLOC 1" >>confdefs.h | ||
9860 | |||
9861 | else | ||
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 | ;; | ||
9868 | esac | ||
9869 | |||
9870 | |||
9871 | $as_echo "#define realloc rpl_realloc" >>confdefs.h | ||
9872 | |||
9873 | fi | ||
9874 | |||
9875 | |||
9876 | # autoconf doesn't have AC_FUNC_CALLOC so fake it if malloc returns NULL; | ||
9877 | if 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 | |||
9884 | fi | ||
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 | ||
13060 | int | 13262 | int |
13061 | main () | 13263 | main () |
@@ -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 | ||
13098 | int | 13297 | int |
13099 | main () | 13298 | main () |
@@ -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 | ||
13136 | int | 13332 | int |
13137 | main () | 13333 | main () |
@@ -13858,6 +14054,7 @@ $as_echo_n "checking if select works with descriptor rlimit... " >&6; } | |||
13858 | if test "$cross_compiling" = yes; then : | 14054 | if 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 | ||
13862 | else | 14059 | else |
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; } | |||
13918 | if test "$cross_compiling" = yes; then : | 14115 | if 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 | ||
13922 | else | 14120 | else |
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 | ||
14053 | elif test "x$sandbox_arg" = "xcapsicum" || \ | 14251 | elif 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 | ||
16188 | fi | 16386 | fi |
16189 | 16387 | ||
16388 | ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "$ac_includes_default" | ||
16389 | if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then : | ||
16390 | |||
16391 | cat >>confdefs.h <<_ACEOF | ||
16392 | #define HAVE_STRUCT_STAT_ST_MTIM 1 | ||
16393 | _ACEOF | ||
16394 | |||
16395 | |||
16396 | fi | ||
16397 | |||
16398 | ac_fn_c_check_member "$LINENO" "struct stat" "st_mtime" "ac_cv_member_struct_stat_st_mtime" "$ac_includes_default" | ||
16399 | if test "x$ac_cv_member_struct_stat_st_mtime" = xyes; then : | ||
16400 | |||
16401 | cat >>confdefs.h <<_ACEOF | ||
16402 | #define HAVE_STRUCT_STAT_ST_MTIME 1 | ||
16403 | _ACEOF | ||
16404 | |||
16405 | |||
16406 | fi | ||
16407 | |||
16190 | ac_fn_c_check_member "$LINENO" "struct passwd" "pw_gecos" "ac_cv_member_struct_passwd_pw_gecos" " | 16408 | ac_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 | |||
19055 | UNSUPPORTED_ALGORITHMS=$unsupported_algorithms | 19273 | UNSUPPORTED_ALGORITHMS=$unsupported_algorithms |
19056 | 19274 | ||
19057 | 19275 | ||
19276 | CFLAGS="${CFLAGS} ${CFLAGS_AFTER}" | ||
19277 | LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}" | ||
19278 | |||
19058 | 19279 | ||
19059 | ac_config_files="$ac_config_files Makefile buildpkg.sh opensshd.init openssh.xml openbsd-compat/Makefile openbsd-compat/regress/Makefile survey.sh" | 19280 | ac_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 | ||
111 | openssl=yes | 111 | openssl=yes |
112 | ssh1=no | ||
113 | COMMENT_OUT_RSA1="#no ssh1#" | ||
114 | AC_ARG_WITH([openssl], | 112 | AC_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]) |
128 | fi | 125 | fi |
129 | 126 | ||
130 | AC_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 | ) | ||
146 | AC_MSG_CHECKING([whether SSH protocol 1 support is enabled]) | ||
147 | if 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]) | ||
151 | else | ||
152 | AC_MSG_RESULT([no]) | ||
153 | fi | ||
154 | |||
155 | use_stack_protector=1 | 127 | use_stack_protector=1 |
156 | use_toolchain_hardening=1 | 128 | use_toolchain_hardening=1 |
157 | AC_ARG_WITH([stackprotect], | 129 | AC_ARG_WITH([stackprotect], |
@@ -179,6 +151,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])], | |||
179 | CFLAGS="$saved_CFLAGS" | 151 | CFLAGS="$saved_CFLAGS" |
180 | 152 | ||
181 | if test "$GCC" = "yes" || test "$GCC" = "egcs"; then | 153 | if 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 | |||
293 | AC_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 | ) | ||
319 | AC_ARG_WITH([cppflags], | 302 | AC_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 | ) |
320 | AC_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 | ) | ||
337 | AC_ARG_WITH([libs], | 329 | AC_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 | ||
424 | AC_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 |
433 | AC_CHECK_HEADERS([lastlog.h], [], [], [ | 431 | AC_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]) | |||
1332 | AC_SEARCH_LIBS([inet_ntop], [resolv nsl]) | 1331 | AC_SEARCH_LIBS([inet_ntop], [resolv nsl]) |
1333 | AC_SEARCH_LIBS([gethostbyname], [resolv nsl]) | 1332 | AC_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 | ||
1335 | AC_FUNC_STRFTIME | 1336 | AC_FUNC_STRFTIME |
1337 | AC_FUNC_MALLOC | ||
1338 | AC_FUNC_REALLOC | ||
1339 | # autoconf doesn't have AC_FUNC_CALLOC so fake it if malloc returns NULL; | ||
1340 | if 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.]) | ||
1344 | fi | ||
1336 | 1345 | ||
1337 | # Check for ALTDIRFUNC glob() extension | 1346 | # Check for ALTDIRFUNC glob() extension |
1338 | AC_MSG_CHECKING([for GLOB_ALTDIRFUNC support]) | 1347 | AC_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 | ||
3203 | AC_MSG_CHECKING([if setrlimit(RLIMIT_NOFILE,{0,0}) works]) | 3213 | AC_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 | ||
3229 | AC_MSG_CHECKING([if setrlimit RLIMIT_FSIZE works]) | 3240 | AC_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]) |
3287 | elif test "x$sandbox_arg" = "xcapsicum" || \ | 3298 | elif 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]) | |||
3845 | OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmpx.h], [HAVE_TV_IN_UTMPX]) | 3856 | OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmpx.h], [HAVE_TV_IN_UTMPX]) |
3846 | 3857 | ||
3847 | AC_CHECK_MEMBERS([struct stat.st_blksize]) | 3858 | AC_CHECK_MEMBERS([struct stat.st_blksize]) |
3859 | AC_CHECK_MEMBERS([struct stat.st_mtim]) | ||
3860 | AC_CHECK_MEMBERS([struct stat.st_mtime]) | ||
3848 | AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_class, | 3861 | AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_class, |
3849 | struct passwd.pw_change, struct passwd.pw_expire], | 3862 | struct passwd.pw_change, struct passwd.pw_expire], |
3850 | [], [], [[ | 3863 | [], [], [[ |
@@ -5044,6 +5057,9 @@ AC_SUBST([TEST_SSH_UTF8], [$TEST_SSH_UTF8]) | |||
5044 | AC_SUBST([TEST_MALLOC_OPTIONS], [$TEST_MALLOC_OPTIONS]) | 5057 | AC_SUBST([TEST_MALLOC_OPTIONS], [$TEST_MALLOC_OPTIONS]) |
5045 | AC_SUBST([UNSUPPORTED_ALGORITHMS], [$unsupported_algorithms]) | 5058 | AC_SUBST([UNSUPPORTED_ALGORITHMS], [$unsupported_algorithms]) |
5046 | 5059 | ||
5060 | CFLAGS="${CFLAGS} ${CFLAGS_AFTER}" | ||
5061 | LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}" | ||
5062 | |||
5047 | AC_EXEEXT | 5063 | AC_EXEEXT |
5048 | AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \ | 5064 | AC_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 | |||
35 | appropriate). It seems to work, though...... | 35 | appropriate). It seems to work, though...... |
36 | 36 | ||
37 | If there are any patches to this that have not yet been integrated they | 37 | If there are any patches to this that have not yet been integrated they |
38 | may be found at http://www.zip.com.au/~dtucker/openssh/. | 38 | may be found at http://www.dtucker.net/openssh/. |
39 | 39 | ||
40 | 40 | ||
41 | Disclaimer: | 41 | Disclaimer: |
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 |
57 | fi | 57 | fi |
58 | 58 | ||
59 | DEFAULT_PUB_ID_FILE="$HOME/$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)" | 59 | most_recent_id="$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)" |
60 | DEFAULT_PUB_ID_FILE="${most_recent_id:+$HOME/}$most_recent_id" | ||
60 | 61 | ||
61 | usage () { | 62 | usage () { |
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() { | |||
74 | use_id_file() { | 75 | use_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 | ||
14 | Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation | 14 | Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation |
15 | Name: openssh | 15 | Name: openssh |
16 | Version: 7.5p1 | 16 | Version: 7.6p1 |
17 | URL: https://www.openssh.com/ | 17 | URL: https://www.openssh.com/ |
18 | Release: 1 | 18 | Release: 1 |
19 | Source0: openssh-%{version}.tar.gz | 19 | Source0: 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 | |||
70 | static void | ||
71 | crc_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 */ | ||
78 | static int | ||
79 | check_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 | |||
97 | void | ||
98 | deattack_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 */ | ||
105 | int | ||
106 | detect_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 | |||
31 | struct deattack_ctx { | ||
32 | u_int16_t *h; | ||
33 | u_int32_t n; | ||
34 | }; | ||
35 | |||
36 | void deattack_init(struct deattack_ctx *); | ||
37 | int detect_attack(struct deattack_ctx *, const u_char *, u_int32_t); | ||
38 | #endif | ||
@@ -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 |
332 | typedef int ssize_t; | 354 | typedef 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 */ |
57 | const struct ssh_digest digests[] = { | 57 | const 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 }, |
@@ -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 | ||
33 | struct sshbuf; | 32 | struct sshbuf; |
34 | struct ssh_digest_ctx; | 33 | struct 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 | ||
41 | int | 40 | int |
42 | dispatch_protocol_error(int type, u_int32_t seq, void *ctx) | 41 | dispatch_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 | ||
58 | int | 54 | int |
59 | dispatch_protocol_ignore(int type, u_int32_t seq, void *ssh) | 55 | dispatch_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 | ||
91 | int | 87 | int |
92 | ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done, | 88 | ssh_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 | ||
134 | void | 128 | void |
135 | ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done, | 129 | ssh_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 | ||
37 | struct ssh; | 37 | struct ssh; |
38 | 38 | ||
39 | typedef int dispatch_fn(int, u_int32_t, void *); | 39 | typedef int dispatch_fn(int, u_int32_t, struct ssh *); |
40 | 40 | ||
41 | int dispatch_protocol_error(int, u_int32_t, void *); | 41 | int dispatch_protocol_error(int, u_int32_t, struct ssh *); |
42 | int dispatch_protocol_ignore(int, u_int32_t, void *); | 42 | int dispatch_protocol_ignore(int, u_int32_t, struct ssh *); |
43 | void ssh_dispatch_init(struct ssh *, dispatch_fn *); | 43 | void ssh_dispatch_init(struct ssh *, dispatch_fn *); |
44 | void ssh_dispatch_set(struct ssh *, int, dispatch_fn *); | 44 | void ssh_dispatch_set(struct ssh *, int, dispatch_fn *); |
45 | void ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *); | 45 | void ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *); |
46 | int ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *, void *); | 46 | int ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *); |
47 | void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *, void *); | 47 | void 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 |
@@ -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. |
@@ -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 */ | ||
397 | const 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 |
@@ -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 | ||
61 | extern const EVP_MD *evp_ssh_sha256(void); | ||
62 | # endif | ||
63 | #endif | ||
64 | |||
65 | /* prototype */ | 57 | /* prototype */ |
66 | static int kex_choose_conf(struct ssh *); | 58 | static int kex_choose_conf(struct ssh *); |
67 | static int kex_input_newkeys(int, u_int32_t, void *); | 59 | static int kex_input_newkeys(int, u_int32_t, struct ssh *); |
68 | 60 | ||
69 | static const char *proposal_names[PROPOSAL_MAX] = { | 61 | static 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 */ |
325 | static int | 317 | static int |
326 | kex_protocol_error(int type, u_int32_t seq, void *ctxt) | 318 | kex_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 | ||
385 | int | 376 | int |
386 | kex_input_ext_info(int type, u_int32_t seq, void *ctxt) | 377 | kex_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 | ||
424 | static int | 422 | static int |
425 | kex_input_newkeys(int type, u_int32_t seq, void *ctxt) | 423 | kex_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 */ |
477 | int | 474 | int |
478 | kex_input_kexinit(int type, u_int32_t seq, void *ctxt) | 475 | kex_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 | ||
992 | int | ||
993 | derive_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) |
1034 | void | 989 | void |
@@ -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]); | |||
181 | void kex_prop_free(char **); | 181 | void kex_prop_free(char **); |
182 | 182 | ||
183 | int kex_send_kexinit(struct ssh *); | 183 | int kex_send_kexinit(struct ssh *); |
184 | int kex_input_kexinit(int, u_int32_t, void *); | 184 | int kex_input_kexinit(int, u_int32_t, struct ssh *); |
185 | int kex_input_ext_info(int, u_int32_t, void *); | 185 | int kex_input_ext_info(int, u_int32_t, struct ssh *); |
186 | int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); | 186 | int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); |
187 | int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *); | 187 | int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *); |
188 | int kex_send_newkeys(struct ssh *); | 188 | int 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 | ||
228 | int | ||
229 | derive_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) |
232 | void dump_digest(char *, u_char *, int); | 229 | void 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 | ||
46 | static int | 46 | static int |
47 | input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt); | 47 | input_kex_c25519_reply(int type, u_int32_t seq, struct ssh *ssh); |
48 | 48 | ||
49 | int | 49 | int |
50 | kexc25519_client(struct ssh *ssh) | 50 | kexc25519_client(struct ssh *ssh) |
@@ -69,9 +69,8 @@ kexc25519_client(struct ssh *ssh) | |||
69 | } | 69 | } |
70 | 70 | ||
71 | static int | 71 | static int |
72 | input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt) | 72 | input_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 | ||
44 | static int input_kex_c25519_init(int, u_int32_t, void *); | 44 | static int input_kex_c25519_init(int, u_int32_t, struct ssh *); |
45 | 45 | ||
46 | int | 46 | int |
47 | kexc25519_server(struct ssh *ssh) | 47 | kexc25519_server(struct ssh *ssh) |
@@ -52,9 +52,8 @@ kexc25519_server(struct ssh *ssh) | |||
52 | } | 52 | } |
53 | 53 | ||
54 | static int | 54 | static int |
55 | input_kex_c25519_init(int type, u_int32_t seq, void *ctxt) | 55 | input_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; |
@@ -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 | ||
52 | static int input_kex_dh(int, u_int32_t, void *); | 52 | static int input_kex_dh(int, u_int32_t, struct ssh *); |
53 | 53 | ||
54 | int | 54 | int |
55 | kexdh_client(struct ssh *ssh) | 55 | kexdh_client(struct ssh *ssh) |
@@ -100,9 +100,8 @@ kexdh_client(struct ssh *ssh) | |||
100 | } | 100 | } |
101 | 101 | ||
102 | static int | 102 | static int |
103 | input_kex_dh(int type, u_int32_t seq, void *ctxt) | 103 | input_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; |
@@ -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 | ||
52 | static int input_kex_dh_init(int, u_int32_t, void *); | 52 | static int input_kex_dh_init(int, u_int32_t, struct ssh *); |
53 | 53 | ||
54 | int | 54 | int |
55 | kexdh_server(struct ssh *ssh) | 55 | kexdh_server(struct ssh *ssh) |
@@ -91,9 +91,8 @@ kexdh_server(struct ssh *ssh) | |||
91 | } | 91 | } |
92 | 92 | ||
93 | int | 93 | int |
94 | input_kex_dh_init(int type, u_int32_t seq, void *ctxt) | 94 | input_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 | ||
52 | static int input_kex_ecdh_reply(int, u_int32_t, void *); | 52 | static int input_kex_ecdh_reply(int, u_int32_t, struct ssh *); |
53 | 53 | ||
54 | int | 54 | int |
55 | kexecdh_client(struct ssh *ssh) | 55 | kexecdh_client(struct ssh *ssh) |
@@ -95,9 +95,8 @@ kexecdh_client(struct ssh *ssh) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | static int | 97 | static int |
98 | input_kex_ecdh_reply(int type, u_int32_t seq, void *ctxt) | 98 | input_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 | ||
50 | static int input_kex_ecdh_init(int, u_int32_t, void *); | 50 | static int input_kex_ecdh_init(int, u_int32_t, struct ssh *); |
51 | 51 | ||
52 | int | 52 | int |
53 | kexecdh_server(struct ssh *ssh) | 53 | kexecdh_server(struct ssh *ssh) |
@@ -58,9 +58,8 @@ kexecdh_server(struct ssh *ssh) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | static int | 60 | static int |
61 | input_kex_ecdh_init(int type, u_int32_t seq, void *ctxt) | 61 | input_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; |
@@ -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 | ||
54 | static int input_kex_dh_gex_group(int, u_int32_t, void *); | 54 | static int input_kex_dh_gex_group(int, u_int32_t, struct ssh *); |
55 | static int input_kex_dh_gex_reply(int, u_int32_t, void *); | 55 | static int input_kex_dh_gex_reply(int, u_int32_t, struct ssh *); |
56 | 56 | ||
57 | int | 57 | int |
58 | kexgex_client(struct ssh *ssh) | 58 | kexgex_client(struct ssh *ssh) |
@@ -89,9 +89,8 @@ kexgex_client(struct ssh *ssh) | |||
89 | } | 89 | } |
90 | 90 | ||
91 | static int | 91 | static int |
92 | input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt) | 92 | input_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 | ||
145 | static int | 144 | static int |
146 | input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt) | 145 | input_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)) { |
@@ -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 | ||
57 | static int input_kex_dh_gex_request(int, u_int32_t, void *); | 57 | static int input_kex_dh_gex_request(int, u_int32_t, struct ssh *); |
58 | static int input_kex_dh_gex_init(int, u_int32_t, void *); | 58 | static int input_kex_dh_gex_init(int, u_int32_t, struct ssh *); |
59 | 59 | ||
60 | int | 60 | int |
61 | kexgex_server(struct ssh *ssh) | 61 | kexgex_server(struct ssh *ssh) |
@@ -67,9 +67,8 @@ kexgex_server(struct ssh *ssh) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | static int | 69 | static int |
70 | input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt) | 70 | input_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 | ||
122 | static int | 121 | static int |
123 | input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt) | 122 | input_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; |
@@ -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 | ||
23 | void | ||
24 | key_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 | |||
32 | Key * | ||
33 | key_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 | |||
42 | int | ||
43 | key_read(Key *ret, char **cpp) | ||
44 | { | ||
45 | return sshkey_read(ret, cpp) == 0 ? 1 : -1; | ||
46 | } | ||
47 | |||
48 | int | ||
49 | key_write(const Key *key, FILE *f) | ||
50 | { | ||
51 | return sshkey_write(key, f) == 0 ? 1 : 0; | ||
52 | } | ||
53 | |||
54 | Key * | ||
55 | key_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 | |||
65 | void | ||
66 | key_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 | |||
74 | Key * | ||
75 | key_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 | |||
85 | static void | 23 | static void |
86 | fatal_on_fatal_errors(int r, const char *func, int extra_fatal) | 24 | fatal_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 | ||
186 | int | 124 | int |
187 | key_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 | |||
199 | int | ||
200 | key_drop_cert(Key *k) | 125 | key_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 | ||
212 | int | 137 | int |
213 | key_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 | |||
225 | int | ||
226 | key_cert_check_authority(const Key *k, int want_host, int require_principal, | 138 | key_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) | ||
241 | int | ||
242 | key_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 | |||
254 | int | ||
255 | key_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 | |||
268 | void | ||
269 | key_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 | |||
277 | Key * | ||
278 | key_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 | ||
293 | int | ||
294 | key_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 | |||
309 | int | ||
310 | key_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 | |||
322 | Key * | 154 | Key * |
323 | key_load_cert(const char *filename) | 155 | key_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 | |||
421 | int | ||
422 | key_perm_ok(int fd, const char *filename) | ||
423 | { | ||
424 | return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0; | ||
425 | } | ||
426 | |||
@@ -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 | ||
62 | void key_add_private(Key *); | ||
63 | Key *key_new_private(int); | ||
64 | void key_free(Key *); | 49 | void key_free(Key *); |
65 | Key *key_demote(const Key *); | 50 | Key *key_demote(const Key *); |
66 | int key_write(const Key *, FILE *); | ||
67 | int key_read(Key *, char **); | ||
68 | 51 | ||
69 | Key *key_generate(int, u_int); | ||
70 | Key *key_from_private(const Key *); | ||
71 | int key_to_certified(Key *); | ||
72 | int key_drop_cert(Key *); | 52 | int key_drop_cert(Key *); |
73 | int key_certify(Key *, Key *); | ||
74 | void key_cert_copy(const Key *, Key *); | ||
75 | int key_cert_check_authority(const Key *, int, int, const char *, | 53 | int 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) | ||
79 | int key_ec_validate_public(const EC_GROUP *, const EC_POINT *); | ||
80 | int key_ec_validate_private(const EC_KEY *); | ||
81 | #endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ | ||
82 | |||
83 | Key *key_from_blob(const u_char *, u_int); | 56 | Key *key_from_blob(const u_char *, u_int); |
84 | int key_to_blob(const Key *, u_char **, u_int *); | 57 | int 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 *); |
88 | int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); | 61 | int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); |
89 | 62 | ||
90 | void key_private_serialize(const Key *, struct sshbuf *); | ||
91 | Key *key_private_deserialize(struct sshbuf *); | ||
92 | |||
93 | /* authfile.c */ | 63 | /* authfile.c */ |
94 | int key_save_private(Key *, const char *, const char *, const char *, | ||
95 | int, const char *, int); | ||
96 | int key_load_file(int, const char *, struct sshbuf *); | ||
97 | Key *key_load_cert(const char *); | 64 | Key *key_load_cert(const char *); |
98 | Key *key_load_public(const char *, char **); | 65 | Key *key_load_public(const char *, char **); |
99 | Key *key_load_private(const char *, const char *, char **); | 66 | Key *key_load_private(const char *, const char *, char **); |
100 | Key *key_load_private_cert(int, const char *, const char *, int *); | 67 | Key *key_load_private_cert(int, const char *, const char *, int *); |
101 | Key *key_load_private_type(int, const char *, const char *, char **, int *); | 68 | Key *key_load_private_type(int, const char *, const char *, char **, int *); |
102 | int key_perm_ok(int, const char *); | ||
103 | 69 | ||
104 | #endif | 70 | #endif |
@@ -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; |
@@ -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 | ||
343 | void | 332 | int |
344 | log_change_level(LogLevel new_log_level) | 333 | log_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 | ||
352 | int | 355 | int |
@@ -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 { | |||
49 | typedef void (log_handler_fn)(LogLevel, const char *, void *); | 49 | typedef void (log_handler_fn)(LogLevel, const char *, void *); |
50 | 50 | ||
51 | void log_init(char *, LogLevel, SyslogFacility, int); | 51 | void log_init(char *, LogLevel, SyslogFacility, int); |
52 | void log_change_level(LogLevel); | 52 | int log_change_level(LogLevel); |
53 | int log_is_on_stderr(void); | 53 | int log_is_on_stderr(void); |
54 | void log_redirect_stderr_to(const char *); | 54 | void log_redirect_stderr_to(const char *); |
55 | 55 | ||
@@ -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 | |||
37 | const EVP_MD *evp_ssh_sha256(void); | ||
38 | |||
39 | static int | ||
40 | ssh_sha256_init(EVP_MD_CTX *ctxt) | ||
41 | { | ||
42 | SHA256_Init(ctxt->md_data); | ||
43 | return (1); | ||
44 | } | ||
45 | |||
46 | static int | ||
47 | ssh_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 | |||
53 | static int | ||
54 | ssh_sha256_final(EVP_MD_CTX *ctxt, unsigned char *digest) | ||
55 | { | ||
56 | SHA256_Final(digest, ctxt->md_data); | ||
57 | return (1); | ||
58 | } | ||
59 | |||
60 | static int | ||
61 | ssh_sha256_cleanup(EVP_MD_CTX *ctxt) | ||
62 | { | ||
63 | memset(ctxt->md_data, 0, sizeof(SHA256_CTX)); | ||
64 | return (1); | ||
65 | } | ||
66 | |||
67 | const EVP_MD * | ||
68 | evp_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 | |||
@@ -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 */ |
66 | char * | 76 | char * |
@@ -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 | */ | ||
1295 | int | ||
1296 | argv_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 | */ | ||
1369 | char * | ||
1370 | argv_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 | */ | ||
1429 | pid_t | ||
1430 | subprocess(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 */ | ||
1573 | int | ||
1574 | exited_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 | */ | ||
1608 | int | ||
1609 | safe_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 | */ | ||
1672 | int | ||
1673 | safe_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 | */ | ||
1691 | void | ||
1692 | child_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 | |||
@@ -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. */ |
21 | struct Forward { | 22 | struct Forward { |
@@ -132,6 +133,25 @@ int parse_ipqos(const char *); | |||
132 | const char *iptos2str(int); | 133 | const char *iptos2str(int); |
133 | void mktemp_proto(char *, size_t); | 134 | void mktemp_proto(char *, size_t); |
134 | 135 | ||
136 | void child_set_env(char ***envp, u_int *envsizep, const char *name, | ||
137 | const char *value); | ||
138 | |||
139 | int argv_split(const char *, int *, char ***); | ||
140 | char *argv_assemble(int, char **argv); | ||
141 | int 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 */ | ||
146 | pid_t subprocess(const char *, struct passwd *, | ||
147 | const char *, int, char **, FILE **, u_int flags); | ||
148 | |||
149 | struct stat; | ||
150 | int safe_path(const char *, struct stat *, const char *, uid_t, | ||
151 | char *, size_t); | ||
152 | int 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 |
@@ -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 | ||
74 | OpenBSD 6.0 September 26, 2012 OpenBSD 6.0 | 74 | OpenBSD 6.2 September 26, 2012 OpenBSD 6.2 |
@@ -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) | |||
1119 | int | 1127 | int |
1120 | mm_answer_keyallowed(int sock, Buffer *m) | 1128 | mm_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 | ||
1332 | int | 1339 | int |
1333 | mm_answer_keyverify(int sock, Buffer *m) | 1340 | mm_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 | ||
1393 | static void | 1401 | static void |
@@ -1513,13 +1521,14 @@ mm_answer_pty_cleanup(int sock, Buffer *m) | |||
1513 | int | 1521 | int |
1514 | mm_answer_term(int sock, Buffer *req) | 1522 | mm_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 | ||
1581 | void | 1590 | void |
1591 | monitor_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 | |||
1601 | void | ||
1582 | monitor_apply_keystate(struct monitor *pmonitor) | 1602 | monitor_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 | |||
1639 | monitor_openfds(struct monitor *mon, int do_logfds) | 1659 | monitor_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 | |||
1774 | mm_answer_gss_userok(int sock, Buffer *m) | 1803 | mm_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 | ||
218 | int | 218 | int |
219 | mm_key_sign(Key *key, u_char **sigp, u_int *lenp, | 219 | mm_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, | |||
242 | struct passwd * | 242 | struct passwd * |
243 | mm_getpwnamallow(const char *username) | 243 | mm_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 | ||
376 | int | 385 | int |
377 | mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt) | 386 | mm_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 | ||
383 | int | 393 | int |
384 | mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host, | 394 | mm_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 | ||
390 | int | 400 | int |
391 | mm_key_allowed(enum mm_keytype type, const char *user, const char *host, | 401 | mm_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 | ||
436 | int | 446 | int |
437 | mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) | 447 | mm_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 | ||
468 | void | 481 | void |
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; | |||
34 | enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY }; | 34 | enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY }; |
35 | 35 | ||
36 | struct monitor; | 36 | struct monitor; |
37 | struct mm_master; | ||
38 | struct Authctxt; | 37 | struct Authctxt; |
39 | 38 | ||
40 | void mm_log_handler(LogLevel, const char *, void *); | 39 | void mm_log_handler(LogLevel, const char *, void *); |
41 | int mm_is_monitor(void); | 40 | int mm_is_monitor(void); |
42 | DH *mm_choose_dh(int, int, int); | 41 | DH *mm_choose_dh(int, int, int); |
43 | int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); | 42 | int mm_key_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int, |
43 | const char *); | ||
44 | void mm_inform_authserv(char *, char *); | 44 | void mm_inform_authserv(char *, char *); |
45 | struct passwd *mm_getpwnamallow(const char *); | 45 | struct passwd *mm_getpwnamallow(const char *); |
46 | char *mm_auth2_read_banner(void); | 46 | char *mm_auth2_read_banner(void); |
47 | int mm_auth_password(struct Authctxt *, char *); | 47 | int mm_auth_password(struct Authctxt *, char *); |
48 | int mm_key_allowed(enum mm_keytype, const char *, const char *, Key *, int); | 48 | int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *, |
49 | int mm_user_key_allowed(struct passwd *, Key *, int); | 49 | int); |
50 | int mm_user_key_allowed(struct passwd *, struct sshkey *, int); | ||
50 | int mm_hostbased_key_allowed(struct passwd *, const char *, | 51 | int mm_hostbased_key_allowed(struct passwd *, const char *, |
51 | const char *, Key *); | 52 | const char *, struct sshkey *); |
52 | int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); | 53 | int 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 |
55 | OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); | 57 | OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); |
@@ -83,6 +85,7 @@ void mm_session_pty_cleanup2(struct Session *); | |||
83 | struct newkeys *mm_newkeys_from_blob(u_char *, int); | 85 | struct newkeys *mm_newkeys_from_blob(u_char *, int); |
84 | int mm_newkeys_to_blob(int, u_char **, u_int *); | 86 | int mm_newkeys_to_blob(int, u_char **, u_int *); |
85 | 87 | ||
88 | void monitor_clear_keystate(struct monitor *); | ||
86 | void monitor_apply_keystate(struct monitor *); | 89 | void monitor_apply_keystate(struct monitor *); |
87 | void mm_get_keystate(struct monitor *); | 90 | void mm_get_keystate(struct monitor *); |
88 | void mm_send_keystate(struct monitor*); | 91 | void mm_send_keystate(struct monitor*); |
@@ -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 | ||
164 | static void mux_session_confirm(int, int, void *); | 164 | static void mux_session_confirm(struct ssh *, int, int, void *); |
165 | static void mux_stdio_confirm(int, int, void *); | 165 | static void mux_stdio_confirm(struct ssh *, int, int, void *); |
166 | 166 | ||
167 | static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *); | 167 | static int process_mux_master_hello(struct ssh *, u_int, |
168 | static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *); | 168 | Channel *, struct sshbuf *, struct sshbuf *); |
169 | static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *); | 169 | static int process_mux_new_session(struct ssh *, u_int, |
170 | static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *); | 170 | Channel *, struct sshbuf *, struct sshbuf *); |
171 | static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *); | 171 | static int process_mux_alive_check(struct ssh *, u_int, |
172 | static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *); | 172 | Channel *, struct sshbuf *, struct sshbuf *); |
173 | static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *); | 173 | static int process_mux_terminate(struct ssh *, u_int, |
174 | static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *); | 174 | Channel *, struct sshbuf *, struct sshbuf *); |
175 | static int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *); | 175 | static int process_mux_open_fwd(struct ssh *, u_int, |
176 | Channel *, struct sshbuf *, struct sshbuf *); | ||
177 | static int process_mux_close_fwd(struct ssh *, u_int, | ||
178 | Channel *, struct sshbuf *, struct sshbuf *); | ||
179 | static int process_mux_stdio_fwd(struct ssh *, u_int, | ||
180 | Channel *, struct sshbuf *, struct sshbuf *); | ||
181 | static int process_mux_stop_listening(struct ssh *, u_int, | ||
182 | Channel *, struct sshbuf *, struct sshbuf *); | ||
183 | static int process_mux_proxy(struct ssh *, u_int, | ||
184 | Channel *, struct sshbuf *, struct sshbuf *); | ||
176 | 185 | ||
177 | static const struct { | 186 | static 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 */ |
195 | static void | 205 | static void |
196 | mux_master_session_cleanup_cb(int cid, void *unused) | 206 | mux_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 */ |
216 | static void | 227 | static void |
217 | mux_master_control_cleanup_cb(int cid, void *unused) | 228 | mux_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 | ||
268 | static int | 280 | static int |
269 | process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r) | 281 | process_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 | ||
310 | static int | 323 | static int |
311 | process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r) | 324 | process_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 | ||
482 | static int | 498 | static int |
483 | process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r) | 499 | process_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 | ||
495 | static int | 512 | static int |
496 | process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r) | 513 | process_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 | ||
584 | static void | 602 | static void |
585 | mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | 603 | mux_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 | ||
661 | static int | 679 | static int |
662 | process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 680 | process_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 | ||
829 | static int | 851 | static int |
830 | process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 852 | process_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 | ||
944 | static int | 967 | static int |
945 | process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) | 968 | process_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. */ |
1041 | static void | 1067 | static void |
1042 | mux_stdio_confirm(int id, int success, void *arg) | 1068 | mux_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 | ||
1085 | static int | 1111 | static int |
1086 | process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r) | 1112 | process_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 | ||
1118 | static int | 1145 | static int |
1119 | process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) | 1146 | process_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 */ |
1131 | static int | 1159 | static int |
1132 | mux_master_read_cb(Channel *c) | 1160 | mux_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 | ||
1211 | void | 1240 | void |
1212 | mux_exit_message(Channel *c, int exitval) | 1241 | mux_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 | ||
1234 | void | 1263 | void |
1235 | mux_tty_alloc_failed(Channel *c) | 1264 | mux_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. */ |
1256 | void | 1285 | void |
1257 | muxserver_listen(void) | 1286 | muxserver_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. */ |
1340 | static void | 1369 | static void |
1341 | mux_session_confirm(int id, int success, void *arg) | 1370 | mux_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 | ||
1612 | static u_int | 1651 | static 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," \ |
@@ -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 | */ |
77 | static void chan_send_ieof1(Channel *); | 77 | static void chan_send_eof2(struct ssh *, Channel *); |
78 | static void chan_send_oclose1(Channel *); | 78 | static void chan_send_eow2(struct ssh *, Channel *); |
79 | static void chan_send_close2(Channel *); | ||
80 | static void chan_send_eof2(Channel *); | ||
81 | static void chan_send_eow2(Channel *); | ||
82 | 79 | ||
83 | /* helper */ | 80 | /* helper */ |
84 | static void chan_shutdown_write(Channel *); | 81 | static void chan_shutdown_write(struct ssh *, Channel *); |
85 | static void chan_shutdown_read(Channel *); | 82 | static void chan_shutdown_read(struct ssh *, Channel *); |
86 | 83 | ||
87 | static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; | 84 | static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; |
88 | static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; | 85 | static const char *istates[] = { "open", "drain", "wait_oclose", "closed" }; |
89 | 86 | ||
90 | static void | 87 | static void |
91 | chan_set_istate(Channel *c, u_int next) | 88 | chan_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 | |||
99 | static void | 97 | static void |
100 | chan_set_ostate(Channel *c, u_int next) | 98 | chan_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 | |||
113 | static void | ||
114 | chan_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 | } | ||
137 | void | 107 | void |
138 | chan_read_failed(Channel *c) | 108 | chan_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 | |||
152 | void | 123 | void |
153 | chan_ibuf_empty(Channel *c) | 124 | chan_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 | } |
178 | static void | 144 | |
179 | chan_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 | } | ||
195 | static void | ||
196 | chan_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 | } | ||
216 | void | 145 | void |
217 | chan_obuf_empty(Channel *c) | 146 | chan_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 | } |
238 | static void | 165 | |
239 | chan_send_ieof1(Channel *c) | 166 | void |
167 | chan_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 | |||
178 | static void | ||
179 | chan_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 | |||
255 | static void | 202 | static void |
256 | chan_send_oclose1(Channel *c) | 203 | chan_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 | */ | ||
277 | static void | 226 | static void |
278 | chan_rcvd_close2(Channel *c) | 227 | chan_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 | |||
251 | void | ||
252 | chan_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 | |||
264 | void | ||
265 | chan_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 | ||
315 | void | 302 | void |
316 | chan_rcvd_eow(Channel *c) | 303 | chan_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 | } | ||
326 | static void | ||
327 | chan_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 | } | ||
334 | static void | ||
335 | chan_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 | } |
352 | static void | ||
353 | chan_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 | } | ||
369 | static void | ||
370 | chan_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 | } | ||
386 | static void | ||
387 | chan_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 | ||
406 | void | 321 | void |
407 | chan_rcvd_ieof(Channel *c) | 322 | chan_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 | } | ||
418 | void | ||
419 | chan_rcvd_oclose(Channel *c) | ||
420 | { | ||
421 | if (compat20) | ||
422 | chan_rcvd_close2(c); | ||
423 | else | ||
424 | chan_rcvd_oclose1(c); | ||
425 | } | ||
426 | void | ||
427 | chan_write_failed(Channel *c) | ||
428 | { | ||
429 | if (compat20) | ||
430 | chan_write_failed2(c); | ||
431 | else | ||
432 | chan_write_failed1(c); | ||
433 | } | ||
434 | |||
435 | void | ||
436 | chan_mark_dead(Channel *c) | ||
437 | { | 323 | { |
438 | c->type = SSH_CHANNEL_ZOMBIE; | 324 | c->type = SSH_CHANNEL_ZOMBIE; |
439 | } | 325 | } |
440 | 326 | ||
441 | int | 327 | int |
442 | chan_is_dead(Channel *c, int do_send) | 328 | chan_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 */ |
487 | static void | 369 | static void |
488 | chan_shutdown_write(Channel *c) | 370 | chan_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 | |||
507 | static void | 390 | static void |
508 | chan_shutdown_read(Channel *c) | 391 | chan_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)); |
@@ -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 | ||
78 | void | ||
79 | ssh_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 |
89 | void | 79 | void |
@@ -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 | ||
154 | void | ||
155 | ssh_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 |
165 | void | 145 | void |
@@ -6,7 +6,6 @@ void ssh_packet_start(struct ssh *, u_char); | |||
6 | void ssh_packet_put_char(struct ssh *, int ch); | 6 | void ssh_packet_put_char(struct ssh *, int ch); |
7 | void ssh_packet_put_int(struct ssh *, u_int value); | 7 | void ssh_packet_put_int(struct ssh *, u_int value); |
8 | void ssh_packet_put_int64(struct ssh *, u_int64_t value); | 8 | void ssh_packet_put_int64(struct ssh *, u_int64_t value); |
9 | void ssh_packet_put_bignum(struct ssh *, BIGNUM * value); | ||
10 | void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value); | 9 | void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value); |
11 | void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *); | 10 | void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *); |
12 | void ssh_packet_put_string(struct ssh *, const void *buf, u_int len); | 11 | void ssh_packet_put_string(struct ssh *, const void *buf, u_int len); |
@@ -17,7 +16,6 @@ void ssh_packet_send(struct ssh *); | |||
17 | u_int ssh_packet_get_char(struct ssh *); | 16 | u_int ssh_packet_get_char(struct ssh *); |
18 | u_int ssh_packet_get_int(struct ssh *); | 17 | u_int ssh_packet_get_int(struct ssh *); |
19 | u_int64_t ssh_packet_get_int64(struct ssh *); | 18 | u_int64_t ssh_packet_get_int64(struct ssh *); |
20 | void ssh_packet_get_bignum(struct ssh *, BIGNUM * value); | ||
21 | void ssh_packet_get_bignum2(struct ssh *, BIGNUM * value); | 19 | void ssh_packet_get_bignum2(struct ssh *, BIGNUM * value); |
22 | void ssh_packet_get_ecpoint(struct ssh *, const EC_GROUP *, EC_POINT *); | 20 | void ssh_packet_get_ecpoint(struct ssh *, const EC_GROUP *, EC_POINT *); |
23 | void *ssh_packet_get_string(struct ssh *, u_int *length_ptr); | 21 | void *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@ | |||
16 | INSTALL=@INSTALL@ | 16 | INSTALL=@INSTALL@ |
17 | LDFLAGS=-L. @LDFLAGS@ | 17 | LDFLAGS=-L. @LDFLAGS@ |
18 | 18 | ||
19 | OPENBSD=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 | 19 | OPENBSD=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 | ||
21 | COMPAT=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 | 21 | COMPAT=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 | ||
23 | PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o | 23 | PORTS=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 |
31 | void | 37 | void |
32 | err(int r, const char *fmt, ...) | 38 | err(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 | |||
8 | int | ||
9 | getpagesize(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 | ||
26 | void * | ||
27 | rpl_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 | ||
36 | void * | ||
37 | rpl_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 | ||
48 | void * | ||
49 | rpl_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) | ||
108 | char *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 |
108 | int utimes(char *filename, struct timeval *tvp) | 118 | int 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); | |||
49 | const char *strerror(int); | 49 | const char *strerror(int); |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | #if !defined(HAVE_STRSIGNAL) | ||
53 | char *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 @@ | |||
20 | void | 20 | void |
21 | explicit_bzero(void *p, size_t n) | 21 | explicit_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; | |||
34 | void | 36 | void |
35 | explicit_bzero(void *p, size_t n) | 37 | explicit_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 | |||
21 | void | ||
22 | freezero(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); | |||
60 | void closefrom(int); | 60 | void closefrom(int); |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | #ifndef HAVE_GETPAGESIZE | ||
64 | int getpagesize(void); | ||
65 | #endif | ||
66 | |||
63 | #ifndef HAVE_GETCWD | 67 | #ifndef HAVE_GETCWD |
64 | char *getcwd(char *pt, size_t size); | 68 | char *getcwd(char *pt, size_t size); |
65 | #endif | 69 | #endif |
@@ -68,6 +72,10 @@ char *getcwd(char *pt, size_t size); | |||
68 | void *reallocarray(void *, size_t, size_t); | 72 | void *reallocarray(void *, size_t, size_t); |
69 | #endif | 73 | #endif |
70 | 74 | ||
75 | #ifndef HAVE_RECALLOCARRAY | ||
76 | void *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, | |||
296 | void explicit_bzero(void *p, size_t n); | 304 | void explicit_bzero(void *p, size_t n); |
297 | #endif | 305 | #endif |
298 | 306 | ||
307 | #ifndef HAVE_FREEZERO | ||
308 | void freezero(void *, size_t); | ||
309 | #endif | ||
310 | |||
299 | char *xcrypt(const char *password, const char *salt); | 311 | char *xcrypt(const char *password, const char *salt); |
300 | char *shadow_pw(struct passwd *pw); | 312 | char *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 | ||
205 | int | 209 | int |
206 | sys_tun_infilter(struct Channel *c, char *buf, int len) | 210 | sys_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 | ||
252 | u_char * | 253 | u_char * |
253 | sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen) | 254 | sys_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 | ||
20 | struct Channel; | 20 | struct Channel; |
21 | struct 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 |
29 | int sys_tun_infilter(struct Channel *, char *, int); | 30 | int sys_tun_infilter(struct ssh *, struct Channel *, char *, int); |
30 | u_char *sys_tun_outfilter(struct Channel *, u_char **, u_int *); | 31 | u_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 | |||
37 | void * | ||
38 | recallocarray(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 */ | ||
@@ -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) | |||
278 | int | 269 | int |
279 | ssh_packet_is_rekeying(struct ssh *ssh) | 270 | ssh_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 | */ |
289 | struct ssh * | 279 | struct ssh * |
290 | ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) | 280 | ssh_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 | ||
573 | void | 562 | static void |
574 | ssh_packet_close(struct ssh *ssh) | 563 | ssh_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 | |||
625 | void | ||
626 | ssh_packet_close(struct ssh *ssh) | ||
627 | { | ||
628 | ssh_packet_close_internal(ssh, 1); | ||
629 | } | ||
630 | |||
631 | void | ||
632 | ssh_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 | |||
811 | void | 813 | void |
812 | ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number) | 814 | ssh_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 | |||
849 | int | ||
850 | ssh_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 | ||
937 | int | 822 | int |
@@ -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 | |||
1536 | int | ||
1537 | ssh_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 | |||
1674 | static int | 1397 | static int |
1675 | ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | 1398 | ssh_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 | |||
2302 | ssh_packet_set_tos(struct ssh *ssh, int tos) | 1997 | ssh_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 | */ | ||
2409 | void | ||
2410 | ssh_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 | |||
2428 | void | 2093 | void |
2429 | ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, u_int32_t seconds) | 2094 | ssh_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 | |||
2556 | ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) | 2219 | ssh_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 | |||
2728 | ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) | 2357 | ssh_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 | ||
2866 | int | ||
2867 | sshpkt_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 | ||
2873 | int | 2467 | int |
2874 | sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) | 2468 | sshpkt_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 | ||
2918 | int | 2512 | int |
2513 | sshpkt_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 | |||
2518 | int | ||
2919 | sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp) | 2519 | sshpkt_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 | ||
2934 | int | ||
2935 | sshpkt_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 | ||
2941 | int | 2534 | int |
2942 | sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v) | 2535 | sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v) |
@@ -2966,15 +2559,13 @@ sshpkt_ptr(struct ssh *ssh, size_t *lenp) | |||
2966 | int | 2559 | int |
2967 | sshpkt_start(struct ssh *ssh, u_char type) | 2560 | sshpkt_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 | ||
2980 | static int | 2571 | static 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 | */ | ||
2612 | int | ||
2613 | sshpkt_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 | ||
3012 | int | 2634 | int |
@@ -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 | ||
3023 | int | 2642 | int |
@@ -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 | ||
@@ -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 *); | |||
93 | int ssh_packet_get_connection_in(struct ssh *); | 99 | int ssh_packet_get_connection_in(struct ssh *); |
94 | int ssh_packet_get_connection_out(struct ssh *); | 100 | int ssh_packet_get_connection_out(struct ssh *); |
95 | void ssh_packet_close(struct ssh *); | 101 | void ssh_packet_close(struct ssh *); |
96 | void ssh_packet_set_encryption_key(struct ssh *, const u_char *, u_int, int); | ||
97 | void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *); | 102 | void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *); |
103 | void ssh_packet_clear_keys(struct ssh *); | ||
104 | void ssh_clear_newkeys(struct ssh *, int); | ||
98 | 105 | ||
99 | int ssh_packet_is_rekeying(struct ssh *); | 106 | int ssh_packet_is_rekeying(struct ssh *); |
100 | void ssh_packet_set_protocol_flags(struct ssh *, u_int); | 107 | void 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 | ||
113 | int ssh_packet_log_type(u_char); | 120 | int ssh_packet_log_type(u_char); |
114 | 121 | ||
115 | int ssh_packet_send1(struct ssh *); | ||
116 | int ssh_packet_send2_wrapped(struct ssh *); | 122 | int ssh_packet_send2_wrapped(struct ssh *); |
117 | int ssh_packet_send2(struct ssh *); | 123 | int ssh_packet_send2(struct ssh *); |
118 | 124 | ||
119 | int ssh_packet_read(struct ssh *); | 125 | int ssh_packet_read(struct ssh *); |
120 | int ssh_packet_read_expect(struct ssh *, u_int type); | 126 | int ssh_packet_read_expect(struct ssh *, u_int type); |
121 | int ssh_packet_read_poll(struct ssh *); | 127 | int ssh_packet_read_poll(struct ssh *); |
122 | int ssh_packet_read_poll1(struct ssh *, u_char *); | ||
123 | int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); | 128 | int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); |
124 | int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); | 129 | int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); |
125 | int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); | 130 | int 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 | ||
142 | int ssh_packet_connection_is_on_socket(struct ssh *); | 147 | int ssh_packet_connection_is_on_socket(struct ssh *); |
143 | int ssh_packet_remaining(struct ssh *); | 148 | int ssh_packet_remaining(struct ssh *); |
144 | void ssh_packet_send_ignore(struct ssh *, int); | ||
145 | 149 | ||
146 | void tty_make_modes(int, struct termios *); | 150 | void tty_make_modes(int, struct termios *); |
147 | void tty_parse_modes(int, int *); | 151 | void 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))); |
173 | int sshpkt_add_padding(struct ssh *, u_char); | 177 | int sshpkt_add_padding(struct ssh *, u_char); |
174 | void sshpkt_fatal(struct ssh *ssh, const char *tag, int r); | 178 | void sshpkt_fatal(struct ssh *ssh, const char *tag, int r); |
179 | int sshpkt_msg_ignore(struct ssh *, u_int); | ||
175 | 180 | ||
176 | int sshpkt_put(struct ssh *ssh, const void *v, size_t len); | 181 | int sshpkt_put(struct ssh *ssh, const void *v, size_t len); |
177 | int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b); | 182 | int 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); | |||
182 | int sshpkt_put_cstring(struct ssh *ssh, const void *v); | 187 | int sshpkt_put_cstring(struct ssh *ssh, const void *v); |
183 | int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); | 188 | int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); |
184 | int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); | 189 | int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); |
185 | int sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v); | ||
186 | int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); | 190 | int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); |
187 | 191 | ||
188 | int sshpkt_get(struct ssh *ssh, void *valp, size_t len); | 192 | int 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); | |||
191 | int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp); | 195 | int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp); |
192 | int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp); | 196 | int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp); |
193 | int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); | 197 | int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); |
198 | int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); | ||
194 | int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); | 199 | int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); |
195 | int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); | 200 | int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); |
196 | int sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v); | ||
197 | int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v); | 201 | int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v); |
198 | int sshpkt_get_end(struct ssh *ssh); | 202 | int sshpkt_get_end(struct ssh *ssh); |
199 | const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); | 203 | const 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 | */ | ||
25 | int | ||
26 | platform_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 | */ | ||
205 | int | ||
206 | platform_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 | }; |
754 | static 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 | }; | ||
757 | static const struct multistate multistate_yesnoaskconfirm[] = { | 764 | static 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 | |||
198 | void initialize_options(Options *); | 198 | void initialize_options(Options *); |
199 | void fill_default_options(Options *); | 199 | void fill_default_options(Options *); |
200 | void fill_default_options_for_canonicalization(Options *); | 200 | void 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 | ||
3 | REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec | 3 | REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec |
4 | tests: prep $(REGRESS_TARGETS) | 4 | tests: 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 | ||
92 | USERNAME!= id -un | 93 | USERNAME= ${LOGNAME} |
93 | CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ | 94 | CLEANFILES= *.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 | ||
117 | SUDO_CLEAN+= /var/run/testdata_${USERNAME} /var/run/keycommand_${USERNAME} | 121 | SUDO_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 | ||
4 | tid="disallow agent attach from other uid" | 4 | tid="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 | ||
4 | tid="pkcs11 agent test" | 4 | tid="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 | ||
4 | tid="simple agent test" | 4 | tid="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 | |||
4 | tid="authinfo" | ||
5 | |||
6 | # Ensure the environment variable doesn't leak when ExposeAuthInfo=no. | ||
7 | verbose "ExposeAuthInfo=no" | ||
8 | env SSH_USER_AUTH=blah ${SSH} -F $OBJ/ssh_proxy x \ | ||
9 | 'test -z "$SSH_USER_AUTH"' || fail "SSH_USER_AUTH present" | ||
10 | |||
11 | verbose "ExposeAuthInfo=yes" | ||
12 | echo 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 | ||
4 | tid="banner" | 4 | tid="banner" |
@@ -9,7 +9,7 @@ touch $OBJ/empty.in | |||
9 | 9 | ||
10 | trace "test missing banner file" | 10 | trace "test missing banner file" |
11 | verbose "test $tid: missing banner file" | 11 | verbose "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" |
36 | done | 36 | done |
37 | 37 | ||
38 | trace "test suppress banner (-q)" | 38 | trace "test suppress banner (-q)" |
39 | verbose "test $tid: suppress banner (-q)" | 39 | verbose "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 | ||
4 | tid="broken pipe test" | 4 | tid="broken pipe test" |
5 | 5 | ||
6 | for p in ${SSH_PROTOCOLS}; do | 6 | for 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 | ||
15 | done | 12 | done |
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 | ||
4 | tid="broken keys" | 4 | tid="broken keys" |
@@ -14,9 +14,9 @@ echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEABTM= bad key" > $KEYS | |||
14 | cat ${KEYS}.bak >> ${KEYS} | 14 | cat ${KEYS}.bak >> ${KEYS} |
15 | cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER | 15 | cat $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 |
18 | if [ $? -ne 0 ]; then | 18 | if [ $? -ne 0 ]; then |
19 | fail "ssh connect with protocol $p failed" | 19 | fail "ssh connect with failed" |
20 | fi | 20 | fi |
21 | 21 | ||
22 | mv ${KEYS}.bak ${KEYS} | 22 | mv ${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 | ||
4 | tid="ssh with certificates" | 4 | tid="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 | ||
57 | for 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" | 58 | verbose "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" | 64 | verbose "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" | 71 | verbose "plain keys" |
73 | ${SSH} $opts2 somehost exit 5$p | 72 | ${SSH} $opts2 somehost exit 52 |
74 | r=$? | 73 | r=$? |
75 | if [ $r -eq 5$p ]; then | 74 | if [ $r -eq 52 ]; then |
76 | fail "ssh succeeded with no certs in protocol $p" | 75 | fail "ssh succeeded with no certs" |
77 | fi | 76 | fi |
78 | 77 | ||
79 | # Keys with untrusted cert should fail. | 78 | # Keys with untrusted cert should fail. |
80 | verbose "protocol $p: untrusted cert" | 79 | verbose "untrusted cert" |
81 | opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" | 80 | opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" |
82 | ${SSH} $opts3 somehost exit 5$p | 81 | ${SSH} $opts3 somehost exit 52 |
83 | r=$? | 82 | r=$? |
84 | if [ $r -eq 5$p ]; then | 83 | if [ $r -eq 52 ]; then |
85 | fail "ssh succeeded with bad cert in protocol $p" | 84 | fail "ssh succeeded with bad cert" |
86 | fi | 85 | fi |
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" | 88 | verbose "good cert, bad key" |
90 | opts3="$opts -i $OBJ/user_key2" | 89 | opts3="$opts -i $OBJ/user_key2" |
91 | opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" | 90 | opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" |
92 | ${SSH} $opts3 somehost exit 5$p | 91 | ${SSH} $opts3 somehost exit 52 |
93 | r=$? | 92 | r=$? |
94 | if [ $r -eq 5$p ]; then | 93 | if [ $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 | 95 | fi |
97 | 96 | ||
98 | # Keys with one trusted cert, should succeed. | 97 | # Keys with one trusted cert, should succeed. |
99 | verbose "protocol $p: single trusted" | 98 | verbose "single trusted" |
100 | opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub" | 99 | opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub" |
101 | ${SSH} $opts3 somehost exit 5$p | 100 | ${SSH} $opts3 somehost exit 52 |
102 | r=$? | 101 | r=$? |
103 | if [ $r -ne 5$p ]; then | 102 | if [ $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 | 104 | fi |
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" | 107 | verbose "multiple trusted" |
109 | opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" | 108 | opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" |
110 | opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" | 109 | opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" |
111 | ${SSH} $opts3 somehost exit 5$p | 110 | ${SSH} $opts3 somehost exit 52 |
112 | r=$? | 111 | r=$? |
113 | if [ $r -ne 5$p ]; then | 112 | if [ $r -ne 52 ]; then |
114 | fail "ssh failed with multiple certs in protocol $p" | 113 | fail "ssh failed with multiple certs" |
115 | fi | 114 | fi |
116 | done | ||
117 | 115 | ||
118 | #next, using an agent in combination with the keys | 116 | #next, using an agent in combination with the keys |
119 | SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1 | 117 | SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1 |
@@ -139,26 +137,25 @@ if [ $? -ne 0 ]; then | |||
139 | fi | 137 | fi |
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 | ||
143 | opts="-F $OBJ/ssh_proxy" | 140 | opts="-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 |
146 | if [ $? -eq 52 ]; then | 143 | if [ $? -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" |
148 | fi | 145 | fi |
149 | 146 | ||
150 | #with an untrusted certificate, should fail | 147 | #with an untrusted certificate, should fail |
151 | opts="$opts -oCertificateFile=$OBJ/cert_user_key1_2.pub" | 148 | opts="$opts -oCertificateFile=$OBJ/cert_user_key1_2.pub" |
152 | ${SSH} -2 $opts somehost exit 52 | 149 | ${SSH} $opts somehost exit 52 |
153 | if [ $? -eq 52 ]; then | 150 | if [ $? -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" |
155 | fi | 152 | fi |
156 | 153 | ||
157 | #with an additional trusted certificate, should succeed | 154 | #with an additional trusted certificate, should succeed |
158 | opts="$opts -oCertificateFile=$OBJ/cert_user_key1_1.pub" | 155 | opts="$opts -oCertificateFile=$OBJ/cert_user_key1_1.pub" |
159 | ${SSH} -2 $opts somehost exit 52 | 156 | ${SSH} $opts somehost exit 52 |
160 | if [ $? -ne 52 ]; then | 157 | if [ $? -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" |
162 | fi | 159 | fi |
163 | 160 | ||
164 | trace "kill agent" | 161 | trace "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 | ||
4 | tid="certified host keys" | 4 | tid="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 | ||
4 | tid="certified user keys" | 4 | tid="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 | ||
4 | tid="sshd_config match" | 4 | tid="sshd_config match" |
@@ -13,7 +13,7 @@ echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_proxy | |||
13 | start_client() | 13 | start_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 |
59 | for p in ${SSH_PROTOCOLS}; do | 59 | trace "match permitopen localhost" |
60 | trace "match permitopen localhost proto $p" | 60 | start_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" | 63 | stop_client |
64 | stop_client | ||
65 | done | ||
66 | 64 | ||
67 | # Same but from different source. This should not be permitted | 65 | # Same but from different source. This should not be permitted |
68 | for p in ${SSH_PROTOCOLS}; do | 66 | trace "match permitopen proxy" |
69 | trace "match permitopen proxy proto $p" | 67 | start_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" | 70 | stop_client |
73 | stop_client | ||
74 | done | ||
75 | 71 | ||
76 | # Retry previous with key option, should also be denied. | 72 | # Retry previous with key option, should also be denied. |
77 | cp /dev/null $OBJ/authorized_keys_$USER | 73 | cp /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 |
81 | done | 77 | done |
82 | for p in ${SSH_PROTOCOLS}; do | 78 | trace "match permitopen proxy w/key opts" |
83 | trace "match permitopen proxy w/key opts proto $p" | 79 | start_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" | 82 | stop_client |
87 | stop_client | ||
88 | done | ||
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. |
92 | for p in ${SSH_PROTOCOLS}; do | 86 | trace "match permitopen localhost" |
93 | trace "match permitopen localhost proto $p" | 87 | start_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" | 90 | stop_client |
97 | stop_client | ||
98 | done | ||
99 | 91 | ||
100 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy | 92 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy |
101 | echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy | 93 | echo "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 | |||
103 | echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy | 95 | echo "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 |
106 | for p in ${SSH_PROTOCOLS}; do | 98 | trace "match permitopen proxy w/key opts" |
107 | trace "match permitopen proxy w/key opts proto $p" | 99 | start_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" | 102 | stop_client |
111 | stop_client | ||
112 | done | ||
113 | 103 | ||
114 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy | 104 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy |
115 | echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy | 105 | echo "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 |
121 | for p in ${SSH_PROTOCOLS}; do | 111 | trace "nomatch permitopen proxy w/key opts" |
122 | trace "nomatch permitopen proxy w/key opts proto $p" | 112 | start_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" | 115 | stop_client |
126 | stop_client | ||
127 | done | ||
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 | ||
4 | tid="cipher speed" | 4 | tid="cipher speed" |
@@ -12,16 +12,16 @@ getbytes () | |||
12 | tries="1 2" | 12 | tries="1 2" |
13 | 13 | ||
14 | for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do | 14 | for 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` |
32 | done; done | 32 | done; done |
33 | |||
34 | if ssh_version 1; then | ||
35 | ciphers="3des blowfish" | ||
36 | else | ||
37 | ciphers="" | ||
38 | fi | ||
39 | for 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 | ||
51 | done | ||
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 | ||
4 | tid="proxy connect with privsep" | 4 | tid="proxy connect with privsep" |
@@ -6,23 +6,19 @@ tid="proxy connect with privsep" | |||
6 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig | 6 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig |
7 | echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy | 7 | echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy |
8 | 8 | ||
9 | for p in ${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 | 10 | if [ $? -ne 0 ]; then |
11 | if [ $? -ne 0 ]; then | 11 | fail "ssh privsep+proxyconnect failed" |
12 | fail "ssh privsep+proxyconnect protocol $p failed" | 12 | fi |
13 | fi | ||
14 | done | ||
15 | 13 | ||
16 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy | 14 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy |
17 | echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy | 15 | echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy |
18 | 16 | ||
19 | for 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 | 18 | if [ $? -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" | 21 | fi |
24 | fi | ||
25 | done | ||
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'` |
33 | fi | 29 | fi |
34 | for m in '' $mopts ; do | 30 | for 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 | ||
41 | done | 35 | done |
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 | ||
4 | tid="simple connect" | 4 | tid="simple connect" |
5 | 5 | ||
6 | start_sshd | 6 | start_sshd |
7 | 7 | ||
8 | for p in ${SSH_PROTOCOLS}; do | 8 | ${SSH} -F $OBJ/ssh_config somehost true |
9 | ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true | 9 | if [ $? -ne 0 ]; then |
10 | if [ $? -ne 0 ]; then | 10 | fail "ssh connect with failed" |
11 | fail "ssh connect with protocol $p failed" | 11 | fi |
12 | fi | ||
13 | done | ||
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 | ||
4 | tid="dhgex" | 4 | tid="dhgex" |
@@ -54,7 +54,6 @@ check() | |||
54 | 54 | ||
55 | #check 2048 3des-cbc | 55 | #check 2048 3des-cbc |
56 | check 3072 `${SSH} -Q cipher | grep 128` | 56 | check 3072 `${SSH} -Q cipher | grep 128` |
57 | check 3072 arcfour blowfish-cbc | ||
58 | check 7680 `${SSH} -Q cipher | grep 192` | 57 | check 7680 `${SSH} -Q cipher | grep 192` |
59 | check 8192 `${SSH} -Q cipher | grep 256` | 58 | check 8192 `${SSH} -Q cipher | grep 256` |
60 | check 8192 rijndael-cbc@lysator.liu.se chacha20-poly1305@openssh.com | 59 | check 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 | ||
4 | tid="dynamic forwarding" | 4 | tid="dynamic forwarding" |
@@ -17,33 +17,34 @@ trace "will use ProxyCommand $proxycmd" | |||
17 | 17 | ||
18 | start_sshd | 18 | start_sshd |
19 | 19 | ||
20 | for p in ${SSH_PROTOCOLS}; do | 20 | for 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 | |||
59 | done | 61 | done |
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 | ||
4 | tid="remote exit status" | 4 | tid="remote exit status" |
5 | 5 | ||
6 | for p in ${SSH_PROTOCOLS}; do | 6 | for 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 | ||
24 | done | 22 | done |
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 | ||
4 | tid="forced command" | 4 | tid="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 |
12 | done | 12 | done |
13 | 13 | ||
14 | for p in ${SSH_PROTOCOLS}; do | 14 | trace "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" | ||
18 | done | ||
19 | 16 | ||
20 | cp /dev/null $OBJ/authorized_keys_$USER | 17 | cp /dev/null $OBJ/authorized_keys_$USER |
21 | for t in ${SSH_KEYTYPES}; do | 18 | for t in ${SSH_KEYTYPES}; do |
@@ -26,19 +23,13 @@ done | |||
26 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy | 23 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy |
27 | echo "ForceCommand true" >> $OBJ/sshd_proxy | 24 | echo "ForceCommand true" >> $OBJ/sshd_proxy |
28 | 25 | ||
29 | for p in ${SSH_PROTOCOLS}; do | 26 | trace "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" | ||
33 | done | ||
34 | 28 | ||
35 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy | 29 | cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy |
36 | echo "ForceCommand false" >> $OBJ/sshd_proxy | 30 | echo "ForceCommand false" >> $OBJ/sshd_proxy |
37 | echo "Match User $USER" >> $OBJ/sshd_proxy | 31 | echo "Match User $USER" >> $OBJ/sshd_proxy |
38 | echo " ForceCommand true" >> $OBJ/sshd_proxy | 32 | echo " ForceCommand true" >> $OBJ/sshd_proxy |
39 | 33 | ||
40 | for p in ${SSH_PROTOCOLS}; do | 34 | trace "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" | ||
44 | done | ||
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 | ||
4 | tid="sshd control of local and remote forwarding" | 4 | tid="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 |
36 | check_lfwd() { | 36 | check_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 |
66 | check_rfwd() { | 65 | check_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 | |||
99 | cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak | 97 | cp ${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 |
102 | for p in ${SSH_PROTOCOLS} ; do | 100 | check_lfwd Y "default configuration" |
103 | check_lfwd $p Y "proto $p, default configuration" | 101 | check_rfwd Y "default configuration" |
104 | check_rfwd $p Y "proto $p, default configuration" | ||
105 | done | ||
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 |
108 | all_tests() { | 104 | all_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 | ||
4 | tid="local and remote forwarding" | 4 | tid="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 |
24 | done | 24 | done |
25 | for 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" | 26 | trace "start forwarding, fork to background" |
35 | ${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \ | 27 | rm -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 | 30 | trace "transfer over forwarded channels and check result" |
41 | done | 31 | ${SSH} -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \ |
32 | somehost cat ${DATA} > ${COPY} | ||
33 | test -s ${COPY} || fail "failed copy of ${DATA}" | ||
34 | cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" | ||
35 | |||
36 | ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost | ||
42 | 37 | ||
43 | for p in ${SSH_PROTOCOLS}; do | ||
44 | for d in L R; do | 38 | for 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 |
70 | done | 64 | done |
71 | done | ||
72 | 65 | ||
73 | for p in ${SSH_PROTOCOLS}; do | 66 | trace "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 | 69 | trace "clear local forward" | |
77 | trace "clear local forward proto $p" | 70 | rm -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 | 73 | if [ $? != 0 ]; then |
81 | if [ $? != 0 ]; then | 74 | fail "connection failed with cleared local forwarding" |
82 | fail "connection failed with cleared local forwarding" | 75 | else |
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" | 80 | fi |
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 | 83 | trace "clear remote forward" | |
91 | trace "clear remote forward proto $p" | 84 | rm -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 | 87 | if [ $? != 0 ]; then |
95 | if [ $? != 0 ]; then | 88 | fail "connection failed with cleared remote forwarding" |
96 | fail "connection failed with cleared remote forwarding" | 89 | else |
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" | 94 | fi |
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 | |
104 | done | 97 | trace "stdio forwarding" |
105 | 98 | cmd="${SSH} -F $OBJ/ssh_config" | |
106 | for p in 2; do | 99 | $cmd -o "ProxyCommand $cmd -q -W localhost:$PORT somehost" somehost true |
107 | trace "stdio forwarding proto $p" | 100 | if [ $? != 0 ]; then |
108 | cmd="${SSH} -$p -F $OBJ/ssh_config" | 101 | fail "stdio forwarding" |
109 | $cmd -o "ProxyCommand $cmd -q -W localhost:$PORT somehost" \ | 102 | fi |
110 | somehost true | ||
111 | if [ $? != 0 ]; then | ||
112 | fail "stdio forwarding proto $p" | ||
113 | fi | ||
114 | done | ||
115 | 103 | ||
116 | echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config | 104 | echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config |
117 | echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config | 105 | echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config |
118 | for 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 | ||
130 | done | ||
131 | 106 | ||
132 | for p in 2; do | 107 | trace "config file: start forwarding, fork to background" |
133 | trace "transfer over chained unix domain socket forwards and check result" | 108 | rm -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 | 111 | trace "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 | 114 | test -s ${COPY} || fail "failed copy of ${DATA}" |
140 | ${SSH} -F $OBJ/ssh_config -p${base}01 -o 'ConnectionAttempts=4' \ | 115 | cmp ${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 | 119 | trace "transfer over chained unix domain socket forwards and check result" | |
145 | ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost | 120 | rm -f $OBJ/unix-[123].fwd |
146 | ${SSH} -F $OBJ/ssh_config -S $CTL.1 -O exit somehost | 121 | rm -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 |
149 | done | 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} | ||
128 | test -s ${COPY} || fail "failed copy ${DATA}" | ||
129 | cmp ${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 | ||
4 | tid="expand %h and %n" | 4 | tid="expand %h and %n" |
@@ -11,9 +11,6 @@ somehost | |||
11 | 127.0.0.1 | 11 | 127.0.0.1 |
12 | EOE | 12 | EOE |
13 | 13 | ||
14 | for p in ${SSH_PROTOCOLS}; do | 14 | ${SSH} -F $OBJ/ssh_proxy somehost true >$OBJ/actual |
15 | verbose "test $tid: proto $p" | 15 | diff $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" | ||
18 | done | ||
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 | ||
4 | tid="hostkey agent" | 4 | tid="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 | ||
4 | tid="integrity" | 4 | tid="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 | ||
4 | tid="key options" | 4 | tid="key options" |
@@ -8,64 +8,56 @@ authkeys="$OBJ/authorized_keys_${USER}" | |||
8 | cp $authkeys $origkeys | 8 | cp $authkeys $origkeys |
9 | 9 | ||
10 | # Test command= forced command | 10 | # Test command= forced command |
11 | for p in ${SSH_PROTOCOLS}; do | 11 | for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do |
12 | for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do | ||
13 | sed "s/.*/$c &/" $origkeys >$authkeys | 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 | ||
23 | done | 21 | done |
24 | 22 | ||
25 | # Test no-pty | 23 | # Test no-pty |
26 | sed 's/.*/no-pty &/' $origkeys >$authkeys | 24 | sed 's/.*/no-pty &/' $origkeys >$authkeys |
27 | for p in ${SSH_PROTOCOLS}; do | 25 | verbose "key option proto no-pty" |
28 | verbose "key option proto $p no-pty" | 26 | r=`${SSH} -q -F $OBJ/ssh_proxy somehost tty` |
29 | r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost tty` | 27 | if [ -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)" | 29 | fi |
32 | fi | ||
33 | done | ||
34 | 30 | ||
35 | # Test environment= | 31 | # Test environment= |
36 | echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy | 32 | echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy |
37 | sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys | 33 | sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys |
38 | for p in ${SSH_PROTOCOLS}; do | 34 | verbose "key option environment" |
39 | verbose "key option proto $p environment" | 35 | r=`${SSH} -q -F $OBJ/ssh_proxy somehost 'echo $FOO'` |
40 | r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo $FOO'` | 36 | if [ "$r" != "bar" ]; then |
41 | if [ "$r" != "bar" ]; then | 37 | fail "key option environment not set" |
42 | fail "key option environment not set" | 38 | fi |
43 | fi | ||
44 | done | ||
45 | 39 | ||
46 | # Test from= restriction | 40 | # Test from= restriction |
47 | start_sshd | 41 | start_sshd |
48 | for p in ${SSH_PROTOCOLS}; do | 42 | for f in 127.0.0.1 '127.0.0.0\/8'; do |
49 | for f in 127.0.0.1 '127.0.0.0\/8'; do | ||
50 | cat $origkeys >$authkeys | 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 | ||
69 | done | 61 | done |
70 | 62 | ||
71 | rm -f "$origkeys" | 63 | rm -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 | ||
4 | tid="change passphrase for key" | 4 | tid="change passphrase for key" |
@@ -7,9 +7,6 @@ S1="secret1" | |||
7 | S2="2secret" | 7 | S2="2secret" |
8 | 8 | ||
9 | KEYTYPES=`${SSH} -Q key-plain` | 9 | KEYTYPES=`${SSH} -Q key-plain` |
10 | if ssh_version 1; then | ||
11 | KEYTYPES="${KEYTYPES} rsa1" | ||
12 | fi | ||
13 | 10 | ||
14 | for t in $KEYTYPES; do | 11 | for 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 | ||
4 | tid="keyscan" | 4 | tid="keyscan" |
@@ -9,10 +9,6 @@ rm -f ${OBJ}/host.dsa | |||
9 | start_sshd | 9 | start_sshd |
10 | 10 | ||
11 | KEYTYPES=`${SSH} -Q key-plain` | 11 | KEYTYPES=`${SSH} -Q key-plain` |
12 | if ssh_version 1; then | ||
13 | KEYTYPES="${KEYTYPES} rsa1" | ||
14 | fi | ||
15 | |||
16 | for t in $KEYTYPES; do | 12 | for 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 | ||
4 | tid="login with different key types" | 4 | tid="login with different key types" |
5 | 5 | ||
6 | TIME=`which time 2>/dev/null` | ||
7 | if test ! -x "$TIME"; then | ||
8 | TIME="" | ||
9 | fi | ||
10 | |||
11 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak | 6 | cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak |
12 | cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak | 7 | cp $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" |
32 | done | 27 | done |
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 | ||
4 | tid="localcommand" | 4 | tid="localcommand" |
@@ -6,10 +6,8 @@ tid="localcommand" | |||
6 | echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy | 6 | echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy |
7 | echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy | 7 | echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy |
8 | 8 | ||
9 | for p in ${SSH_PROTOCOLS}; do | 9 | verbose "test $tid: proto $p localcommand" |
10 | verbose "test $tid: proto $p localcommand" | 10 | a=`${SSH} -F $OBJ/ssh_proxy somehost true` |
11 | a=`${SSH} -F $OBJ/ssh_proxy -$p somehost true` | 11 | if [ "$a" != "foo" ] ; then |
12 | if [ "$a" != "foo" ] ; then | 12 | fail "$tid proto $p" |
13 | fail "$tid proto $p" | 13 | fi |
14 | fi | ||
15 | done | ||
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 | ||
4 | tid="connect after login grace timeout" | 4 | tid="connect after login grace timeout" |
@@ -10,23 +10,9 @@ echo "LoginGraceTime 10s" >> $OBJ/sshd_config | |||
10 | echo "MaxStartups 1" >> $OBJ/sshd_config | 10 | echo "MaxStartups 1" >> $OBJ/sshd_config |
11 | start_sshd | 11 | start_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 & |
14 | sleep 15 | 14 | sleep 15 |
15 | ${SSH} -F $OBJ/ssh_config somehost true | 15 | ${SSH} -F $OBJ/ssh_config somehost true |
16 | if [ $? -ne 0 ]; then | 16 | if [ $? -ne 0 ]; then |
17 | fail "ssh connect after login grace timeout failed with privsep" | 17 | fail "ssh connect after login grace timeout failed" |
18 | fi | ||
19 | |||
20 | stop_sshd | ||
21 | |||
22 | trace "test login grace without privsep" | ||
23 | echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config | ||
24 | start_sshd | ||
25 | sleep 1 | ||
26 | |||
27 | (echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 & | ||
28 | sleep 15 | ||
29 | ${SSH} -F $OBJ/ssh_config somehost true | ||
30 | if [ $? -ne 0 ]; then | ||
31 | fail "ssh connect after login grace timeout failed without privsep" | ||
32 | fi | 18 | fi |
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. | ||
2 | CXX=clang++-3.9 | ||
3 | FUZZ_FLAGS=-fsanitize=address,undefined -fsanitize-coverage=edge | ||
4 | FUZZ_LIBS=-lFuzzer | ||
5 | |||
6 | CXXFLAGS=-O2 -g -Wall -Wextra -I ../../.. $(FUZZ_FLAGS) | ||
7 | LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g $(FUZZ_FLAGS) | ||
8 | LIBS=-lssh -lopenbsd-compat -lcrypto $(FUZZ_LIBS) | ||
9 | |||
10 | all: pubkey_fuzz sig_fuzz | ||
11 | |||
12 | .cc.o: | ||
13 | $(CXX) $(CXXFLAGS) -c $< -o $@ | ||
14 | |||
15 | pubkey_fuzz: pubkey_fuzz.o | ||
16 | $(CXX) -o $@ pubkey_fuzz.o $(LDFLAGS) $(LIBS) | ||
17 | |||
18 | sig_fuzz: sig_fuzz.o | ||
19 | $(CXX) -o $@ sig_fuzz.o $(LDFLAGS) $(LIBS) | ||
20 | |||
21 | clean: | ||
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 | |||
5 | extern "C" { | ||
6 | |||
7 | #include "sshkey.h" | ||
8 | |||
9 | int 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 | |||
9 | extern "C" { | ||
10 | |||
11 | #include "includes.h" | ||
12 | #include "sshkey.h" | ||
13 | #include "ssherr.h" | ||
14 | |||
15 | static 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 | |||
25 | int 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 | |||
49 | CDIAGFLAGS+= -Wtrigraphs | 49 | CDIAGFLAGS+= -Wtrigraphs |
50 | CDIAGFLAGS+= -Wuninitialized | 50 | CDIAGFLAGS+= -Wuninitialized |
51 | CDIAGFLAGS+= -Wunused | 51 | CDIAGFLAGS+= -Wunused |
52 | .if ${COMPILER_VERSION} == "gcc4" | 52 | .if ${COMPILER_VERSION:L} != "gcc3" |
53 | CDIAGFLAGS+= -Wpointer-sign | 53 | CDIAGFLAGS+= -Wpointer-sign |
54 | CDIAGFLAGS+= -Wold-style-definition | 54 | CDIAGFLAGS+= -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 | ||
4 | CTL=/tmp/openssh.regress.ctl-sock.$$ | 4 | CTL=/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 |
115 | done | 115 | done |
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 | ||
4 | tid="authorized principals command" | 4 | tid="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 | ||
4 | tid="protocol version mismatch" | 4 | tid="protocol version mismatch" |
5 | 5 | ||
6 | mismatch () | 6 | mismatch () |
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 | ||
18 | mismatch 2 SSH-1.5-HALLO | 17 | mismatch SSH-1.5-HALLO |
19 | if ssh_version 1; then | ||
20 | mismatch 1 SSH-2.0-HALLO | ||
21 | fi | ||
diff --git a/regress/proto-version.sh b/regress/proto-version.sh index 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 | ||
4 | tid="sshd version with different protocol combinations" | 4 | tid="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 |
7 | check_version () | 7 | check_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 | ||
31 | check_version 2 20 | 30 | check_version 20 |
32 | if ssh_version 1; then | ||
33 | check_version 2,1 199 | ||
34 | check_version 1,2 199 | ||
35 | check_version 1 15 | ||
36 | fi | ||
diff --git a/regress/proxy-connect.sh b/regress/proxy-connect.sh index 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 | ||
4 | tid="proxy connect" | 4 | tid="proxy connect" |
@@ -6,27 +6,22 @@ tid="proxy connect" | |||
6 | mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig | 6 | mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig |
7 | 7 | ||
8 | for ps in no yes; do | 8 | for ps in no yes; do |
9 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy | 9 | cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy |
10 | echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy | 10 | echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy |
11 | 11 | 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 | ||
26 | done | 23 | done |
27 | 24 | ||
28 | for p in ${SSH_PROTOCOLS}; do | 25 | verbose "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" | ||
32 | done | ||
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 | ||
4 | tid="putty ciphers" | 4 | tid="putty ciphers" |
@@ -8,7 +8,7 @@ if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then | |||
8 | exit 0 | 8 | exit 0 |
9 | fi | 9 | fi |
10 | 10 | ||
11 | for c in aes blowfish 3des arcfour aes128-ctr aes192-ctr aes256-ctr ; do | 11 | for 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 | ||
4 | tid="putty transfer data" | 4 | tid="putty transfer data" |
@@ -8,33 +8,30 @@ if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then | |||
8 | exit 0 | 8 | exit 0 |
9 | fi | 9 | fi |
10 | 10 | ||
11 | # XXX support protocol 1 too | 11 | for c in 0 1 ; do |
12 | for 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 |
39 | done | 36 | done |
40 | rm -f ${COPY} | 37 | rm -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 | ||
4 | tid="simple connect after reconfigure" | 4 | tid="simple connect after reconfigure" |
@@ -18,12 +18,10 @@ fi | |||
18 | start_sshd | 18 | start_sshd |
19 | 19 | ||
20 | trace "connect before restart" | 20 | trace "connect before restart" |
21 | for p in ${SSH_PROTOCOLS} ; do | 21 | ${SSH} -F $OBJ/ssh_config somehost true |
22 | ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true | 22 | if [ $? -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" | 24 | fi |
25 | fi | ||
26 | done | ||
27 | 25 | ||
28 | PID=`$SUDO cat $PIDFILE` | 26 | PID=`$SUDO cat $PIDFILE` |
29 | rm -f $PIDFILE | 27 | rm -f $PIDFILE |
@@ -39,9 +37,7 @@ done | |||
39 | test -f $PIDFILE || fatal "sshd did not restart" | 37 | test -f $PIDFILE || fatal "sshd did not restart" |
40 | 38 | ||
41 | trace "connect after restart" | 39 | trace "connect after restart" |
42 | for p in ${SSH_PROTOCOLS} ; do | 40 | ${SSH} -F $OBJ/ssh_config somehost true |
43 | ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true | 41 | if [ $? -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" | 43 | fi |
46 | fi | ||
47 | done | ||
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 | ||
4 | tid="reexec tests" | 4 | tid="reexec tests" |
@@ -19,16 +19,13 @@ start_sshd_copy () | |||
19 | copy_tests () | 19 | copy_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 | ||
34 | verbose "test config passing" | 31 | verbose "test config passing" |
@@ -54,17 +51,4 @@ rm -f $SSHD_COPY | |||
54 | copy_tests | 51 | copy_tests |
55 | 52 | ||
56 | stop_sshd | 53 | stop_sshd |
57 | |||
58 | verbose "test reexec fallback without privsep" | ||
59 | |||
60 | cp $OBJ/sshd_config.orig $OBJ/sshd_config | ||
61 | echo "UsePrivilegeSeparation=no" >> $OBJ/sshd_config | ||
62 | |||
63 | start_sshd_copy | ||
64 | rm -f $SSHD_COPY | ||
65 | |||
66 | copy_tests | ||
67 | |||
68 | stop_sshd | ||
69 | |||
70 | fi | 54 | fi |
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 | ||
4 | tid="connect to ssh.com server" | 4 | tid="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 | ||
4 | tid="stderr data after eof" | 4 | tid="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} |
11 | done | 11 | done |
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} |
16 | r=$? | 16 | r=$? |
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 | ||
4 | tid="stderr data transfer" | 4 | tid="stderr data transfer" |
5 | 5 | ||
6 | for n in '' -n; do | 6 | for n in '' -n; do |
7 | for p in ${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} |
28 | done | 27 | done |
29 | done | ||
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 |
131 | fi | 131 | fi |
132 | 132 | ||
133 | SSH_PROTOCOLS=2 | ||
134 | #SSH_PROTOCOLS=`$SSH -Q protocol-version` | ||
135 | if [ "x$TEST_SSH_PROTOCOLS" != "x" ]; then | ||
136 | SSH_PROTOCOLS="${TEST_SSH_PROTOCOLS}" | ||
137 | fi | ||
138 | |||
139 | # Path to sshd must be absolute for rexec | 133 | # Path to sshd must be absolute for rexec |
140 | case "$SSHD" in | 134 | case "$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 | ||
389 | ssh_version () | ||
390 | { | ||
391 | echo ${SSH_PROTOCOLS} | grep "$1" >/dev/null | ||
392 | } | ||
393 | |||
394 | RESULT=0 | 390 | RESULT=0 |
395 | PIDFILE=$OBJ/pidfile | 391 | PIDFILE=$OBJ/pidfile |
396 | 392 | ||
397 | trap fatal 3 2 | 393 | trap fatal 3 2 |
398 | 394 | ||
399 | if ssh_version 1; then | ||
400 | PROTO="2,1" | ||
401 | else | ||
402 | PROTO="2" | ||
403 | fi | ||
404 | |||
405 | # create server config | 395 | # create server config |
406 | cat << EOF > $OBJ/sshd_config | 396 | cat << EOF > $OBJ/sshd_config |
407 | StrictModes no | 397 | StrictModes no |
@@ -460,11 +450,8 @@ fi | |||
460 | 450 | ||
461 | rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER | 451 | rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER |
462 | 452 | ||
463 | if ssh_version 1; then | 453 | SSH_KEYTYPES="rsa ed25519" |
464 | SSH_KEYTYPES="rsa rsa1" | 454 | |
465 | else | ||
466 | SSH_KEYTYPES="rsa ed25519" | ||
467 | fi | ||
468 | trace "generate keys" | 455 | trace "generate keys" |
469 | for t in ${SSH_KEYTYPES}; do | 456 | for 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 | ||
4 | tid="transfer data" | 4 | tid="transfer data" |
5 | 5 | ||
6 | for p in ${SSH_PROTOCOLS}; do | 6 | rm -f ${COPY} |
7 | verbose "$tid: proto $p" | 7 | ${SSH} -n -q -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY} |
8 | if [ $? -ne 0 ]; then | ||
9 | fail "ssh cat $DATA failed" | ||
10 | fi | ||
11 | cmp ${DATA} ${COPY} || fail "corrupted copy" | ||
12 | |||
13 | for 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 | ||
25 | done | 22 | done |
26 | rm -f ${COPY} | 23 | rm -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 | ||
4 | tid="try ciphers" | 4 | tid="try ciphers" |
@@ -8,14 +8,14 @@ cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak | |||
8 | for c in `${SSH} -Q cipher`; do | 8 | for 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 |
27 | done | 27 | done |
28 | 28 | ||
29 | if ssh_version 1; then | ||
30 | ciphers="3des blowfish" | ||
31 | else | ||
32 | ciphers="" | ||
33 | fi | ||
34 | for 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 | ||
41 | done | ||
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 | |||
30 | CDIAGFLAGS+= -Wtrigraphs | 30 | CDIAGFLAGS+= -Wtrigraphs |
31 | CDIAGFLAGS+= -Wuninitialized | 31 | CDIAGFLAGS+= -Wuninitialized |
32 | CDIAGFLAGS+= -Wunused | 32 | CDIAGFLAGS+= -Wunused |
33 | .if ${COMPILER_VERSION} == "gcc4" | 33 | .if ${COMPILER_VERSION:L} != "gcc3" |
34 | CDIAGFLAGS+= -Wpointer-sign | 34 | CDIAGFLAGS+= -Wpointer-sign |
35 | CDIAGFLAGS+= -Wold-style-definition | 35 | CDIAGFLAGS+= -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 | ||
4 | set -ex | 4 | set -ex |
5 | 5 | ||
6 | cd testdata | 6 | cd testdata |
7 | 7 | ||
8 | rm -f rsa1* rsa* dsa* ecdsa* ed25519* | 8 | rm -f rsa* dsa* ecdsa* ed25519* |
9 | rm -f known_hosts* | 9 | rm -f known_hosts* |
10 | 10 | ||
11 | gen_all() { | 11 | gen_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 | ||
25 | hentries() { | 24 | hentries() { |
@@ -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 @@ | |||
2 | sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 | 2 | sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 |
3 | sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 | 3 | sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 |
4 | sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 | 4 | sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 |
5 | sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 | ||
6 | sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 | 5 | sisyphus.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 |
9 | prometheus.example.com,192.0.2.1,2001:db8::1 ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 | 8 | prometheus.example.com,192.0.2.1,2001:db8::1 ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 |
10 | prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 | 9 | prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 |
11 | prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 | 10 | prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 |
12 | prometheus.example.com,192.0.2.1,2001:db8::1 1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 | ||
13 | prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 | 11 | prometheus.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 |
54 | sisyphus.example.com | 46 | sisyphus.example.com |
55 | prometheus.example.com ssh-ed25519 | 47 | prometheus.example.com ssh-ed25519 |
56 | sisyphus.example.com ssh-dsa AAAATgAAAAdz | 48 | sisyphus.example.com ssh-dsa AAAATgAAAAdz |
57 | prometheus.example.com 1024 | ||
58 | sisyphus.example.com 1024 65535 | ||
59 | prometheus.example.com 1025 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 | ||
60 | sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== | 49 | sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== |
61 | prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== | 50 | prometheus.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 | ||
4 | PW=mekmitasdigoat | 4 | PW=mekmitasdigoat |
5 | 5 | ||
6 | rsa1_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 | |||
23 | rsa_params() { | 6 | rsa_params() { |
24 | _in="$1" | 7 | _in="$1" |
25 | _outbase="$2" | 8 | _outbase="$2" |
@@ -87,20 +70,18 @@ set -ex | |||
87 | 70 | ||
88 | cd testdata | 71 | cd testdata |
89 | 72 | ||
90 | rm -f rsa1_1 rsa_1 dsa_1 ecdsa_1 ed25519_1 | 73 | rm -f rsa_1 dsa_1 ecdsa_1 ed25519_1 |
91 | rm -f rsa1_2 rsa_2 dsa_2 ecdsa_2 ed25519_2 | 74 | rm -f rsa_2 dsa_2 ecdsa_2 ed25519_2 |
92 | rm -f rsa_n dsa_n ecdsa_n # new-format keys | 75 | rm -f rsa_n dsa_n ecdsa_n # new-format keys |
93 | rm -f rsa1_1_pw rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw | 76 | rm -f rsa_1_pw dsa_1_pw ecdsa_1_pw ed25519_1_pw |
94 | rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw | 77 | rm -f rsa_n_pw dsa_n_pw ecdsa_n_pw |
95 | rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb | 78 | rm -f pw *.pub *.bn.* *.param.* *.fp *.fp.bb |
96 | 79 | ||
97 | ssh-keygen -t rsa1 -b 1024 -C "RSA1 test key #1" -N "" -f rsa1_1 | ||
98 | ssh-keygen -t rsa -b 1024 -C "RSA test key #1" -N "" -f rsa_1 | 80 | ssh-keygen -t rsa -b 1024 -C "RSA test key #1" -N "" -f rsa_1 |
99 | ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1 | 81 | ssh-keygen -t dsa -b 1024 -C "DSA test key #1" -N "" -f dsa_1 |
100 | ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1 | 82 | ssh-keygen -t ecdsa -b 256 -C "ECDSA test key #1" -N "" -f ecdsa_1 |
101 | ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1 | 83 | ssh-keygen -t ed25519 -C "ED25519 test key #1" -N "" -f ed25519_1 |
102 | 84 | ||
103 | ssh-keygen -t rsa1 -b 2048 -C "RSA1 test key #2" -N "" -f rsa1_2 | ||
104 | ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2 | 85 | ssh-keygen -t rsa -b 2048 -C "RSA test key #2" -N "" -f rsa_2 |
105 | ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2 | 86 | ssh-keygen -t dsa -b 1024 -C "DSA test key #2" -N "" -f dsa_2 |
106 | ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2 | 87 | ssh-keygen -t ecdsa -b 521 -C "ECDSA test key #2" -N "" -f ecdsa_2 |
@@ -110,7 +91,6 @@ cp rsa_1 rsa_n | |||
110 | cp dsa_1 dsa_n | 91 | cp dsa_1 dsa_n |
111 | cp ecdsa_1 ecdsa_n | 92 | cp ecdsa_1 ecdsa_n |
112 | 93 | ||
113 | cp rsa1_1 rsa1_1_pw | ||
114 | cp rsa_1 rsa_1_pw | 94 | cp rsa_1 rsa_1_pw |
115 | cp dsa_1 dsa_1_pw | 95 | cp dsa_1 dsa_1_pw |
116 | cp ecdsa_1 ecdsa_1_pw | 96 | cp ecdsa_1 ecdsa_1_pw |
@@ -119,7 +99,6 @@ cp rsa_1 rsa_n_pw | |||
119 | cp dsa_1 dsa_n_pw | 99 | cp dsa_1 dsa_n_pw |
120 | cp ecdsa_1 ecdsa_n_pw | 100 | cp ecdsa_1 ecdsa_n_pw |
121 | 101 | ||
122 | ssh-keygen -pf rsa1_1_pw -N "$PW" | ||
123 | ssh-keygen -pf rsa_1_pw -N "$PW" | 102 | ssh-keygen -pf rsa_1_pw -N "$PW" |
124 | ssh-keygen -pf dsa_1_pw -N "$PW" | 103 | ssh-keygen -pf dsa_1_pw -N "$PW" |
125 | ssh-keygen -pf ecdsa_1_pw -N "$PW" | 104 | ssh-keygen -pf ecdsa_1_pw -N "$PW" |
@@ -128,8 +107,6 @@ ssh-keygen -opf rsa_n_pw -N "$PW" | |||
128 | ssh-keygen -opf dsa_n_pw -N "$PW" | 107 | ssh-keygen -opf dsa_n_pw -N "$PW" |
129 | ssh-keygen -opf ecdsa_n_pw -N "$PW" | 108 | ssh-keygen -opf ecdsa_n_pw -N "$PW" |
130 | 109 | ||
131 | rsa1_params rsa1_1 rsa1_1.param | ||
132 | rsa1_params rsa1_2 rsa1_2.param | ||
133 | rsa_params rsa_1 rsa_1.param | 110 | rsa_params rsa_1 rsa_1.param |
134 | rsa_params rsa_2 rsa_2.param | 111 | rsa_params rsa_2 rsa_2.param |
135 | dsa_params dsa_1 dsa_1.param | 112 | dsa_params dsa_1 dsa_1.param |
@@ -160,12 +137,10 @@ ssh-keygen -s ecdsa_1 -I julius -n host1,host2 -h \ | |||
160 | ssh-keygen -s ed25519_1 -I julius -n host1,host2 -h \ | 137 | ssh-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 | ||
163 | ssh-keygen -lf rsa1_1 | awk '{print $2}' > rsa1_1.fp | ||
164 | ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp | 140 | ssh-keygen -lf rsa_1 | awk '{print $2}' > rsa_1.fp |
165 | ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp | 141 | ssh-keygen -lf dsa_1 | awk '{print $2}' > dsa_1.fp |
166 | ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp | 142 | ssh-keygen -lf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp |
167 | ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp | 143 | ssh-keygen -lf ed25519_1 | awk '{print $2}' > ed25519_1.fp |
168 | ssh-keygen -lf rsa1_2 | awk '{print $2}' > rsa1_2.fp | ||
169 | ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp | 144 | ssh-keygen -lf rsa_2 | awk '{print $2}' > rsa_2.fp |
170 | ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp | 145 | ssh-keygen -lf dsa_2 | awk '{print $2}' > dsa_2.fp |
171 | ssh-keygen -lf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp | 146 | ssh-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 | |||
176 | ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp | 151 | ssh-keygen -lf ed25519_1-cert.pub | awk '{print $2}' > ed25519_1-cert.fp |
177 | ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp | 152 | ssh-keygen -lf rsa_1-cert.pub | awk '{print $2}' > rsa_1-cert.fp |
178 | 153 | ||
179 | ssh-keygen -Bf rsa1_1 | awk '{print $2}' > rsa1_1.fp.bb | ||
180 | ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb | 154 | ssh-keygen -Bf rsa_1 | awk '{print $2}' > rsa_1.fp.bb |
181 | ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb | 155 | ssh-keygen -Bf dsa_1 | awk '{print $2}' > dsa_1.fp.bb |
182 | ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb | 156 | ssh-keygen -Bf ecdsa_1 | awk '{print $2}' > ecdsa_1.fp.bb |
183 | ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb | 157 | ssh-keygen -Bf ed25519_1 | awk '{print $2}' > ed25519_1.fp.bb |
184 | ssh-keygen -Bf rsa1_2 | awk '{print $2}' > rsa1_2.fp.bb | ||
185 | ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb | 158 | ssh-keygen -Bf rsa_2 | awk '{print $2}' > rsa_2.fp.bb |
186 | ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb | 159 | ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb |
187 | ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb | 160 | ssh-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 | ||
4 | tid="yes pipe head" | 4 | tid="yes pipe head" |
5 | 5 | ||
6 | for p in ${SSH_PROTOCOLS}; do | 6 | lines=`${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)` | 7 | if [ $? -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; | 10 | fi |
11 | fi | 11 | if [ $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" | 13 | fi |
14 | fi | ||
15 | done | ||
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 | |||
74 | int | ||
75 | rsa_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 | |||
120 | int | ||
121 | rsa_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 */ | ||
161 | int | ||
162 | rsa_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 | |||
22 | int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *); | ||
23 | int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *); | ||
24 | int 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 || |
@@ -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 | ||
6 | SYNOPSIS | 6 | SYNOPSIS |
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 | ||
168 | OpenBSD 6.0 July 16, 2016 OpenBSD 6.0 | 159 | OpenBSD 6.2 May 3, 2017 OpenBSD 6.2 |
@@ -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 |
66 | The options are as follows: | 66 | The options are as follows: |
67 | .Bl -tag -width Ds | 67 | .Bl -tag -width Ds |
68 | .It Fl 1 | ||
69 | Forces | ||
70 | .Nm | ||
71 | to use protocol 1. | ||
72 | .It Fl 2 | ||
73 | Forces | ||
74 | .Nm | ||
75 | to use protocol 2. | ||
76 | .It Fl 3 | 68 | .It Fl 3 |
77 | Copies between two remote hosts are transferred through the local host. | 69 | Copies between two remote hosts are transferred through the local host. |
78 | Without this option the data is copied directly between the two remote | 70 | Without 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 |
@@ -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 | |||
918 | void | 930 | void |
919 | sink(int argc, char **argv) | 931 | sink(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 | |||
1256 | usage(void) | 1274 | usage(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 | */ | ||
703 | void | ||
704 | process_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 | |||
695 | struct connection_info * | 738 | struct connection_info * |
696 | get_connection_info(int populate, int use_dns) | 739 | get_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 | }; |
938 | static 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 | }; | ||
945 | static const struct multistate multistate_tcpfwd[] = { | 981 | static 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 | ||
2054 | void | 2105 | void |
2055 | parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, | 2106 | parse_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 | ||
61 | struct ssh; | ||
62 | struct fwd_perm_list; | ||
63 | |||
57 | typedef struct { | 64 | typedef 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 | ||
233 | struct connection_info *get_connection_info(int, int); | 243 | struct connection_info *get_connection_info(int, int); |
@@ -235,6 +245,7 @@ void initialize_server_options(ServerOptions *); | |||
235 | void fill_default_server_options(ServerOptions *); | 245 | void fill_default_server_options(ServerOptions *); |
236 | int process_server_config_line(ServerOptions *, char *, const char *, int, | 246 | int process_server_config_line(ServerOptions *, char *, const char *, int, |
237 | int *, struct connection_info *); | 247 | int *, struct connection_info *); |
248 | void process_permitopen(struct ssh *ssh, ServerOptions *options); | ||
238 | void load_server_config(const char *, Buffer *); | 249 | void load_server_config(const char *, Buffer *); |
239 | void parse_server_config(ServerOptions *, const char *, Buffer *, | 250 | void 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 | ||
167 | static void | 167 | static void |
168 | client_alive_check(void) | 168 | client_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 | */ |
198 | static void | 199 | static void |
199 | wait_until_can_do_something(int connection_in, int connection_out, | 200 | wait_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 | */ |
281 | static int | 295 | static int |
282 | process_input(fd_set *readset, int connection_in) | 296 | process_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 | ||
323 | static void | 336 | static void |
324 | process_buffered_input_packets(void) | 337 | process_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 | ||
329 | static void | 342 | static void |
330 | collect_children(void) | 343 | collect_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 | ||
351 | void | 364 | void |
352 | server_loop2(Authctxt *authctxt) | 365 | server_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 | ||
419 | static int | 431 | static int |
420 | server_input_keep_alive(int type, u_int32_t seq, void *ctxt) | 432 | server_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 | ||
432 | static Channel * | 444 | static Channel * |
433 | server_request_direct_tcpip(int *reason, const char **errmsg) | 445 | server_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 | ||
467 | static Channel * | 479 | static Channel * |
468 | server_request_direct_streamlocal(void) | 480 | server_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 | ||
504 | static Channel * | 516 | static Channel * |
505 | server_request_tun(void) | 517 | server_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 | ||
550 | static Channel * | 562 | static Channel * |
551 | server_request_session(void) | 563 | server_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 | ||
581 | static int | 593 | static int |
582 | server_input_channel_open(int type, u_int32_t seq, void *ctxt) | 594 | server_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 | ||
635 | static int | 648 | static int |
636 | server_input_hostkeys_prove(struct sshbuf **respp) | 649 | server_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 | ||
705 | static int | 717 | static int |
706 | server_input_global_request(int type, u_int32_t seq, void *ctxt) | 718 | server_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 | ||
812 | static int | 824 | static int |
813 | server_input_channel_req(int type, u_int32_t seq, void *ctxt) | 825 | server_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 | ||
24 | void server_loop2(Authctxt *); | 24 | struct ssh; |
25 | |||
26 | void server_loop2(struct ssh *, Authctxt *); | ||
25 | 27 | ||
26 | #endif | 28 | #endif |
@@ -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 | ||
114 | Session *session_new(void); | 115 | Session *session_new(void); |
115 | void session_set_fds(Session *, int, int, int, int, int); | 116 | void session_set_fds(struct ssh *, Session *, int, int, int, int, int); |
116 | void session_pty_cleanup(Session *); | 117 | void session_pty_cleanup(Session *); |
117 | void session_proctitle(Session *); | 118 | void session_proctitle(Session *); |
118 | int session_setup_x11fwd(Session *); | 119 | int session_setup_x11fwd(struct ssh *, Session *); |
119 | int do_exec_pty(Session *, const char *); | 120 | int do_exec_pty(struct ssh *, Session *, const char *); |
120 | int do_exec_no_pty(Session *, const char *); | 121 | int do_exec_no_pty(struct ssh *, Session *, const char *); |
121 | int do_exec(Session *, const char *); | 122 | int do_exec(struct ssh *, Session *, const char *); |
122 | void do_login(Session *, const char *); | 123 | void do_login(struct ssh *, Session *, const char *); |
124 | void do_child(struct ssh *, Session *, const char *); | ||
123 | #ifdef LOGIN_NEEDS_UTMPX | 125 | #ifdef LOGIN_NEEDS_UTMPX |
124 | static void do_pre_login(Session *s); | 126 | static void do_pre_login(Session *s); |
125 | #endif | 127 | #endif |
126 | void do_child(Session *, const char *); | ||
127 | void do_motd(void); | 128 | void do_motd(void); |
128 | int check_quietlogin(Session *, const char *); | 129 | int check_quietlogin(Session *, const char *); |
129 | 130 | ||
130 | static void do_authenticated2(Authctxt *); | 131 | static void do_authenticated2(struct ssh *, Authctxt *); |
131 | 132 | ||
132 | static int session_pty_req(Session *); | 133 | static int session_pty_req(struct ssh *, Session *); |
133 | 134 | ||
134 | /* import */ | 135 | /* import */ |
135 | extern ServerOptions options; | 136 | extern ServerOptions options; |
136 | extern char *__progname; | 137 | extern char *__progname; |
137 | extern int log_stderr; | ||
138 | extern int debug_flag; | 138 | extern int debug_flag; |
139 | extern u_int utmp_len; | 139 | extern u_int utmp_len; |
140 | extern int startup_pipe; | 140 | extern int startup_pipe; |
@@ -161,6 +161,9 @@ login_cap_t *lc; | |||
161 | static int is_child = 0; | 161 | static int is_child = 0; |
162 | static int in_chroot = 0; | 162 | static int in_chroot = 0; |
163 | 163 | ||
164 | /* File containing userauth info, if ExposeAuthInfo set */ | ||
165 | static 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. */ |
165 | static char *auth_sock_name = NULL; | 168 | static char *auth_sock_name = NULL; |
166 | static char *auth_sock_dir = NULL; | 169 | static char *auth_sock_dir = NULL; |
@@ -180,7 +183,7 @@ auth_sock_cleanup_proc(struct passwd *pw) | |||
180 | } | 183 | } |
181 | 184 | ||
182 | static int | 185 | static int |
183 | auth_input_request_forwarding(struct passwd * pw) | 186 | auth_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 | ||
256 | static void | ||
257 | prepare_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 | |||
253 | void | 290 | void |
254 | do_authenticated(Authctxt *authctxt) | 291 | do_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 | */ |
293 | int | 333 | int |
294 | do_exec_no_pty(Session *s, const char *command) | 334 | do_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 | */ |
477 | int | 513 | int |
478 | do_exec_pty(Session *s, const char *command) | 514 | do_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 | */ |
615 | int | 648 | int |
616 | do_exec(Session *s, const char *command) | 649 | do_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 */ |
694 | void | 726 | void |
695 | do_login(Session *s, const char *command) | 727 | do_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 | */ | ||
798 | void | ||
799 | child_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 | ||
954 | void | 926 | static void |
955 | copy_environment(char **source, char ***env, u_int *envsize) | 927 | copy_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 | ||
954 | void | ||
955 | copy_environment(char **source, char ***env, u_int *envsize) | ||
956 | { | ||
957 | copy_environment_blacklist(source, env, envsize, NULL); | ||
958 | } | ||
959 | |||
978 | static char ** | 960 | static char ** |
979 | do_setup_env(Session *s, const char *shell) | 961 | do_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 | ||
1433 | static void | 1420 | static void |
1434 | child_close_fds(void) | 1421 | child_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 |
1477 | void | 1464 | void |
1478 | do_child(Session *s, const char *command) | 1465 | do_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 | ||
1851 | static int | 1839 | static int |
1852 | session_window_change_req(Session *s) | 1840 | session_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 | ||
1863 | static int | 1851 | static int |
1864 | session_pty_req(Session *s) | 1852 | session_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 | ||
1916 | static int | 1904 | static int |
1917 | session_subsystem_req(Session *s) | 1905 | session_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 | ||
1956 | static int | 1944 | static int |
1957 | session_x11_req(Session *s) | 1945 | session_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 | ||
1988 | static int | 1976 | static int |
1989 | session_shell_req(Session *s) | 1977 | session_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 | ||
1995 | static int | 1983 | static int |
1996 | session_exec_req(Session *s) | 1984 | session_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 | ||
2007 | static int | 1995 | static int |
2008 | session_break_req(Session *s) | 1996 | session_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 | ||
2019 | static int | 2007 | static int |
2020 | session_env_req(Session *s) | 2008 | session_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 | ||
2054 | static int | 2042 | static int |
2055 | session_auth_agent_req(Session *s) | 2043 | session_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 | ||
2071 | int | 2059 | int |
2072 | session_input_channel_req(Channel *c, const char *rtype) | 2060 | session_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 | ||
2114 | void | 2101 | void |
2115 | session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr, | 2102 | session_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 | ||
2194 | static void | 2181 | static void |
2195 | session_close_x11(int id) | 2182 | session_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 | ||
2210 | static void | 2197 | static void |
2211 | session_close_single_x11(int id, void *arg) | 2198 | session_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 | ||
2242 | static void | 2229 | static void |
2243 | session_exit_message(Session *s, int status) | 2230 | session_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 | ||
2293 | void | 2280 | void |
2294 | session_close(Session *s) | 2281 | session_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 | ||
2325 | void | 2311 | void |
2326 | session_close_by_pid(pid_t pid, int status) | 2312 | session_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 | */ |
2345 | void | 2330 | void |
2346 | session_close_by_channel(int id, void *arg) | 2331 | session_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 | ||
2382 | void | 2366 | void |
2383 | session_destroy_all(void (*closefunc)(Session *)) | 2367 | session_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 | ||
2434 | int | 2418 | int |
2435 | session_setup_x11fwd(Session *s) | 2419 | session_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 | ||
2510 | static void | 2494 | static void |
2511 | do_authenticated2(Authctxt *authctxt) | 2495 | do_authenticated2(struct ssh *ssh, Authctxt *authctxt) |
2512 | { | 2496 | { |
2513 | server_loop2(authctxt); | 2497 | server_loop2(ssh, authctxt); |
2514 | } | 2498 | } |
2515 | 2499 | ||
2516 | void | 2500 | void |
2517 | do_cleanup(Authctxt *authctxt) | 2501 | do_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 */ |
@@ -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 | ||
65 | void do_authenticated(Authctxt *); | 65 | void do_authenticated(struct ssh *, Authctxt *); |
66 | void do_cleanup(Authctxt *); | 66 | void do_cleanup(struct ssh *, Authctxt *); |
67 | 67 | ||
68 | int session_open(Authctxt *, int); | 68 | int session_open(Authctxt *, int); |
69 | void session_unused(int); | 69 | void session_unused(int); |
70 | int session_input_channel_req(Channel *, const char *); | 70 | int session_input_channel_req(struct ssh *, Channel *, const char *); |
71 | void session_close_by_pid(pid_t, int); | 71 | void session_close_by_pid(struct ssh *ssh, pid_t, int); |
72 | void session_close_by_channel(int, void *); | 72 | void session_close_by_channel(struct ssh *, int, void *); |
73 | void session_destroy_all(void (*)(Session *)); | 73 | void session_destroy_all(struct ssh *, void (*)(Session *)); |
74 | void session_pty_cleanup2(Session *); | 74 | void session_pty_cleanup2(Session *); |
75 | 75 | ||
76 | Session *session_new(void); | 76 | Session *session_new(void); |
77 | Session *session_by_tty(char *); | 77 | Session *session_by_tty(char *); |
78 | void session_close(Session *); | 78 | void session_close(struct ssh *, Session *); |
79 | void do_setusercontext(struct passwd *); | 79 | void do_setusercontext(struct passwd *); |
80 | void child_set_env(char ***envp, u_int *envsizep, const char *name, | ||
81 | const char *value); | ||
82 | 80 | ||
83 | const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); | 81 | const 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 | |||
93 | AUTHORS | 93 | AUTHORS |
94 | Markus Friedl <markus@openbsd.org> | 94 | Markus Friedl <markus@openbsd.org> |
95 | 95 | ||
96 | OpenBSD 6.0 December 11, 2014 OpenBSD 6.0 | 96 | OpenBSD 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 { |
@@ -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 | ||
6 | SYNOPSIS | 6 | SYNOPSIS |
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 | ||
386 | OpenBSD 6.0 July 16, 2016 OpenBSD 6.0 | 377 | OpenBSD 6.2 May 3, 2017 OpenBSD 6.2 |
@@ -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 |
96 | The options are as follows: | 96 | The options are as follows: |
97 | .Bl -tag -width Ds | 97 | .Bl -tag -width Ds |
98 | .It Fl 1 | ||
99 | Specify the use of protocol version 1. | ||
100 | .It Fl 2 | ||
101 | Specify the use of protocol version 2. | ||
102 | .It Fl 4 | 98 | .It Fl 4 |
103 | Forces | 99 | Forces |
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 |
283 | Specifies the SSH2 subsystem or the path for an sftp server | 275 | Specifies the SSH2 subsystem or the path for an sftp server |
284 | on the remote host. | 276 | on the remote host. |
285 | A path is useful for using | 277 | A path is useful when the remote |
286 | .Nm | ||
287 | over protocol version 1, or when the remote | ||
288 | .Xr sshd 8 | 278 | .Xr sshd 8 |
289 | does not have an sftp subsystem configured. | 279 | does not have an sftp subsystem configured. |
290 | .It Fl v | 280 | .It Fl v |
@@ -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...*/ |
108 | int sort_flag; | 108 | int sort_flag; |
109 | glob_t *sort_glob; | ||
109 | 110 | ||
110 | /* Context used for commandline completion */ | 111 | /* Context used for commandline completion */ |
111 | struct complete_ctx { | 112 | struct 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 | ||
883 | static int | ||
884 | sglob_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 */ |
883 | static int | 912 | static int |
884 | do_globbed_ls(struct sftp_conn *conn, const char *path, | 913 | do_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] " |
@@ -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 | ||
6 | SYNOPSIS | 6 | SYNOPSIS |
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 | ||
11 | DESCRIPTION | 11 | DESCRIPTION |
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 | ||
91 | FILES | 93 | FILES |
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 | ||
129 | OpenBSD 6.0 March 30, 2015 OpenBSD 6.0 | 123 | OpenBSD 6.2 August 29, 2017 OpenBSD 6.2 |
@@ -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 | ||
63 | and | 62 | and |
64 | .Pa ~/.ssh/identity . | 63 | .Pa ~/.ssh/id_ed25519 . |
65 | After loading a private key, | 64 | After loading a private key, |
66 | .Nm | 65 | .Nm |
67 | will try to load corresponding certificate information from the | 66 | will try to load corresponding certificate information from the |
@@ -127,6 +126,8 @@ Lists public key parameters of all identities currently represented | |||
127 | by the agent. | 126 | by the agent. |
128 | .It Fl l | 127 | .It Fl l |
129 | Lists fingerprints of all identities currently represented by the agent. | 128 | Lists fingerprints of all identities currently represented by the agent. |
129 | .It Fl q | ||
130 | Be quiet after a successful operation. | ||
130 | .It Fl s Ar pkcs11 | 131 | .It Fl s Ar pkcs11 |
131 | Add keys provided by the PKCS#11 shared library | 132 | Add 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 | ||
178 | Contains the protocol version 1 RSA authentication identity of the user. | ||
179 | .It Pa ~/.ssh/id_dsa | 178 | .It Pa ~/.ssh/id_dsa |
180 | Contains the protocol version 2 DSA authentication identity of the user. | 179 | Contains the DSA authentication identity of the user. |
181 | .It Pa ~/.ssh/id_ecdsa | 180 | .It Pa ~/.ssh/id_ecdsa |
182 | Contains the protocol version 2 ECDSA authentication identity of the user. | 181 | Contains the ECDSA authentication identity of the user. |
183 | .It Pa ~/.ssh/id_ed25519 | 182 | .It Pa ~/.ssh/id_ed25519 |
184 | Contains the protocol version 2 Ed25519 authentication identity of the user. | 183 | Contains the Ed25519 authentication identity of the user. |
185 | .It Pa ~/.ssh/id_rsa | 184 | .It Pa ~/.ssh/id_rsa |
186 | Contains the protocol version 2 RSA authentication identity of the user. | 185 | Contains the RSA authentication identity of the user. |
187 | .El | 186 | .El |
188 | .Pp | 187 | .Pp |
189 | Identity files should not be readable by anyone but the user. | 188 | Identity files should not be readable by anyone but the user. |
@@ -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 | ||
108 | static int | 104 | static int |
109 | delete_file(int agent_fd, const char *filename, int key_only) | 105 | delete_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 | ||
180 | static int | 186 | static int |
181 | add_file(int agent_fd, const char *filename, int key_only) | 187 | add_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 | |||
360 | list_identities(int agent_fd, int do_fp) | 366 | list_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 | ||
442 | static int | 434 | static int |
443 | do_file(int agent_fd, int deleting, int key_only, char *file) | 435 | do_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 | ||
474 | int | 467 | int |
@@ -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 | ||
120 | OpenBSD 6.0 November 30, 2016 OpenBSD 6.0 | 120 | OpenBSD 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 | |||
95 | typedef enum { | 100 | typedef 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 | ||
121 | typedef struct { | 126 | struct 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 */ |
127 | Idtab idtable[3]; | 132 | struct idtable *idtab; |
128 | 133 | ||
129 | int max_fd = 0; | 134 | int max_fd = 0; |
130 | 135 | ||
@@ -171,21 +176,9 @@ close_socket(SocketEntry *e) | |||
171 | static void | 176 | static void |
172 | idtab_init(void) | 177 | idtab_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 */ | ||
183 | static Idtab * | ||
184 | idtab_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 | ||
191 | static void | 184 | static 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 */ |
201 | static Identity * | 194 | static Identity * |
202 | lookup_identity(struct sshkey *key, int version) | 195 | lookup_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' */ |
243 | static void | 235 | static void |
244 | process_request_identities(SocketEntry *e, int version) | 236 | process_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 */ | ||
294 | static void | ||
295 | process_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 | ||
374 | static char * | 261 | static char * |
375 | agent_decode_alg(struct sshkey *key, u_int flags) | 262 | agent_decode_alg(struct sshkey *key, u_int flags) |
@@ -387,27 +274,24 @@ agent_decode_alg(struct sshkey *key, u_int flags) | |||
387 | static void | 274 | static void |
388 | process_sign_request2(SocketEntry *e) | 275 | process_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 */ |
444 | static void | 326 | static void |
445 | process_remove_identity(SocketEntry *e, int version) | 327 | process_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 | ||
507 | static void | 354 | static void |
508 | process_remove_all_identities(SocketEntry *e, int version) | 355 | process_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 | ||
563 | static int | ||
564 | agent_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 | |||
602 | static void | 399 | static void |
603 | process_add_identity(SocketEntry *e, int version) | 400 | process_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 | ||
726 | static void | 513 | static void |
727 | no_identities(SocketEntry *e, u_int type) | 514 | no_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 | |||
746 | process_add_smartcard_key(SocketEntry *e) | 530 | process_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 | |||
822 | process_remove_smartcard_key(SocketEntry *e) | 602 | process_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"); | ||
860 | send: | 635 | send: |
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 | ||
868 | static void | 643 | static int |
869 | process_message(SocketEntry *e) | 644 | process_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 | ||
969 | static void | 743 | static void |
@@ -1005,19 +779,141 @@ new_socket(sock_type type, int fd) | |||
1005 | } | 779 | } |
1006 | 780 | ||
1007 | static int | 781 | static int |
1008 | prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, | 782 | handle_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 | |||
811 | static int | ||
812 | handle_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 | |||
835 | static int | ||
836 | handle_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 | |||
860 | static void | ||
861 | after_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 | |||
904 | static int | ||
905 | prepare_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 | ||
1070 | static void | 962 | static void |
1071 | after_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 | |||
1153 | static void | ||
1154 | cleanup_socket(void) | 963 | cleanup_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 | } |
@@ -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); | |||
128 | void ssh_gssapi_do_child(char ***, u_int *); | 128 | void ssh_gssapi_do_child(char ***, u_int *); |
129 | void ssh_gssapi_cleanup_creds(void); | 129 | void ssh_gssapi_cleanup_creds(void); |
130 | void ssh_gssapi_storecreds(void); | 130 | void ssh_gssapi_storecreds(void); |
131 | const 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 | ||
6 | SYNOPSIS | 6 | SYNOPSIS |
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 | ||
32 | DESCRIPTION | 33 | DESCRIPTION |
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 | ||
514 | FILES | 533 | FILES |
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 | ||
570 | OpenBSD 6.0 June 16, 2016 OpenBSD 6.0 | 573 | OpenBSD 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 @@ | |||
141 | generates, manages and converts authentication keys for | 144 | generates, manages and converts authentication keys for |
142 | .Xr ssh 1 . | 145 | .Xr ssh 1 . |
143 | .Nm | 146 | .Nm |
144 | can create keys for use by SSH protocol versions 1 and 2. | 147 | can create keys for use by SSH protocol version 2. |
145 | Protocol 1 should not be used | ||
146 | and is only offered to support legacy devices. | ||
147 | It suffers from a number of cryptographic weaknesses | ||
148 | and doesn't support many of the advanced features available for protocol 2. | ||
149 | .Pp | 148 | .Pp |
150 | The type of key to be generated is specified with the | 149 | The type of key to be generated is specified with the |
151 | .Fl t | 150 | .Fl t |
152 | option. | 151 | option. |
153 | If invoked without any arguments, | 152 | If invoked without any arguments, |
154 | .Nm | 153 | .Nm |
155 | will generate an RSA key for use in SSH protocol 2 connections. | 154 | will generate an RSA key. |
156 | .Pp | 155 | .Pp |
157 | .Nm | 156 | .Nm |
158 | is also used to generate groups for use in Diffie-Hellman group | 157 | is also used to generate groups for use in Diffie-Hellman group |
@@ -172,7 +171,6 @@ section for details. | |||
172 | Normally each user wishing to use SSH | 171 | Normally each user wishing to use SSH |
173 | with public key authentication runs this once to create the authentication | 172 | with public key authentication runs this once to create the authentication |
174 | key in | 173 | key 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. | |||
207 | If the passphrase is lost or forgotten, a new key must be generated | 205 | If the passphrase is lost or forgotten, a new key must be generated |
208 | and the corresponding public key copied to other machines. | 206 | and the corresponding public key copied to other machines. |
209 | .Pp | 207 | .Pp |
210 | For RSA1 keys and keys stored in the newer OpenSSH format, | 208 | For keys stored in the newer OpenSSH format, |
211 | there is also a comment field in the key file that is only for | 209 | there is also a comment field in the key file that is only for |
212 | convenience to the user to help identify the key. | 210 | convenience to the user to help identify the key. |
213 | The comment can tell what the key is for, or whatever is useful. | 211 | The comment can tell what the key is for, or whatever is useful. |
@@ -223,24 +221,26 @@ should be placed to be activated. | |||
223 | The options are as follows: | 221 | The options are as follows: |
224 | .Bl -tag -width Ds | 222 | .Bl -tag -width Ds |
225 | .It Fl A | 223 | .It Fl A |
226 | For each of the key types (rsa1, rsa, dsa, ecdsa and ed25519) | 224 | For each of the key types (rsa, dsa, ecdsa and ed25519) |
227 | for which host keys | 225 | for which host keys |
228 | do not exist, generate the host keys with the default key file path, | 226 | do not exist, generate the host keys with the default key file path, |
229 | an empty passphrase, default bits for the key type, and default comment. | 227 | an empty passphrase, default bits for the key type, and default comment. |
228 | If | ||
229 | .Fl f | ||
230 | has also been specified, its argument is used as a prefix to the | ||
231 | default path for the resulting host key files. | ||
230 | This is used by | 232 | This is used by |
231 | .Pa /etc/rc | 233 | .Pa /etc/rc |
232 | to generate new host keys. | 234 | to generate new host keys. |
233 | .It Fl a Ar rounds | 235 | .It Fl a Ar rounds |
234 | When saving a new-format private key (i.e. an ed25519 key or any SSH protocol | 236 | When saving a new-format private key (i.e. an ed25519 key or when the |
235 | 2 key when the | ||
236 | .Fl o | 237 | .Fl o |
237 | flag is set), this option specifies the number of KDF (key derivation function) | 238 | flag is set), this option specifies the number of KDF (key derivation function) |
238 | rounds used. | 239 | rounds used. |
239 | Higher numbers result in slower passphrase verification and increased | 240 | Higher numbers result in slower passphrase verification and increased |
240 | resistance to brute-force password cracking (should the keys be stolen). | 241 | resistance to brute-force password cracking (should the keys be stolen). |
241 | .Pp | 242 | .Pp |
242 | When screening DH-GEX candidates ( | 243 | When screening DH-GEX candidates (using the |
243 | using the | ||
244 | .Fl T | 244 | .Fl T |
245 | command). | 245 | command). |
246 | This option specifies the number of primality tests to perform. | 246 | This option specifies the number of primality tests to perform. |
@@ -264,7 +264,7 @@ flag will be ignored. | |||
264 | Provides a new comment. | 264 | Provides a new comment. |
265 | .It Fl c | 265 | .It Fl c |
266 | Requests changing the comment in the private and public key files. | 266 | Requests changing the comment in the private and public key files. |
267 | This operation is only supported for RSA1 keys and keys stored in the | 267 | This operation is only supported for keys stored in the |
268 | newer OpenSSH format. | 268 | newer OpenSSH format. |
269 | The program will prompt for the file containing the private keys, for | 269 | The program will prompt for the file containing the private keys, for |
270 | the passphrase if the key has one, and for the new comment. | 270 | the passphrase if the key has one, and for the new comment. |
@@ -384,7 +384,6 @@ section. | |||
384 | Prints the contents of one or more certificates. | 384 | Prints the contents of one or more certificates. |
385 | .It Fl l | 385 | .It Fl l |
386 | Show fingerprint of specified public key file. | 386 | Show fingerprint of specified public key file. |
387 | Private RSA1 keys are also supported. | ||
388 | For RSA and DSA keys | 387 | For RSA and DSA keys |
389 | .Nm | 388 | .Nm |
390 | tries to find the matching public key file and prints its fingerprint. | 389 | tries 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 |
424 | Specify a certificate option when signing a key. | 423 | Specify a certificate option when signing a key. |
425 | This option may be specified multiple times. | 424 | This option may be specified multiple times. |
426 | Please see the | 425 | See also the |
427 | .Sx CERTIFICATES | 426 | .Sx CERTIFICATES |
428 | section for details. | 427 | section for further details. |
429 | The options that are valid for user certificates are: | 428 | The 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 |
432 | Clear all enabled permissions. | 432 | Clear all enabled permissions. |
433 | This is useful for clearing the default set of permissions so permissions may | 433 | This is useful for clearing the default set of permissions so permissions may |
434 | be added individually. | 434 | be 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 | ||
438 | Includes an arbitrary certificate critical option or extension. | ||
439 | The specified | ||
440 | .Ar name | ||
441 | should include a domain suffix, e.g.\& | ||
442 | .Dq name@example.com . | ||
443 | If | ||
444 | .Ar contents | ||
445 | is specified then it is included as the contents of the extension/option | ||
446 | encoded as a string, otherwise the extension/option is created with no | ||
447 | contents (usually indicating a flag). | ||
448 | Extensions may be ignored by a client or server that does not recognise them, | ||
449 | whereas unknown critical options will cause the certificate to be refused. | ||
450 | .Pp | ||
451 | At 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 |
436 | Forces the execution of | 454 | Forces the execution of |
437 | .Ar command | 455 | .Ar command |
438 | instead of any shell or command specified by the user when | 456 | instead of any shell or command specified by the user when |
439 | the certificate is used for authentication. | 457 | the certificate is used for authentication. |
458 | .Pp | ||
440 | .It Ic no-agent-forwarding | 459 | .It Ic no-agent-forwarding |
441 | Disable | 460 | Disable |
442 | .Xr ssh-agent 1 | 461 | .Xr ssh-agent 1 |
443 | forwarding (permitted by default). | 462 | forwarding (permitted by default). |
463 | .Pp | ||
444 | .It Ic no-port-forwarding | 464 | .It Ic no-port-forwarding |
445 | Disable port forwarding (permitted by default). | 465 | Disable port forwarding (permitted by default). |
466 | .Pp | ||
446 | .It Ic no-pty | 467 | .It Ic no-pty |
447 | Disable PTY allocation (permitted by default). | 468 | Disable PTY allocation (permitted by default). |
469 | .Pp | ||
448 | .It Ic no-user-rc | 470 | .It Ic no-user-rc |
449 | Disable execution of | 471 | Disable execution of |
450 | .Pa ~/.ssh/rc | 472 | .Pa ~/.ssh/rc |
451 | by | 473 | by |
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 |
455 | Disable X11 forwarding (permitted by default). | 478 | Disable X11 forwarding (permitted by default). |
479 | .Pp | ||
456 | .It Ic permit-agent-forwarding | 480 | .It Ic permit-agent-forwarding |
457 | Allows | 481 | Allows |
458 | .Xr ssh-agent 1 | 482 | .Xr ssh-agent 1 |
459 | forwarding. | 483 | forwarding. |
484 | .Pp | ||
460 | .It Ic permit-port-forwarding | 485 | .It Ic permit-port-forwarding |
461 | Allows port forwarding. | 486 | Allows port forwarding. |
487 | .Pp | ||
462 | .It Ic permit-pty | 488 | .It Ic permit-pty |
463 | Allows PTY allocation. | 489 | Allows PTY allocation. |
490 | .Pp | ||
464 | .It Ic permit-user-rc | 491 | .It Ic permit-user-rc |
465 | Allows execution of | 492 | Allows execution of |
466 | .Pa ~/.ssh/rc | 493 | .Pa ~/.ssh/rc |
467 | by | 494 | by |
468 | .Xr sshd 8 . | 495 | .Xr sshd 8 . |
496 | .Pp | ||
469 | .It Ic permit-x11-forwarding | 497 | .It Ic permit-x11-forwarding |
470 | Allows X11 forwarding. | 498 | Allows X11 forwarding. |
499 | .Pp | ||
471 | .It Ic source-address Ns = Ns Ar address_list | 500 | .It Ic source-address Ns = Ns Ar address_list |
472 | Restrict the source addresses from which the certificate is considered valid. | 501 | Restrict the source addresses from which the certificate is considered valid. |
473 | The | 502 | The |
@@ -475,8 +504,6 @@ The | |||
475 | is a comma-separated list of one or more address/netmask pairs in CIDR | 504 | is a comma-separated list of one or more address/netmask pairs in CIDR |
476 | format. | 505 | format. |
477 | .El | 506 | .El |
478 | .Pp | ||
479 | At present, no options are valid for host keys. | ||
480 | .It Fl o | 507 | .It Fl o |
481 | Causes | 508 | Causes |
482 | .Nm | 509 | .Nm |
@@ -530,17 +557,22 @@ section for details. | |||
530 | Test DH group exchange candidate primes (generated using the | 557 | Test DH group exchange candidate primes (generated using the |
531 | .Fl G | 558 | .Fl G |
532 | option) for safety. | 559 | option) for safety. |
533 | .It Fl t Cm dsa | ecdsa | ed25519 | rsa | rsa1 | 560 | .It Fl t Cm dsa | ecdsa | ed25519 | rsa |
534 | Specifies the type of key to create. | 561 | Specifies the type of key to create. |
535 | The possible values are | 562 | The possible values are |
536 | .Dq rsa1 | ||
537 | for protocol version 1 and | ||
538 | .Dq dsa , | 563 | .Dq dsa , |
539 | .Dq ecdsa , | 564 | .Dq ecdsa , |
540 | .Dq ed25519 , | 565 | .Dq ed25519 , |
541 | or | 566 | or |
542 | .Dq rsa | 567 | .Dq rsa . |
543 | for protocol version 2. | 568 | .It Fl U |
569 | When used in combination with | ||
570 | .Fl s , | ||
571 | this option indicates that a CA key resides in a | ||
572 | .Xr ssh-agent 1 . | ||
573 | See the | ||
574 | .Sx CERTIFICATES | ||
575 | section for more information. | ||
544 | .It Fl u | 576 | .It Fl u |
545 | Update a KRL. | 577 | Update a KRL. |
546 | When specified with | 578 | When 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 |
723 | Similarly, it is possible for the CA key to be hosted in a | ||
724 | .Xr ssh-agent 1 . | ||
725 | This is indicated by the | ||
726 | .Fl U | ||
727 | flag 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 | ||
691 | In all cases, | 731 | In all cases, |
692 | .Ar key_id | 732 | .Ar key_id |
693 | is a "key identifier" that is logged by the server when the certificate | 733 | is a "key identifier" that is logged by the server when the certificate |
@@ -795,31 +835,11 @@ will exit with a non-zero exit status. | |||
795 | A zero exit status will only be returned if no key was revoked. | 835 | A 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 | ||
799 | Contains the protocol version 1 RSA authentication identity of the user. | ||
800 | This file should not be readable by anyone but the user. | ||
801 | It is possible to | ||
802 | specify a passphrase when generating the key; that passphrase will be | ||
803 | used to encrypt the private part of this file using 3DES. | ||
804 | This file is not automatically accessed by | ||
805 | .Nm | ||
806 | but it is offered as the default file for the private key. | ||
807 | .Xr ssh 1 | ||
808 | will read this file when a login attempt is made. | ||
809 | .Pp | ||
810 | .It Pa ~/.ssh/identity.pub | ||
811 | Contains the protocol version 1 RSA public key for authentication. | ||
812 | The contents of this file should be added to | ||
813 | .Pa ~/.ssh/authorized_keys | ||
814 | on all machines | ||
815 | where the user wishes to log in using RSA authentication. | ||
816 | There 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 |
822 | Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA | 842 | Contains the DSA, ECDSA, Ed25519 or RSA |
823 | authentication identity of the user. | 843 | authentication identity of the user. |
824 | This file should not be readable by anyone but the user. | 844 | This file should not be readable by anyone but the user. |
825 | It is possible to | 845 | It 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 |
838 | Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA | 858 | Contains the DSA, ECDSA, Ed25519 or RSA |
839 | public key for authentication. | 859 | public key for authentication. |
840 | The contents of this file should be added to | 860 | The 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. */ |
122 | char *ca_key_path = NULL; | 122 | char *ca_key_path = NULL; |
123 | 123 | ||
124 | /* Prefer to use agent keys for CA signing */ | ||
125 | int prefer_agent = 0; | ||
126 | |||
124 | /* Certificate serial number */ | 127 | /* Certificate serial number */ |
125 | unsigned long long cert_serial = 0; | 128 | unsigned long long cert_serial = 0; |
126 | 129 | ||
@@ -149,6 +152,15 @@ u_int32_t certflags_flags = CERTOPT_DEFAULT; | |||
149 | char *certflags_command = NULL; | 152 | char *certflags_command = NULL; |
150 | char *certflags_src_addr = NULL; | 153 | char *certflags_src_addr = NULL; |
151 | 154 | ||
155 | /* Arbitrary extensions specified by user */ | ||
156 | struct cert_userext { | ||
157 | char *key; | ||
158 | char *val; | ||
159 | int crit; | ||
160 | }; | ||
161 | struct cert_userext *cert_userext; | ||
162 | size_t ncert_userext; | ||
163 | |||
152 | /* Conversion to/from various formats */ | 164 | /* Conversion to/from various formats */ |
153 | int convert_to = 0; | 165 | int convert_to = 0; |
154 | int convert_from = 0; | 166 | int 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 | |||
334 | do_convert_to_pkcs8(struct sshkey *k) | 349 | do_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 | |||
359 | do_convert_to_pem(struct sshkey *k) | 373 | do_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) | |||
1531 | static void | 1571 | static void |
1532 | prepare_options_buf(struct sshbuf *c, int which) | 1572 | prepare_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 | ||
1558 | static struct sshkey * | 1611 | static 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 */ | ||
1642 | static int | ||
1643 | agent_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 | |||
1588 | static void | 1653 | static void |
1589 | do_ca_sign(struct passwd *pw, int argc, char **argv) | 1654 | do_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) | |||
1789 | static void | 1892 | static void |
1790 | add_cert_option(char *opt) | 1893 | add_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 | |||
2218 | static void | 2328 | static void |
2219 | usage(void) | 2329 | usage(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 | ||
111 | OpenBSD 6.0 November 8, 2015 OpenBSD 6.0 | 106 | OpenBSD 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 |
91 | Specifies the type of the key to fetch from the scanned hosts. | 91 | Specifies the type of the key to fetch from the scanned hosts. |
92 | The possible values are | 92 | The possible values are |
93 | .Dq rsa1 | ||
94 | for protocol version 1 and | ||
95 | .Dq dsa , | 93 | .Dq dsa , |
96 | .Dq ecdsa , | 94 | .Dq ecdsa , |
97 | .Dq ed25519 , | 95 | .Dq ed25519 , |
98 | or | 96 | or |
99 | .Dq rsa | 97 | .Dq rsa . |
100 | for protocol version 2. | ||
101 | Multiple values may be specified by separating them with commas. | 98 | Multiple values may be specified by separating them with commas. |
102 | The default is to fetch | 99 | The default is to fetch |
103 | .Dq rsa , | 100 | .Dq rsa , |
@@ -127,11 +124,6 @@ Input format: | |||
127 | 1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4 | 124 | 1.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 |
130 | Output format for RSA1 keys: | ||
131 | .Bd -literal | ||
132 | host-or-namelist bits exponent modulus | ||
133 | .Ed | ||
134 | .Pp | ||
135 | Output format for RSA, DSA, ECDSA, and Ed25519 keys: | 127 | Output format for RSA, DSA, ECDSA, and Ed25519 keys: |
136 | .Bd -literal | 128 | .Bd -literal |
137 | host-or-namelist keytype base64-encoded-key | 129 | host-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 | ||
55 | int ssh_port = SSH_DEFAULT_PORT; | 54 | int 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 | ||
63 | int get_cert = 0; | 64 | int get_cert = 0; |
64 | int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519; | 65 | int 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 | ||
191 | static struct sshkey * | ||
192 | keygrab_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 | ||
237 | static int | 192 | static int |
238 | key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh) | 193 | key_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 | ||
323 | static void | 277 | static 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 | ||
561 | static void | 505 | static 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 | |||
49 | AUTHORS | 49 | AUTHORS |
50 | Markus Friedl <markus@openbsd.org> | 50 | Markus Friedl <markus@openbsd.org> |
51 | 51 | ||
52 | OpenBSD 6.0 February 17, 2016 OpenBSD 6.0 | 52 | OpenBSD 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 | |||
106 | pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, | 106 | pkcs11_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) | |||
186 | int | 186 | int |
187 | pkcs11_add_provider(char *name, char *pin, Key ***keysp) | 187 | pkcs11_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 | |||
22 | AUTHORS | 22 | AUTHORS |
23 | Markus Friedl <markus@openbsd.org> | 23 | Markus Friedl <markus@openbsd.org> |
24 | 24 | ||
25 | OpenBSD 6.0 July 16, 2013 OpenBSD 6.0 | 25 | OpenBSD 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 | ||
44 | struct pkcs11_keyinfo { | 44 | struct 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; | |||
60 | Buffer oqueue; | 60 | Buffer oqueue; |
61 | 61 | ||
62 | static void | 62 | static void |
63 | add_key(Key *k, char *name) | 63 | add_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 */ |
90 | static Key * | 90 | static struct sshkey * |
91 | lookup_key(Key *k) | 91 | lookup_key(struct sshkey *k) |
92 | { | 92 | { |
93 | struct pkcs11_keyinfo *ki; | 93 | struct pkcs11_keyinfo *ki; |
94 | 94 | ||
@@ -114,7 +114,7 @@ static void | |||
114 | process_add(void) | 114 | process_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); |
@@ -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 */ | ||
82 | int | ||
83 | ssh_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 */ |
82 | int | 117 | int |
83 | ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | 118 | ssh_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; |
@@ -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 | ||
6 | SYNOPSIS | 6 | SYNOPSIS |
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 | ||
440 | AUTHENTICATION | 432 | AUTHENTICATION |
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 | ||
971 | OpenBSD 6.0 July 16, 2016 OpenBSD 6.0 | 960 | OpenBSD 6.2 September 21, 2017 OpenBSD 6.2 |
@@ -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. | |||
95 | The options are as follows: | 95 | The options are as follows: |
96 | .Pp | 96 | .Pp |
97 | .Bl -tag -width Ds -compact | 97 | .Bl -tag -width Ds -compact |
98 | .It Fl 1 | ||
99 | Forces | ||
100 | .Nm | ||
101 | to try protocol version 1 only. | ||
102 | .Pp | ||
103 | .It Fl 2 | ||
104 | Forces | ||
105 | .Nm | ||
106 | to try protocol version 2 only. | ||
107 | .Pp | ||
108 | .It Fl 4 | 98 | .It Fl 4 |
109 | Forces | 99 | Forces |
110 | .Nm | 100 | .Nm |
@@ -144,12 +134,7 @@ data for forwarded X11, TCP and | |||
144 | .Ux Ns -domain | 134 | .Ux Ns -domain |
145 | connections). | 135 | connections). |
146 | The compression algorithm is the same used by | 136 | The compression algorithm is the same used by |
147 | .Xr gzip 1 , | 137 | .Xr gzip 1 . |
148 | and the | ||
149 | .Dq level | ||
150 | can be controlled by the | ||
151 | .Cm CompressionLevel | ||
152 | option for protocol version 1. | ||
153 | Compression is desirable on modem lines and other | 138 | Compression is desirable on modem lines and other |
154 | slow connections, but will only slow down things on fast networks. | 139 | slow connections, but will only slow down things on fast networks. |
155 | The default value can be set on a host-by-host basis in the | 140 | The 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 |
161 | Selects the cipher specification for encrypting the session. | 146 | Selects the cipher specification for encrypting the session. |
162 | .Pp | ||
163 | Protocol version 1 allows specification of a single cipher. | ||
164 | The supported values are | ||
165 | .Dq 3des , | ||
166 | .Dq blowfish , | ||
167 | and | ||
168 | .Dq des . | ||
169 | For protocol version 2, | ||
170 | .Ar cipher_spec | 147 | .Ar cipher_spec |
171 | is a comma-separated list of ciphers | 148 | is a comma-separated list of ciphers |
172 | listed in order of preference. | 149 | listed in order of preference. |
@@ -290,14 +267,11 @@ private RSA key. | |||
290 | Selects a file from which the identity (private key) for | 267 | Selects a file from which the identity (private key) for |
291 | public key authentication is read. | 268 | public key authentication is read. |
292 | The default is | 269 | The default is |
293 | .Pa ~/.ssh/identity | ||
294 | for 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 |
298 | and | 273 | and |
299 | .Pa ~/.ssh/id_rsa | 274 | .Pa ~/.ssh/id_rsa . |
300 | for protocol version 2. | ||
301 | Identity files may also be specified on | 275 | Identity files may also be specified on |
302 | a per-host basis in the configuration file. | 276 | a per-host basis in the configuration file. |
303 | It is possible to have multiple | 277 | It 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 | ||
625 | Specifies that connections to the given TCP port or Unix socket on the remote | 601 | Specifies 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. |
627 | on the local side. | 603 | .Pp |
628 | This works by allocating a socket to listen to either a TCP | 604 | This works by allocating a socket to listen to either a TCP |
629 | .Ar port | 605 | .Ar port |
630 | or to a Unix socket on the remote side. | 606 | or to a Unix socket on the remote side. |
631 | Whenever a connection is made to this port or Unix socket, the | 607 | Whenever a connection is made to this port or Unix socket, the |
632 | connection is forwarded over the secure channel, and a connection | 608 | connection is forwarded over the secure channel, and a connection |
633 | is made to either | 609 | is made from the local machine to either an explicit destination specified by |
634 | .Ar host | 610 | .Ar host |
635 | port | 611 | port |
636 | .Ar hostport , | 612 | .Ar hostport , |
637 | or | 613 | or |
638 | .Ar local_socket , | 614 | .Ar local_socket , |
639 | from the local machine. | 615 | or, if no explicit destination was specified, |
616 | .Nm | ||
617 | will act as a SOCKS 4/5 proxy and forward connections to the destinations | ||
618 | requested by the remote SOCKS client. | ||
640 | .Pp | 619 | .Pp |
641 | Port forwardings can also be specified in the configuration file. | 620 | Port forwardings can also be specified in the configuration file. |
642 | Privileged ports can be forwarded only when | 621 | Privileged ports can be forwarded only when |
@@ -806,21 +785,7 @@ a per-user configuration file and a system-wide configuration file. | |||
806 | The file format and configuration options are described in | 785 | The file format and configuration options are described in |
807 | .Xr ssh_config 5 . | 786 | .Xr ssh_config 5 . |
808 | .Sh AUTHENTICATION | 787 | .Sh AUTHENTICATION |
809 | The OpenSSH SSH client supports SSH protocols 1 and 2. | 788 | The OpenSSH SSH client supports SSH protocol 2. |
810 | The default is to use protocol 2 only, | ||
811 | though this can be changed via the | ||
812 | .Cm Protocol | ||
813 | option in | ||
814 | .Xr ssh_config 5 | ||
815 | or the | ||
816 | .Fl 1 | ||
817 | and | ||
818 | .Fl 2 | ||
819 | options (see above). | ||
820 | Protocol 1 should not be used | ||
821 | and is only offered to support legacy devices. | ||
822 | It suffers from a number of cryptographic weaknesses | ||
823 | and doesn't support many of the advanced features available for protocol 2. | ||
824 | .Pp | 789 | .Pp |
825 | The methods available for authentication are: | 790 | The methods available for authentication are: |
826 | GSSAPI-based authentication, | 791 | GSSAPI-based authentication, |
@@ -890,11 +855,20 @@ The client proves that it has access to the private key | |||
890 | and the server checks that the corresponding public key | 855 | and the server checks that the corresponding public key |
891 | is authorized to accept the account. | 856 | is authorized to accept the account. |
892 | .Pp | 857 | .Pp |
858 | The server may inform the client of errors that prevented public key | ||
859 | authentication from succeeding after authentication completes using a | ||
860 | different method. | ||
861 | These may be viewed by increasing the | ||
862 | .Cm LogLevel | ||
863 | to | ||
864 | .Cm DEBUG | ||
865 | or higher (e.g. by using the | ||
866 | .Fl v | ||
867 | flag). | ||
868 | .Pp | ||
893 | The user creates his/her key pair by running | 869 | The user creates his/her key pair by running |
894 | .Xr ssh-keygen 1 . | 870 | .Xr ssh-keygen 1 . |
895 | This stores the private key in | 871 | This 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) |
907 | and stores the public key in | 881 | and 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 , |
1491 | above. | 1463 | above. |
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 | |||
1505 | generating the key which will be used to encrypt the | 1476 | generating the key which will be used to encrypt the |
1506 | sensitive part of this file using 3DES. | 1477 | sensitive 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 |
@@ -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 | |||
198 | usage(void) | 197 | usage(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 | ||
212 | static int ssh_session(void); | 211 | static int ssh_session2(struct ssh *); |
213 | static int ssh_session2(void); | ||
214 | static void load_public_identity_files(void); | 212 | static void load_public_identity_files(void); |
215 | static void main_sigchld_handler(int); | 213 | static void main_sigchld_handler(int); |
216 | 214 | ||
@@ -511,13 +509,13 @@ int | |||
511 | main(int ac, char **av) | 509 | main(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 */ |
1527 | static void | 1540 | static void |
1528 | ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) | 1541 | ssh_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 | ||
1577 | static void | 1590 | static void |
1578 | client_cleanup_stdio_fwd(int id, void *arg) | 1591 | client_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 | ||
1584 | static void | 1597 | static void |
1585 | ssh_stdio_confirm(int id, int success, void *arg) | 1598 | ssh_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 | ||
1591 | static void | 1604 | static void |
1592 | ssh_init_stdio_forwarding(void) | 1605 | ssh_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 | ||
1615 | static void | 1626 | static void |
1616 | ssh_init_forwarding(void) | 1627 | ssh_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 | ||
1699 | static int | ||
1700 | ssh_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 */ | ||
1865 | static void | 1711 | static void |
1866 | ssh_session2_setup(int id, int success, void *arg) | 1712 | ssh_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 */ |
1908 | static int | 1754 | static int |
1909 | ssh_session2_open(void) | 1755 | ssh_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 | ||
1954 | static int | 1800 | static int |
1955 | ssh_session2(void) | 1801 | ssh_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 | ||
@@ -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 */ | ||
@@ -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) | |||
3 | NAME | 3 | NAME |
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 | ||
6 | SYNOPSIS | ||
7 | ~/.ssh/config | ||
8 | /etc/ssh/ssh_config | ||
9 | |||
10 | DESCRIPTION | 6 | DESCRIPTION |
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 | |||
1068 | FILES | 1049 | FILES |
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 | ||
1092 | OpenBSD 6.0 February 27, 2017 OpenBSD 6.0 | 1073 | OpenBSD 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 |
48 | obtains configuration data from the following sources in | 45 | obtains configuration data from the following sources in |
@@ -391,25 +388,8 @@ in the process, regardless of the setting of | |||
391 | If the option is set to | 388 | If the option is set to |
392 | .Cm no , | 389 | .Cm no , |
393 | the check will not be executed. | 390 | the check will not be executed. |
394 | .It Cm Cipher | ||
395 | Specifies the cipher to use for encrypting the session | ||
396 | in protocol version 1. | ||
397 | Currently, | ||
398 | .Cm blowfish , | ||
399 | .Cm 3des | ||
400 | (the default), | ||
401 | and | ||
402 | .Cm des | ||
403 | are supported, | ||
404 | though | ||
405 | .Cm des | ||
406 | is only supported in the | ||
407 | .Xr ssh 1 | ||
408 | client for interoperability with legacy protocol 1 implementations; | ||
409 | its use is strongly discouraged due to cryptographic weaknesses. | ||
410 | .It Cm Ciphers | 391 | .It Cm Ciphers |
411 | Specifies the ciphers allowed for protocol version 2 | 392 | Specifies the ciphers allowed and their order of preference. |
412 | in order of preference. | ||
413 | Multiple ciphers must be comma-separated. | 393 | Multiple ciphers must be comma-separated. |
414 | If the specified value begins with a | 394 | If the specified value begins with a |
415 | .Sq + | 395 | .Sq + |
@@ -431,11 +411,6 @@ aes192-ctr | |||
431 | aes256-ctr | 411 | aes256-ctr |
432 | aes128-gcm@openssh.com | 412 | aes128-gcm@openssh.com |
433 | aes256-gcm@openssh.com | 413 | aes256-gcm@openssh.com |
434 | arcfour | ||
435 | arcfour128 | ||
436 | arcfour256 | ||
437 | blowfish-cbc | ||
438 | cast128-cbc | ||
439 | chacha20-poly1305@openssh.com | 414 | chacha20-poly1305@openssh.com |
440 | .Ed | 415 | .Ed |
441 | .Pp | 416 | .Pp |
@@ -472,13 +447,6 @@ The argument must be | |||
472 | or | 447 | or |
473 | .Cm no | 448 | .Cm no |
474 | (the default). | 449 | (the default). |
475 | .It Cm CompressionLevel | ||
476 | Specifies the compression level to use if compression is enabled. | ||
477 | The argument must be an integer from 1 (fast) to 9 (slow, best). | ||
478 | The default level is 6, which is good for most applications. | ||
479 | The meaning of the values is the same as in | ||
480 | .Xr gzip 1 . | ||
481 | Note that this option applies to protocol version 1 only. | ||
482 | .It Cm ConnectionAttempts | 450 | .It Cm ConnectionAttempts |
483 | Specifies the number of tries (one per second) to make before exiting. | 451 | Specifies the number of tries (one per second) to make before exiting. |
484 | The argument must be an integer. | 452 | The 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 |
839 | Specifies an alias that should be used instead of the | 807 | Specifies an alias that should be used instead of the |
840 | real host name when looking up or saving the host key | 808 | real host name when looking up or saving the host key |
841 | in the host key database files. | 809 | in the host key database files and when validating host certificates. |
842 | This option is useful for tunneling SSH connections | 810 | This option is useful for tunneling SSH connections |
843 | or for multiple servers running on a single host. | 811 | or for multiple servers running on a single host. |
844 | .It Cm HostName | 812 | .It Cm HostName |
@@ -902,14 +870,11 @@ section. | |||
902 | Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA authentication | 870 | Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA authentication |
903 | identity is read. | 871 | identity is read. |
904 | The default is | 872 | The default is |
905 | .Pa ~/.ssh/identity | ||
906 | for 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 |
910 | and | 876 | and |
911 | .Pa ~/.ssh/id_rsa | 877 | .Pa ~/.ssh/id_rsa . |
912 | for protocol version 2. | ||
913 | Additionally, any identities represented by the authentication agent | 878 | Additionally, any identities represented by the authentication agent |
914 | will be used for authentication unless | 879 | will 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 , |
1007 | or a numeric value. | 972 | a numeric value, or |
973 | .Cm none | ||
974 | to use the operating system default. | ||
1008 | This option may take one or two arguments, separated by whitespace. | 975 | This option may take one or two arguments, separated by whitespace. |
1009 | If one argument is specified, it is used as the packet class unconditionally. | 976 | If one argument is specified, it is used as the packet class unconditionally. |
1010 | If two values are specified, the first is automatically selected for | 977 | If two values are specified, the first is automatically selected for |
@@ -1192,21 +1159,6 @@ The default is: | |||
1192 | gssapi-with-mic,hostbased,publickey, | 1159 | gssapi-with-mic,hostbased,publickey, |
1193 | keyboard-interactive,password | 1160 | keyboard-interactive,password |
1194 | .Ed | 1161 | .Ed |
1195 | .It Cm Protocol | ||
1196 | Specifies the protocol versions | ||
1197 | .Xr ssh 1 | ||
1198 | should support in order of preference. | ||
1199 | The possible values are 1 and 2. | ||
1200 | Multiple versions must be comma-separated. | ||
1201 | When this option is set to | ||
1202 | .Cm 2,1 | ||
1203 | .Nm ssh | ||
1204 | will try version 2 and fall back to version 1 | ||
1205 | if version 2 is not available. | ||
1206 | The default is version 2. | ||
1207 | Protocol 1 suffers from a number of cryptographic weaknesses and should | ||
1208 | not be used. | ||
1209 | It is only offered to support legacy devices. | ||
1210 | .It Cm ProxyCommand | 1162 | .It Cm ProxyCommand |
1211 | Specifies the command to use to connect to the server. | 1163 | Specifies the command to use to connect to the server. |
1212 | The command | 1164 | The command |
@@ -1334,15 +1286,31 @@ is | |||
1334 | .Cm default none , | 1286 | .Cm default none , |
1335 | which means that rekeying is performed after the cipher's default amount | 1287 | which means that rekeying is performed after the cipher's default amount |
1336 | of data has been sent or received and no time based rekeying is done. | 1288 | of data has been sent or received and no time based rekeying is done. |
1289 | .It Cm RemoteCommand | ||
1290 | Specifies a command to execute on the remote machine after successfully | ||
1291 | connecting to the server. | ||
1292 | The command string extends to the end of the line, and is executed with | ||
1293 | the user's shell. | ||
1294 | Arguments to | ||
1295 | .Cm RemoteCommand | ||
1296 | accept the tokens described in the | ||
1297 | .Sx TOKENS | ||
1298 | section. | ||
1337 | .It Cm RemoteForward | 1299 | .It Cm RemoteForward |
1338 | Specifies that a TCP port on the remote machine be forwarded over | 1300 | Specifies that a TCP port on the remote machine be forwarded over |
1339 | the secure channel to the specified host and port from the local machine. | 1301 | the secure channel. |
1302 | The remote port may either be fowarded to a specified host and port | ||
1303 | from the local machine, or may act as a SOCKS 4/5 proxy that allows a remote | ||
1304 | client to connect to arbitrary destinations from the local machine. | ||
1340 | The first argument must be | 1305 | The 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 |
1344 | and the second argument must be | 1309 | If forwarding to a specific destination then the second argument must be |
1345 | .Ar host : Ns Ar hostport . | 1310 | .Ar host : Ns Ar hostport , |
1311 | otherwise if no destination argument is specified then the remote forwarding | ||
1312 | will be established as a SOCKS proxy. | ||
1313 | .Pp | ||
1346 | IPv6 addresses can be specified by enclosing addresses in square brackets. | 1314 | IPv6 addresses can be specified by enclosing addresses in square brackets. |
1347 | Multiple forwardings may be specified, and additional | 1315 | Multiple forwardings may be specified, and additional |
1348 | forwardings can be given on the command line. | 1316 | forwardings 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 . |
1398 | For more information on KRLs, see the KEY REVOCATION LISTS section in | 1366 | For 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 | ||
1401 | Specifies whether to try rhosts based authentication with RSA host | ||
1402 | authentication. | ||
1403 | The argument must be | ||
1404 | .Cm yes | ||
1405 | or | ||
1406 | .Cm no | ||
1407 | (the default). | ||
1408 | This option applies to protocol version 1 only and requires | ||
1409 | .Xr ssh 1 | ||
1410 | to be setuid root. | ||
1411 | .It Cm RSAAuthentication | ||
1412 | Specifies whether to try RSA authentication. | ||
1413 | The argument to this keyword must be | ||
1414 | .Cm yes | ||
1415 | (the default) | ||
1416 | or | ||
1417 | .Cm no . | ||
1418 | RSA authentication will only be | ||
1419 | attempted if the identity file exists, or an authentication agent is | ||
1420 | running. | ||
1421 | Note that this option applies to protocol version 1 only. | ||
1422 | .It Cm SendEnv | 1368 | .It Cm SendEnv |
1423 | Specifies what variables from the local | 1369 | Specifies 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 | |||
1518 | frequently made. | 1464 | frequently made. |
1519 | This option forces the user to manually | 1465 | This option forces the user to manually |
1520 | add all new hosts. | 1466 | add all new hosts. |
1467 | .Pp | ||
1521 | If this flag is set to | 1468 | If this flag is set to |
1522 | .Cm no , | 1469 | .Dq accept-new |
1523 | ssh will automatically add new host keys to the | 1470 | then ssh will automatically add new host keys to the user |
1524 | user known hosts files. | 1471 | known hosts files, but will not permit connections to hosts with |
1472 | changed host keys. | ||
1473 | If this flag is set to | ||
1474 | .Dq no | ||
1475 | or | ||
1476 | .Dq off , | ||
1477 | ssh will automatically add new host keys to the user known hosts files | ||
1478 | and allow connections to hosts with changed hostkeys to proceed, | ||
1479 | subject to some restrictions. | ||
1525 | If this flag is set to | 1480 | If 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 | |||
1531 | ssh will refuse to connect to hosts whose host key has changed. | 1486 | ssh will refuse to connect to hosts whose host key has changed. |
1532 | The host keys of | 1487 | The host keys of |
1533 | known hosts will be verified automatically in all cases. | 1488 | known hosts will be verified automatically in all cases. |
1489 | .It Cm SyslogFacility | ||
1490 | Gives the facility code that is used when logging messages from | ||
1491 | .Xr ssh 1 . | ||
1492 | The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, | ||
1493 | LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. | ||
1494 | The default is USER. | ||
1534 | .It Cm TCPKeepAlive | 1495 | .It Cm TCPKeepAlive |
1535 | Specifies whether the system should send TCP keepalive messages to the | 1496 | Specifies whether the system should send TCP keepalive messages to the |
1536 | other side. | 1497 | other side. |
@@ -1627,11 +1588,6 @@ If set to | |||
1627 | .Cm yes , | 1588 | .Cm yes , |
1628 | .Xr ssh 1 | 1589 | .Xr ssh 1 |
1629 | must be setuid root. | 1590 | must be setuid root. |
1630 | Note that this option must be set to | ||
1631 | .Cm yes | ||
1632 | for | ||
1633 | .Cm RhostsRSAAuthentication | ||
1634 | with older servers. | ||
1635 | .It Cm User | 1591 | .It Cm User |
1636 | Specifies the user to log in as. | 1592 | Specifies the user to log in as. |
1637 | This can be useful when a different user name is used on different machines. | 1593 | This 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 |
1772 | accepts the tokens %%, %h, %p, and %r. | 1728 | accepts the tokens %%, %h, %p, and %r. |
1729 | .Pp | ||
1730 | .Cm RemoteCommand | ||
1731 | accepts 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) | |||
365 | int | 365 | int |
366 | sshbuf_put_cstring(struct sshbuf *buf, const char *v) | 366 | sshbuf_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 | ||
371 | int | 371 | int |
@@ -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 | ||
207 | size_t | 208 | size_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 | } |
@@ -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 */ |
212 | int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, | 212 | int 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 | ||
68 | char *client_version_string = NULL; | 70 | char *client_version_string = NULL; |
69 | char *server_version_string = NULL; | 71 | char *server_version_string = NULL; |
70 | Key *previous_host_key = NULL; | 72 | struct sshkey *previous_host_key = NULL; |
71 | 73 | ||
72 | static int matching_host_key_dns = 0; | 74 | static int matching_host_key_dns = 0; |
73 | 75 | ||
@@ -79,8 +81,8 @@ extern char *__progname; | |||
79 | extern uid_t original_real_uid; | 81 | extern uid_t original_real_uid; |
80 | extern uid_t original_effective_uid; | 82 | extern uid_t original_effective_uid; |
81 | 83 | ||
82 | static int show_other_keys(struct hostkeys *, Key *); | 84 | static int show_other_keys(struct hostkeys *, struct sshkey *); |
83 | static void warn_changed_key(Key *); | 85 | static void warn_changed_key(struct sshkey *); |
84 | 86 | ||
85 | /* Expand a proxy command */ | 87 | /* Expand a proxy command */ |
86 | static char * | 88 | static 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 | */ |
104 | static int | 106 | static int |
105 | ssh_proxy_fdpass_connect(const char *host, u_short port, | 107 | ssh_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 | */ |
184 | static int | 187 | static int |
185 | ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) | 188 | ssh_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 | */ | ||
331 | static int | 340 | static int |
332 | timeout_connect(int sockfd, const struct sockaddr *serv_addr, | 341 | waitrfd(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), | 367 | static int |
360 | sizeof(fd_mask)); | 368 | timeout_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 | */ |
425 | static int | 413 | static int |
426 | ssh_connect_direct(const char *host, struct addrinfo *aitop, | 414 | ssh_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 | ||
505 | int | 494 | int |
506 | ssh_connect(const char *host, struct addrinfo *addrs, | 495 | ssh_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 | ||
523 | static void | 515 | static void |
524 | send_client_banner(int connection_out, int minor1) | 516 | send_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 | ||
709 | static int | 646 | static int |
710 | check_host_cert(const char *host, const Key *host_key) | 647 | check_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 |
806 | static int | 743 | static int |
807 | check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, | 744 | check_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 */ |
1238 | int | 1186 | int |
1239 | verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) | 1187 | verify_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 */ |
1414 | static int | 1352 | static int |
1415 | show_other_keys(struct hostkeys *hostkeys, Key *key) | 1353 | show_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 | ||
1455 | static void | 1392 | static void |
1456 | warn_changed_key(Key *host_key) | 1393 | warn_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 | ||
1518 | void | 1455 | void |
1519 | maybe_add_key_to_agent(char *authfile, Key *private, char *comment, | 1456 | maybe_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 | ||
27 | typedef struct Sensitive Sensitive; | 27 | typedef struct Sensitive Sensitive; |
28 | struct Sensitive { | 28 | struct 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 | ||
34 | struct addrinfo; | 34 | struct addrinfo; |
35 | int ssh_connect(const char *, struct addrinfo *, struct sockaddr_storage *, | 35 | struct ssh; |
36 | u_short, int, int, int *, int, int); | 36 | |
37 | int ssh_connect(struct ssh *, const char *, struct addrinfo *, | ||
38 | struct sockaddr_storage *, u_short, int, int, int *, int, int); | ||
37 | void ssh_kill_proxy_command(void); | 39 | void ssh_kill_proxy_command(void); |
38 | 40 | ||
39 | void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short, | 41 | void 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 | ||
42 | void ssh_exchange_identification(int); | 44 | void ssh_exchange_identification(int); |
43 | 45 | ||
44 | int verify_host_key(char *, struct sockaddr *, Key *); | 46 | int verify_host_key(char *, struct sockaddr *, struct sshkey *); |
45 | 47 | ||
46 | void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short, | 48 | void 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 *); | |||
55 | void ssh_put_password(char *); | 57 | void ssh_put_password(char *); |
56 | int ssh_local_cmd(const char *); | 58 | int ssh_local_cmd(const char *); |
57 | 59 | ||
58 | void maybe_add_key_to_agent(char *, Key *, char *, char *); | 60 | void 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. */ | ||
56 | u_char session_id[16]; | ||
57 | u_int supported_authentications = 0; | ||
58 | |||
59 | extern Options options; | ||
60 | extern char *__progname; | ||
61 | |||
62 | /* | ||
63 | * Checks if the user has an authentication agent, and if so, tries to | ||
64 | * authenticate using the agent. | ||
65 | */ | ||
66 | static int | ||
67 | try_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 | */ | ||
172 | static void | ||
173 | respond_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 | */ | ||
219 | static int | ||
220 | try_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 | */ | ||
346 | static int | ||
347 | try_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 | */ | ||
406 | static int | ||
407 | try_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 | */ | ||
467 | static int | ||
468 | try_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 | */ | ||
500 | void | ||
501 | ssh_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 | */ | ||
690 | void | ||
691 | ssh_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; | |||
93 | struct sockaddr *xxx_hostaddr; | 93 | struct sockaddr *xxx_hostaddr; |
94 | 94 | ||
95 | static int | 95 | static int |
96 | verify_host_key_callback(Key *hostkey, struct ssh *ssh) | 96 | verify_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 | ||
290 | int input_userauth_service_accept(int, u_int32_t, void *); | 290 | int input_userauth_service_accept(int, u_int32_t, struct ssh *); |
291 | int input_userauth_ext_info(int, u_int32_t, void *); | 291 | int input_userauth_ext_info(int, u_int32_t, struct ssh *); |
292 | int input_userauth_success(int, u_int32_t, void *); | 292 | int input_userauth_success(int, u_int32_t, struct ssh *); |
293 | int input_userauth_success_unexpected(int, u_int32_t, void *); | 293 | int input_userauth_success_unexpected(int, u_int32_t, struct ssh *); |
294 | int input_userauth_failure(int, u_int32_t, void *); | 294 | int input_userauth_failure(int, u_int32_t, struct ssh *); |
295 | int input_userauth_banner(int, u_int32_t, void *); | 295 | int input_userauth_banner(int, u_int32_t, struct ssh *); |
296 | int input_userauth_error(int, u_int32_t, void *); | 296 | int input_userauth_error(int, u_int32_t, struct ssh *); |
297 | int input_userauth_info_req(int, u_int32_t, void *); | 297 | int input_userauth_info_req(int, u_int32_t, struct ssh *); |
298 | int input_userauth_pk_ok(int, u_int32_t, void *); | 298 | int input_userauth_pk_ok(int, u_int32_t, struct ssh *); |
299 | int input_userauth_passwd_changereq(int, u_int32_t, void *); | 299 | int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *); |
300 | 300 | ||
301 | int userauth_none(Authctxt *); | 301 | int userauth_none(Authctxt *); |
302 | int userauth_pubkey(Authctxt *); | 302 | int userauth_pubkey(Authctxt *); |
@@ -306,11 +306,11 @@ int userauth_hostbased(Authctxt *); | |||
306 | 306 | ||
307 | #ifdef GSSAPI | 307 | #ifdef GSSAPI |
308 | int userauth_gssapi(Authctxt *authctxt); | 308 | int userauth_gssapi(Authctxt *authctxt); |
309 | int input_gssapi_response(int type, u_int32_t, void *); | 309 | int input_gssapi_response(int type, u_int32_t, struct ssh *); |
310 | int input_gssapi_token(int type, u_int32_t, void *); | 310 | int input_gssapi_token(int type, u_int32_t, struct ssh *); |
311 | int input_gssapi_hash(int type, u_int32_t, void *); | 311 | int input_gssapi_hash(int type, u_int32_t, struct ssh *); |
312 | int input_gssapi_error(int, u_int32_t, void *); | 312 | int input_gssapi_error(int, u_int32_t, struct ssh *); |
313 | int input_gssapi_errtok(int, u_int32_t, void *); | 313 | int input_gssapi_errtok(int, u_int32_t, struct ssh *); |
314 | #endif | 314 | #endif |
315 | 315 | ||
316 | void userauth(Authctxt *, char *); | 316 | void userauth(Authctxt *, char *); |
@@ -319,7 +319,7 @@ static int sign_and_send_pubkey(Authctxt *, Identity *); | |||
319 | static void pubkey_prepare(Authctxt *); | 319 | static void pubkey_prepare(Authctxt *); |
320 | static void pubkey_cleanup(Authctxt *); | 320 | static void pubkey_cleanup(Authctxt *); |
321 | static void pubkey_reset(Authctxt *); | 321 | static void pubkey_reset(Authctxt *); |
322 | static Key *load_identity_file(Identity *); | 322 | static struct sshkey *load_identity_file(Identity *); |
323 | 323 | ||
324 | static Authmethod *authmethod_get(char *authlist); | 324 | static Authmethod *authmethod_get(char *authlist); |
325 | static Authmethod *authmethod_lookup(const char *name); | 325 | static 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 */ |
414 | int | 416 | int |
415 | input_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt) | 417 | input_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 */ |
448 | int | 449 | int |
449 | input_userauth_ext_info(int type, u_int32_t seqnr, void *ctxt) | 450 | input_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 | ||
454 | void | 455 | void |
@@ -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 */ |
490 | int | 492 | int |
491 | input_userauth_error(int type, u_int32_t seq, void *ctxt) | 493 | input_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 */ |
499 | int | 501 | int |
500 | input_userauth_banner(int type, u_int32_t seq, void *ctxt) | 502 | input_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 */ |
516 | int | 518 | int |
517 | input_userauth_success(int type, u_int32_t seq, void *ctxt) | 519 | input_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 | ||
533 | int | 535 | int |
534 | input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt) | 536 | input_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 */ |
547 | int | 549 | int |
548 | input_userauth_failure(int type, u_int32_t seq, void *ctxt) | 550 | input_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 */ |
573 | int | 575 | int |
574 | input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) | 576 | input_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 | ||
704 | static OM_uint32 | 706 | static OM_uint32 |
705 | process_gssapi_token(void *ctxt, gss_buffer_t recv_tok) | 707 | process_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 */ |
759 | int | 761 | int |
760 | input_gssapi_response(int type, u_int32_t plen, void *ctxt) | 762 | input_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 */ |
800 | int | 802 | int |
801 | input_gssapi_token(int type, u_int32_t plen, void *ctxt) | 803 | input_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 */ |
829 | int | 831 | int |
830 | input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) | 832 | input_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 */ |
860 | int | 862 | int |
861 | input_gssapi_error(int type, u_int32_t plen, void *ctxt) | 863 | input_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 | |||
893 | userauth_passwd(Authctxt *authctxt) | 895 | userauth_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 */ |
931 | int | 933 | int |
932 | input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) | 934 | input_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 | |||
1015 | identity_sign(struct identity *id, u_char **sigp, size_t *lenp, | 1017 | identity_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 | ||
1228 | static Key * | 1235 | static struct sshkey * |
1229 | load_identity_file(Identity *id) | 1236 | load_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 | ||
1477 | int | 1482 | int |
@@ -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 | */ |
1554 | int | 1568 | int |
1555 | input_userauth_info_req(int type, u_int32_t seq, void *ctxt) | 1569 | input_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( |
@@ -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 | ||
626 | OpenBSD 6.0 January 30, 2017 OpenBSD 6.0 | 632 | OpenBSD 6.2 June 24, 2017 OpenBSD 6.2 |
@@ -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 | |||
260 | to use from those offered by the server. | 260 | to use from those offered by the server. |
261 | Additionally, session integrity is provided | 261 | Additionally, session integrity is provided |
262 | through a cryptographic message authentication code | 262 | through 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, |
264 | hmac-sha2-256 or hmac-sha2-512). | 264 | hmac-sha2-256 or hmac-sha2-512). |
265 | .Pp | 265 | .Pp |
266 | Finally, the server and the client enter an authentication dialog. | 266 | Finally, the server and the client enter an authentication dialog. |
@@ -652,9 +652,23 @@ Hostnames is a comma-separated list of patterns | |||
652 | and | 652 | and |
653 | .Ql \&? | 653 | .Ql \&? |
654 | act as | 654 | act as |
655 | wildcards); each pattern in turn is matched against the canonical host | 655 | wildcards); each pattern in turn is matched against the host name. |
656 | name (when authenticating a client) or against the user-supplied | 656 | When |
657 | name (when authenticating a server). | 657 | .Nm sshd |
658 | is authenticating a client, such as when using | ||
659 | .Cm HostbasedAuthentication , | ||
660 | this will be the canonical client host name. | ||
661 | When | ||
662 | .Xr ssh 1 | ||
663 | is authenticating a server, this will be the host name | ||
664 | given by the user, the value of the | ||
665 | .Xr ssh 1 | ||
666 | .Cm HostkeyAlias | ||
667 | if it was specified, or the canonical server hostname if the | ||
668 | .Xr ssh 1 | ||
669 | .Cm CanonicalizeHostname | ||
670 | option was used. | ||
671 | .Pp | ||
658 | A pattern may also be preceded by | 672 | A pattern may also be preceded by |
659 | .Ql \&! | 673 | .Ql \&! |
660 | to indicate negation: if the host name matches a negated | 674 | to indicate negation: if the host name matches a negated |
@@ -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 | */ |
197 | struct { | 196 | struct { |
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 */ | |||
223 | int use_privsep = -1; | 222 | int use_privsep = -1; |
224 | struct monitor *pmonitor = NULL; | 223 | struct monitor *pmonitor = NULL; |
225 | int privsep_is_preauth = 1; | 224 | int privsep_is_preauth = 1; |
225 | static int privsep_chroot = 1; | ||
226 | 226 | ||
227 | /* global authentication context */ | 227 | /* global authentication context */ |
228 | Authctxt *the_authctxt = NULL; | 228 | Authctxt *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) | |||
487 | void | 485 | void |
488 | demote_sensitive_data(void) | 486 | demote_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 | ||
746 | static Key * | 745 | static struct sshkey * |
747 | get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) | 746 | get_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 | ||
774 | Key * | 773 | struct sshkey * |
775 | get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) | 774 | get_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 | ||
780 | Key * | 779 | struct sshkey * |
781 | get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) | 780 | get_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 | ||
786 | Key * | 785 | struct sshkey * |
787 | get_hostkey_by_index(int ind) | 786 | get_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 | ||
794 | Key * | 793 | struct sshkey * |
795 | get_hostkey_public_by_index(int ind, struct ssh *ssh) | 794 | get_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 | ||
802 | int | 801 | int |
803 | get_hostkey_index(Key *key, int compare, struct ssh *ssh) | 802 | get_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 | ||
2119 | int | 2115 | int |
2120 | sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, | 2116 | sshd_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) | |||
2217 | void | 2214 | void |
2218 | cleanup_exit(int i) | 2215 | cleanup_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) | |||
3 | NAME | 3 | NAME |
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 | ||
6 | SYNOPSIS | ||
7 | /etc/ssh/sshd_config | ||
8 | |||
9 | DESCRIPTION | 6 | DESCRIPTION |
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 | ||
1020 | OpenBSD 6.0 March 14, 2017 OpenBSD 6.0 | 1022 | OpenBSD 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 |
47 | reads configuration data from | 45 | reads configuration data from |
@@ -225,6 +223,18 @@ requires successful authentication using two different public keys. | |||
225 | .Pp | 223 | .Pp |
226 | Note that each authentication method listed should also be explicitly enabled | 224 | Note that each authentication method listed should also be explicitly enabled |
227 | in the configuration. | 225 | in the configuration. |
226 | .Pp | ||
227 | The 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 | ||
234 | is enabled), | ||
235 | .Qq password | ||
236 | and | ||
237 | .Qq publickey . | ||
228 | .It Cm AuthorizedKeysCommand | 238 | .It Cm AuthorizedKeysCommand |
229 | Specifies a program to be used to look up the user's public keys. | 239 | Specifies a program to be used to look up the user's public keys. |
230 | The program must be owned by root, not writable by group or others and | 240 | The 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 |
465 | aes256-gcm@openssh.com | 475 | aes256-gcm@openssh.com |
466 | .It | 476 | .It |
467 | arcfour | ||
468 | .It | ||
469 | arcfour128 | ||
470 | .It | ||
471 | arcfour256 | ||
472 | .It | ||
473 | blowfish-cbc | ||
474 | .It | ||
475 | cast128-cbc | ||
476 | .It | ||
477 | chacha20-poly1305@openssh.com | 477 | chacha20-poly1305@openssh.com |
478 | .El | 478 | .El |
479 | .Pp | 479 | .Pp |
@@ -574,6 +574,14 @@ Disables all forwarding features, including X11, | |||
574 | TCP and StreamLocal. | 574 | TCP and StreamLocal. |
575 | This option overrides all other forwarding-related options and may | 575 | This option overrides all other forwarding-related options and may |
576 | simplify restricted configurations. | 576 | simplify restricted configurations. |
577 | .It Cm ExposeAuthInfo | ||
578 | Writes a temporary file containing a list of authentication methods and | ||
579 | public credentials (e.g. keys) used to authenticate the user. | ||
580 | The location of the file is exposed to the user session through the | ||
581 | .Ev SSH_USER_AUTH | ||
582 | environment variable. | ||
583 | The default is | ||
584 | .Cm no . | ||
577 | .It Cm FingerprintHash | 585 | .It Cm FingerprintHash |
578 | Specifies the hash algorithm used when logging key fingerprints. | 586 | Specifies the hash algorithm used when logging key fingerprints. |
579 | Valid options are: | 587 | Valid 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 , |
801 | or a numeric value. | 809 | a numeric value, or |
810 | .Cm none | ||
811 | to use the operating system default. | ||
802 | This option may take one or two arguments, separated by whitespace. | 812 | This option may take one or two arguments, separated by whitespace. |
803 | If one argument is specified, it is used as the packet class unconditionally. | 813 | If one argument is specified, it is used as the packet class unconditionally. |
804 | If two values are specified, the first is automatically selected for | 814 | If two values are specified, the first is automatically selected for |
@@ -962,8 +972,6 @@ hmac-md5 | |||
962 | .It | 972 | .It |
963 | hmac-md5-96 | 973 | hmac-md5-96 |
964 | .It | 974 | .It |
965 | hmac-ripemd160 | ||
966 | .It | ||
967 | hmac-sha1 | 975 | hmac-sha1 |
968 | .It | 976 | .It |
969 | hmac-sha1-96 | 977 | hmac-sha1-96 |
@@ -980,8 +988,6 @@ hmac-md5-etm@openssh.com | |||
980 | .It | 988 | .It |
981 | hmac-md5-96-etm@openssh.com | 989 | hmac-md5-96-etm@openssh.com |
982 | .It | 990 | .It |
983 | hmac-ripemd160-etm@openssh.com | ||
984 | .It | ||
985 | hmac-sha1-etm@openssh.com | 991 | hmac-sha1-etm@openssh.com |
986 | .It | 992 | .It |
987 | hmac-sha1-96-etm@openssh.com | 993 | hmac-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 , |
@@ -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 | } |
@@ -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 */ |
82 | const char *ssh_err(int n); | 84 | const char *ssh_err(int n); |
@@ -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 | */ | ||
1204 | static int | ||
1205 | read_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 */ |
1232 | int | 1166 | int |
@@ -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 | ||
1421 | static int | 1333 | int |
1422 | sshkey_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 | |||
1459 | static int | ||
1460 | sshkey_format_text(const struct sshkey *key, struct sshbuf *b) | 1334 | sshkey_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. */ |
2380 | int | 2249 | int |
2381 | sshkey_certify(struct sshkey *k, struct sshkey *ca, const char *alg) | 2250 | sshkey_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 | ||
2357 | static int | ||
2358 | default_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 | |||
2367 | int | ||
2368 | sshkey_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 | |||
2487 | int | 2373 | int |
2488 | sshkey_cert_check_authority(const struct sshkey *k, | 2374 | sshkey_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 | */ | ||
3414 | static int | ||
3415 | sshkey_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 | */ | ||
3600 | int | ||
3601 | sshkey_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 | 3379 | static int |
3619 | * from the buffer. | 3380 | translate_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 | ||
3658 | static int | 3413 | static void |
3659 | sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, | 3414 | clear_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 | */ | ||
3424 | static int | ||
3425 | convert_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 | ||
3774 | static int | 3437 | static int |
3775 | sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, | 3438 | sshkey_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 | } |
@@ -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 | ||
52 | struct sshbuf; | 52 | struct sshbuf; |
53 | 53 | ||
54 | /* Key types */ | 54 | /* Key types */ |
55 | enum sshkey_types { | 55 | enum 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); |
126 | const char *sshkey_type(const struct sshkey *); | 125 | const char *sshkey_type(const struct sshkey *); |
127 | const char *sshkey_cert_type(const struct sshkey *); | 126 | const char *sshkey_cert_type(const struct sshkey *); |
127 | int sshkey_format_text(const struct sshkey *, struct sshbuf *); | ||
128 | int sshkey_write(const struct sshkey *, FILE *); | 128 | int sshkey_write(const struct sshkey *, FILE *); |
129 | int sshkey_read(struct sshkey *, char **); | 129 | int sshkey_read(struct sshkey *, char **); |
130 | u_int sshkey_size(const struct sshkey *); | 130 | u_int sshkey_size(const struct sshkey *); |
@@ -137,13 +137,19 @@ int sshkey_type_is_cert(int); | |||
137 | int sshkey_type_plain(int); | 137 | int sshkey_type_plain(int); |
138 | int sshkey_to_certified(struct sshkey *); | 138 | int sshkey_to_certified(struct sshkey *); |
139 | int sshkey_drop_cert(struct sshkey *); | 139 | int sshkey_drop_cert(struct sshkey *); |
140 | int sshkey_certify(struct sshkey *, struct sshkey *, const char *); | ||
141 | int sshkey_cert_copy(const struct sshkey *, struct sshkey *); | 140 | int sshkey_cert_copy(const struct sshkey *, struct sshkey *); |
142 | int sshkey_cert_check_authority(const struct sshkey *, int, int, | 141 | int sshkey_cert_check_authority(const struct sshkey *, int, int, |
143 | const char *, const char **); | 142 | const char *, const char **); |
144 | size_t sshkey_format_cert_validity(const struct sshkey_cert *, | 143 | size_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 | ||
146 | int sshkey_certify(struct sshkey *, struct sshkey *, const char *); | ||
147 | /* Variant allowing use of a custom signature function (e.g. for ssh-agent) */ | ||
148 | typedef int sshkey_certify_signer(const struct sshkey *, u_char **, size_t *, | ||
149 | const u_char *, size_t, const char *, u_int, void *); | ||
150 | int sshkey_certify_custom(struct sshkey *, struct sshkey *, const char *, | ||
151 | sshkey_certify_signer *, void *); | ||
152 | |||
147 | int sshkey_ecdsa_nid_from_name(const char *); | 153 | int sshkey_ecdsa_nid_from_name(const char *); |
148 | int sshkey_curve_name_to_nid(const char *); | 154 | int sshkey_curve_name_to_nid(const char *); |
149 | const char * sshkey_curve_nid_to_name(int); | 155 | const char * sshkey_curve_nid_to_name(int); |
@@ -185,13 +191,14 @@ int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp); | |||
185 | int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, | 191 | int 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); |
188 | int sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob, | ||
189 | struct sshkey **keyp, char **commentp); | ||
190 | int sshkey_parse_private_fileblob(struct sshbuf *buffer, | 194 | int 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); |
192 | int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, | 196 | int 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 */ | ||
200 | int ssh_rsa_generate_additional_parameters(struct sshkey *); | ||
201 | |||
195 | #ifdef SSHKEY_INTERNAL | 202 | #ifdef SSHKEY_INTERNAL |
196 | int ssh_rsa_sign(const struct sshkey *key, | 203 | int 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) | |||
333 | end: | 320 | end: |
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 |
@@ -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 | ||
232 | static void pdf_gen_xor(pdf_ctx *pc, const UINT8 nonce[8], UINT8 buf[8]) | 235 | static 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); |
@@ -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 | ||
67 | static int | 68 | static 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; |
@@ -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 |
@@ -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 | ||
80 | void * | ||
81 | xrecallocarray(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 | |||
80 | char * | 92 | char * |
81 | xstrdup(const char *str) | 93 | xstrdup(const char *str) |
82 | { | 94 | { |
@@ -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); | |||
20 | void *xmalloc(size_t); | 20 | void *xmalloc(size_t); |
21 | void *xcalloc(size_t, size_t); | 21 | void *xcalloc(size_t, size_t); |
22 | void *xreallocarray(void *, size_t, size_t); | 22 | void *xreallocarray(void *, size_t, size_t); |
23 | void *xrecallocarray(void *, size_t, size_t, size_t); | ||
23 | char *xstrdup(const char *); | 24 | char *xstrdup(const char *); |
24 | int xasprintf(char **, const char *, ...) | 25 | int xasprintf(char **, const char *, ...) |
25 | __attribute__((__format__ (printf, 2, 3))) | 26 | __attribute__((__format__ (printf, 2, 3))) |