From nobody Tue Dec 19 20:32:23 2023 X-Original-To: dev-commits-doc-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 4SvpK331jCz54scm for ; Tue, 19 Dec 2023 20:32:23 +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 4SvpK322Ccz4d2r; Tue, 19 Dec 2023 20:32:23 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1703017943; 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=aKSTqgsiH+p9UijJawkXgr71DfDXae/1cD3K9uz/x5Q=; b=g2Cg7G6KhLt1utUcrwUUjAckDXKwf4kuhJlKzpSqsk42Rzu92CdlhNqk2D7I3WFiLp66T7 X4mcSlGJmtrDUdnSuTRwUNjJeLV5jRb0ehcpNbB9OJBWkjrHEqJdWbUTRKDCLPJFrMbMjU p0hFs/MFaWsgu1X6M6hMWyjna4sYfpo6kUAXljNPhq44UuFbYkrHnpxtYuFgkWhBwpxz6g 7j1MyfLaRSyIQBpuEtEjjuQ9HyaghaJLGrp/It1BZF0nWEQiDBHXJBI9ocHIpDn0MlVVQB oIIMcc7RBrSO8NzYOMR2JLXIHI059pH7pO65KgN7hq6zFqkByWWbXyZN8FKnBA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1703017943; a=rsa-sha256; cv=none; b=Mi+OsZgnaEGk1vGgWm90LL2+Zi6K29Na4s/zpACY5yhN0qnBxhJcfzu+tTV1Rj3hZYpQg3 FCB+Uzfa9xRVraaqMu1Ajw7v7IMKvp0Osj13BS0epqkJbsItZz3bf+IN1fo/RhWGt/AwGI DusGIhqW5iTgC15G3Inb+kLylD68vciU7BlfV61eawgAXO7s+ldgJsu2WMzqWd9DZxeGKi is3A3H9XFxihzpMZf56Mn/+UdSktLhHBM1xpdXGc9zZbUvCiRmi7ph3y4FL7qf611JWkOQ gtIUDlyPBtJTQZl7DmQcFV58shcLXJuAoIsIg5FZgiCGD0r2ojCFJ547c+BSGQ== 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=1703017943; 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=aKSTqgsiH+p9UijJawkXgr71DfDXae/1cD3K9uz/x5Q=; b=ZSIFQTvncVvrllOqAAqGfseA4Mk0oolWT1cyuCyKMiilnCNvG48mXloxhb8X9IoVQTaA/T wWuwlhlf+RrPCsePi9+rpl+uqTtskMdEfXw/K8KkjeWJ+9jLwL89OqoRoJXQXsX7JKSOI1 PhtqV6bUFT3aQZMy6KrpOIN+drY/Lz5t4Qfy31uwj00FJdThqTj69mo1ait73CqkTJKyzJ zsTwQhg2L66JL6OkmtK4Jw5HLMY7JcKqWk9f5iA5qHTXAO/YghBhX5U1b8Gs3UwTAL+XrC dhbxLJngcc5gY1Sj/noacbaMdCzy0ZPLtJC6nyY3IofaliMPwy+/6Tlsm/FRuQ== 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 4SvpK315Wmz56s; Tue, 19 Dec 2023 20:32:23 +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 3BJKWNSY031901; Tue, 19 Dec 2023 20:32:23 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 3BJKWNvH031898; Tue, 19 Dec 2023 20:32:23 GMT (envelope-from git) Date: Tue, 19 Dec 2023 20:32:23 GMT Message-Id: <202312192032.3BJKWNvH031898@gitrepo.freebsd.org> To: doc-committers@FreeBSD.org, dev-commits-doc-all@FreeBSD.org From: Gordon Tetlow Subject: git: 6e508486e4 - main - Add SA-23:19.openssh. List-Id: Commit messages for all branches of the doc repository List-Archive: https://lists.freebsd.org/archives/dev-commits-doc-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-doc-all@freebsd.org X-BeenThere: dev-commits-doc-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: doc X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6e508486e413dd16c913a664c712dc88a32414e1 Auto-Submitted: auto-generated The branch main has been updated by gordon: URL: https://cgit.FreeBSD.org/doc/commit/?id=6e508486e413dd16c913a664c712dc88a32414e1 commit 6e508486e413dd16c913a664c712dc88a32414e1 Author: Gordon Tetlow AuthorDate: 2023-12-19 20:32:05 +0000 Commit: Gordon Tetlow CommitDate: 2023-12-19 20:32:05 +0000 Add SA-23:19.openssh. Approved by: so --- website/data/security/advisories.toml | 4 + .../advisories/FreeBSD-SA-23:19.openssh.asc | 147 +++++++ .../static/security/patches/SA-23:19/openssh.patch | 460 +++++++++++++++++++++ .../security/patches/SA-23:19/openssh.patch.asc | 16 + 4 files changed, 627 insertions(+) diff --git a/website/data/security/advisories.toml b/website/data/security/advisories.toml index e914a98428..5a4783bd59 100644 --- a/website/data/security/advisories.toml +++ b/website/data/security/advisories.toml @@ -1,6 +1,10 @@ # Sort advisories by year, month and day # $FreeBSD$ +[[advisories]] +name = "FreeBSD-SA-23:19.openssh" +date = "2023-12-19" + [[advisories]] name = "FreeBSD-SA-23:18.nfsclient" date = "2023-12-12" diff --git a/website/static/security/advisories/FreeBSD-SA-23:19.openssh.asc b/website/static/security/advisories/FreeBSD-SA-23:19.openssh.asc new file mode 100644 index 0000000000..bf48a4a6db --- /dev/null +++ b/website/static/security/advisories/FreeBSD-SA-23:19.openssh.asc @@ -0,0 +1,147 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-23:19.openssh Security Advisory + The FreeBSD Project + +Topic: Prefix Truncation Attack in the SSH protocol + +Category: contrib +Module: openssh +Announced: 2023-12-19 +Credits: Fabian Bäumer, Marcus Brinkmann, Jörg Schwenk +Affects: All supported versions of FreeBSD. +Corrected: 2023-12-18 16:54:31 UTC (stable/14, 14.0-STABLE) + 2023-12-19 20:19:48 UTC (releng/14.0, 14.0-RELEASE-p4) + 2023-12-18 17:10:15 UTC (stable/13, 13.2-STABLE) + 2023-12-19 20:19:57 UTC (releng/13.2, 13.2-RELEASE-p9) +CVE Name: CVE-2023-48795 + +Note: While this issue does affect 12.4-STABLE and 12.4-RELEASE, the version +of OpenSSH in 12.4 is old enough the vendor provided patch does not cleanly +apply. As 12.4 goes out of support at the end of December and in order to +quickly get fixes out for 14.0 and 13.2, the FreeBSD Security Team is issuing +this advisory now while feasibility of a 12.4 backport is investigated. Users +with 12.4 are encouraged to either implement the documented workaround or +leverage an up to date version of OpenSSH from the ports/pkg collection. + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit . + +I. Background + +OpenSSH is an implementation of the SSH protocol suite, providing an +encrypted and authenticated transport for a variety of services, including +remote shell access. + +II. Problem Description + +The SSH protocol executes an initial handshake between the server and the +client. This protocol handshake includes the possibility of several +extensions allowing different options to be selected. Validation of the +packets in the handshake is done through sequence numbers. + +III. Impact + +A man in the middle attacker can silently manipulate handshake messages to +truncate extension negotiation messages potentially leading to less secure +client authentication algorithms or deactivating keystroke timing attack +countermeasures. + +IV. Workaround + +Add the following lines to /etc/ssh_config and /etc/sshd_config: + Ciphers -chacha20-poly1305@openssh.com + MACs -*etm@openssh.com + +V. Solution + +Upgrade your vulnerable system to a supported FreeBSD stable or +release / security branch (releng) dated after the correction date. + +Perform one of the following: + +1) To update your vulnerable system via a binary patch: + +Systems running a RELEASE version of FreeBSD on the amd64 or arm64 platforms, +or the i386 platfrom on FreeBSD 13 and earlier, can be updated via +the freebsd-update(8) utility: + +# freebsd-update fetch +# freebsd-update install + +2) To update your vulnerable system via a source code patch: + +The following patches have been verified to apply to the applicable +FreeBSD release branches. + +a) Download the relevant patch from the location below, and verify the +detached PGP signature using your PGP utility. + +# fetch https://security.FreeBSD.org/patches/SA-23:19/openssh.patch +# fetch https://security.FreeBSD.org/patches/SA-23:19/openssh.patch.asc +# gpg --verify openssh.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch < /path/to/patch + +c) Recompile the operating system using buildworld and installworld as +described in . + +Restart the applicable daemons, or reboot the system. + +VI. Correction details + +This issue is corrected as of the corresponding Git commit hash or Subversion +revision number in the following stable and release branches: + +Branch/path Hash Revision +- ------------------------------------------------------------------------- +stable/14/ 673d1ead65c9 stable/14-n266020 +releng/14.0/ b9856d61e99d releng/14.0-n265399 +stable/13/ 3bafcb9744c9 stable/13-n256910 +releng/13.2/ 69bd68ba30c0 releng/13.2-n254651 +- ------------------------------------------------------------------------- + +Run the following command to see which files were modified by a +particular commit: + +# git show --stat + +Or visit the following URL, replacing NNNNNN with the hash: + + + +To determine the commit count in a working tree (for comparison against +nNNNNNN in the table above), run: + +# git rev-list --count --first-parent HEAD + +VII. References + + + + + +The latest revision of this advisory is available at + +-----BEGIN PGP SIGNATURE----- + +iQIzBAEBCgAdFiEEthUnfoEIffdcgYM7bljekB8AGu8FAmWB/ZIACgkQbljekB8A +Gu8exRAA5OqnHpTSa3cPpnfBJNyJsWqD1bry8M8fxt6OpD3b8l/pVnH6HMaUSdQ/ +K4SebhwVJgq4sIfTILWey5X3EKOsp2CpRZb6K+h7iKtrGdDVbXWQj7Dbi5/cCTy6 +hdCSWqFwGJq/FpX15osAa2eEhv9DizE6jmYJ6YwnAfqLvvDSCVbtjeWs6wBJHeH3 +q5jlvdiAT64fhWBpC51MeLShLDG95hJEHAfloVaN0asAs0jYj73XFzcoPv+1Cf8J +qURC5d6KlGYTyaF2ltiQTtssB8I+vhb+GQOyk01t4oyUPnU3myTiooW873xE0321 +as1UeXmzTjuaD/V/5QFawIWbnKOKoVP745llvDyJsF0dLf2Se45vndRH3fP7CdVK +SPy3/u1ohkwNlm11RmeKSm2LbCa4RUwGZ3CqnEQ+dgYa6HBTATP68rWsaL4kIR/b +N30AGeW8xMbhTSFsHYNn3rQ+2RnHCzlSN7eKGfdd9yBVwsRls0ckVVgldmyR26lQ +7eYCbFMAdSCL45qKgYNww8PWSB1ge7AxnlC1MHPAct+kr6TrBwG4b6SAlI7GiDRP +zzqOG2o6k2pEetvn3suLmoMYmmBVZYwzITHUFvyEF1UwF00QCa68xoUW0s2haWnJ +riv7Wewt8m/vUXQ2ad2noElL31hdoRusaKCKVIVOKsCCvwAB/WI= +=RQjY +-----END PGP SIGNATURE----- diff --git a/website/static/security/patches/SA-23:19/openssh.patch b/website/static/security/patches/SA-23:19/openssh.patch new file mode 100644 index 0000000000..4131565ed7 --- /dev/null +++ b/website/static/security/patches/SA-23:19/openssh.patch @@ -0,0 +1,460 @@ +--- crypto/openssh/PROTOCOL.orig ++++ crypto/openssh/PROTOCOL +@@ -137,6 +137,32 @@ + 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" +--- crypto/openssh/kex.c.orig ++++ 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 @@ + 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 @@ + 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 @@ + } + 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 @@ + 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 @@ + prop[i] = xstrdup(defprop[i]); + } + } ++ free(cp); + } + + void +@@ -466,7 +485,12 @@ + { + 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 @@ + 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 @@ + 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 @@ + 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 @@ + 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 @@ + 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 */ +--- crypto/openssh/kex.h.orig ++++ crypto/openssh/kex.h +@@ -149,6 +149,7 @@ + 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; +--- crypto/openssh/packet.c.orig ++++ crypto/openssh/packet.c +@@ -1208,8 +1208,13 @@ + 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 @@ + 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 @@ + /* 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 @@ + 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 @@ + 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 @@ + #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 @@ + 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 @@ + 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 @@ + (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 @@ + (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 @@ + 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 || +--- crypto/openssh/packet.h.orig ++++ crypto/openssh/packet.h +@@ -124,7 +124,6 @@ + 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); +--- crypto/openssh/sshconnect2.c.orig ++++ crypto/openssh/sshconnect2.c +@@ -358,7 +358,6 @@ + }; + + 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->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 @@ + 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 @@ + free(authctxt->methoddata); + authctxt->methoddata = NULL; + authctxt->success = 1; /* break out */ ++ ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, dispatch_protocol_error); + return 0; + } diff --git a/website/static/security/patches/SA-23:19/openssh.patch.asc b/website/static/security/patches/SA-23:19/openssh.patch.asc new file mode 100644 index 0000000000..33c0f2e785 --- /dev/null +++ b/website/static/security/patches/SA-23:19/openssh.patch.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEthUnfoEIffdcgYM7bljekB8AGu8FAmWB/ZcACgkQbljekB8A +Gu9Okg/+ImvzoJbeXz+q/hza0Ehc+mJcGEJ0Xs3WKRcexXXDcfrHTnOQGj4dNiDr +BtL/Sbga5FMWS1JQBFwrUMcYiATL6g3m9Cut5hwGbJ3eQg5ytxyiRamrELxT/eJa +Q9s0fs+tQH3We9FNy33wjexD5slMPtaScoywmkk7CdRf8RJc6Ett4D+qWlfzOrLE +L1HjjrWGyRaw1YVe4pduIA0M8yeaFC1vCIzYaCEd8g/IQwe29NXVaULXBcIXs/kv +LB8A22d75ksGlGx+MDYr6e03KYMEmHF11q9NwaFl4+S3lNIBuwf5naDahQjYwWDg +7cJu7VpPpUduFB+NCHn/WVt9dQ5gST1gW5CN/WolsXcZe8qTLh+ry0rve0sQc5t/ +iWZ6YnrXM5wihyUAzM89jxc9krkS/1tKBKsLWCpgIYBzGrQHJrUT5RYcEQSWMlhc +2vAk7XvWxE3M4zxekUzo3Y71gtNzbdbbV8uOBq2sdHQ2XgMQR0jA6GfdpgfNL33+ +ukP+Zsb3NsQ7tfp2k4YSulihK+aDFervZSFtN81rjetl7w3+hW8g/EuRQDlmaPBl +zju4jh7udz9deo7DpX90VWWVqucQOkGFvgvKs/in668nL6WfqaNCOakonWfU6IZU +xyi0ae6YhXS1P/ZiB0OMs5MHuOSYmoziBbLxP4PSFq1zPkchflk= +=MDwh +-----END PGP SIGNATURE-----