Compare commits
11 Commits
5758f88d2c
...
b461db1c89
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b461db1c89 | ||
|
|
9f753913aa | ||
|
|
eabe3e656d | ||
|
|
13650e780e | ||
|
|
aefe46293d | ||
|
|
4d1fb06d59 | ||
|
|
312a515552 | ||
|
|
4543567fec | ||
|
|
0c0abaf639 | ||
|
|
0984a309b3 | ||
|
|
99c0b207e8 |
@ -0,0 +1,32 @@
|
||||
From 724effcb47ebb713d3ef1776684b8f6407b4b6a5 Mon Sep 17 00:00:00 2001
|
||||
From: ren mingshuai <78132473+rmsh1216@users.noreply.github.com>
|
||||
Date: Sat, 1 Jul 2023 01:34:44 +0800
|
||||
Subject: [PATCH] Add NULL pointer check for outlen before use (#1109)
|
||||
|
||||
Before assigning a value to the outlen, we need to check whether it is NULL.
|
||||
|
||||
Credit: Ren Mingshuai <renmingshuai@huawei.com>
|
||||
|
||||
Reference:https://github.com/libssh2/libssh2/commit/724effcb47ebb713d3ef1776684b8f6407b4b6a5
|
||||
Conflict:NA
|
||||
---
|
||||
src/misc.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/misc.c b/src/misc.c
|
||||
index b386e3d6..398457d4 100644
|
||||
--- a/src/misc.c
|
||||
+++ b/src/misc.c
|
||||
@@ -901,7 +901,8 @@ int _libssh2_copy_string(LIBSSH2_SESSION *session, struct string_buf *buf,
|
||||
}
|
||||
}
|
||||
else {
|
||||
- *outlen = 0;
|
||||
+ if(outlen)
|
||||
+ *outlen = 0;
|
||||
*outbuf = NULL;
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
From 63b4c20eb031227d040a3aca3224c80189411464 Mon Sep 17 00:00:00 2001
|
||||
From: renmingshuai <renmingshuai@huawei.com>
|
||||
Date: Tue, 1 Aug 2023 12:36:24 +0800
|
||||
Subject: [PATCH] Add a new structure to separate memory read and file read. We
|
||||
use different APIs when we read one private key from memory, so it is
|
||||
improper to store the private key information in the structure that stores
|
||||
the private key file information.
|
||||
|
||||
Fixes https://github.com/libssh2/libssh2/issues/773
|
||||
Reported-by: mike-jumper
|
||||
|
||||
Reference:https://github.com/libssh2/libssh2/commit/63b4c20eb031227d040a3aca3224c80189411464
|
||||
Conflict:NA
|
||||
---
|
||||
src/userauth.c | 23 +++++++++++++++--------
|
||||
1 file changed, 15 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/userauth.c b/src/userauth.c
|
||||
index 5ce4ccb1..c382e661 100644
|
||||
--- a/src/userauth.c
|
||||
+++ b/src/userauth.c
|
||||
@@ -818,11 +818,17 @@ struct privkey_file {
|
||||
const char *passphrase;
|
||||
};
|
||||
|
||||
+struct privkey_mem {
|
||||
+ const char *passphrase;
|
||||
+ const char *data;
|
||||
+ size_t data_len;
|
||||
+};
|
||||
+
|
||||
static int
|
||||
sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
const unsigned char *data, size_t data_len, void **abstract)
|
||||
{
|
||||
- struct privkey_file *pk_file = (struct privkey_file *) (*abstract);
|
||||
+ struct privkey_mem *pk_mem = (struct privkey_mem *) (*abstract);
|
||||
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
|
||||
void *hostkey_abstract;
|
||||
struct iovec datavec;
|
||||
@@ -831,9 +837,9 @@ sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
rc = memory_read_privatekey(session, &privkeyobj, &hostkey_abstract,
|
||||
session->userauth_pblc_method,
|
||||
session->userauth_pblc_method_len,
|
||||
- pk_file->filename,
|
||||
- strlen(pk_file->filename),
|
||||
- pk_file->passphrase);
|
||||
+ pk_mem->data,
|
||||
+ pk_mem->data_len,
|
||||
+ pk_mem->passphrase);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
@@ -1835,12 +1841,13 @@ userauth_publickey_frommemory(LIBSSH2_SESSION *session,
|
||||
{
|
||||
unsigned char *pubkeydata = NULL;
|
||||
size_t pubkeydata_len = 0;
|
||||
- struct privkey_file privkey_file;
|
||||
- void *abstract = &privkey_file;
|
||||
+ struct privkey_mem privkey_mem;
|
||||
+ void *abstract = &privkey_mem;
|
||||
int rc;
|
||||
|
||||
- privkey_file.filename = privatekeydata;
|
||||
- privkey_file.passphrase = passphrase;
|
||||
+ privkey_mem.data = privatekeydata;
|
||||
+ privkey_mem.data_len = privatekeydata_len;
|
||||
+ privkey_mem.passphrase = passphrase;
|
||||
|
||||
if(session->userauth_pblc_state == libssh2_NB_state_idle) {
|
||||
if(publickeydata_len && publickeydata) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
From f52ffc1ccdedcd5a885e85c2d0f0cb872b2b0a7f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Buckley <michael@buckleyisms.com>
|
||||
Date: Mon, 8 Jan 2024 15:04:52 -0800
|
||||
Subject: [PATCH] Fix an out-of-bounds read in _libssh2_kex_agree_instr when
|
||||
searching for a KEX not in the server list (#1302)
|
||||
|
||||
Reference:https://github.com/libssh2/libssh2/commit/f52ffc1ccdedcd5a885e85c2d0f0cb872b2b0a7f
|
||||
Conflict:NA
|
||||
---
|
||||
src/kex.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/kex.c b/src/kex.c
|
||||
index a7b301e1..65973297 100644
|
||||
--- a/src/kex.c
|
||||
+++ b/src/kex.c
|
||||
@@ -3349,6 +3349,7 @@ _libssh2_kex_agree_instr(unsigned char *haystack, size_t haystack_len,
|
||||
left = end_haystack - s;
|
||||
if((left >= 1) && (left <= haystack_len) && (left > needle_len)) {
|
||||
s++;
|
||||
+ left--;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
From de0048759b871ee61bbd98619daff16be95a3e67 Mon Sep 17 00:00:00 2001
|
||||
From: rolag <10981866+rolag@users.noreply.github.com>
|
||||
Date: Fri, 27 Sep 2024 15:52:47 +0000
|
||||
Subject: [PATCH] Fix unstable connections over nonblocking sockets (#1454)
|
||||
|
||||
The `send_existing()` function allows partially sent packets to be sent
|
||||
fully before any further packets are sent. Originally this returned
|
||||
`LIBSSH2_ERROR_BAD_USE` when a different caller or thread tried to send
|
||||
an existing packet created by a different caller or thread causing the
|
||||
connection to disconnect. Commit 33dddd2f8ac3bc81 removed the return
|
||||
allowing any caller to continue sending another caller's packet. This
|
||||
caused connection instability as discussed in #1397 and confused the
|
||||
client and server causing occasional duplicate packets to be sent and
|
||||
giving the error `rcvd too much data` as discussed in #1431. We return
|
||||
`LIBSSH2_ERROR_EAGAIN` instead to allow existing callers to finish
|
||||
sending their own packets.
|
||||
|
||||
Fixes #1397
|
||||
Fixes #1431
|
||||
Related #720
|
||||
|
||||
Credit: klux21, rolag
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/libssh2/libssh2/commit/de0048759b871ee61bbd98619daff16be95a3e67
|
||||
|
||||
---
|
||||
src/transport.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/transport.c b/src/transport.c
|
||||
index 3b30ff8..bbe7f5b 100644
|
||||
--- a/src/transport.c
|
||||
+++ b/src/transport.c
|
||||
@@ -782,7 +782,8 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
|
||||
make the caller really notice his/hers flaw, we return error for
|
||||
this case */
|
||||
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
|
||||
- "Address is different, but will resume nonetheless"));
|
||||
+ "Address is different, returning EAGAIN"));
|
||||
+ return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
|
||||
*ret = 1; /* set to make our parent return */
|
||||
--
|
||||
2.43.0
|
||||
|
||||
33
backport-Prevent-possible-double-free-of-hostkey.patch
Normal file
33
backport-Prevent-possible-double-free-of-hostkey.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From b3465418471ffa4cf0bbe1e8f28c4d007f060f99 Mon Sep 17 00:00:00 2001
|
||||
From: Will Cosgrove <will@panic.com>
|
||||
Date: Tue, 10 Sep 2024 09:35:26 -0700
|
||||
Subject: [PATCH] Prevent possible double free of hostkey (#1452)
|
||||
NULL server hostkey based on fuzzer failure case.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/libssh2/libssh2/commit/b3465418471ffa4cf0bbe1e8f28c4d007f060f99
|
||||
|
||||
---
|
||||
src/kex.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/kex.c b/src/kex.c
|
||||
index 5f381ec..7053316 100644
|
||||
--- a/src/kex.c
|
||||
+++ b/src/kex.c
|
||||
@@ -379,8 +379,11 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session,
|
||||
buf.dataptr = buf.data;
|
||||
buf.dataptr++; /* advance past type */
|
||||
|
||||
- if(session->server_hostkey)
|
||||
+ if(session->server_hostkey) {
|
||||
LIBSSH2_FREE(session, session->server_hostkey);
|
||||
+ session->server_hostkey = NULL;
|
||||
+ session->server_hostkey_len = 0;
|
||||
+ }
|
||||
|
||||
if(_libssh2_copy_string(session, &buf, &(session->server_hostkey),
|
||||
&host_key_len)) {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,63 +0,0 @@
|
||||
From 50a1262772fd9cdbdd8f747958e42ef480aecb2b Mon Sep 17 00:00:00 2001
|
||||
From: Ian Hattendorf <ian@ianhattendorf.com>
|
||||
Date: Thu, 13 Jan 2022 16:05:53 -0700
|
||||
Subject: [PATCH] Support rsa-sha2 agent flags (#661)
|
||||
|
||||
File: agent.c
|
||||
Notes: implements rsa-sha2 flags used to tell the agent which signing algo to use.
|
||||
https://tools.ietf.org/id/draft-miller-ssh-agent-01.html#rfc.section.4.5.1
|
||||
|
||||
Credit:
|
||||
Ian Hattendorf
|
||||
Conflict:NA
|
||||
Reference:https://github.com/libssh2/commit/50a1262772fd9cdbdd8f747958e42ef480aecb2b
|
||||
---
|
||||
src/agent.c | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/agent.c b/src/agent.c
|
||||
index a526c77..bce7175 100644
|
||||
--- a/src/agent.c
|
||||
+++ b/src/agent.c
|
||||
@@ -94,6 +94,10 @@
|
||||
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
|
||||
+/* Signature request methods */
|
||||
+#define SSH_AGENT_RSA_SHA2_256 2
|
||||
+#define SSH_AGENT_RSA_SHA2_512 4
|
||||
+
|
||||
#ifdef PF_UNIX
|
||||
static int
|
||||
agent_connect_unix(LIBSSH2_AGENT *agent)
|
||||
@@ -375,6 +379,7 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
ssize_t method_len;
|
||||
unsigned char *s;
|
||||
int rc;
|
||||
+ uint32_t sign_flags = 0;
|
||||
|
||||
/* Create a request to sign the data */
|
||||
if(transctx->state == agent_NB_state_init) {
|
||||
@@ -391,7 +396,18 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
|
||||
_libssh2_store_str(&s, (const char *)data, data_len);
|
||||
|
||||
/* flags */
|
||||
- _libssh2_store_u32(&s, 0);
|
||||
+ if(session->userauth_pblc_method_len > 0 &&
|
||||
+ session->userauth_pblc_method) {
|
||||
+ if(session->userauth_pblc_method_len == 12 &&
|
||||
+ !memcmp(session->userauth_pblc_method, "rsa-sha2-512", 12)) {
|
||||
+ sign_flags = SSH_AGENT_RSA_SHA2_512;
|
||||
+ }
|
||||
+ else if(session->userauth_pblc_method_len == 12 &&
|
||||
+ !memcmp(session->userauth_pblc_method, "rsa-sha2-256", 12)) {
|
||||
+ sign_flags = SSH_AGENT_RSA_SHA2_256;
|
||||
+ }
|
||||
+ }
|
||||
+ _libssh2_store_u32(&s, sign_flags);
|
||||
|
||||
transctx->request_len = s - transctx->request;
|
||||
transctx->send_recv_total = 0;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
From bec57c409d40822a23f03d2136f33b75b01b4b58 Mon Sep 17 00:00:00 2001
|
||||
From: renmingshuai <renmingshuai@huawei.com>
|
||||
Date: Sat, 1 Jul 2023 10:14:48 +0800
|
||||
Subject: [PATCH] We should check whether *key_method is a NULL pointer instead
|
||||
of key_method
|
||||
|
||||
Signed-off-by: renmingshuai <renmingshuai@huawei.com>
|
||||
|
||||
Reference:https://github.com/libssh2/libssh2/commit/bec57c409d40822a23f03d2136f33b75b01b4b58
|
||||
Conflict:NA
|
||||
---
|
||||
src/userauth.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/userauth.c b/src/userauth.c
|
||||
index e7578759..5ce4ccb1 100644
|
||||
--- a/src/userauth.c
|
||||
+++ b/src/userauth.c
|
||||
@@ -1410,7 +1410,7 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
|
||||
LIBSSH2_FREE(session, *key_method);
|
||||
|
||||
*key_method = LIBSSH2_ALLOC(session, match_len);
|
||||
- if(key_method) {
|
||||
+ if(*key_method) {
|
||||
memcpy(*key_method, match, match_len);
|
||||
*key_method_len = match_len;
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
72
backport-buildconf-drop.patch
Normal file
72
backport-buildconf-drop.patch
Normal file
@ -0,0 +1,72 @@
|
||||
From 814a850c97b0d535341868b4aefdfe76179330e9 Mon Sep 17 00:00:00 2001
|
||||
From: Viktor Szakats <commit@vsz.me>
|
||||
Date: Tue, 6 Aug 2024 12:55:05 +0200
|
||||
Subject: [PATCH] buildconf: drop
|
||||
Use `autoreconf -fi` instead.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/libssh2/libssh2/commit/814a850c97b0d535341868b4aefdfe76179330e9
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
Makefile.in | 2 +-
|
||||
buildconf | 8 --------
|
||||
tests/ossfuzz/ossfuzz.sh | 2 +-
|
||||
4 files changed, 3 insertions(+), 11 deletions(-)
|
||||
delete mode 100755 buildconf
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 677be76..9f4252e 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -38,7 +38,7 @@ OS400FILES = os400/README400 os400/initscript.sh os400/make.sh \
|
||||
EXTRA_DIST = $(WIN32FILES) get_ver.awk \
|
||||
maketgz RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath \
|
||||
CMakeLists.txt cmake git2news.pl libssh2-style.el README.md $(OS400FILES) \
|
||||
- buildconf Makefile.mk
|
||||
+ Makefile.mk
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index ec124e2..e45cabc 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -427,7 +427,7 @@ OS400FILES = os400/README400 os400/initscript.sh os400/make.sh \
|
||||
EXTRA_DIST = $(WIN32FILES) get_ver.awk \
|
||||
maketgz RELEASE-NOTES libssh2.pc.in $(VMSFILES) config.rpath \
|
||||
CMakeLists.txt cmake git2news.pl libssh2-style.el README.md $(OS400FILES) \
|
||||
- buildconf Makefile.mk
|
||||
+ Makefile.mk
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
all: all-recursive
|
||||
diff --git a/buildconf b/buildconf
|
||||
deleted file mode 100755
|
||||
index 1649f37..0000000
|
||||
--- a/buildconf
|
||||
+++ /dev/null
|
||||
@@ -1,8 +0,0 @@
|
||||
-#!/bin/sh
|
||||
-
|
||||
-echo "***" >&2
|
||||
-echo "*** Do not use buildconf. Instead, use: autoreconf -fi" >&2
|
||||
-echo "*** Doing it for you now, but buildconf may disappear in the future." >&2
|
||||
-echo "***" >&2
|
||||
-
|
||||
-exec ${AUTORECONF:-autoreconf} -fi "${@}"
|
||||
diff --git a/tests/ossfuzz/ossfuzz.sh b/tests/ossfuzz/ossfuzz.sh
|
||||
index 7925fb7..032b686 100755
|
||||
--- a/tests/ossfuzz/ossfuzz.sh
|
||||
+++ b/tests/ossfuzz/ossfuzz.sh
|
||||
@@ -22,7 +22,7 @@ export MAKEFLAGS
|
||||
apt-get -y install automake libtool libssl-dev zlib1g-dev
|
||||
|
||||
# Compile the fuzzer.
|
||||
-./buildconf
|
||||
+autoreconf -fi
|
||||
./configure --disable-shared \
|
||||
--enable-ossfuzzers \
|
||||
--disable-examples-build \
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
From: https://github.com/libssh2/libssh2/commit/e7e1312b0cbfa643e2f8bf5f2036ce5147ed797d
|
||||
From: bagder <daniel@haxx.se>
|
||||
Date: 21 Mar 2022 10:11 -0800
|
||||
Subject: misc/libssh2_copy_string: avoid malloc zero bytes #686
|
||||
|
||||
Notes:
|
||||
* Avoid the inconsistent malloc return code for malloc(0)
|
||||
|
||||
--- libssh2-1.10.0/src/misc.c 2019-09-13 14:39:11.000000000 +0800
|
||||
+++ libssh2-1.10.0/src/misc.c 2022-09-29 18:27:13.604424483 +0800
|
||||
@@ -794,12 +794,18 @@
|
||||
return -1;
|
||||
}
|
||||
|
||||
- *outbuf = LIBSSH2_ALLOC(session, str_len);
|
||||
- if(*outbuf) {
|
||||
- memcpy(*outbuf, str, str_len);
|
||||
+ if(str_len) {
|
||||
+ *outbuf = LIBSSH2_ALLOC(session, str_len);
|
||||
+ if(*outbuf) {
|
||||
+ memcpy(*outbuf, str, str_len);
|
||||
+ }
|
||||
+ else {
|
||||
+ return -1;
|
||||
+ }
|
||||
}
|
||||
else {
|
||||
- return -1;
|
||||
+ *outlen = 0;
|
||||
+ *outbuf = NULL;
|
||||
}
|
||||
|
||||
if(outlen)
|
||||
170
backport-openssl-fix-cppcheck-found-NULL-dereferences-1304.patch
Normal file
170
backport-openssl-fix-cppcheck-found-NULL-dereferences-1304.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From f2945905fbae7728869bffb9e034604cafcffb49 Mon Sep 17 00:00:00 2001
|
||||
From: Ryan Kelley <ryan.parker.kelley@gmail.com>
|
||||
Date: Thu, 18 Jan 2024 14:37:52 -0500
|
||||
Subject: [PATCH] openssl: fix cppcheck found NULL dereferences (#1304)
|
||||
|
||||
* Fix NULL dereference in gen_publickey_from_rsa_evp and
|
||||
gen_publickey_from_dsa_evp.
|
||||
* Add checks for en_publickey_from_ec_evp and en_publickey_from_ed_evp
|
||||
|
||||
Reference:https://github.com/libssh2/libssh2/commit/f2945905fbae7728869bffb9e034604cafcffb49
|
||||
Conflict:b0ab005fe792(openssl: use non-deprecated APIs with OpenSSL3.x)
|
||||
ed439a29bb04(Support for sk-ecdsa-sha2-nistp256 and sk-ssh-ed25519 keys)
|
||||
|
||||
---
|
||||
src/openssl.c | 83 ++++++++++++++++++++++++++++++++-------------------
|
||||
1 file changed, 53 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/src/openssl.c b/src/openssl.c
|
||||
index 919a8d9..905af3e 100644
|
||||
--- a/src/openssl.c
|
||||
+++ b/src/openssl.c
|
||||
@@ -820,10 +820,14 @@ gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
|
||||
RSA_free(rsa);
|
||||
|
||||
memcpy(method_buf, "ssh-rsa", 7);
|
||||
- *method = method_buf;
|
||||
- *method_len = 7;
|
||||
- *pubkeydata = key;
|
||||
- *pubkeydata_len = key_len;
|
||||
+ *method = method_buf;
|
||||
+ if(method_len) {
|
||||
+ *method_len = 7;
|
||||
+ }
|
||||
+ *pubkeydata = key;
|
||||
+ if(pubkeydata_len) {
|
||||
+ *pubkeydata_len = key_len;
|
||||
+ }
|
||||
return 0;
|
||||
|
||||
__alloc_error:
|
||||
@@ -1219,10 +1223,14 @@ gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
|
||||
DSA_free(dsa);
|
||||
|
||||
memcpy(method_buf, "ssh-dss", 7);
|
||||
- *method = method_buf;
|
||||
- *method_len = 7;
|
||||
- *pubkeydata = key;
|
||||
- *pubkeydata_len = key_len;
|
||||
+ *method = method_buf;
|
||||
+ if(method_len) {
|
||||
+ *method_len = 7;
|
||||
+ }
|
||||
+ *pubkeydata = key;
|
||||
+ if(pubkeydata_len) {
|
||||
+ *pubkeydata_len = key_len;
|
||||
+ }
|
||||
return 0;
|
||||
|
||||
__alloc_error:
|
||||
@@ -1589,10 +1597,14 @@ gen_publickey_from_ed_evp(LIBSSH2_SESSION *session,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- *method = methodBuf;
|
||||
- *method_len = sizeof(methodName) - 1;
|
||||
- *pubkeydata = keyBuf;
|
||||
- *pubkeydata_len = bufLen;
|
||||
+ *method = methodBuf;
|
||||
+ if(method_len) {
|
||||
+ *method_len = sizeof(methodName) - 1;
|
||||
+ }
|
||||
+ *pubkeydata = keyBuf;
|
||||
+ if(pubkeydata_len) {
|
||||
+ *pubkeydata_len = bufLen;
|
||||
+ }
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@@ -2561,6 +2573,7 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
|
||||
unsigned char *p;
|
||||
unsigned char *method_buf = NULL;
|
||||
unsigned char *key;
|
||||
+ size_t method_buf_len = 0;
|
||||
size_t key_len = 0;
|
||||
unsigned char *octal_value = NULL;
|
||||
size_t octal_len;
|
||||
@@ -2588,24 +2601,29 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
|
||||
type = _libssh2_ecdsa_get_curve_type(ec);
|
||||
|
||||
if(is_sk)
|
||||
- *method_len = 34;
|
||||
+ method_buf_len = 34;
|
||||
else
|
||||
- *method_len = 19;
|
||||
+ method_buf_len = 19;
|
||||
|
||||
- method_buf = LIBSSH2_ALLOC(session, *method_len);
|
||||
+ method_buf = LIBSSH2_ALLOC(session, method_buf_len);
|
||||
if(!method_buf) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"out of memory");
|
||||
}
|
||||
|
||||
- if(is_sk)
|
||||
- memcpy(method_buf, "sk-ecdsa-sha2-nistp256@openssh.com", *method_len);
|
||||
- else if(type == LIBSSH2_EC_CURVE_NISTP256)
|
||||
- memcpy(method_buf, "ecdsa-sha2-nistp256", *method_len);
|
||||
- else if(type == LIBSSH2_EC_CURVE_NISTP384)
|
||||
- memcpy(method_buf, "ecdsa-sha2-nistp384", *method_len);
|
||||
- else if(type == LIBSSH2_EC_CURVE_NISTP521)
|
||||
- memcpy(method_buf, "ecdsa-sha2-nistp521", *method_len);
|
||||
+ if(is_sk) {
|
||||
+ memcpy(method_buf, "sk-ecdsa-sha2-nistp256@openssh.com",
|
||||
+ method_buf_len);
|
||||
+ }
|
||||
+ else if(type == LIBSSH2_EC_CURVE_NISTP256) {
|
||||
+ memcpy(method_buf, "ecdsa-sha2-nistp256", method_buf_len);
|
||||
+ }
|
||||
+ else if(type == LIBSSH2_EC_CURVE_NISTP384) {
|
||||
+ memcpy(method_buf, "ecdsa-sha2-nistp384", method_buf_len);
|
||||
+ }
|
||||
+ else if(type == LIBSSH2_EC_CURVE_NISTP521) {
|
||||
+ memcpy(method_buf, "ecdsa-sha2-nistp521", method_buf_len);
|
||||
+ }
|
||||
else {
|
||||
_libssh2_debug((session,
|
||||
LIBSSH2_TRACE_ERROR,
|
||||
@@ -2636,9 +2654,9 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
- /* Key form is: type_len(4) + type(method_len) + domain_len(4) + domain(8)
|
||||
- + pub_key_len(4) + pub_key(~65). */
|
||||
- key_len = 4 + *method_len + 4 + 8 + 4 + octal_len;
|
||||
+ /* Key form is: type_len(4) + type(method_buf_len) + domain_len(4)
|
||||
+ + domain(8) + pub_key_len(4) + pub_key(~65). */
|
||||
+ key_len = 4 + method_buf_len + 4 + 8 + 4 + octal_len;
|
||||
key = LIBSSH2_ALLOC(session, key_len);
|
||||
if(!key) {
|
||||
rc = -1;
|
||||
@@ -2649,7 +2667,7 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
|
||||
p = key;
|
||||
|
||||
/* Key type */
|
||||
- _libssh2_store_str(&p, (const char *)method_buf, *method_len);
|
||||
+ _libssh2_store_str(&p, (const char *)method_buf, method_buf_len);
|
||||
|
||||
/* Name domain */
|
||||
if(is_sk) {
|
||||
@@ -2662,9 +2680,14 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
|
||||
/* Public key */
|
||||
_libssh2_store_str(&p, (const char *)octal_value, octal_len);
|
||||
|
||||
- *method = method_buf;
|
||||
- *pubkeydata = key;
|
||||
- *pubkeydata_len = key_len;
|
||||
+ *method = method_buf;
|
||||
+ if(method_len) {
|
||||
+ *method_len = method_buf_len;
|
||||
+ }
|
||||
+ *pubkeydata = key;
|
||||
+ if(pubkeydata_len) {
|
||||
+ *pubkeydata_len = key_len;
|
||||
+ }
|
||||
|
||||
clean_exit:
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
From 1a9e8811f7fa7538a52e2dd0150a094368471bf3 Mon Sep 17 00:00:00 2001
|
||||
From: Anders Borum <palmin@users.noreply.github.com>
|
||||
Date: Tue, 8 Oct 2024 08:11:02 +0200
|
||||
Subject: [PATCH] session: support server banners up to 8192 bytes (was: 256)
|
||||
|
||||
If server had banner exceeding 256 bytes there wasn't enough room in
|
||||
`_LIBSSH2_SESSION.banner_TxRx_banner`. Only the first 256 bytes would be
|
||||
read making the first packet read fail but also dooming key exchange as
|
||||
`session->remote.banner` didn't include everything.
|
||||
|
||||
This change bumps the banner buffer to 8KB to match OpenSSH.
|
||||
|
||||
Fixes #1442
|
||||
Closes #1443
|
||||
|
||||
Reference:https://github.com/libssh2/libssh2/commit/1a9e8811f7fa7538a52e2dd0150a094368471bf3
|
||||
Conflict:NA
|
||||
|
||||
---
|
||||
src/libssh2_priv.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
|
||||
index ee1d8b5..b1f32b1 100644
|
||||
--- a/src/libssh2_priv.h
|
||||
+++ b/src/libssh2_priv.h
|
||||
@@ -742,7 +742,7 @@ struct _LIBSSH2_SESSION
|
||||
|
||||
/* State variables used in libssh2_banner_send() */
|
||||
libssh2_nonblocking_states banner_TxRx_state;
|
||||
- char banner_TxRx_banner[256];
|
||||
+ char banner_TxRx_banner[8192];
|
||||
ssize_t banner_TxRx_total_send;
|
||||
|
||||
/* State variables used in libssh2_kexinit() */
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@ -0,0 +1,465 @@
|
||||
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
|
||||
|
||||
Reference:https://github.com/libssh2/libssh2/commit/d34d9258b8420b19ec3f97b4cc5bf7aa7d98e35a
|
||||
---
|
||||
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 d4034a0..b4b748c 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 82c3afe..ee1d8b5 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 b5b4198..35d4d39 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 79018bc..6ea100a 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 a4d602b..f4bafb5 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 6d902d3..3b30ff8 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.33.0
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
From a6a9093b39824a00258f96a5301a844b4d870cdc Mon Sep 17 00:00:00 2001
|
||||
From: Viktor Szakats <commit@vsz.me>
|
||||
Date: Thu, 28 Mar 2024 16:59:58 +0000
|
||||
Subject: [PATCH] userauth: avoid oob with huge interactive kbd response
|
||||
|
||||
- If the length of a response is `UINT_MAX - 3` or larger, an unsigned
|
||||
integer overflow occurs on 64-bit systems. Avoid such truncation to
|
||||
always allocate enough memory to avoid subsequent out of boundary
|
||||
writes.
|
||||
|
||||
Patch-by: Tobias Stoeckmann
|
||||
|
||||
- also add FIXME to bump up length field to `size_t` (ABI break)
|
||||
|
||||
Closes #1337
|
||||
|
||||
Reference:https://github.com/libssh2/libssh2/commit/a6a9093b39824a00258f96a5301a844b4d870cdc
|
||||
Conflict:NA
|
||||
---
|
||||
include/libssh2.h | 2 +-
|
||||
src/userauth.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/libssh2.h b/include/libssh2.h
|
||||
index 8bc8a138..71673801 100644
|
||||
--- a/include/libssh2.h
|
||||
+++ b/include/libssh2.h
|
||||
@@ -292,7 +292,7 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT
|
||||
typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
|
||||
{
|
||||
char *text;
|
||||
- unsigned int length;
|
||||
+ unsigned int length; /* FIXME: change type to size_t */
|
||||
} LIBSSH2_USERAUTH_KBDINT_RESPONSE;
|
||||
|
||||
typedef struct _LIBSSH2_SK_SIG_INFO {
|
||||
diff --git a/src/userauth.c b/src/userauth.c
|
||||
index 60fd48e4..43df3e15 100644
|
||||
--- a/src/userauth.c
|
||||
+++ b/src/userauth.c
|
||||
@@ -2188,7 +2188,7 @@ userauth_keyboard_interactive(LIBSSH2_SESSION * session,
|
||||
if(session->userauth_kybd_responses[i].length <=
|
||||
(SIZE_MAX - 4 - session->userauth_kybd_packet_len)) {
|
||||
session->userauth_kybd_packet_len +=
|
||||
- 4 + session->userauth_kybd_responses[i].length;
|
||||
+ 4 + (size_t)session->userauth_kybd_responses[i].length;
|
||||
}
|
||||
else {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
--
|
||||
2.33.0
|
||||
|
||||
Binary file not shown.
15
libssh2-1.11.0-strict-modes.patch
Normal file
15
libssh2-1.11.0-strict-modes.patch
Normal file
@ -0,0 +1,15 @@
|
||||
Group-writeable directories in the hierarchy above where we
|
||||
run the tests from can cause failures due to openssh's strict
|
||||
permissions checks. Adding this option helps the tests to run
|
||||
more reliably on a variety of build systems.
|
||||
|
||||
--- /tests/test_sshd.test
|
||||
+++ /tests/test_sshd.test
|
||||
@@ -71,6 +71,7 @@ chmod go-rwx \
|
||||
# shellcheck disable=SC2086
|
||||
"${SSHD}" \
|
||||
-f "${SSHD_FIXTURE_CONFIG:-${d}/openssh_server/sshd_config}" \
|
||||
+ -o 'StrictModes no' \
|
||||
-o 'Port 4711' \
|
||||
-h "${d}/openssh_server/ssh_host_rsa_key" \
|
||||
-h "${d}/openssh_server/ssh_host_ecdsa_key" \
|
||||
BIN
libssh2-1.11.0.tar.gz
Normal file
BIN
libssh2-1.11.0.tar.gz
Normal file
Binary file not shown.
62
libssh2.spec
62
libssh2.spec
@ -1,18 +1,26 @@
|
||||
Name: libssh2
|
||||
Version: 1.10.0
|
||||
Release: 5
|
||||
Version: 1.11.0
|
||||
Release: 4
|
||||
Summary: A library implementing the SSH2 protocol
|
||||
License: BSD
|
||||
URL: https://www.libssh2.org/
|
||||
Source0: https://libssh2.org/download/libssh2-%{version}.tar.gz
|
||||
|
||||
Patch0: backport-RSA-SHA2-256-512-key-upgrade-support-RFC-8332.patch
|
||||
Patch1: backport-misc-libssh2_copy_string-avoid-malloc-zero-bytes.patch
|
||||
Patch2: sftp-Prevent-files-from-being-skipped-if-the-output.patch
|
||||
Patch3: backport-Support-rsa-sha2-agent-flags.patch
|
||||
|
||||
Patch0: backport-src-add-strict-KEX-to-fix-CVE-2023-48795-Terrapin-At.patch
|
||||
Patch1: libssh2-1.11.0-strict-modes.patch
|
||||
Patch2: backport-Add-NULL-pointer-check-for-outlen-before-use-1109.patch
|
||||
Patch3: backport-We-should-check-whether-key_method-is-a-NULL-pointer.patch
|
||||
Patch4: backport-Add-a-new-structure-to-separate-memory-read-and-file.patch
|
||||
Patch5: backport-Fix-an-out-of-bounds-read-in-_libssh2_kex_agree_inst.patch
|
||||
Patch6: backport-openssl-fix-cppcheck-found-NULL-dereferences-1304.patch
|
||||
Patch7: backport-userauth-avoid-oob-with-huge-interactive-kbd-respons.patch
|
||||
Patch8: backport-buildconf-drop.patch
|
||||
Patch9: backport-Prevent-possible-double-free-of-hostkey.patch
|
||||
Patch10: backport-Fix-unstable-connections-over-nonblocking-sockets.patch
|
||||
Patch11: backport-session-support-server-banners-up-to-8192-bytes-was-256.patch
|
||||
|
||||
BuildRequires: coreutils findutils /usr/bin/man zlib-devel
|
||||
BuildRequires: gcc make sed openssl-devel > 1:1.0.1 openssh-server
|
||||
BuildRequires: gcc make sed openssl-devel > 1:1.0.2 openssh-server
|
||||
BuildRequires: glibc-langpack-en groff
|
||||
|
||||
%description
|
||||
@ -34,10 +42,10 @@ developing applications that use libssh2.
|
||||
%prep
|
||||
%autosetup -n %{name}-%{version} -p1
|
||||
|
||||
sed -i s/4711/47%{__isa_bits}/ tests/ssh2.{c,sh}
|
||||
sed -i s/4711/47%{?__isa_bits}/ tests/{openssh_fixture.c,test_ssh{2.c,d.test}}
|
||||
|
||||
%build
|
||||
%configure --disable-silent-rules --enable-shared
|
||||
%configure --disable-silent-rules --enable-shared --disable-docker-tests
|
||||
%make_build
|
||||
|
||||
%install
|
||||
@ -85,11 +93,41 @@ LC_ALL=en_US.UTF-8 make -C tests check
|
||||
|
||||
%files help
|
||||
%defattr(-,root,root)
|
||||
%doc docs/BINDINGS docs/HACKING docs/TODO NEWS
|
||||
%doc docs/BINDINGS.md docs/HACKING.md docs/TODO NEWS
|
||||
%{_mandir}/man3/libssh2_*.3*
|
||||
|
||||
%changelog
|
||||
* Thu Feb 16 2023 renmingshuai <renmingshuai> - 1.10.0-5
|
||||
* Tue Oct 29 2024 bitianyuan <bitianyuan@huawei.com> - 1.11.0-4
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:backport some upstream patches
|
||||
|
||||
* Tue Jun 04 2024 yueyuankun<yueyuankun@kylinos.cn> - 1.11.0-3
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:add patch to work around strict permissions issues for sshd tests
|
||||
|
||||
* Tue Apr 16 2024 renmingshuai <renmingshuai@huawei.com> - 1.11.0-2
|
||||
- Type:CVE
|
||||
- ID:CVE-2023-48795
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2023-48795
|
||||
|
||||
* Mon Aug 7 2023 renmingshuai <renmingshuai@huawei.com> - 1.11.0-1
|
||||
- Type:requirement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:update to 1.11.0
|
||||
|
||||
* Tue Mar 28 2023 renmingshuai <renmingshuai@huawei.com> - 1.10.0-6
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:backport some upstream patches
|
||||
|
||||
* Thu Feb 16 2023 renmingshuai <renmingshuai@huawei.com> - 1.10.0-5
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
From bd9c65d68c4152ba0726f5588b4b611410972fbc Mon Sep 17 00:00:00 2001
|
||||
From: Gabriel Smith <ga29smith@gmail.com>
|
||||
Date: Fri, 23 Sep 2022 13:03:56 -0400
|
||||
Subject: [PATCH] sftp: Prevent files from being skipped if the output buffer
|
||||
is too small (#746)
|
||||
|
||||
Notes:
|
||||
LIBSSH2_ERROR_BUFFER_TOO_SMALL is returned if the buffer is too small
|
||||
to contain a returned directory entry. On this condition we jump to the
|
||||
label `end`. At this point the number of names left is decremented
|
||||
despite no name being returned.
|
||||
|
||||
As suggested in #714, this commit moves the error label after the
|
||||
decrement of `names_left`.
|
||||
|
||||
Fixes #714
|
||||
|
||||
Credit:
|
||||
Co-authored-by: Gabriel Smith <gabriel.smith@precisionot.com>
|
||||
---
|
||||
src/sftp.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sftp.c b/src/sftp.c
|
||||
index b1a5352..2df918a 100644
|
||||
--- a/src/sftp.c
|
||||
+++ b/src/sftp.c
|
||||
@@ -1852,11 +1852,11 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
|
||||
|
||||
handle->u.dir.next_name = (char *) s;
|
||||
handle->u.dir.names_packet_len = names_packet_len;
|
||||
- end:
|
||||
|
||||
if((--handle->u.dir.names_left) == 0)
|
||||
LIBSSH2_FREE(session, handle->u.dir.names_packet);
|
||||
|
||||
+ end:
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
|
||||
"libssh2_sftp_readdir_ex() return %d",
|
||||
filename_len);
|
||||
--
|
||||
2.25.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user