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)
This commit is contained in:
djm@openbsd.org 2015-02-20 22:17:21 +00:00 committed by Damien Miller
parent 13a39414d2
commit 44732de068
7 changed files with 42 additions and 30 deletions

View File

@ -282,15 +282,15 @@ by the client cancel the forwarding of a Unix domain socket.
boolean FALSE boolean FALSE
string socket path string socket path
2.5. connection: hostkey update and rotation "hostkeys@openssh.com" 2.5. connection: hostkey update and rotation "hostkeys-00@openssh.com"
and "hostkeys-prove@openssh.com" and "hostkeys-prove-00@openssh.com"
OpenSSH supports a protocol extension allowing a server to inform OpenSSH supports a protocol extension allowing a server to inform
a client of all its protocol v.2 host keys after user-authentication a client of all its protocol v.2 host keys after user-authentication
has completed. has completed.
byte SSH_MSG_GLOBAL_REQUEST byte SSH_MSG_GLOBAL_REQUEST
string "hostkeys@openssh.com" string "hostkeys-00@openssh.com"
string[] hostkeys string[] hostkeys
Upon receiving this message, a client should check which of the 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
key. key.
byte SSH_MSG_GLOBAL_REQUEST byte SSH_MSG_GLOBAL_REQUEST
string "hostkeys-prove@openssh.com" string "hostkeys-prove-00@openssh.com"
char 1 /* want-reply */ char 1 /* want-reply */
string[] hostkeys string[] hostkeys
When a server receives this message, it should generate a signature When a server receives this message, it should generate a signature
using each requested key over the following: using each requested key over the following:
string "hostkeys-prove-00@openssh.com"
string session identifier string session identifier
string "hostkeys-prove@openssh.com"
string hostkey string hostkey
These signatures should be included in the reply, in the order matching These signatures should be included in the reply, in the order matching
@ -453,4 +453,4 @@ respond with a SSH_FXP_STATUS message.
This extension is advertised in the SSH_FXP_VERSION hello with version This extension is advertised in the SSH_FXP_VERSION hello with version
"1". "1".
$OpenBSD: PROTOCOL,v 1.26 2015/02/16 22:13:32 djm Exp $ $OpenBSD: PROTOCOL,v 1.27 2015/02/20 22:17:21 djm Exp $

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.269 2015/02/16 22:13:32 djm Exp $ */ /* $OpenBSD: clientloop.c,v 1.270 2015/02/20 22:17:21 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * 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)
continue; continue;
/* Prepare data to be signed: session ID, unique string, key */ /* Prepare data to be signed: session ID, unique string, key */
sshbuf_reset(signdata); sshbuf_reset(signdata);
if ((r = sshbuf_put_string(signdata, ssh->kex->session_id, if ( (r = sshbuf_put_cstring(signdata,
"hostkeys-prove-00@openssh.com")) != 0 ||
(r = sshbuf_put_string(signdata, ssh->kex->session_id,
ssh->kex->session_id_len)) != 0 || ssh->kex->session_id_len)) != 0 ||
(r = sshbuf_put_cstring(signdata,
"hostkeys-prove@openssh.com")) != 0 ||
(r = sshkey_puts(ctx->keys[i], signdata)) != 0) (r = sshkey_puts(ctx->keys[i], signdata)) != 0)
fatal("%s: failed to prepare signature: %s", fatal("%s: failed to prepare signature: %s",
__func__, ssh_err(r)); __func__, ssh_err(r));
@ -2300,7 +2300,7 @@ client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx)
} }
/* /*
* Handle hostkeys@openssh.com global request to inform the client of all * Handle hostkeys-00@openssh.com global request to inform the client of all
* the server's hostkeys. The keys are checked against the user's * the server's hostkeys. The keys are checked against the user's
* HostkeyAlgorithms preference before they are accepted. * HostkeyAlgorithms preference before they are accepted.
*/ */
@ -2335,8 +2335,10 @@ client_input_hostkeys(void)
__func__, ssh_err(r)); __func__, ssh_err(r));
goto out; goto out;
} }
if ((r = sshkey_from_blob(blob, len, &key)) != 0) if ((r = sshkey_from_blob(blob, len, &key)) != 0) {
fatal("%s: parse key: %s", __func__, ssh_err(r)); error("%s: parse key: %s", __func__, ssh_err(r));
goto out;
}
fp = sshkey_fingerprint(key, options.fingerprint_hash, fp = sshkey_fingerprint(key, options.fingerprint_hash,
SSH_FP_DEFAULT); SSH_FP_DEFAULT);
debug3("%s: received %s key %s", __func__, debug3("%s: received %s key %s", __func__,
@ -2376,9 +2378,10 @@ client_input_hostkeys(void)
} }
if (ctx->nkeys == 0) { if (ctx->nkeys == 0) {
error("%s: server sent no hostkeys", __func__); debug("%s: server sent no hostkeys", __func__);
goto out; goto out;
} }
if ((ctx->keys_seen = calloc(ctx->nkeys, if ((ctx->keys_seen = calloc(ctx->nkeys,
sizeof(*ctx->keys_seen))) == NULL) sizeof(*ctx->keys_seen))) == NULL)
fatal("%s: calloc failed", __func__); fatal("%s: calloc failed", __func__);
@ -2418,7 +2421,7 @@ client_input_hostkeys(void)
__func__, ctx->nnew); __func__, ctx->nnew);
if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, (r = sshpkt_put_cstring(ssh,
"hostkeys-prove@openssh.com")) != 0 || "hostkeys-prove-00@openssh.com")) != 0 ||
(r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */ (r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */
fatal("%s: cannot prepare packet: %s", fatal("%s: cannot prepare packet: %s",
__func__, ssh_err(r)); __func__, ssh_err(r));
@ -2465,7 +2468,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt)
want_reply = packet_get_char(); want_reply = packet_get_char();
debug("client_input_global_request: rtype %s want_reply %d", debug("client_input_global_request: rtype %s want_reply %d",
rtype, want_reply); rtype, want_reply);
if (strcmp(rtype, "hostkeys@openssh.com") == 0) if (strcmp(rtype, "hostkeys-00@openssh.com") == 0)
success = client_input_hostkeys(); success = client_input_hostkeys();
if (want_reply) { if (want_reply) {
packet_start(success ? packet_start(success ?

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.c,v 1.144 2015/02/16 22:13:32 djm Exp $ */ /* $OpenBSD: monitor.c,v 1.145 2015/02/20 22:17:21 djm Exp $ */
/* /*
* Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org> * Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -693,7 +693,7 @@ mm_answer_sign(int sock, Buffer *m)
u_char *signature; u_char *signature;
size_t datlen, siglen; size_t datlen, siglen;
int r, keyid, is_proof = 0; int r, keyid, is_proof = 0;
const char proof_req[] = "hostkeys-prove@openssh.com"; const char proof_req[] = "hostkeys-prove-00@openssh.com";
debug3("%s", __func__); debug3("%s", __func__);
@ -723,9 +723,9 @@ mm_answer_sign(int sock, Buffer *m)
fatal("%s: no hostkey for index %d", __func__, keyid); fatal("%s: no hostkey for index %d", __func__, keyid);
if ((sigbuf = sshbuf_new()) == NULL) if ((sigbuf = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new", __func__); fatal("%s: sshbuf_new", __func__);
if ((r = sshbuf_put_string(sigbuf, session_id2, if ((r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 ||
(r = sshbuf_put_string(sigbuf, session_id2,
session_id2_len) != 0) || session_id2_len) != 0) ||
(r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 ||
(r = sshkey_puts(key, sigbuf)) != 0) (r = sshkey_puts(key, sigbuf)) != 0)
fatal("%s: couldn't prepare private key " fatal("%s: couldn't prepare private key "
"proof buffer: %s", __func__, ssh_err(r)); "proof buffer: %s", __func__, ssh_err(r));

View File

@ -1,4 +1,4 @@
/* $OpenBSD: serverloop.c,v 1.177 2015/02/16 22:13:32 djm Exp $ */ /* $OpenBSD: serverloop.c,v 1.178 2015/02/20 22:17:21 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1195,10 +1195,10 @@ server_input_hostkeys_prove(struct sshbuf **respp)
sshbuf_reset(sigbuf); sshbuf_reset(sigbuf);
free(sig); free(sig);
sig = NULL; sig = NULL;
if ((r = sshbuf_put_string(sigbuf, if ((r = sshbuf_put_cstring(sigbuf,
"hostkeys-prove-00@openssh.com")) != 0 ||
(r = sshbuf_put_string(sigbuf,
ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || ssh->kex->session_id, ssh->kex->session_id_len)) != 0 ||
(r = sshbuf_put_cstring(sigbuf,
"hostkeys-prove@openssh.com")) != 0 ||
(r = sshkey_puts(key, sigbuf)) != 0 || (r = sshkey_puts(key, sigbuf)) != 0 ||
(r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen,
sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), 0)) != 0 || sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), 0)) != 0 ||
@ -1310,7 +1310,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
} else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
no_more_sessions = 1; no_more_sessions = 1;
success = 1; success = 1;
} else if (strcmp(rtype, "hostkeys-prove@openssh.com") == 0) { } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
success = server_input_hostkeys_prove(&resp); success = server_input_hostkeys_prove(&resp);
} }
if (want_reply) { if (want_reply) {

8
ssh.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh.c,v 1.414 2015/01/20 23:14:00 deraadt Exp $ */ /* $OpenBSD: ssh.c,v 1.415 2015/02/20 22:17:21 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1072,6 +1072,12 @@ main(int ac, char **av)
strcmp(options.proxy_command, "-") == 0 && strcmp(options.proxy_command, "-") == 0 &&
options.proxy_use_fdpass) options.proxy_use_fdpass)
fatal("ProxyCommand=- and ProxyUseFDPass are incompatible"); fatal("ProxyCommand=- and ProxyUseFDPass are incompatible");
if (options.control_persist &&
options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) {
debug("UpdateHostKeys=ask is incompatible with ControlPersist; "
"disabling");
options.update_hostkeys = 0;
}
#ifndef HAVE_CYGWIN #ifndef HAVE_CYGWIN
if (original_effective_uid != 0) if (original_effective_uid != 0)
options.use_privileged_port = 0; options.use_privileged_port = 0;

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.\" $OpenBSD: ssh_config.5,v 1.204 2015/02/16 22:13:32 djm Exp $ .\" $OpenBSD: ssh_config.5,v 1.205 2015/02/20 22:17:21 djm Exp $
.Dd $Mdocdate: February 16 2015 $ .Dd $Mdocdate: February 20 2015 $
.Dt SSH_CONFIG 5 .Dt SSH_CONFIG 5
.Os .Os
.Sh NAME .Sh NAME
@ -1524,6 +1524,9 @@ If
is set to is set to
.Dq ask , .Dq ask ,
then the user is asked to confirm the modifications to the known_hosts file. then the user is asked to confirm the modifications to the known_hosts file.
Confirmation is currently incompatible with
.Cm ControlPersist ,
and will be disabled if it is enabled.
.Pp .Pp
Presently, only Presently, only
.Xr sshd 8 .Xr sshd 8

4
sshd.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.443 2015/02/16 22:30:03 djm Exp $ */ /* $OpenBSD: sshd.c,v 1.444 2015/02/20 22:17:21 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -942,7 +942,7 @@ notify_hostkeys(struct ssh *ssh)
free(fp); free(fp);
if (nkeys == 0) { if (nkeys == 0) {
packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_start(SSH2_MSG_GLOBAL_REQUEST);
packet_put_cstring("hostkeys@openssh.com"); packet_put_cstring("hostkeys-00@openssh.com");
packet_put_char(0); /* want-reply */ packet_put_char(0); /* want-reply */
} }
sshbuf_reset(buf); sshbuf_reset(buf);