diff options
author | djm@openbsd.org <djm@openbsd.org> | 2015-02-20 22:17:21 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2015-02-21 09:20:28 +1100 |
commit | 44732de06884238049f285f1455b2181baa7dc82 (patch) | |
tree | deb3c48176195cfc4028b55d2a1a71607e9f7fb0 | |
parent | 13a39414d25646f93e6d355521d832a03aaaffe2 (diff) |
upstream commit
UpdateHostKeys fixes:
I accidentally changed the format of the hostkeys@openssh.com messages
last week without changing the extension name, and this has been causing
connection failures for people who are running -current. First reported
by sthen@
s/hostkeys@openssh.com/hostkeys-00@openssh.com/
Change the name of the proof message too, and reorder it a little.
Also, UpdateHostKeys=ask is incompatible with ControlPersist (no TTY
available to read the response) so disable UpdateHostKeys if it is in
ask mode and ControlPersist is active (and document this)
-rw-r--r-- | PROTOCOL | 12 | ||||
-rw-r--r-- | clientloop.c | 23 | ||||
-rw-r--r-- | monitor.c | 8 | ||||
-rw-r--r-- | serverloop.c | 10 | ||||
-rw-r--r-- | ssh.c | 8 | ||||
-rw-r--r-- | ssh_config.5 | 7 | ||||
-rw-r--r-- | sshd.c | 4 |
7 files changed, 42 insertions, 30 deletions
@@ -282,15 +282,15 @@ by the client cancel the forwarding of a Unix domain socket. | |||
282 | boolean FALSE | 282 | boolean FALSE |
283 | string socket path | 283 | string socket path |
284 | 284 | ||
285 | 2.5. connection: hostkey update and rotation "hostkeys@openssh.com" | 285 | 2.5. connection: hostkey update and rotation "hostkeys-00@openssh.com" |
286 | and "hostkeys-prove@openssh.com" | 286 | and "hostkeys-prove-00@openssh.com" |
287 | 287 | ||
288 | OpenSSH supports a protocol extension allowing a server to inform | 288 | OpenSSH supports a protocol extension allowing a server to inform |
289 | a client of all its protocol v.2 host keys after user-authentication | 289 | a client of all its protocol v.2 host keys after user-authentication |
290 | has completed. | 290 | has completed. |
291 | 291 | ||
292 | byte SSH_MSG_GLOBAL_REQUEST | 292 | byte SSH_MSG_GLOBAL_REQUEST |
293 | string "hostkeys@openssh.com" | 293 | string "hostkeys-00@openssh.com" |
294 | string[] hostkeys | 294 | string[] hostkeys |
295 | 295 | ||
296 | Upon receiving this message, a client should check which of the | 296 | Upon receiving this message, a client should check which of the |
@@ -300,15 +300,15 @@ to request the server prove ownership of the private half of the | |||
300 | key. | 300 | key. |
301 | 301 | ||
302 | byte SSH_MSG_GLOBAL_REQUEST | 302 | byte SSH_MSG_GLOBAL_REQUEST |
303 | string "hostkeys-prove@openssh.com" | 303 | string "hostkeys-prove-00@openssh.com" |
304 | char 1 /* want-reply */ | 304 | char 1 /* want-reply */ |
305 | string[] hostkeys | 305 | string[] hostkeys |
306 | 306 | ||
307 | When a server receives this message, it should generate a signature | 307 | When a server receives this message, it should generate a signature |
308 | using each requested key over the following: | 308 | using each requested key over the following: |
309 | 309 | ||
310 | string "hostkeys-prove-00@openssh.com" | ||
310 | string session identifier | 311 | string session identifier |
311 | string "hostkeys-prove@openssh.com" | ||
312 | string hostkey | 312 | string hostkey |
313 | 313 | ||
314 | These signatures should be included in the reply, in the order matching | 314 | These signatures should be included in the reply, in the order matching |
@@ -453,4 +453,4 @@ respond with a SSH_FXP_STATUS message. | |||
453 | This extension is advertised in the SSH_FXP_VERSION hello with version | 453 | This extension is advertised in the SSH_FXP_VERSION hello with version |
454 | "1". | 454 | "1". |
455 | 455 | ||
456 | $OpenBSD: PROTOCOL,v 1.26 2015/02/16 22:13:32 djm Exp $ | 456 | $OpenBSD: PROTOCOL,v 1.27 2015/02/20 22:17:21 djm Exp $ |
diff --git a/clientloop.c b/clientloop.c index a19d9d06f..ca3a4595b 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.269 2015/02/16 22:13:32 djm Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.270 2015/02/20 22:17: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 |
@@ -2265,10 +2265,10 @@ client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx) | |||
2265 | continue; | 2265 | continue; |
2266 | /* Prepare data to be signed: session ID, unique string, key */ | 2266 | /* Prepare data to be signed: session ID, unique string, key */ |
2267 | sshbuf_reset(signdata); | 2267 | sshbuf_reset(signdata); |
2268 | if ((r = sshbuf_put_string(signdata, ssh->kex->session_id, | 2268 | if ( (r = sshbuf_put_cstring(signdata, |
2269 | "hostkeys-prove-00@openssh.com")) != 0 || | ||
2270 | (r = sshbuf_put_string(signdata, ssh->kex->session_id, | ||
2269 | ssh->kex->session_id_len)) != 0 || | 2271 | ssh->kex->session_id_len)) != 0 || |
2270 | (r = sshbuf_put_cstring(signdata, | ||
2271 | "hostkeys-prove@openssh.com")) != 0 || | ||
2272 | (r = sshkey_puts(ctx->keys[i], signdata)) != 0) | 2272 | (r = sshkey_puts(ctx->keys[i], signdata)) != 0) |
2273 | fatal("%s: failed to prepare signature: %s", | 2273 | fatal("%s: failed to prepare signature: %s", |
2274 | __func__, ssh_err(r)); | 2274 | __func__, ssh_err(r)); |
@@ -2300,7 +2300,7 @@ client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx) | |||
2300 | } | 2300 | } |
2301 | 2301 | ||
2302 | /* | 2302 | /* |
2303 | * Handle hostkeys@openssh.com global request to inform the client of all | 2303 | * Handle hostkeys-00@openssh.com global request to inform the client of all |
2304 | * the server's hostkeys. The keys are checked against the user's | 2304 | * the server's hostkeys. The keys are checked against the user's |
2305 | * HostkeyAlgorithms preference before they are accepted. | 2305 | * HostkeyAlgorithms preference before they are accepted. |
2306 | */ | 2306 | */ |
@@ -2335,8 +2335,10 @@ client_input_hostkeys(void) | |||
2335 | __func__, ssh_err(r)); | 2335 | __func__, ssh_err(r)); |
2336 | goto out; | 2336 | goto out; |
2337 | } | 2337 | } |
2338 | if ((r = sshkey_from_blob(blob, len, &key)) != 0) | 2338 | if ((r = sshkey_from_blob(blob, len, &key)) != 0) { |
2339 | fatal("%s: parse key: %s", __func__, ssh_err(r)); | 2339 | error("%s: parse key: %s", __func__, ssh_err(r)); |
2340 | goto out; | ||
2341 | } | ||
2340 | fp = sshkey_fingerprint(key, options.fingerprint_hash, | 2342 | fp = sshkey_fingerprint(key, options.fingerprint_hash, |
2341 | SSH_FP_DEFAULT); | 2343 | SSH_FP_DEFAULT); |
2342 | debug3("%s: received %s key %s", __func__, | 2344 | debug3("%s: received %s key %s", __func__, |
@@ -2376,9 +2378,10 @@ client_input_hostkeys(void) | |||
2376 | } | 2378 | } |
2377 | 2379 | ||
2378 | if (ctx->nkeys == 0) { | 2380 | if (ctx->nkeys == 0) { |
2379 | error("%s: server sent no hostkeys", __func__); | 2381 | debug("%s: server sent no hostkeys", __func__); |
2380 | goto out; | 2382 | goto out; |
2381 | } | 2383 | } |
2384 | |||
2382 | if ((ctx->keys_seen = calloc(ctx->nkeys, | 2385 | if ((ctx->keys_seen = calloc(ctx->nkeys, |
2383 | sizeof(*ctx->keys_seen))) == NULL) | 2386 | sizeof(*ctx->keys_seen))) == NULL) |
2384 | fatal("%s: calloc failed", __func__); | 2387 | fatal("%s: calloc failed", __func__); |
@@ -2418,7 +2421,7 @@ client_input_hostkeys(void) | |||
2418 | __func__, ctx->nnew); | 2421 | __func__, ctx->nnew); |
2419 | if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || | 2422 | if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || |
2420 | (r = sshpkt_put_cstring(ssh, | 2423 | (r = sshpkt_put_cstring(ssh, |
2421 | "hostkeys-prove@openssh.com")) != 0 || | 2424 | "hostkeys-prove-00@openssh.com")) != 0 || |
2422 | (r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */ | 2425 | (r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */ |
2423 | fatal("%s: cannot prepare packet: %s", | 2426 | fatal("%s: cannot prepare packet: %s", |
2424 | __func__, ssh_err(r)); | 2427 | __func__, ssh_err(r)); |
@@ -2465,7 +2468,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) | |||
2465 | want_reply = packet_get_char(); | 2468 | want_reply = packet_get_char(); |
2466 | debug("client_input_global_request: rtype %s want_reply %d", | 2469 | debug("client_input_global_request: rtype %s want_reply %d", |
2467 | rtype, want_reply); | 2470 | rtype, want_reply); |
2468 | if (strcmp(rtype, "hostkeys@openssh.com") == 0) | 2471 | if (strcmp(rtype, "hostkeys-00@openssh.com") == 0) |
2469 | success = client_input_hostkeys(); | 2472 | success = client_input_hostkeys(); |
2470 | if (want_reply) { | 2473 | if (want_reply) { |
2471 | packet_start(success ? | 2474 | packet_start(success ? |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.144 2015/02/16 22:13:32 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.145 2015/02/20 22:17:21 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> |
@@ -693,7 +693,7 @@ mm_answer_sign(int sock, Buffer *m) | |||
693 | u_char *signature; | 693 | u_char *signature; |
694 | size_t datlen, siglen; | 694 | size_t datlen, siglen; |
695 | int r, keyid, is_proof = 0; | 695 | int r, keyid, is_proof = 0; |
696 | const char proof_req[] = "hostkeys-prove@openssh.com"; | 696 | const char proof_req[] = "hostkeys-prove-00@openssh.com"; |
697 | 697 | ||
698 | debug3("%s", __func__); | 698 | debug3("%s", __func__); |
699 | 699 | ||
@@ -723,9 +723,9 @@ mm_answer_sign(int sock, Buffer *m) | |||
723 | fatal("%s: no hostkey for index %d", __func__, keyid); | 723 | fatal("%s: no hostkey for index %d", __func__, keyid); |
724 | if ((sigbuf = sshbuf_new()) == NULL) | 724 | if ((sigbuf = sshbuf_new()) == NULL) |
725 | fatal("%s: sshbuf_new", __func__); | 725 | fatal("%s: sshbuf_new", __func__); |
726 | if ((r = sshbuf_put_string(sigbuf, session_id2, | 726 | if ((r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 || |
727 | (r = sshbuf_put_string(sigbuf, session_id2, | ||
727 | session_id2_len) != 0) || | 728 | session_id2_len) != 0) || |
728 | (r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 || | ||
729 | (r = sshkey_puts(key, sigbuf)) != 0) | 729 | (r = sshkey_puts(key, sigbuf)) != 0) |
730 | fatal("%s: couldn't prepare private key " | 730 | fatal("%s: couldn't prepare private key " |
731 | "proof buffer: %s", __func__, ssh_err(r)); | 731 | "proof buffer: %s", __func__, ssh_err(r)); |
diff --git a/serverloop.c b/serverloop.c index 5633ceb41..306ac36be 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: serverloop.c,v 1.177 2015/02/16 22:13:32 djm Exp $ */ | 1 | /* $OpenBSD: serverloop.c,v 1.178 2015/02/20 22:17: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 |
@@ -1195,10 +1195,10 @@ server_input_hostkeys_prove(struct sshbuf **respp) | |||
1195 | sshbuf_reset(sigbuf); | 1195 | sshbuf_reset(sigbuf); |
1196 | free(sig); | 1196 | free(sig); |
1197 | sig = NULL; | 1197 | sig = NULL; |
1198 | if ((r = sshbuf_put_string(sigbuf, | 1198 | if ((r = sshbuf_put_cstring(sigbuf, |
1199 | "hostkeys-prove-00@openssh.com")) != 0 || | ||
1200 | (r = sshbuf_put_string(sigbuf, | ||
1199 | ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || | 1201 | ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || |
1200 | (r = sshbuf_put_cstring(sigbuf, | ||
1201 | "hostkeys-prove@openssh.com")) != 0 || | ||
1202 | (r = sshkey_puts(key, sigbuf)) != 0 || | 1202 | (r = sshkey_puts(key, sigbuf)) != 0 || |
1203 | (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, | 1203 | (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, |
1204 | sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), 0)) != 0 || | 1204 | sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), 0)) != 0 || |
@@ -1310,7 +1310,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) | |||
1310 | } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { | 1310 | } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { |
1311 | no_more_sessions = 1; | 1311 | no_more_sessions = 1; |
1312 | success = 1; | 1312 | success = 1; |
1313 | } else if (strcmp(rtype, "hostkeys-prove@openssh.com") == 0) { | 1313 | } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { |
1314 | success = server_input_hostkeys_prove(&resp); | 1314 | success = server_input_hostkeys_prove(&resp); |
1315 | } | 1315 | } |
1316 | if (want_reply) { | 1316 | if (want_reply) { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.414 2015/01/20 23:14:00 deraadt Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.415 2015/02/20 22:17: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 |
@@ -1072,6 +1072,12 @@ main(int ac, char **av) | |||
1072 | strcmp(options.proxy_command, "-") == 0 && | 1072 | strcmp(options.proxy_command, "-") == 0 && |
1073 | options.proxy_use_fdpass) | 1073 | options.proxy_use_fdpass) |
1074 | fatal("ProxyCommand=- and ProxyUseFDPass are incompatible"); | 1074 | fatal("ProxyCommand=- and ProxyUseFDPass are incompatible"); |
1075 | if (options.control_persist && | ||
1076 | options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) { | ||
1077 | debug("UpdateHostKeys=ask is incompatible with ControlPersist; " | ||
1078 | "disabling"); | ||
1079 | options.update_hostkeys = 0; | ||
1080 | } | ||
1075 | #ifndef HAVE_CYGWIN | 1081 | #ifndef HAVE_CYGWIN |
1076 | if (original_effective_uid != 0) | 1082 | if (original_effective_uid != 0) |
1077 | options.use_privileged_port = 0; | 1083 | options.use_privileged_port = 0; |
diff --git a/ssh_config.5 b/ssh_config.5 index fa59c518e..140d0ba98 100644 --- a/ssh_config.5 +++ b/ssh_config.5 | |||
@@ -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_config.5,v 1.204 2015/02/16 22:13:32 djm Exp $ | 36 | .\" $OpenBSD: ssh_config.5,v 1.205 2015/02/20 22:17:21 djm Exp $ |
37 | .Dd $Mdocdate: February 16 2015 $ | 37 | .Dd $Mdocdate: February 20 2015 $ |
38 | .Dt SSH_CONFIG 5 | 38 | .Dt SSH_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -1524,6 +1524,9 @@ If | |||
1524 | is set to | 1524 | is set to |
1525 | .Dq ask , | 1525 | .Dq ask , |
1526 | then the user is asked to confirm the modifications to the known_hosts file. | 1526 | then the user is asked to confirm the modifications to the known_hosts file. |
1527 | Confirmation is currently incompatible with | ||
1528 | .Cm ControlPersist , | ||
1529 | and will be disabled if it is enabled. | ||
1527 | .Pp | 1530 | .Pp |
1528 | Presently, only | 1531 | Presently, only |
1529 | .Xr sshd 8 | 1532 | .Xr sshd 8 |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.443 2015/02/16 22:30:03 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.444 2015/02/20 22:17: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 |
@@ -942,7 +942,7 @@ notify_hostkeys(struct ssh *ssh) | |||
942 | free(fp); | 942 | free(fp); |
943 | if (nkeys == 0) { | 943 | if (nkeys == 0) { |
944 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 944 | packet_start(SSH2_MSG_GLOBAL_REQUEST); |
945 | packet_put_cstring("hostkeys@openssh.com"); | 945 | packet_put_cstring("hostkeys-00@openssh.com"); |
946 | packet_put_char(0); /* want-reply */ | 946 | packet_put_char(0); /* want-reply */ |
947 | } | 947 | } |
948 | sshbuf_reset(buf); | 948 | sshbuf_reset(buf); |