diff options
Diffstat (limited to 'meta/recipes-support/libssh2')
-rw-r--r-- | meta/recipes-support/libssh2/files/0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch | 46 | ||||
-rw-r--r-- | meta/recipes-support/libssh2/files/0001-configure-Conditionally-undefine-backend-m4-macro.patch | 30 | ||||
-rw-r--r-- | meta/recipes-support/libssh2/files/0001-kex.c-move-EC-macro-outside-of-if-check-549-550.patch | 112 | ||||
-rw-r--r-- | meta/recipes-support/libssh2/files/CVE-2019-17498.patch | 131 | ||||
-rw-r--r-- | meta/recipes-support/libssh2/libssh2/CVE-2023-48795.patch | 466 | ||||
-rw-r--r-- | meta/recipes-support/libssh2/libssh2/run-ptest (renamed from meta/recipes-support/libssh2/files/run-ptest) | 2 | ||||
-rw-r--r-- | meta/recipes-support/libssh2/libssh2_1.11.0.bb (renamed from meta/recipes-support/libssh2/libssh2_1.9.0.bb) | 23 |
7 files changed, 478 insertions, 332 deletions
diff --git a/meta/recipes-support/libssh2/files/0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch b/meta/recipes-support/libssh2/files/0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch deleted file mode 100644 index 5ff9bf8462..0000000000 --- a/meta/recipes-support/libssh2/files/0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch +++ /dev/null @@ -1,46 +0,0 @@ -From f9e3e2ee7b18ba5bb8efe083171f3e701eb0a663 Mon Sep 17 00:00:00 2001 -From: Your Name <you@example.com> -Date: Mon, 28 Dec 2020 02:08:03 +0000 -Subject: [PATCH] Don't let host enviroment to decide if a test is build - -test ssh2.sh need sshd, for cross compile, we need it on target, so -don't use SSHD on host to decide weither to build a test - -Upstream-Status: Inappropriate[oe specific] - -Signed-off-by: Changqing Li <changqing.li@windriver.com> ---- - tests/Makefile.am | 6 +----- - 1 file changed, 1 insertion(+), 5 deletions(-) - -diff --git a/tests/Makefile.am b/tests/Makefile.am -index dc0922f..6cbc35d 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -1,16 +1,12 @@ - AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include -I$(top_builddir)/src - LDADD = ../src/libssh2.la - --if SSHD - noinst_PROGRAMS = ssh2 - ssh2_SOURCES = ssh2.c --endif - - ctests = simple$(EXEEXT) - TESTS = $(ctests) mansyntax.sh --if SSHD - TESTS += ssh2.sh --endif - check_PROGRAMS = $(ctests) - - TESTS_ENVIRONMENT = SSHD=$(SSHD) EXEEXT=$(EXEEXT) -@@ -38,4 +34,4 @@ if OPENSSL - # EXTRA_DIST += test_public_key_auth_succeeds_with_correct_encrypted_ed25519_key.c - # EXTRA_DIST += test_public_key_auth_succeeds_with_correct_ed25519_key_from_mem.c - EXTRA_DIST += test_public_key_auth_succeeds_with_correct_rsa_openssh_key.c --endif -\ No newline at end of file -+endif --- -2.20.1 - diff --git a/meta/recipes-support/libssh2/files/0001-configure-Conditionally-undefine-backend-m4-macro.patch b/meta/recipes-support/libssh2/files/0001-configure-Conditionally-undefine-backend-m4-macro.patch deleted file mode 100644 index 1128c7ea0c..0000000000 --- a/meta/recipes-support/libssh2/files/0001-configure-Conditionally-undefine-backend-m4-macro.patch +++ /dev/null @@ -1,30 +0,0 @@ -From efe7101786193eaddb749c0583af6b54aec6f289 Mon Sep 17 00:00:00 2001 -From: Khem Raj <raj.khem@gmail.com> -Date: Tue, 2 Feb 2021 18:45:16 -0800 -Subject: [PATCH] configure: Conditionally undefine backend m4 macro - -Unlike the M4 builtin, this macro fails if macro is not defined -therefore recover the behavior of the builtin. - -Upstream-Status: Pending -Signed-off-by: Khem Raj <raj.khem@gmail.com> ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index fe5054a..758f8c2 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -127,7 +127,7 @@ fi - m4_set_foreach([crypto_backends], [backend], - [AM_CONDITIONAL(m4_toupper(backend), test "$found_crypto" = "backend")] - ) --m4_undefine([backend]) -+m4_ifdef([backend], [m4_undefine([backend])]) - - - # libz --- -2.30.0 - diff --git a/meta/recipes-support/libssh2/files/0001-kex.c-move-EC-macro-outside-of-if-check-549-550.patch b/meta/recipes-support/libssh2/files/0001-kex.c-move-EC-macro-outside-of-if-check-549-550.patch deleted file mode 100644 index b331c1bf81..0000000000 --- a/meta/recipes-support/libssh2/files/0001-kex.c-move-EC-macro-outside-of-if-check-549-550.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 1f76151c92e1b52e9c24ebf06adc77fbd6c062bc Mon Sep 17 00:00:00 2001 -From: Will Cosgrove <will@panic.com> -Date: Tue, 26 Jan 2021 11:41:21 -0800 -Subject: [PATCH] kex.c: move EC macro outside of if check #549 (#550) - -File: kex.c - -Notes: -Moved the macro LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY outside of the LIBSSH2_ECDSA since it's also now used by the ED25519 code. - -Sha 256, 384 and 512 need to be defined for all backends now even if they aren't used directly. I believe this is already the case, but just a heads up. - -Credit: -Stefan-Ghinea - -Upstream-Status: Backport - -Reference to upstream patch: -https://github.com/libssh2/libssh2/commit/1f76151c92e1b52e9c24ebf06adc77fbd6c062bc - -Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com> ---- - src/kex.c | 66 +++++++++++++++++++++++++++---------------------------- - 1 file changed, 33 insertions(+), 33 deletions(-) - -diff --git a/src/kex.c b/src/kex.c -index cb16639..19ab6ec 100644 ---- a/src/kex.c -+++ b/src/kex.c -@@ -1885,39 +1885,6 @@ kex_method_diffie_hellman_group_exchange_sha256_key_exchange - } - - --#if LIBSSH2_ECDSA -- --/* kex_session_ecdh_curve_type -- * returns the EC curve type by name used in key exchange -- */ -- --static int --kex_session_ecdh_curve_type(const char *name, libssh2_curve_type *out_type) --{ -- int ret = 0; -- libssh2_curve_type type; -- -- if(name == NULL) -- return -1; -- -- if(strcmp(name, "ecdh-sha2-nistp256") == 0) -- type = LIBSSH2_EC_CURVE_NISTP256; -- else if(strcmp(name, "ecdh-sha2-nistp384") == 0) -- type = LIBSSH2_EC_CURVE_NISTP384; -- else if(strcmp(name, "ecdh-sha2-nistp521") == 0) -- type = LIBSSH2_EC_CURVE_NISTP521; -- else { -- ret = -1; -- } -- -- if(ret == 0 && out_type) { -- *out_type = type; -- } -- -- return ret; --} -- -- - /* LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY - * - * Macro that create and verifies EC SHA hash with a given digest bytes -@@ -2027,6 +1994,39 @@ kex_session_ecdh_curve_type(const char *name, libssh2_curve_type *out_type) - } \ - - -+#if LIBSSH2_ECDSA -+ -+/* kex_session_ecdh_curve_type -+ * returns the EC curve type by name used in key exchange -+ */ -+ -+static int -+kex_session_ecdh_curve_type(const char *name, libssh2_curve_type *out_type) -+{ -+ int ret = 0; -+ libssh2_curve_type type; -+ -+ if(name == NULL) -+ return -1; -+ -+ if(strcmp(name, "ecdh-sha2-nistp256") == 0) -+ type = LIBSSH2_EC_CURVE_NISTP256; -+ else if(strcmp(name, "ecdh-sha2-nistp384") == 0) -+ type = LIBSSH2_EC_CURVE_NISTP384; -+ else if(strcmp(name, "ecdh-sha2-nistp521") == 0) -+ type = LIBSSH2_EC_CURVE_NISTP521; -+ else { -+ ret = -1; -+ } -+ -+ if(ret == 0 && out_type) { -+ *out_type = type; -+ } -+ -+ return ret; -+} -+ -+ - /* ecdh_sha2_nistp - * Elliptic Curve Diffie Hellman Key Exchange - */ --- -2.17.1 - diff --git a/meta/recipes-support/libssh2/files/CVE-2019-17498.patch b/meta/recipes-support/libssh2/files/CVE-2019-17498.patch deleted file mode 100644 index 001080072b..0000000000 --- a/meta/recipes-support/libssh2/files/CVE-2019-17498.patch +++ /dev/null @@ -1,131 +0,0 @@ -From dedcbd106f8e52d5586b0205bc7677e4c9868f9c Mon Sep 17 00:00:00 2001 -From: Will Cosgrove <will@panic.com> -Date: Fri, 30 Aug 2019 09:57:38 -0700 -Subject: [PATCH] packet.c: improve message parsing (#402) - -* packet.c: improve parsing of packets - -file: packet.c - -notes: -Use _libssh2_get_string API in SSH_MSG_DEBUG/SSH_MSG_DISCONNECT. Additional uint32 bounds check in SSH_MSG_GLOBAL_REQUEST. - -Upstream-Status: Backport -CVE: CVE-2019-17498 -Signed-off-by: Li Zhou <li.zhou@windriver.com> ---- - src/packet.c | 68 ++++++++++++++++++++++------------------------------ - 1 file changed, 29 insertions(+), 39 deletions(-) - -diff --git a/src/packet.c b/src/packet.c -index 38ab629..2e01bfc 100644 ---- a/src/packet.c -+++ b/src/packet.c -@@ -419,8 +419,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, - size_t datalen, int macstate) - { - int rc = 0; -- char *message = NULL; -- char *language = NULL; -+ unsigned char *message = NULL; -+ unsigned char *language = NULL; - size_t message_len = 0; - size_t language_len = 0; - LIBSSH2_CHANNEL *channelp = NULL; -@@ -472,33 +472,23 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, - - case SSH_MSG_DISCONNECT: - if(datalen >= 5) { -- size_t reason = _libssh2_ntohu32(data + 1); -+ uint32_t reason = 0; -+ struct string_buf buf; -+ buf.data = (unsigned char *)data; -+ buf.dataptr = buf.data; -+ buf.len = datalen; -+ buf.dataptr++; /* advance past type */ - -- if(datalen >= 9) { -- message_len = _libssh2_ntohu32(data + 5); -+ _libssh2_get_u32(&buf, &reason); -+ _libssh2_get_string(&buf, &message, &message_len); -+ _libssh2_get_string(&buf, &language, &language_len); - -- if(message_len < datalen-13) { -- /* 9 = packet_type(1) + reason(4) + message_len(4) */ -- message = (char *) data + 9; -- -- language_len = -- _libssh2_ntohu32(data + 9 + message_len); -- language = (char *) data + 9 + message_len + 4; -- -- if(language_len > (datalen-13-message_len)) { -- /* bad input, clear info */ -- language = message = NULL; -- language_len = message_len = 0; -- } -- } -- else -- /* bad size, clear it */ -- message_len = 0; -- } - if(session->ssh_msg_disconnect) { -- LIBSSH2_DISCONNECT(session, reason, message, -- message_len, language, language_len); -+ LIBSSH2_DISCONNECT(session, reason, (const char *)message, -+ message_len, (const char *)language, -+ language_len); - } -+ - _libssh2_debug(session, LIBSSH2_TRACE_TRANS, - "Disconnect(%d): %s(%s)", reason, - message, language); -@@ -539,24 +529,24 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, - int always_display = data[1]; - - if(datalen >= 6) { -- message_len = _libssh2_ntohu32(data + 2); -- -- if(message_len <= (datalen - 10)) { -- /* 6 = packet_type(1) + display(1) + message_len(4) */ -- message = (char *) data + 6; -- language_len = _libssh2_ntohu32(data + 6 + -- message_len); -- -- if(language_len <= (datalen - 10 - message_len)) -- language = (char *) data + 10 + message_len; -- } -+ struct string_buf buf; -+ buf.data = (unsigned char *)data; -+ buf.dataptr = buf.data; -+ buf.len = datalen; -+ buf.dataptr += 2; /* advance past type & always display */ -+ -+ _libssh2_get_string(&buf, &message, &message_len); -+ _libssh2_get_string(&buf, &language, &language_len); - } - - if(session->ssh_msg_debug) { -- LIBSSH2_DEBUG(session, always_display, message, -- message_len, language, language_len); -+ LIBSSH2_DEBUG(session, always_display, -+ (const char *)message, -+ message_len, (const char *)language, -+ language_len); - } - } -+ - /* - * _libssh2_debug will actually truncate this for us so - * that it's not an inordinate about of data -@@ -579,7 +569,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, - uint32_t len = 0; - unsigned char want_reply = 0; - len = _libssh2_ntohu32(data + 1); -- if(datalen >= (6 + len)) { -+ if((len <= (UINT_MAX - 6)) && (datalen >= (6 + len))) { - want_reply = data[5 + len]; - _libssh2_debug(session, - LIBSSH2_TRACE_CONN, --- -2.17.1 - diff --git a/meta/recipes-support/libssh2/libssh2/CVE-2023-48795.patch b/meta/recipes-support/libssh2/libssh2/CVE-2023-48795.patch new file mode 100644 index 0000000000..ab0f419ac5 --- /dev/null +++ b/meta/recipes-support/libssh2/libssh2/CVE-2023-48795.patch @@ -0,0 +1,466 @@ +From d4634630432594b139b3af6b9f254b890c0f275d Mon Sep 17 00:00:00 2001 +From: Michael Buckley <michael@buckleyisms.com> +Date: Thu, 30 Nov 2023 15:08:02 -0800 +Subject: [PATCH] src: add 'strict KEX' to fix CVE-2023-48795 "Terrapin Attack" + +Refs: +https://terrapin-attack.com/ +https://seclists.org/oss-sec/2023/q4/292 +https://osv.dev/list?ecosystem=&q=CVE-2023-48795 +https://github.com/advisories/GHSA-45x7-px36-x8w8 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-48795 + +Fixes #1290 +Closes #1291 + +CVE: CVE-2023-48795 +Upstream-Status: Backport +Signed-off-by: Ross Burton <ross.burton@arm.com> +--- + src/kex.c | 63 +++++++++++++++++++++++------------ + src/libssh2_priv.h | 18 +++++++--- + src/packet.c | 83 +++++++++++++++++++++++++++++++++++++++++++--- + src/packet.h | 2 +- + src/session.c | 3 ++ + src/transport.c | 12 ++++++- + 6 files changed, 149 insertions(+), 32 deletions(-) + +diff --git a/src/kex.c b/src/kex.c +index d4034a0a..b4b748ca 100644 +--- a/src/kex.c ++++ b/src/kex.c +@@ -3037,6 +3037,13 @@ kex_method_extension_negotiation = { + 0, + }; + ++static const LIBSSH2_KEX_METHOD ++kex_method_strict_client_extension = { ++ "kex-strict-c-v00@openssh.com", ++ NULL, ++ 0, ++}; ++ + static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = { + #if LIBSSH2_ED25519 + &kex_method_ssh_curve25519_sha256, +@@ -3055,6 +3062,7 @@ static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = { + &kex_method_diffie_helman_group1_sha1, + &kex_method_diffie_helman_group_exchange_sha1, + &kex_method_extension_negotiation, ++ &kex_method_strict_client_extension, + NULL + }; + +@@ -3307,13 +3315,13 @@ static int kexinit(LIBSSH2_SESSION * session) + return 0; + } + +-/* kex_agree_instr ++/* _libssh2_kex_agree_instr + * Kex specific variant of strstr() + * Needle must be preceded by BOL or ',', and followed by ',' or EOL + */ +-static unsigned char * +-kex_agree_instr(unsigned char *haystack, size_t haystack_len, +- const unsigned char *needle, size_t needle_len) ++unsigned char * ++_libssh2_kex_agree_instr(unsigned char *haystack, size_t haystack_len, ++ const unsigned char *needle, size_t needle_len) + { + unsigned char *s; + unsigned char *end_haystack; +@@ -3398,7 +3406,7 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session, + while(s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); +- if(kex_agree_instr(hostkey, hostkey_len, s, method_len)) { ++ if(_libssh2_kex_agree_instr(hostkey, hostkey_len, s, method_len)) { + const LIBSSH2_HOSTKEY_METHOD *method = + (const LIBSSH2_HOSTKEY_METHOD *) + kex_get_method_by_name((char *) s, method_len, +@@ -3432,9 +3440,9 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session, + } + + while(hostkeyp && (*hostkeyp) && (*hostkeyp)->name) { +- s = kex_agree_instr(hostkey, hostkey_len, +- (unsigned char *) (*hostkeyp)->name, +- strlen((*hostkeyp)->name)); ++ s = _libssh2_kex_agree_instr(hostkey, hostkey_len, ++ (unsigned char *) (*hostkeyp)->name, ++ strlen((*hostkeyp)->name)); + if(s) { + /* So far so good, but does it suit our purposes? (Encrypting vs + Signing) */ +@@ -3468,6 +3476,12 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex, + { + const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods; + unsigned char *s; ++ const unsigned char *strict = ++ (unsigned char *)"kex-strict-s-v00@openssh.com"; ++ ++ if(_libssh2_kex_agree_instr(kex, kex_len, strict, 28)) { ++ session->kex_strict = 1; ++ } + + if(session->kex_prefs) { + s = (unsigned char *) session->kex_prefs; +@@ -3475,7 +3489,7 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex, + while(s && *s) { + unsigned char *q, *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); +- q = kex_agree_instr(kex, kex_len, s, method_len); ++ q = _libssh2_kex_agree_instr(kex, kex_len, s, method_len); + if(q) { + const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *) + kex_get_method_by_name((char *) s, method_len, +@@ -3509,9 +3523,9 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex, + } + + while(*kexp && (*kexp)->name) { +- s = kex_agree_instr(kex, kex_len, +- (unsigned char *) (*kexp)->name, +- strlen((*kexp)->name)); ++ s = _libssh2_kex_agree_instr(kex, kex_len, ++ (unsigned char *) (*kexp)->name, ++ strlen((*kexp)->name)); + if(s) { + /* We've agreed on a key exchange method, + * Can we agree on a hostkey that works with this kex? +@@ -3555,7 +3569,7 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session, + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + +- if(kex_agree_instr(crypt, crypt_len, s, method_len)) { ++ if(_libssh2_kex_agree_instr(crypt, crypt_len, s, method_len)) { + const LIBSSH2_CRYPT_METHOD *method = + (const LIBSSH2_CRYPT_METHOD *) + kex_get_method_by_name((char *) s, method_len, +@@ -3577,9 +3591,9 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session, + } + + while(*cryptp && (*cryptp)->name) { +- s = kex_agree_instr(crypt, crypt_len, +- (unsigned char *) (*cryptp)->name, +- strlen((*cryptp)->name)); ++ s = _libssh2_kex_agree_instr(crypt, crypt_len, ++ (unsigned char *) (*cryptp)->name, ++ strlen((*cryptp)->name)); + if(s) { + endpoint->crypt = *cryptp; + return 0; +@@ -3619,7 +3633,7 @@ static int kex_agree_mac(LIBSSH2_SESSION * session, + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + +- if(kex_agree_instr(mac, mac_len, s, method_len)) { ++ if(_libssh2_kex_agree_instr(mac, mac_len, s, method_len)) { + const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) +@@ -3640,8 +3654,9 @@ static int kex_agree_mac(LIBSSH2_SESSION * session, + } + + while(*macp && (*macp)->name) { +- s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name, +- strlen((*macp)->name)); ++ s = _libssh2_kex_agree_instr(mac, mac_len, ++ (unsigned char *) (*macp)->name, ++ strlen((*macp)->name)); + if(s) { + endpoint->mac = *macp; + return 0; +@@ -3672,7 +3687,7 @@ static int kex_agree_comp(LIBSSH2_SESSION *session, + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + +- if(kex_agree_instr(comp, comp_len, s, method_len)) { ++ if(_libssh2_kex_agree_instr(comp, comp_len, s, method_len)) { + const LIBSSH2_COMP_METHOD *method = + (const LIBSSH2_COMP_METHOD *) + kex_get_method_by_name((char *) s, method_len, +@@ -3694,8 +3709,9 @@ static int kex_agree_comp(LIBSSH2_SESSION *session, + } + + while(*compp && (*compp)->name) { +- s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name, +- strlen((*compp)->name)); ++ s = _libssh2_kex_agree_instr(comp, comp_len, ++ (unsigned char *) (*compp)->name, ++ strlen((*compp)->name)); + if(s) { + endpoint->comp = *compp; + return 0; +@@ -3876,6 +3892,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + session->local.kexinit = key_state->oldlocal; + session->local.kexinit_len = key_state->oldlocal_len; + key_state->state = libssh2_NB_state_idle; ++ session->state &= ~LIBSSH2_STATE_INITIAL_KEX; + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + return -1; +@@ -3901,6 +3918,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + session->local.kexinit = key_state->oldlocal; + session->local.kexinit_len = key_state->oldlocal_len; + key_state->state = libssh2_NB_state_idle; ++ session->state &= ~LIBSSH2_STATE_INITIAL_KEX; + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + return -1; +@@ -3949,6 +3967,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + session->remote.kexinit = NULL; + } + ++ session->state &= ~LIBSSH2_STATE_INITIAL_KEX; + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + +diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h +index 82c3afe2..ee1d8b5c 100644 +--- a/src/libssh2_priv.h ++++ b/src/libssh2_priv.h +@@ -699,6 +699,9 @@ struct _LIBSSH2_SESSION + /* key signing algorithm preferences -- NULL yields server order */ + char *sign_algo_prefs; + ++ /* Whether to use the OpenSSH Strict KEX extension */ ++ int kex_strict; ++ + /* (remote as source of data -- packet_read ) */ + libssh2_endpoint_data remote; + +@@ -870,6 +873,7 @@ struct _LIBSSH2_SESSION + int fullpacket_macstate; + size_t fullpacket_payload_len; + int fullpacket_packet_type; ++ uint32_t fullpacket_required_type; + + /* State variables used in libssh2_sftp_init() */ + libssh2_nonblocking_states sftpInit_state; +@@ -910,10 +914,11 @@ struct _LIBSSH2_SESSION + }; + + /* session.state bits */ +-#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001 +-#define LIBSSH2_STATE_NEWKEYS 0x00000002 +-#define LIBSSH2_STATE_AUTHENTICATED 0x00000004 +-#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008 ++#define LIBSSH2_STATE_INITIAL_KEX 0x00000001 ++#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000002 ++#define LIBSSH2_STATE_NEWKEYS 0x00000004 ++#define LIBSSH2_STATE_AUTHENTICATED 0x00000008 ++#define LIBSSH2_STATE_KEX_ACTIVE 0x00000010 + + /* session.flag helpers */ + #ifdef MSG_NOSIGNAL +@@ -1144,6 +1149,11 @@ ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, + int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + key_exchange_state_t * state); + ++unsigned char *_libssh2_kex_agree_instr(unsigned char *haystack, ++ size_t haystack_len, ++ const unsigned char *needle, ++ size_t needle_len); ++ + /* Let crypt.c/hostkey.c expose their method structs */ + const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void); + const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void); +diff --git a/src/packet.c b/src/packet.c +index b5b41981..35d4d39e 100644 +--- a/src/packet.c ++++ b/src/packet.c +@@ -605,14 +605,13 @@ authagent_exit: + * layer when it has received a packet. + * + * The input pointer 'data' is pointing to allocated data that this function +- * is asked to deal with so on failure OR success, it must be freed fine. +- * The only exception is when the return code is LIBSSH2_ERROR_EAGAIN. ++ * will be freed unless return the code is LIBSSH2_ERROR_EAGAIN. + * + * This function will always be called with 'datalen' greater than zero. + */ + int + _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, +- size_t datalen, int macstate) ++ size_t datalen, int macstate, uint32_t seq) + { + int rc = 0; + unsigned char *message = NULL; +@@ -657,6 +656,70 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, + break; + } + ++ if(session->state & LIBSSH2_STATE_INITIAL_KEX) { ++ if(msg == SSH_MSG_KEXINIT) { ++ if(!session->kex_strict) { ++ if(datalen < 17) { ++ LIBSSH2_FREE(session, data); ++ session->packAdd_state = libssh2_NB_state_idle; ++ return _libssh2_error(session, ++ LIBSSH2_ERROR_BUFFER_TOO_SMALL, ++ "Data too short extracting kex"); ++ } ++ else { ++ const unsigned char *strict = ++ (unsigned char *)"kex-strict-s-v00@openssh.com"; ++ struct string_buf buf; ++ unsigned char *algs = NULL; ++ size_t algs_len = 0; ++ ++ buf.data = (unsigned char *)data; ++ buf.dataptr = buf.data; ++ buf.len = datalen; ++ buf.dataptr += 17; /* advance past type and cookie */ ++ ++ if(_libssh2_get_string(&buf, &algs, &algs_len)) { ++ LIBSSH2_FREE(session, data); ++ session->packAdd_state = libssh2_NB_state_idle; ++ return _libssh2_error(session, ++ LIBSSH2_ERROR_BUFFER_TOO_SMALL, ++ "Algs too short"); ++ } ++ ++ if(algs_len == 0 || ++ _libssh2_kex_agree_instr(algs, algs_len, strict, 28)) { ++ session->kex_strict = 1; ++ } ++ } ++ } ++ ++ if(session->kex_strict && seq) { ++ LIBSSH2_FREE(session, data); ++ session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; ++ session->packAdd_state = libssh2_NB_state_idle; ++ libssh2_session_disconnect(session, "strict KEX violation: " ++ "KEXINIT was not the first packet"); ++ ++ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT, ++ "strict KEX violation: " ++ "KEXINIT was not the first packet"); ++ } ++ } ++ ++ if(session->kex_strict && session->fullpacket_required_type && ++ session->fullpacket_required_type != msg) { ++ LIBSSH2_FREE(session, data); ++ session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; ++ session->packAdd_state = libssh2_NB_state_idle; ++ libssh2_session_disconnect(session, "strict KEX violation: " ++ "unexpected packet type"); ++ ++ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT, ++ "strict KEX violation: " ++ "unexpected packet type"); ++ } ++ } ++ + if(session->packAdd_state == libssh2_NB_state_allocated) { + /* A couple exceptions to the packet adding rule: */ + switch(msg) { +@@ -1341,6 +1404,15 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type, + + return 0; + } ++ else if(session->kex_strict && ++ (session->state & LIBSSH2_STATE_INITIAL_KEX)) { ++ libssh2_session_disconnect(session, "strict KEX violation: " ++ "unexpected packet type"); ++ ++ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT, ++ "strict KEX violation: " ++ "unexpected packet type"); ++ } + packet = _libssh2_list_next(&packet->node); + } + return -1; +@@ -1402,7 +1474,10 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type, + } + + while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) { +- int ret = _libssh2_transport_read(session); ++ int ret; ++ session->fullpacket_required_type = packet_type; ++ ret = _libssh2_transport_read(session); ++ session->fullpacket_required_type = 0; + if(ret == LIBSSH2_ERROR_EAGAIN) + return ret; + else if(ret < 0) { +diff --git a/src/packet.h b/src/packet.h +index 79018bcf..6ea100a5 100644 +--- a/src/packet.h ++++ b/src/packet.h +@@ -71,6 +71,6 @@ int _libssh2_packet_burn(LIBSSH2_SESSION * session, + int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long data_len); + int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, +- size_t datalen, int macstate); ++ size_t datalen, int macstate, uint32_t seq); + + #endif /* __LIBSSH2_PACKET_H */ +diff --git a/src/session.c b/src/session.c +index a4d602ba..f4bafb57 100644 +--- a/src/session.c ++++ b/src/session.c +@@ -464,6 +464,8 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), + session->abstract = abstract; + session->api_timeout = 0; /* timeout-free API by default */ + session->api_block_mode = 1; /* blocking API by default */ ++ session->state = LIBSSH2_STATE_INITIAL_KEX; ++ session->fullpacket_required_type = 0; + session->packet_read_timeout = LIBSSH2_DEFAULT_READ_TIMEOUT; + session->flag.quote_paths = 1; /* default behavior is to quote paths + for the scp subsystem */ +@@ -1186,6 +1188,7 @@ libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, + const char *desc, const char *lang) + { + int rc; ++ session->state &= ~LIBSSH2_STATE_INITIAL_KEX; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + BLOCK_ADJUST(rc, session, + session_disconnect(session, reason, desc, lang)); +diff --git a/src/transport.c b/src/transport.c +index 6d902d33..3b30ff84 100644 +--- a/src/transport.c ++++ b/src/transport.c +@@ -187,6 +187,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) + struct transportpacket *p = &session->packet; + int rc; + int compressed; ++ uint32_t seq = session->remote.seqno; + + if(session->fullpacket_state == libssh2_NB_state_idle) { + session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; +@@ -318,7 +319,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) + if(session->fullpacket_state == libssh2_NB_state_created) { + rc = _libssh2_packet_add(session, p->payload, + session->fullpacket_payload_len, +- session->fullpacket_macstate); ++ session->fullpacket_macstate, seq); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + if(rc) { +@@ -329,6 +330,11 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) + + session->fullpacket_state = libssh2_NB_state_idle; + ++ if(session->kex_strict && ++ session->fullpacket_packet_type == SSH_MSG_NEWKEYS) { ++ session->remote.seqno = 0; ++ } ++ + return session->fullpacket_packet_type; + } + +@@ -1091,6 +1097,10 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session, + + session->local.seqno++; + ++ if(session->kex_strict && data[0] == SSH_MSG_NEWKEYS) { ++ session->local.seqno = 0; ++ } ++ + ret = LIBSSH2_SEND(session, p->outbuf, total_length, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if(ret < 0) +-- +2.34.1 + diff --git a/meta/recipes-support/libssh2/files/run-ptest b/meta/recipes-support/libssh2/libssh2/run-ptest index 5fd7ec65f6..0f5526e316 100644 --- a/meta/recipes-support/libssh2/files/run-ptest +++ b/meta/recipes-support/libssh2/libssh2/run-ptest @@ -2,7 +2,7 @@ ptestdir=$(dirname "$(readlink -f "$0")") cd tests -for test in simple ssh2.sh mansyntax.sh +for test in mansyntax.sh test_simple test_sshd.test do ./../test-driver --test-name $test --log-file ../$test.log --trs-file ../$test.trs --color-tests no --enable-hard-errors yes --expect-failure no -- ./$test done diff --git a/meta/recipes-support/libssh2/libssh2_1.9.0.bb b/meta/recipes-support/libssh2/libssh2_1.11.0.bb index 9ae736d25a..5100e6f7f9 100644 --- a/meta/recipes-support/libssh2/libssh2_1.9.0.bb +++ b/meta/recipes-support/libssh2/libssh2_1.11.0.bb @@ -5,26 +5,23 @@ SECTION = "libs" DEPENDS = "zlib" LICENSE = "BSD-3-Clause" -LIC_FILES_CHKSUM = "file://COPYING;md5=c5cf34fc0acb44b082ef50ef5e4354ca" +LIC_FILES_CHKSUM = "file://COPYING;md5=24a33237426720395ebb1dd1349ca225" SRC_URI = "http://www.libssh2.org/download/${BP}.tar.gz \ - file://CVE-2019-17498.patch \ - file://0001-configure-Conditionally-undefine-backend-m4-macro.patch \ file://run-ptest \ - file://0001-kex.c-move-EC-macro-outside-of-if-check-549-550.patch \ -" + file://CVE-2023-48795.patch \ + " -SRC_URI:append_ptest = " file://0001-Don-t-let-host-enviroment-to-decide-if-a-test-is-bui.patch" - -SRC_URI[md5sum] = "1beefafe8963982adc84b408b2959927" -SRC_URI[sha256sum] = "d5fb8bd563305fd1074dda90bd053fb2d29fc4bce048d182f96eaa466dfadafd" +SRC_URI[sha256sum] = "3736161e41e2693324deb38c26cfdc3efe6209d634ba4258db1cecff6a5ad461" inherit autotools pkgconfig ptest EXTRA_OECONF += "\ --with-libz \ --with-libz-prefix=${STAGING_LIBDIR} \ + --disable-rpath \ " +DISABLE_STATIC = "" # only one of openssl and gcrypt could be set PACKAGECONFIG ??= "openssl" @@ -34,7 +31,7 @@ PACKAGECONFIG[gcrypt] = "--with-crypto=libgcrypt --with-libgcrypt-prefix=${STAGI BBCLASSEXTEND = "native nativesdk" # required for ptest on documentation -RDEPENDS:${PN}-ptest = "man-db openssh util-linux-col" +RDEPENDS:${PN}-ptest = "bash man-db openssh util-linux-col" RDEPENDS:${PN}-ptest:append:libc-glibc = " locale-base-en-us" do_compile_ptest() { @@ -46,9 +43,11 @@ do_install_ptest() { install -d ${D}${PTEST_PATH}/tests install -m 0755 ${S}/test-driver ${D}${PTEST_PATH}/ cp -rf ${B}/tests/.libs/* ${D}${PTEST_PATH}/tests/ + cp -rf ${B}/tests/test_simple ${D}${PTEST_PATH}/tests/ cp -rf ${S}/tests/mansyntax.sh ${D}${PTEST_PATH}/tests/ - cp -rf ${S}/tests/ssh2.sh ${D}${PTEST_PATH}/tests/ - cp -rf ${S}/tests/etc ${D}${PTEST_PATH}/tests/ + cp -rf ${S}/tests/key* ${D}${PTEST_PATH}/tests/ + cp -rf ${S}/tests/openssh_server/ ${D}${PTEST_PATH}/tests/ + cp -rf ${S}/tests/*.test ${D}${PTEST_PATH}/tests/ mkdir -p ${D}${PTEST_PATH}/docs cp -r ${S}/docs/* ${D}${PTEST_PATH}/docs/ } |