From nobody Mon Dec 18 16:23:28 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Sv4rK3238z54jFB; Mon, 18 Dec 2023 16:23:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Sv4rK2KtDz4cpw; Mon, 18 Dec 2023 16:23:29 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1702916609; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=CgFQmJl4QNwNHZcSkZYWvO3YF7IqV9+/4M5QzGFDsCw=; b=fKOROFwcfvH9oUENJIZHdrOI7gTIW84zK7Axh201WO0QHIG0EoVMQf7Ur3vfN3Bgl7zKh1 UP1DPUgHpdU+ZKDy5bbo/YmtzWGGEZ0rFCYSy0rGPgt5Uf4X8wyZxl9o5nO4aAP35cxcgy gS0Jw0E2S5uUQJMye4JcVI+Hr26az9UlatYrhaqRum2bt5W+ZDyPhXPZhriYkcYNgTfxBZ 7jK2LFjTSlx4Dh1ZA3yym58vcpQd0bMvcGMlZOGYDBiDYS5WTjCPzx/1BsAeOBwyHVBvf6 bXVl1FozFYmKIZQuBWNemOPhUMTmOGO3oLcWPHxWrO5fpoNH/ISst4LV7rgT9w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1702916609; a=rsa-sha256; cv=none; b=x6vUzgtj6d1MW65DjPMX+UMtFLtoG79aU3rldUyDk+9JXvTNwxH9huO7UjlXemOhAjJNHm +kSzzGuEtx0jCUKOaShV+biHfPdpG5meEkEEdP+T2X/HiqhAywZ5N6EZVN8bUTrsT6CGDk mE4M8Mi9aTw83bfjI0XnRvBC4rJ00TXiJ85dJXMBXCnhuEDcQtpUaWlox8gGXJWL72UvHm kv55sgRTjSBHTwQyrnUTrm4Vw/DzrS80Nhqoe2DzlIWt7JXvM6Q8sbokY87tnNIAqTTavU jswKvr3Fi71NWTVOo9314F/GRbA9uzXWwF0pzs7HuWmShTQHEPVKArehfiVaTg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1702916609; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=CgFQmJl4QNwNHZcSkZYWvO3YF7IqV9+/4M5QzGFDsCw=; b=WlGKzfmR6Mv8jgS6xoU6iM5TR5hsk0qdjNF5yjBP6H/WTZjXuuiJ4uDVkH8xfS8oWKPxPL F5ssEM9PwSTjvnB1bIrXe0giXVaYi6Gw2c0gto3HePzC960NJh5iXFs78nYy/qLxYD8MkQ sziCRy/hVWU12xeKiFsxVvwKPC7oGl5Gzj/wIddmB6RCwdu+aqEwh/2oG8Rb6Od4RMpuv7 MVUy8BQBEwdfJsFWsnUYwxEtrOYdAfqxsI7r499oAAJefHJ1oWLOhRt4Ykd14HBkAMqfmz SZKwm9AfOQ0rD/BenDFtoTxnOi/F+eHPXLe5ebg8OWBdI5y60YBo9W4Ff3i/zw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Sv4rK0H9PzCmJ; Mon, 18 Dec 2023 16:23:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 3BIGNSVF003703; Mon, 18 Dec 2023 16:23:28 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3BIGNSHr003700; Mon, 18 Dec 2023 16:23:28 GMT (envelope-from git) Date: Mon, 18 Dec 2023 16:23:28 GMT Message-Id: <202312181623.3BIGNSHr003700@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gordon Tetlow Subject: git: 92f58c69a14c - main - Implement "strict key exchange" in ssh and sshd. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: gordon X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 92f58c69a14c0afe910145f177c0e8aeaf9c7da4 Auto-Submitted: auto-generated The branch main has been updated by gordon: URL: https://cgit.FreeBSD.org/src/commit/?id=92f58c69a14c0afe910145f177c0e8aeaf9c7da4 commit 92f58c69a14c0afe910145f177c0e8aeaf9c7da4 Author: Gordon Tetlow AuthorDate: 2023-12-18 16:22:22 +0000 Commit: Gordon Tetlow CommitDate: 2023-12-18 16:22:22 +0000 Implement "strict key exchange" in ssh and sshd. This adds a protocol extension to improve the integrity of the SSH transport protocol, particular in and around the initial key exchange (KEX) phase. Full details of the extension are in the PROTOCOL file. OpenBSD-Commit-ID: 2a66ac962f0a630d7945fee54004ed9e9c439f14 Approved by: so (implicit) Obtained from: https://anongit.mindrot.org/openssh.git/patch/?id=1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 Security: CVE-2023-48795 --- crypto/openssh/PROTOCOL | 28 +++++++++++- crypto/openssh/kex.c | 82 ++++++++++++++++++++++------------ crypto/openssh/kex.h | 3 +- crypto/openssh/packet.c | 103 +++++++++++++++++++++++++------------------ crypto/openssh/packet.h | 3 +- crypto/openssh/sshconnect2.c | 10 +---- 6 files changed, 146 insertions(+), 83 deletions(-) diff --git a/crypto/openssh/PROTOCOL b/crypto/openssh/PROTOCOL index d453c779be92..ded935eb6752 100644 --- a/crypto/openssh/PROTOCOL +++ b/crypto/openssh/PROTOCOL @@ -137,6 +137,32 @@ than as a named global or channel request to allow pings with very short packet lengths, which would not be possible with other approaches. +1.9 transport: strict key exchange extension + +OpenSSH supports a number of transport-layer hardening measures under +a "strict KEX" feature. This feature is signalled similarly to the +RFC8308 ext-info feature: by including a additional algorithm in the +initiial SSH2_MSG_KEXINIT kex_algorithms field. The client may append +"kex-strict-c-v00@openssh.com" to its kex_algorithms and the server +may append "kex-strict-s-v00@openssh.com". These pseudo-algorithms +are only valid in the initial SSH2_MSG_KEXINIT and MUST be ignored +if they are present in subsequent SSH2_MSG_KEXINIT packets. + +When an endpoint that supports this extension observes this algorithm +name in a peer's KEXINIT packet, it MUST make the following changes to +the the protocol: + +a) During initial KEX, terminate the connection if any unexpected or + out-of-sequence packet is received. This includes terminating the + connection if the first packet received is not SSH2_MSG_KEXINIT. + Unexpected packets for the purpose of strict KEX include messages + that are otherwise valid at any time during the connection such as + SSH2_MSG_DEBUG and SSH2_MSG_IGNORE. +b) After sending or receiving a SSH2_MSG_NEWKEYS message, reset the + packet sequence number to zero. This behaviour persists for the + duration of the connection (i.e. not just the first + SSH2_MSG_NEWKEYS). + 2. Connection protocol changes 2.1. connection: Channel write close extension "eow@openssh.com" @@ -745,4 +771,4 @@ master instance and later clients. OpenSSH extends the usual agent protocol. These changes are documented in the PROTOCOL.agent file. -$OpenBSD: PROTOCOL,v 1.49 2023/08/28 03:28:43 djm Exp $ +$OpenBSD: PROTOCOL,v 1.50 2023/12/18 14:45:17 djm Exp $ diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c index 8ff92f2a2d5e..2cb5ab3cf07c 100644 --- a/crypto/openssh/kex.c +++ b/crypto/openssh/kex.c @@ -65,7 +65,7 @@ #include "xmalloc.h" /* prototype */ -static int kex_choose_conf(struct ssh *); +static int kex_choose_conf(struct ssh *, uint32_t seq); static int kex_input_newkeys(int, u_int32_t, struct ssh *); static const char * const proposal_names[PROPOSAL_MAX] = { @@ -177,6 +177,18 @@ kex_names_valid(const char *names) return 1; } +/* returns non-zero if proposal contains any algorithm from algs */ +static int +has_any_alg(const char *proposal, const char *algs) +{ + char *cp; + + if ((cp = match_list(proposal, algs, NULL)) == NULL) + return 0; + free(cp); + return 1; +} + /* * Concatenate algorithm names, avoiding duplicates in the process. * Caller must free returned string. @@ -184,7 +196,7 @@ kex_names_valid(const char *names) char * kex_names_cat(const char *a, const char *b) { - char *ret = NULL, *tmp = NULL, *cp, *p, *m; + char *ret = NULL, *tmp = NULL, *cp, *p; size_t len; if (a == NULL || *a == '\0') @@ -201,10 +213,8 @@ kex_names_cat(const char *a, const char *b) } strlcpy(ret, a, len); for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { - if ((m = match_list(ret, p, NULL)) != NULL) { - free(m); + if (has_any_alg(ret, p)) continue; /* Algorithm already present */ - } if (strlcat(ret, ",", len) >= len || strlcat(ret, p, len) >= len) { free(tmp); @@ -334,15 +344,23 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX], const char *defpropclient[PROPOSAL_MAX] = { KEX_CLIENT }; const char **defprop = ssh->kex->server ? defpropserver : defpropclient; u_int i; + char *cp; if (prop == NULL) fatal_f("proposal missing"); + /* Append EXT_INFO signalling to KexAlgorithms */ + if (kexalgos == NULL) + kexalgos = defprop[PROPOSAL_KEX_ALGS]; + if ((cp = kex_names_cat(kexalgos, ssh->kex->server ? + "kex-strict-s-v00@openssh.com" : + "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL) + fatal_f("kex_names_cat"); + for (i = 0; i < PROPOSAL_MAX; i++) { switch(i) { case PROPOSAL_KEX_ALGS: - prop[i] = compat_kex_proposal(ssh, - kexalgos ? kexalgos : defprop[i]); + prop[i] = compat_kex_proposal(ssh, cp); break; case PROPOSAL_ENC_ALGS_CTOS: case PROPOSAL_ENC_ALGS_STOC: @@ -363,6 +381,7 @@ kex_proposal_populate_entries(struct ssh *ssh, char *prop[PROPOSAL_MAX], prop[i] = xstrdup(defprop[i]); } } + free(cp); } void @@ -466,7 +485,12 @@ kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh) { int r; - error("kex protocol error: type %d seq %u", type, seq); + /* If in strict mode, any unexpected message is an error */ + if ((ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict) { + ssh_packet_disconnect(ssh, "strict KEX violation: " + "unexpected packet type %u (seqnr %u)", type, seq); + } + error_f("type %u seq %u", type, seq); if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || (r = sshpkt_put_u32(ssh, seq)) != 0 || (r = sshpkt_send(ssh)) != 0) @@ -563,7 +587,7 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh) if (ninfo >= 1024) { error("SSH2_MSG_EXT_INFO with too many entries, expected " "<=1024, received %u", ninfo); - return SSH_ERR_INVALID_FORMAT; + return dispatch_protocol_error(type, seq, ssh); } for (i = 0; i < ninfo; i++) { if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) @@ -681,7 +705,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) error_f("no kex"); return SSH_ERR_INTERNAL_ERROR; } - ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL); + ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error); ptr = sshpkt_ptr(ssh, &dlen); if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) return r; @@ -717,7 +741,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) if (!(kex->flags & KEX_INIT_SENT)) if ((r = kex_send_kexinit(ssh)) != 0) return r; - if ((r = kex_choose_conf(ssh)) != 0) + if ((r = kex_choose_conf(ssh, seq)) != 0) return r; if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL) @@ -981,20 +1005,14 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) return (1); } -/* returns non-zero if proposal contains any algorithm from algs */ static int -has_any_alg(const char *proposal, const char *algs) +kexalgs_contains(char **peer, const char *ext) { - char *cp; - - if ((cp = match_list(proposal, algs, NULL)) == NULL) - return 0; - free(cp); - return 1; + return has_any_alg(peer[PROPOSAL_KEX_ALGS], ext); } static int -kex_choose_conf(struct ssh *ssh) +kex_choose_conf(struct ssh *ssh, uint32_t seq) { struct kex *kex = ssh->kex; struct newkeys *newkeys; @@ -1019,13 +1037,23 @@ kex_choose_conf(struct ssh *ssh) sprop=peer; } - /* Check whether client supports ext_info_c */ - if (kex->server && (kex->flags & KEX_INITIAL)) { - char *ext; - - ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL); - kex->ext_info_c = (ext != NULL); - free(ext); + /* Check whether peer supports ext_info/kex_strict */ + if ((kex->flags & KEX_INITIAL) != 0) { + if (kex->server) { + kex->ext_info_c = kexalgs_contains(peer, "ext-info-c"); + kex->kex_strict = kexalgs_contains(peer, + "kex-strict-c-v00@openssh.com"); + } else { + kex->kex_strict = kexalgs_contains(peer, + "kex-strict-s-v00@openssh.com"); + } + if (kex->kex_strict) { + debug3_f("will use strict KEX ordering"); + if (seq != 0) + ssh_packet_disconnect(ssh, + "strict KEX violation: " + "KEXINIT was not the first packet"); + } } /* Check whether client supports rsa-sha2 algorithms */ diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h index 5f7ef784eec9..272ebb43d79d 100644 --- a/crypto/openssh/kex.h +++ b/crypto/openssh/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.119 2023/08/28 03:28:43 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.120 2023/12/18 14:45:17 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -149,6 +149,7 @@ struct kex { u_int kex_type; char *server_sig_algs; int ext_info_c; + int kex_strict; struct sshbuf *my; struct sshbuf *peer; struct sshbuf *client_version; diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c index d69b903c844c..2d1401e7c9f5 100644 --- a/crypto/openssh/packet.c +++ b/crypto/openssh/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.312 2023/08/28 03:31:16 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.313 2023/12/18 14:45:17 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1208,8 +1208,13 @@ ssh_packet_send2_wrapped(struct ssh *ssh) sshbuf_dump(state->output, stderr); #endif /* increment sequence number for outgoing packets */ - if (++state->p_send.seqnr == 0) + if (++state->p_send.seqnr == 0) { + if ((ssh->kex->flags & KEX_INITIAL) != 0) { + ssh_packet_disconnect(ssh, "outgoing sequence number " + "wrapped during initial key exchange"); + } logit("outgoing seqnr wraps around"); + } if (++state->p_send.packets == 0) if (!(ssh->compat & SSH_BUG_NOREKEY)) return SSH_ERR_NEED_REKEY; @@ -1217,6 +1222,11 @@ ssh_packet_send2_wrapped(struct ssh *ssh) state->p_send.bytes += len; sshbuf_reset(state->outgoing_packet); + if (type == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) { + debug_f("resetting send seqnr %u", state->p_send.seqnr); + state->p_send.seqnr = 0; + } + if (type == SSH2_MSG_NEWKEYS) r = ssh_set_newkeys(ssh, MODE_OUT); else if (type == SSH2_MSG_USERAUTH_SUCCESS && state->server_side) @@ -1345,8 +1355,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) /* Stay in the loop until we have received a complete packet. */ for (;;) { /* Try to read a packet from the buffer. */ - r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p); - if (r != 0) + if ((r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p)) != 0) break; /* If we got a packet, return it. */ if (*typep != SSH_MSG_NONE) @@ -1417,29 +1426,6 @@ ssh_packet_read(struct ssh *ssh) return type; } -/* - * Waits until a packet has been received, verifies that its type matches - * that given, and gives a fatal error and exits if there is a mismatch. - */ - -int -ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) -{ - int r; - u_char type; - - if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) - return r; - if (type != expected_type) { - if ((r = sshpkt_disconnect(ssh, - "Protocol error: expected packet type %d, got %d", - expected_type, type)) != 0) - return r; - return SSH_ERR_PROTOCOL_ERROR; - } - return 0; -} - static int ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { @@ -1630,10 +1616,16 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0) goto out; } + if (seqnr_p != NULL) *seqnr_p = state->p_read.seqnr; - if (++state->p_read.seqnr == 0) + if (++state->p_read.seqnr == 0) { + if ((ssh->kex->flags & KEX_INITIAL) != 0) { + ssh_packet_disconnect(ssh, "incoming sequence number " + "wrapped during initial key exchange"); + } logit("incoming seqnr wraps around"); + } if (++state->p_read.packets == 0) if (!(ssh->compat & SSH_BUG_NOREKEY)) return SSH_ERR_NEED_REKEY; @@ -1699,6 +1691,10 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) #endif /* reset for next packet */ state->packlen = 0; + if (*typep == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) { + debug_f("resetting read seqnr %u", state->p_read.seqnr); + state->p_read.seqnr = 0; + } if ((r = ssh_packet_check_rekey(ssh)) != 0) return r; @@ -1721,10 +1717,39 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) r = ssh_packet_read_poll2(ssh, typep, seqnr_p); if (r != 0) return r; - if (*typep) { - state->keep_alive_timeouts = 0; - DBG(debug("received packet type %d", *typep)); + if (*typep == 0) { + /* no message ready */ + return 0; } + state->keep_alive_timeouts = 0; + DBG(debug("received packet type %d", *typep)); + + /* Always process disconnect messages */ + if (*typep == SSH2_MSG_DISCONNECT) { + if ((r = sshpkt_get_u32(ssh, &reason)) != 0 || + (r = sshpkt_get_string(ssh, &msg, NULL)) != 0) + return r; + /* Ignore normal client exit notifications */ + do_log2(ssh->state->server_side && + reason == SSH2_DISCONNECT_BY_APPLICATION ? + SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, + "Received disconnect from %s port %d:" + "%u: %.400s", ssh_remote_ipaddr(ssh), + ssh_remote_port(ssh), reason, msg); + free(msg); + return SSH_ERR_DISCONNECTED; + } + + /* + * Do not implicitly handle any messages here during initial + * KEX when in strict mode. They will be need to be allowed + * explicitly by the KEX dispatch table or they will generate + * protocol errors. + */ + if (ssh->kex != NULL && + (ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict) + return 0; + /* Implicitly handle transport-level messages */ switch (*typep) { case SSH2_MSG_IGNORE: debug3("Received SSH2_MSG_IGNORE"); @@ -1739,19 +1764,6 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) debug("Remote: %.900s", msg); free(msg); break; - case SSH2_MSG_DISCONNECT: - if ((r = sshpkt_get_u32(ssh, &reason)) != 0 || - (r = sshpkt_get_string(ssh, &msg, NULL)) != 0) - return r; - /* Ignore normal client exit notifications */ - do_log2(ssh->state->server_side && - reason == SSH2_DISCONNECT_BY_APPLICATION ? - SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, - "Received disconnect from %s port %d:" - "%u: %.400s", ssh_remote_ipaddr(ssh), - ssh_remote_port(ssh), reason, msg); - free(msg); - return SSH_ERR_DISCONNECTED; case SSH2_MSG_UNIMPLEMENTED: if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0) return r; @@ -2244,6 +2256,7 @@ kex_to_blob(struct sshbuf *m, struct kex *kex) (r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 || (r = sshbuf_put_u32(m, kex->hostkey_nid)) != 0 || (r = sshbuf_put_u32(m, kex->kex_type)) != 0 || + (r = sshbuf_put_u32(m, kex->kex_strict)) != 0 || (r = sshbuf_put_stringb(m, kex->my)) != 0 || (r = sshbuf_put_stringb(m, kex->peer)) != 0 || (r = sshbuf_put_stringb(m, kex->client_version)) != 0 || @@ -2406,6 +2419,7 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp) (r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 || (r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_nid)) != 0 || (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 || + (r = sshbuf_get_u32(m, &kex->kex_strict)) != 0 || (r = sshbuf_get_stringb(m, kex->my)) != 0 || (r = sshbuf_get_stringb(m, kex->peer)) != 0 || (r = sshbuf_get_stringb(m, kex->client_version)) != 0 || @@ -2734,6 +2748,7 @@ sshpkt_disconnect(struct ssh *ssh, const char *fmt,...) vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); + debug2_f("sending SSH2_MSG_DISCONNECT: %s", buf); if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || (r = sshpkt_put_cstring(ssh, buf)) != 0 || diff --git a/crypto/openssh/packet.h b/crypto/openssh/packet.h index 11925a27d438..b2bc3215ddbc 100644 --- a/crypto/openssh/packet.h +++ b/crypto/openssh/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.95 2023/08/28 03:31:16 djm Exp $ */ +/* $OpenBSD: packet.h,v 1.96 2023/12/18 14:45:17 djm Exp $ */ /* * Author: Tatu Ylonen @@ -124,7 +124,6 @@ int ssh_packet_send2_wrapped(struct ssh *); int ssh_packet_send2(struct ssh *); int ssh_packet_read(struct ssh *); -int ssh_packet_read_expect(struct ssh *, u_int type); int ssh_packet_read_poll(struct ssh *); int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c index 90cbba6821e9..6401e304a977 100644 --- a/crypto/openssh/sshconnect2.c +++ b/crypto/openssh/sshconnect2.c @@ -358,7 +358,6 @@ struct cauthmethod { }; static int input_userauth_service_accept(int, u_int32_t, struct ssh *); -static int input_userauth_ext_info(int, u_int32_t, struct ssh *); static int input_userauth_success(int, u_int32_t, struct ssh *); static int input_userauth_failure(int, u_int32_t, struct ssh *); static int input_userauth_banner(int, u_int32_t, struct ssh *); @@ -472,7 +471,7 @@ ssh_userauth2(struct ssh *ssh, const char *local_user, ssh->authctxt = &authctxt; ssh_dispatch_init(ssh, &input_userauth_error); - ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info); + ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, kex_input_ext_info); ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept); ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */ pubkey_cleanup(ssh); @@ -523,12 +522,6 @@ input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) return r; } -static int -input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh) -{ - return kex_input_ext_info(type, seqnr, ssh); -} - void userauth(struct ssh *ssh, char *authlist) { @@ -607,6 +600,7 @@ input_userauth_success(int type, u_int32_t seq, struct ssh *ssh) free(authctxt->methoddata); authctxt->methoddata = NULL; authctxt->success = 1; /* break out */ + ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, dispatch_protocol_error); return 0; }