Compare commits
No commits in common. "factory" and "factory" have entirely different histories.
BIN
libssh2-1.11.0.tar.xz
(Stored with Git LFS)
Normal file
BIN
libssh2-1.11.0.tar.xz
(Stored with Git LFS)
Normal file
Binary file not shown.
11
libssh2-1.11.0.tar.xz.asc
Normal file
11
libssh2-1.11.0.tar.xz.asc
Normal file
@ -0,0 +1,11 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQEzBAABCgAdFiEEJ+3q8i86vOtQ25oSXMkI/bceEsIFAmR2HWEACgkQXMkI/bce
|
||||
EsIBgwf/ZExq9GsrLaX3eFiOe6/qjcixscNfP2TfBn/b9miKzmTCEle9H/wLUaeI
|
||||
VVB/Zs9pNAlROJ+QEGQKfBb5fzGJm9nifWsuZ+Y65s8JGUzI3Y3cKdsyYTV8Myaj
|
||||
1IvMR/oQoPjW8bd0a3SsKRLdWhN/9/Q4fiEjSs2Zp1OuCaLnLebyPgXx8f3BpXKQ
|
||||
YfLYUslRgKGND+VULfUki1i8mvF4ledhanf1nTRxwfK5HrXWLT/Yd+lVRKTZgWl+
|
||||
2YqXvGU9pI9N7GSVfHttYEbqP8hd8ncxea46bSaSauc4e5Sn9lYAvo2Wri33zPLw
|
||||
MwI17cyi7s1H0CuIc2cT4L8BUYg3vw==
|
||||
=eRz/
|
||||
-----END PGP SIGNATURE-----
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9954cb54c4f548198a7cbebad248bdc87dd64bd26185708a294b2b50771e3769
|
||||
size 721700
|
@ -1,11 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQEzBAABCgAdFiEEJ+3q8i86vOtQ25oSXMkI/bceEsIFAmcPc1kACgkQXMkI/bce
|
||||
EsKxdgf+LjRlDPkkUP5kKPRKHvS9saip8NO/O/Ewv1x5+mllYb1wUxSJyqpEb4po
|
||||
0ao0+9hT5OkKQIbWhWnw/UDPflB7LM/gau8zFDyw7Eb8xAXc+TqgD+mMpeAowAyf
|
||||
pSDZP8QvJ+zBa/EUMtoO+HnqVYDCZMvtMHkabNybo4ZWalBHnUssev1y5Qibwkz2
|
||||
ZhAKkfduAXvXOcZhg9381EV+9/IlypE7JCsDKZxOZbYsxmi0IG6z909lkJay419G
|
||||
EGEGTz2GwHp0I+DujjrFmt/30+1l6wYAVZI47J1J9zJ3sxJhzyvrzqeENaG4EDhG
|
||||
+s+Z61taJ5JCykScTozVFq9spM+rKw==
|
||||
=jToS
|
||||
-----END PGP SIGNATURE-----
|
@ -9,11 +9,11 @@ Subject: [PATCH] Use O_CLOEXEC where needed
|
||||
src/userauth.c | 2 +-
|
||||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
Index: libssh2-1.11.1/src/agent.c
|
||||
Index: libssh2-1.11.0/src/agent.c
|
||||
===================================================================
|
||||
--- libssh2-1.11.1.orig/src/agent.c
|
||||
+++ libssh2-1.11.1/src/agent.c
|
||||
@@ -183,7 +183,7 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
|
||||
--- libssh2-1.11.0.orig/src/agent.c
|
||||
+++ libssh2-1.11.0/src/agent.c
|
||||
@@ -177,7 +177,7 @@ agent_connect_unix(LIBSSH2_AGENT *agent)
|
||||
"no auth sock variable");
|
||||
}
|
||||
|
||||
@ -22,11 +22,11 @@ Index: libssh2-1.11.1/src/agent.c
|
||||
if(agent->fd < 0)
|
||||
return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_SOCKET,
|
||||
"failed creating socket");
|
||||
Index: libssh2-1.11.1/src/knownhost.c
|
||||
Index: libssh2-1.11.0/src/knownhost.c
|
||||
===================================================================
|
||||
--- libssh2-1.11.1.orig/src/knownhost.c
|
||||
+++ libssh2-1.11.1/src/knownhost.c
|
||||
@@ -970,7 +970,7 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWN
|
||||
--- libssh2-1.11.0.orig/src/knownhost.c
|
||||
+++ libssh2-1.11.0/src/knownhost.c
|
||||
@@ -962,7 +962,7 @@ libssh2_knownhost_readfile(LIBSSH2_KNOWN
|
||||
"Unsupported type of known-host information "
|
||||
"store");
|
||||
|
||||
@ -35,7 +35,7 @@ Index: libssh2-1.11.1/src/knownhost.c
|
||||
if(file) {
|
||||
while(fgets(buf, sizeof(buf), file)) {
|
||||
if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type)) {
|
||||
@@ -1213,7 +1213,7 @@ libssh2_knownhost_writefile(LIBSSH2_KNOW
|
||||
@@ -1203,7 +1203,7 @@ libssh2_knownhost_writefile(LIBSSH2_KNOW
|
||||
"Unsupported type of known-host information "
|
||||
"store");
|
||||
|
||||
@ -44,11 +44,11 @@ Index: libssh2-1.11.1/src/knownhost.c
|
||||
if(!file)
|
||||
return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE,
|
||||
"Failed to open file");
|
||||
Index: libssh2-1.11.1/src/userauth.c
|
||||
Index: libssh2-1.11.0/src/userauth.c
|
||||
===================================================================
|
||||
--- libssh2-1.11.1.orig/src/userauth.c
|
||||
+++ libssh2-1.11.1/src/userauth.c
|
||||
@@ -658,7 +658,7 @@ file_read_publickey(LIBSSH2_SESSION * se
|
||||
--- libssh2-1.11.0.orig/src/userauth.c
|
||||
+++ libssh2-1.11.0/src/userauth.c
|
||||
@@ -654,7 +654,7 @@ file_read_publickey(LIBSSH2_SESSION * se
|
||||
_libssh2_debug((session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s",
|
||||
pubkeyfile));
|
||||
/* Read Public Key */
|
||||
@ -57,11 +57,11 @@ Index: libssh2-1.11.1/src/userauth.c
|
||||
if(!fd) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
|
||||
"Unable to open public key file");
|
||||
Index: libssh2-1.11.1/src/libssh2_priv.h
|
||||
Index: libssh2-1.11.0/src/libssh2_priv.h
|
||||
===================================================================
|
||||
--- libssh2-1.11.1.orig/src/libssh2_priv.h
|
||||
+++ libssh2-1.11.1/src/libssh2_priv.h
|
||||
@@ -1278,6 +1278,8 @@ size_t plain_method(char *method, size_t
|
||||
--- libssh2-1.11.0.orig/src/libssh2_priv.h
|
||||
+++ libssh2-1.11.0/src/libssh2_priv.h
|
||||
@@ -1218,6 +1218,8 @@ size_t plain_method(char *method, size_t
|
||||
#define FOPEN_READTEXT "r"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#define FOPEN_APPENDTEXT "a"
|
||||
@ -69,4 +69,4 @@ Index: libssh2-1.11.1/src/libssh2_priv.h
|
||||
+#define FOPEN_WRITETEXT_CLOEXEC "we"
|
||||
#endif
|
||||
|
||||
#endif /* LIBSSH2_PRIV_H */
|
||||
#endif /* __LIBSSH2_PRIV_H */
|
||||
|
65
libssh2_org-CVE-2023-48795-ext.patch
Normal file
65
libssh2_org-CVE-2023-48795-ext.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 59786b186d4de8fd6cd5aeebedbce2362a849566 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Josef=20=C4=8Cejka?= <jcejka@suse.cz>
|
||||
Date: Tue, 6 Feb 2024 15:14:29 +0100
|
||||
Subject: [PATCH] Always add extension indicators to kex_algorithms
|
||||
|
||||
KEX pseudo-methods "ext-info-c" and "kex-strict-c-v00@openssh.com"
|
||||
are in default kex method list but they were lost
|
||||
after configuring custom kex method list in libssh2_session_method_pref().
|
||||
---
|
||||
src/kex.c | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/src/kex.c b/src/kex.c
|
||||
index 8c65a0fe..1d1dadfa 100644
|
||||
--- a/src/kex.c
|
||||
+++ b/src/kex.c
|
||||
@@ -4027,13 +4027,25 @@ libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
|
||||
const char *prefs)
|
||||
{
|
||||
char **prefvar, *s, *newprefs;
|
||||
+ char *tmpprefs = NULL;
|
||||
size_t prefs_len = strlen(prefs);
|
||||
const LIBSSH2_COMMON_METHOD **mlist;
|
||||
+ const char *kex_extensions = "ext-info-c,kex-strict-c-v00@openssh.com,";
|
||||
+ size_t kex_extensions_len = strlen(kex_extensions);
|
||||
|
||||
switch(method_type) {
|
||||
case LIBSSH2_METHOD_KEX:
|
||||
prefvar = &session->kex_prefs;
|
||||
mlist = (const LIBSSH2_COMMON_METHOD **)libssh2_kex_methods;
|
||||
+ tmpprefs = LIBSSH2_ALLOC(session, kex_extensions_len + prefs_len + 1);
|
||||
+ if(!tmpprefs) {
|
||||
+ return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
+ "Error allocated space for kex method preferences");
|
||||
+ }
|
||||
+ memcpy(tmpprefs, kex_extensions, kex_extensions_len);
|
||||
+ memcpy(tmpprefs + kex_extensions_len, prefs, prefs_len + 1);
|
||||
+ prefs = tmpprefs;
|
||||
+ prefs_len = strlen(prefs);
|
||||
break;
|
||||
|
||||
case LIBSSH2_METHOD_HOSTKEY:
|
||||
@@ -4093,6 +4105,9 @@ libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
|
||||
|
||||
s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1);
|
||||
if(!newprefs) {
|
||||
+ if (tmpprefs) {
|
||||
+ LIBSSH2_FREE(session, tmpprefs);
|
||||
+ }
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Error allocated space for method preferences");
|
||||
}
|
||||
@@ -4121,6 +4136,10 @@ libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (tmpprefs) {
|
||||
+ LIBSSH2_FREE(session, tmpprefs);
|
||||
+ }
|
||||
+
|
||||
if(!*newprefs) {
|
||||
LIBSSH2_FREE(session, newprefs);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
|
||||
--
|
||||
2.26.2
|
459
libssh2_org-CVE-2023-48795.patch
Normal file
459
libssh2_org-CVE-2023-48795.patch
Normal file
@ -0,0 +1,459 @@
|
||||
From d34d9258b8420b19ec3f97b4cc5bf7aa7d98e35a 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
|
||||
---
|
||||
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(-)
|
||||
|
||||
Index: libssh2-1.11.0/src/kex.c
|
||||
===================================================================
|
||||
--- libssh2-1.11.0.orig/src/kex.c
|
||||
+++ libssh2-1.11.0/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_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 * ses
|
||||
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_SES
|
||||
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_SES
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
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_SESSI
|
||||
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_SESSI
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
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_SESSIO
|
||||
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_SESSIO
|
||||
}
|
||||
|
||||
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->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->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->remote.kexinit = NULL;
|
||||
}
|
||||
|
||||
+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
|
||||
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
|
||||
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
|
||||
|
||||
Index: libssh2-1.11.0/src/libssh2_priv.h
|
||||
===================================================================
|
||||
--- libssh2-1.11.0.orig/src/libssh2_priv.h
|
||||
+++ libssh2-1.11.0/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 s
|
||||
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);
|
||||
Index: libssh2-1.11.0/src/packet.c
|
||||
===================================================================
|
||||
--- libssh2-1.11.0.orig/src/packet.c
|
||||
+++ libssh2-1.11.0/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 * se
|
||||
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 * se
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
Index: libssh2-1.11.0/src/packet.h
|
||||
===================================================================
|
||||
--- libssh2-1.11.0.orig/src/packet.h
|
||||
+++ libssh2-1.11.0/src/packet.h
|
||||
@@ -71,6 +71,6 @@ int _libssh2_packet_burn(LIBSSH2_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 */
|
||||
Index: libssh2-1.11.0/src/session.c
|
||||
===================================================================
|
||||
--- libssh2-1.11.0.orig/src/session.c
|
||||
+++ libssh2-1.11.0/src/session.c
|
||||
@@ -464,6 +464,8 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FU
|
||||
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_SE
|
||||
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));
|
||||
Index: libssh2-1.11.0/src/transport.c
|
||||
===================================================================
|
||||
--- libssh2-1.11.0.orig/src/transport.c
|
||||
+++ libssh2-1.11.0/src/transport.c
|
||||
@@ -187,6 +187,7 @@ fullpacket(LIBSSH2_SESSION * session, in
|
||||
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, in
|
||||
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, in
|
||||
|
||||
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_SESS
|
||||
|
||||
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)
|
26
libssh2_org-ETM-remote.patch
Normal file
26
libssh2_org-ETM-remote.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From bde10825f1271769d56a0e99793da61d37abc23c Mon Sep 17 00:00:00 2001
|
||||
From: Josef Cejka <jcejka@suse.com>
|
||||
Date: Thu, 28 Mar 2024 23:38:47 +0100
|
||||
Subject: [PATCH] transport: check ETM on remote end when receiving (#1332)
|
||||
|
||||
We should check if encrypt-then-MAC feature is enabled in remote end's
|
||||
configuration.
|
||||
|
||||
Fixes #1331
|
||||
---
|
||||
src/transport.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/transport.c b/src/transport.c
|
||||
index 531f5aa15a..af175d3fa1 100644
|
||||
--- a/src/transport.c
|
||||
+++ b/src/transport.c
|
||||
@@ -425,7 +425,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
make the checks below work fine still */
|
||||
}
|
||||
|
||||
- etm = encrypted && session->local.mac ? session->local.mac->etm : 0;
|
||||
+ etm = encrypted && session->remote.mac ? session->remote.mac->etm : 0;
|
||||
|
||||
/* read/use a whole big chunk into a temporary area stored in
|
||||
the LIBSSH2_SESSION struct. We will decrypt data from that
|
@ -1,58 +1,3 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue Oct 22 07:29:06 UTC 2024 - Pedro Monreal <pmonreal@suse.com>
|
||||
|
||||
- Update to 1.11.1:
|
||||
* build: enable '-pedantic-errors'
|
||||
* build: add 'LIBSSH2_NO_DEPRECATED' option
|
||||
* build: stop requiring libssl from openssl
|
||||
* disable DSA by default
|
||||
* hostkey: do not advertise ssh-rsa when SHA1 is disabled
|
||||
* kex: prevent possible double free of hostkey
|
||||
* kex: always check for null pointers before calling _libssh2_bn_set_word
|
||||
* kex: fix a memory leak in key exchange
|
||||
* kex: always add extension indicators to kex_algorithms
|
||||
* md5: allow disabling old-style encrypted private keys at build-time
|
||||
* openssl: free allocated resources when using openssl3
|
||||
* openssl: fix memory leaks in '_libssh2_ecdsa_curve_name_with_octal_new'
|
||||
and '_libssh2_ecdsa_verify'
|
||||
* openssl: fix calculating DSA public key with OpenSSL 3
|
||||
* openssl: initialize BIGNUMs to NULL in 'gen_publickey_from_dsa' for OpenSSL 3
|
||||
* openssl: fix cppcheck found NULL dereferences
|
||||
* openssl: delete internal 'read_openssh_private_key_from_memory()'
|
||||
* openssl: use OpenSSL 3 HMAC API, add 'no-deprecated' CI job
|
||||
* openssl: make a function static, add '#ifdef' comments
|
||||
* openssl: fix DSA code to use OpenSSL 3 API
|
||||
* openssl: fix 'EC_KEY' reference with OpenSSL 3 'no-deprecated' build
|
||||
* openssl: use non-deprecated APIs with OpenSSL 3.x
|
||||
* openssl: silence '-Wunused-value' warnings
|
||||
* openssl: add missing check for 'LIBRESSL_VERSION_NUMBER' before use
|
||||
* packet: properly bounds check packet_authagent_open()
|
||||
* pem: fix private keys encrypted with AES-GCM methods
|
||||
* reuse: provide SPDX identifiers
|
||||
* scp: fix missing cast for targets without large file support
|
||||
* session: support server banners up to 8192 bytes
|
||||
* session: add 'libssh2_session_callback_set2()'
|
||||
* session: handle EINTR from send/recv/poll/select to try again as the error is not fatal
|
||||
* sftp: increase SFTP_HANDLE_MAXLEN back to 4092
|
||||
* sftp: implement posix-rename@openssh.com
|
||||
* src: implement chacha20-poly1305@openssh.com
|
||||
* src: check the return value from '_libssh2_bn_*()' functions
|
||||
* src: support RSA-SHA2 cert-based authentication (rsa-sha2-512_cert and rsa-sha2-256_cert)
|
||||
* src: check hash update/final success
|
||||
* src: check hash init success
|
||||
* src: add 'strict KEX' to fix CVE-2023-48795 "Terrapin Attack"
|
||||
* transport: fix unstable connections over non-blocking sockets
|
||||
* transport: check ETM on remote end when receiving
|
||||
* transport: fix incorrect byte offset in debug message
|
||||
* userauth: avoid oob with huge interactive kbd response
|
||||
* userauth: add a new structure to separate memory read and file read
|
||||
* userauth: check whether '*key_method' is a NULL pointer instead of 'key_method'
|
||||
* Rebase libssh2-ocloexec.patch
|
||||
* Remove patches fixed upstream:
|
||||
- libssh2_org-CVE-2023-48795.patch
|
||||
- libssh2_org-CVE-2023-48795-ext.patch
|
||||
- libssh2_org-ETM-remote.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Apr 2 16:48:26 UTC 2024 - Pedro Monreal <pmonreal@suse.com>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
%define pkg_name libssh2
|
||||
Name: libssh2_org
|
||||
Version: 1.11.1
|
||||
Version: 1.11.0
|
||||
Release: 0
|
||||
Summary: A library implementing the SSH2 protocol
|
||||
License: BSD-3-Clause
|
||||
@ -29,6 +29,12 @@ Source1: https://www.libssh2.org/download/%{pkg_name}-%{version}.tar.xz.a
|
||||
Source2: baselibs.conf
|
||||
Source3: libssh2_org.keyring
|
||||
Patch0: libssh2-ocloexec.patch
|
||||
# PATCH-FIX-UPSTREAM bsc#1218127 CVE-2023-48795: Add 'strict KEX' to fix Terrapin Attack
|
||||
Patch1: libssh2_org-CVE-2023-48795.patch
|
||||
# PATCH-FIX-SUSE bsc#1218971 Always add extension indicators to kex_algorithms
|
||||
Patch2: libssh2_org-CVE-2023-48795-ext.patch
|
||||
# PATCH-FIX-UPSTREAM bsc#1221622 Test ETM feature in remote end's config when receiving data
|
||||
Patch3: libssh2_org-ETM-remote.patch
|
||||
BuildRequires: libtool
|
||||
BuildRequires: openssl-devel
|
||||
BuildRequires: pkgconfig
|
||||
|
Loading…
x
Reference in New Issue
Block a user