summaryrefslogtreecommitdiff
path: root/libs/libcurl/src
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2024-12-12 09:52:45 +0300
committerdartraiden <wowemuh@gmail.com>2024-12-12 09:55:10 +0300
commitcefdd26d62e01878b8e8acbb78a8fcc477a63fd9 (patch)
tree023cc726019de25ac01e7d6098b620e1f36f426a /libs/libcurl/src
parent583ab0796b113df6474cfce7416084215cb850e7 (diff)
libcurl: update to 8.11.1
Diffstat (limited to 'libs/libcurl/src')
-rw-r--r--libs/libcurl/src/CMakeLists.txt2
-rw-r--r--libs/libcurl/src/Makefile.in1
-rw-r--r--libs/libcurl/src/cf-h2-proxy.c4
-rw-r--r--libs/libcurl/src/cf-socket.c47
-rw-r--r--libs/libcurl/src/config-win32.h11
-rw-r--r--libs/libcurl/src/cookie.c10
-rw-r--r--libs/libcurl/src/curl_config.h.cmake3
-rw-r--r--libs/libcurl/src/curl_config.h.in5
-rw-r--r--libs/libcurl/src/curl_ntlm_core.c26
-rw-r--r--libs/libcurl/src/curl_setup.h41
-rw-r--r--libs/libcurl/src/curl_trc.c4
-rw-r--r--libs/libcurl/src/easy.c1
-rw-r--r--libs/libcurl/src/formdata.c2
-rw-r--r--libs/libcurl/src/hostip.c4
-rw-r--r--libs/libcurl/src/http.c159
-rw-r--r--libs/libcurl/src/http.h3
-rw-r--r--libs/libcurl/src/http2.c28
-rw-r--r--libs/libcurl/src/http2.h5
-rw-r--r--libs/libcurl/src/http_negotiate.c2
-rw-r--r--libs/libcurl/src/http_proxy.c145
-rw-r--r--libs/libcurl/src/http_proxy.h6
-rw-r--r--libs/libcurl/src/krb5.c44
-rw-r--r--libs/libcurl/src/ldap.c4
-rw-r--r--libs/libcurl/src/md4.c7
-rw-r--r--libs/libcurl/src/md5.c27
-rw-r--r--libs/libcurl/src/mime.c62
-rw-r--r--libs/libcurl/src/mprintf.c12
-rw-r--r--libs/libcurl/src/multi.c11
-rw-r--r--libs/libcurl/src/netrc.c119
-rw-r--r--libs/libcurl/src/rtsp.c5
-rw-r--r--libs/libcurl/src/setopt.c6
-rw-r--r--libs/libcurl/src/smb.c8
-rw-r--r--libs/libcurl/src/socketpair.h16
-rw-r--r--libs/libcurl/src/strerror.c8
-rw-r--r--libs/libcurl/src/strtok.h8
-rw-r--r--libs/libcurl/src/url.c60
-rw-r--r--libs/libcurl/src/vauth/digest.c24
-rw-r--r--libs/libcurl/src/version.c2
-rw-r--r--libs/libcurl/src/vssh/libssh.c55
-rw-r--r--libs/libcurl/src/vssh/ssh.h4
-rw-r--r--libs/libcurl/src/vtls/mbedtls.c28
-rw-r--r--libs/libcurl/src/vtls/openssl.c86
-rw-r--r--libs/libcurl/src/vtls/schannel.c198
-rw-r--r--libs/libcurl/src/vtls/schannel_verify.c3
-rw-r--r--libs/libcurl/src/vtls/sectransp.c4
-rw-r--r--libs/libcurl/src/vtls/wolfssl.c2
46 files changed, 670 insertions, 642 deletions
diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt
index 7ba1780edb..6173ceac1b 100644
--- a/libs/libcurl/src/CMakeLists.txt
+++ b/libs/libcurl/src/CMakeLists.txt
@@ -125,7 +125,7 @@ if(BUILD_STATIC_LIBS)
add_library(${LIB_STATIC} STATIC ${LIB_SOURCE})
add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
if(WIN32)
- set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB")
+ set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB")
endif()
target_link_libraries(${LIB_STATIC} PRIVATE ${CURL_LIBS})
# Remove the "lib" prefix since the library is already named "libcurl".
diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in
index abe6e4cdb7..c9cfc9a5d5 100644
--- a/libs/libcurl/src/Makefile.in
+++ b/libs/libcurl/src/Makefile.in
@@ -1066,6 +1066,7 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LIBCURL_PC_CFLAGS = @LIBCURL_PC_CFLAGS@
LIBCURL_PC_CFLAGS_PRIVATE = @LIBCURL_PC_CFLAGS_PRIVATE@
+LIBCURL_PC_LDFLAGS_PRIVATE = @LIBCURL_PC_LDFLAGS_PRIVATE@
LIBCURL_PC_LIBS = @LIBCURL_PC_LIBS@
LIBCURL_PC_LIBS_PRIVATE = @LIBCURL_PC_LIBS_PRIVATE@
LIBCURL_PC_REQUIRES = @LIBCURL_PC_REQUIRES@
diff --git a/libs/libcurl/src/cf-h2-proxy.c b/libs/libcurl/src/cf-h2-proxy.c
index e978b83804..92c2bbb93c 100644
--- a/libs/libcurl/src/cf-h2-proxy.c
+++ b/libs/libcurl/src/cf-h2-proxy.c
@@ -277,6 +277,8 @@ static int proxy_h2_client_new(struct Curl_cfilter *cf,
{
struct cf_h2_proxy_ctx *ctx = cf->ctx;
nghttp2_option *o;
+ nghttp2_mem mem = {NULL, Curl_nghttp2_malloc, Curl_nghttp2_free,
+ Curl_nghttp2_calloc, Curl_nghttp2_realloc};
int rc = nghttp2_option_new(&o);
if(rc)
@@ -289,7 +291,7 @@ static int proxy_h2_client_new(struct Curl_cfilter *cf,
HTTP field value. */
nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
#endif
- rc = nghttp2_session_client_new2(&ctx->h2, cbs, cf, o);
+ rc = nghttp2_session_client_new3(&ctx->h2, cbs, cf, o, &mem);
nghttp2_option_del(o);
return rc;
}
diff --git a/libs/libcurl/src/cf-socket.c b/libs/libcurl/src/cf-socket.c
index 89f19cb317..c2e633f7e6 100644
--- a/libs/libcurl/src/cf-socket.c
+++ b/libs/libcurl/src/cf-socket.c
@@ -600,36 +600,39 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
if(!iface && !host && !port)
/* no local kind of binding was requested */
return CURLE_OK;
+ else if(iface && (strlen(iface) >= 255) )
+ return CURLE_BAD_FUNCTION_ARGUMENT;
memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
- if(iface && (strlen(iface) < 255) ) {
+ if(iface || host) {
char myhost[256] = "";
int done = 0; /* -1 for error, 1 for address found */
if2ip_result_t if2ip_result = IF2IP_NOT_FOUND;
- /* interface */
#ifdef SO_BINDTODEVICE
- /*
- * This binds the local socket to a particular interface. This will
- * force even requests to other local interfaces to go out the external
- * interface. Only bind to the interface when specified as interface,
- * not just as a hostname or ip address.
- *
- * The interface might be a VRF, eg: vrf-blue, which means it cannot be
- * converted to an IP address and would fail Curl_if2ip. Simply try to
- * use it straight away.
- */
- if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
- iface, (curl_socklen_t)strlen(iface) + 1) == 0) {
- /* This is often "errno 1, error: Operation not permitted" if you are
- * not running as root or another suitable privileged user. If it
- * succeeds it means the parameter was a valid interface and not an IP
- * address. Return immediately.
- */
- if(!host_input) {
- infof(data, "socket successfully bound to interface '%s'", iface);
- return CURLE_OK;
+ if(iface) {
+ /*
+ * This binds the local socket to a particular interface. This will
+ * force even requests to other local interfaces to go out the external
+ * interface. Only bind to the interface when specified as interface,
+ * not just as a hostname or ip address.
+ *
+ * The interface might be a VRF, eg: vrf-blue, which means it cannot be
+ * converted to an IP address and would fail Curl_if2ip. Simply try to
+ * use it straight away.
+ */
+ if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
+ iface, (curl_socklen_t)strlen(iface) + 1) == 0) {
+ /* This is often "errno 1, error: Operation not permitted" if you are
+ * not running as root or another suitable privileged user. If it
+ * succeeds it means the parameter was a valid interface and not an IP
+ * address. Return immediately.
+ */
+ if(!host_input) {
+ infof(data, "socket successfully bound to interface '%s'", iface);
+ return CURLE_OK;
+ }
}
}
#endif
diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h
index 7b4c9d2748..6aa9f0d292 100644
--- a/libs/libcurl/src/config-win32.h
+++ b/libs/libcurl/src/config-win32.h
@@ -149,10 +149,6 @@
/* Define if you have the select function. */
#define HAVE_SELECT 1
-/* Define if libSSH2 is in use */
-#define USE_LIBSSH2 1
-#define HAVE_LIBSSH2_H 1
-
/* Define if you have the setlocale function. */
#define HAVE_SETLOCALE 1
@@ -431,10 +427,6 @@ Vista
# endif
#endif
-#ifdef USE_WIN32_LARGE_FILES
-#define HAVE__FSEEKI64
-#endif
-
/* Define to the size of `off_t', as computed by sizeof. */
#if defined(__MINGW32__) && \
defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
@@ -481,9 +473,6 @@ Vista
#define USE_WIN32_LDAP 1
#endif
-/* if SSL is enabled */
-#define USE_OPENSSL 1
-
/* Define to use the Windows crypto library. */
#if !defined(CURL_WINDOWS_UWP)
#define USE_WIN32_CRYPTO
diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c
index b190bb3767..44197b586c 100644
--- a/libs/libcurl/src/cookie.c
+++ b/libs/libcurl/src/cookie.c
@@ -833,14 +833,16 @@ parse_netscape(struct Cookie *co,
if(ptr)
*ptr = 0; /* clear it */
- firstptr = strtok_r((char *)lineptr, "\t", &tok_buf); /* tokenize on TAB */
+ /* tokenize on TAB */
+ firstptr = Curl_strtok_r((char *)lineptr, "\t", &tok_buf);
/*
* Now loop through the fields and init the struct we already have
* allocated
*/
fields = 0;
- for(ptr = firstptr; ptr; ptr = strtok_r(NULL, "\t", &tok_buf), fields++) {
+ for(ptr = firstptr; ptr;
+ ptr = Curl_strtok_r(NULL, "\t", &tok_buf), fields++) {
switch(fields) {
case 0:
if(ptr[0]=='.') /* skip preceding dots */
@@ -989,7 +991,7 @@ replace_existing(struct Curl_easy *data,
size_t myhash = cookiehash(co->domain);
for(n = Curl_llist_head(&ci->cookielist[myhash]); n; n = Curl_node_next(n)) {
struct Cookie *clist = Curl_node_elem(n);
- if(strcasecompare(clist->name, co->name)) {
+ if(!strcmp(clist->name, co->name)) {
/* the names are identical */
bool matching_domains = FALSE;
@@ -1029,7 +1031,7 @@ replace_existing(struct Curl_easy *data,
}
}
- if(!replace_n && strcasecompare(clist->name, co->name)) {
+ if(!replace_n && !strcmp(clist->name, co->name)) {
/* the names are identical */
if(clist->domain && co->domain) {
diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake
index 6f318d1cf4..3fa058aa19 100644
--- a/libs/libcurl/src/curl_config.h.cmake
+++ b/libs/libcurl/src/curl_config.h.cmake
@@ -246,9 +246,6 @@
/* Define to 1 if you have the fseeko declaration. */
#cmakedefine HAVE_DECL_FSEEKO 1
-/* Define to 1 if you have the _fseeki64 function. */
-#cmakedefine HAVE__FSEEKI64 1
-
/* Define to 1 if you have the ftruncate function. */
#cmakedefine HAVE_FTRUNCATE 1
diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in
index 89b1a8a6cf..60ad77859b 100644
--- a/libs/libcurl/src/curl_config.h.in
+++ b/libs/libcurl/src/curl_config.h.in
@@ -792,9 +792,6 @@
/* Define to 1 if you have the <zstd.h> header file. */
#undef HAVE_ZSTD_H
-/* Define to 1 if you have the `_fseeki64' function. */
-#undef HAVE__FSEEKI64
-
/* Define to 1 if you have the `_setmode' function. */
#undef HAVE__SETMODE
@@ -881,7 +878,7 @@
/* GSASL support enabled */
#undef USE_GSASL
-/* force HTTPS RR support for ECH */
+/* enable HTTPS RR support */
#undef USE_HTTPSRR
/* if hyper is in use */
diff --git a/libs/libcurl/src/curl_ntlm_core.c b/libs/libcurl/src/curl_ntlm_core.c
index 70474b269c..944bfa2c09 100644
--- a/libs/libcurl/src/curl_ntlm_core.c
+++ b/libs/libcurl/src/curl_ntlm_core.c
@@ -71,13 +71,6 @@
# include <openssl/md5.h>
# include <openssl/ssl.h>
# include <openssl/rand.h>
-#else
-# include <wolfssl/openssl/des.h>
-# include <wolfssl/openssl/md5.h>
-# include <wolfssl/openssl/ssl.h>
-# include <wolfssl/openssl/rand.h>
-#endif
-
# if (defined(OPENSSL_VERSION_NUMBER) && \
(OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL)
# define DES_key_schedule des_key_schedule
@@ -95,6 +88,25 @@
# define DESKEYARG(x) *x
# define DESKEY(x) &x
# endif
+#else
+# include <wolfssl/openssl/des.h>
+# include <wolfssl/openssl/md5.h>
+# include <wolfssl/openssl/ssl.h>
+# include <wolfssl/openssl/rand.h>
+# if defined(OPENSSL_COEXIST)
+# define DES_key_schedule WOLFSSL_DES_key_schedule
+# define DES_cblock WOLFSSL_DES_cblock
+# define DES_set_odd_parity wolfSSL_DES_set_odd_parity
+# define DES_set_key wolfSSL_DES_set_key
+# define DES_set_key_unchecked wolfSSL_DES_set_key_unchecked
+# define DES_ecb_encrypt wolfSSL_DES_ecb_encrypt
+# define DESKEY(x) ((WOLFSSL_DES_key_schedule *)(x))
+# define DESKEYARG(x) *x
+# else
+# define DESKEYARG(x) *x
+# define DESKEY(x) &x
+# endif
+#endif
#elif defined(USE_GNUTLS)
diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h
index dc4a4553aa..7c057097ec 100644
--- a/libs/libcurl/src/curl_setup.h
+++ b/libs/libcurl/src/curl_setup.h
@@ -43,7 +43,7 @@
#include <_mingw.h>
#endif
-/* Workaround for Homebrew gcc 12.4.0, 13.3.0, 14.1.0 and newer (as of 14.1.0)
+/* Workaround for Homebrew gcc 12.4.0, 13.3.0, 14.1.0, 14.2.0 (initial build)
that started advertising the `availability` attribute, which then gets used
by Apple SDK, but, in a way incompatible with gcc, resulting in misc errors
inside SDK headers, e.g.:
@@ -51,13 +51,16 @@
definition
error: expected ',' or '}' before
Followed by missing declarations.
- Fix it by overriding the built-in feature-check macro used by the headers
- to enable the problematic attributes. This makes the feature check fail. */
-#if defined(__APPLE__) && \
- !defined(__clang__) && \
- defined(__GNUC__) && __GNUC__ >= 12 && \
+ Work it around by overriding the built-in feature-check macro used by the
+ headers to enable the problematic attributes. This makes the feature check
+ fail. Fixed in 14.2.0_1. Disable the workaround if the fix is detected. */
+#if defined(__APPLE__) && !defined(__clang__) && defined(__GNUC__) && \
defined(__has_attribute)
-#define availability curl_pp_attribute_disabled
+# if !defined(__has_feature)
+# define availability curl_pp_attribute_disabled
+# elif !__has_feature(attribute_availability)
+# define availability curl_pp_attribute_disabled
+# endif
#endif
#if defined(__APPLE__)
@@ -102,6 +105,16 @@
# ifndef NOGDI
# define NOGDI
# endif
+/* Detect Windows App environment which has a restricted access
+ * to the Win32 APIs. */
+# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \
+ defined(WINAPI_FAMILY)
+# include <winapifamily.h>
+# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
+ !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+# define CURL_WINDOWS_UWP
+# endif
+# endif
#endif
/* Compatibility */
@@ -277,6 +290,14 @@
# define CURL_DISABLE_HTTP_AUTH 1
#endif
+/*
+ * ECH requires HTTPSRR.
+ */
+
+#if defined(USE_ECH) && !defined(USE_HTTPSRR)
+# define USE_HTTPSRR
+#endif
+
/* ================================================================ */
/* No system header file shall be included in this file before this */
/* point. */
@@ -444,6 +465,12 @@
#include <curl/stdcheaders.h>
#endif
+#ifdef _WIN32
+#define Curl_getpid() GetCurrentProcessId()
+#else
+#define Curl_getpid() getpid()
+#endif
+
/*
* Large file (>2Gb) support using Win32 functions.
*/
diff --git a/libs/libcurl/src/curl_trc.c b/libs/libcurl/src/curl_trc.c
index 3385cd3da2..9075de25fd 100644
--- a/libs/libcurl/src/curl_trc.c
+++ b/libs/libcurl/src/curl_trc.c
@@ -365,7 +365,7 @@ static CURLcode trc_opt(const char *config)
if(!tmp)
return CURLE_OUT_OF_MEMORY;
- token = strtok_r(tmp, ", ", &tok_buf);
+ token = Curl_strtok_r(tmp, ", ", &tok_buf);
while(token) {
switch(*token) {
case '-':
@@ -391,7 +391,7 @@ static CURLcode trc_opt(const char *config)
else
trc_apply_level_by_name(token, lvl);
- token = strtok_r(NULL, ", ", &tok_buf);
+ token = Curl_strtok_r(NULL, ", ", &tok_buf);
}
free(tmp);
return CURLE_OK;
diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c
index ae99f6d84c..54269e34d9 100644
--- a/libs/libcurl/src/easy.c
+++ b/libs/libcurl/src/easy.c
@@ -940,6 +940,7 @@ CURL *curl_easy_duphandle(CURL *d)
goto fail;
Curl_dyn_init(&outcurl->state.headerb, CURL_MAX_HTTP_HEADER);
+ Curl_netrc_init(&outcurl->state.netrc);
/* the connection pool is setup on demand */
outcurl->state.lastconnect_id = -1;
diff --git a/libs/libcurl/src/formdata.c b/libs/libcurl/src/formdata.c
index 2f45376413..84ad27891d 100644
--- a/libs/libcurl/src/formdata.c
+++ b/libs/libcurl/src/formdata.c
@@ -793,7 +793,7 @@ static CURLcode setname(curl_mimepart *part, const char *name, size_t len)
/* wrap call to fseeko so it matches the calling convention of callback */
static int fseeko_wrapper(void *stream, curl_off_t offset, int whence)
{
-#if defined(HAVE__FSEEKI64)
+#if defined(_WIN32) && defined(USE_WIN32_LARGE_FILES)
return _fseeki64(stream, (__int64)offset, whence);
#elif defined(HAVE_FSEEKO) && defined(HAVE_DECL_FSEEKO)
return fseeko(stream, (off_t)offset, whence);
diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c
index 2629492504..151fc7bf9d 100644
--- a/libs/libcurl/src/hostip.c
+++ b/libs/libcurl/src/hostip.c
@@ -798,7 +798,9 @@ enum resolve_t Curl_resolv(struct Curl_easy *data,
return CURLRESOLV_ERROR;
if(strcasecompare(hostname, "localhost") ||
- tailmatch(hostname, ".localhost"))
+ strcasecompare(hostname, "localhost.") ||
+ tailmatch(hostname, ".localhost") ||
+ tailmatch(hostname, ".localhost."))
addr = get_localhost(port, hostname);
#ifndef CURL_DISABLE_DOH
else if(allowDOH && data->set.doh && !ipnum)
diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c
index 6d61a9ec34..ed8a3598f1 100644
--- a/libs/libcurl/src/http.c
+++ b/libs/libcurl/src/http.c
@@ -1229,163 +1229,6 @@ static const char *get_http_string(const struct Curl_easy *data,
}
#endif
-enum proxy_use {
- HEADER_SERVER, /* direct to server */
- HEADER_PROXY, /* regular request to proxy */
- HEADER_CONNECT /* sending CONNECT to a proxy */
-};
-
-static bool hd_name_eq(const char *n1, size_t n1len,
- const char *n2, size_t n2len)
-{
- if(n1len == n2len) {
- return strncasecompare(n1, n2, n1len);
- }
- return FALSE;
-}
-
-CURLcode Curl_dynhds_add_custom(struct Curl_easy *data,
- bool is_connect,
- struct dynhds *hds)
-{
- struct connectdata *conn = data->conn;
- char *ptr;
- struct curl_slist *h[2];
- struct curl_slist *headers;
- int numlists = 1; /* by default */
- int i;
-
-#ifndef CURL_DISABLE_PROXY
- enum proxy_use proxy;
-
- if(is_connect)
- proxy = HEADER_CONNECT;
- else
- proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy ?
- HEADER_PROXY : HEADER_SERVER;
-
- switch(proxy) {
- case HEADER_SERVER:
- h[0] = data->set.headers;
- break;
- case HEADER_PROXY:
- h[0] = data->set.headers;
- if(data->set.sep_headers) {
- h[1] = data->set.proxyheaders;
- numlists++;
- }
- break;
- case HEADER_CONNECT:
- if(data->set.sep_headers)
- h[0] = data->set.proxyheaders;
- else
- h[0] = data->set.headers;
- break;
- }
-#else
- (void)is_connect;
- h[0] = data->set.headers;
-#endif
-
- /* loop through one or two lists */
- for(i = 0; i < numlists; i++) {
- for(headers = h[i]; headers; headers = headers->next) {
- const char *name, *value;
- size_t namelen, valuelen;
-
- /* There are 2 quirks in place for custom headers:
- * 1. setting only 'name:' to suppress a header from being sent
- * 2. setting only 'name;' to send an empty (illegal) header
- */
- ptr = strchr(headers->data, ':');
- if(ptr) {
- name = headers->data;
- namelen = ptr - headers->data;
- ptr++; /* pass the colon */
- while(*ptr && ISSPACE(*ptr))
- ptr++;
- if(*ptr) {
- value = ptr;
- valuelen = strlen(value);
- }
- else {
- /* quirk #1, suppress this header */
- continue;
- }
- }
- else {
- ptr = strchr(headers->data, ';');
-
- if(!ptr) {
- /* neither : nor ; in provided header value. We seem
- * to ignore this silently */
- continue;
- }
-
- name = headers->data;
- namelen = ptr - headers->data;
- ptr++; /* pass the semicolon */
- while(*ptr && ISSPACE(*ptr))
- ptr++;
- if(!*ptr) {
- /* quirk #2, send an empty header */
- value = "";
- valuelen = 0;
- }
- else {
- /* this may be used for something else in the future,
- * ignore this for now */
- continue;
- }
- }
-
- DEBUGASSERT(name && value);
- if(data->state.aptr.host &&
- /* a Host: header was sent already, do not pass on any custom Host:
- header as that will produce *two* in the same request! */
- hd_name_eq(name, namelen, STRCONST("Host:")))
- ;
- else if(data->state.httpreq == HTTPREQ_POST_FORM &&
- /* this header (extended by formdata.c) is sent later */
- hd_name_eq(name, namelen, STRCONST("Content-Type:")))
- ;
- else if(data->state.httpreq == HTTPREQ_POST_MIME &&
- /* this header is sent later */
- hd_name_eq(name, namelen, STRCONST("Content-Type:")))
- ;
- else if(data->req.authneg &&
- /* while doing auth neg, do not allow the custom length since
- we will force length zero then */
- hd_name_eq(name, namelen, STRCONST("Content-Length:")))
- ;
- else if(data->state.aptr.te &&
- /* when asking for Transfer-Encoding, do not pass on a custom
- Connection: */
- hd_name_eq(name, namelen, STRCONST("Connection:")))
- ;
- else if((conn->httpversion >= 20) &&
- hd_name_eq(name, namelen, STRCONST("Transfer-Encoding:")))
- /* HTTP/2 does not support chunked requests */
- ;
- else if((hd_name_eq(name, namelen, STRCONST("Authorization:")) ||
- hd_name_eq(name, namelen, STRCONST("Cookie:"))) &&
- /* be careful of sending this potentially sensitive header to
- other hosts */
- !Curl_auth_allowed_to_host(data))
- ;
- else {
- CURLcode result;
-
- result = Curl_dynhds_add(hds, name, namelen, value, valuelen);
- if(result)
- return result;
- }
- }
- }
-
- return CURLE_OK;
-}
-
CURLcode Curl_add_custom_headers(struct Curl_easy *data,
bool is_connect,
#ifndef USE_HYPER
@@ -1403,7 +1246,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
int i;
#ifndef CURL_DISABLE_PROXY
- enum proxy_use proxy;
+ enum Curl_proxy_use proxy;
if(is_connect)
proxy = HEADER_CONNECT;
diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h
index 677825ae73..c1b02dd992 100644
--- a/libs/libcurl/src/http.h
+++ b/libs/libcurl/src/http.h
@@ -89,9 +89,6 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
void *headers
#endif
);
-CURLcode Curl_dynhds_add_custom(struct Curl_easy *data,
- bool is_connect,
- struct dynhds *hds);
void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
const char **method, Curl_HttpReq *);
diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c
index b9a21d2987..c5f10c678b 100644
--- a/libs/libcurl/src/http2.c
+++ b/libs/libcurl/src/http2.c
@@ -433,6 +433,8 @@ static int h2_client_new(struct Curl_cfilter *cf,
{
struct cf_h2_ctx *ctx = cf->ctx;
nghttp2_option *o;
+ nghttp2_mem mem = {NULL, Curl_nghttp2_malloc, Curl_nghttp2_free,
+ Curl_nghttp2_calloc, Curl_nghttp2_realloc};
int rc = nghttp2_option_new(&o);
if(rc)
@@ -445,7 +447,7 @@ static int h2_client_new(struct Curl_cfilter *cf,
HTTP field value. */
nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1);
#endif
- rc = nghttp2_session_client_new2(&ctx->h2, cbs, cf, o);
+ rc = nghttp2_session_client_new3(&ctx->h2, cbs, cf, o, &mem);
nghttp2_option_del(o);
return rc;
}
@@ -2960,6 +2962,30 @@ bool Curl_h2_http_1_1_error(struct Curl_easy *data)
return FALSE;
}
+void *Curl_nghttp2_malloc(size_t size, void *user_data)
+{
+ (void)user_data;
+ return Curl_cmalloc(size);
+}
+
+void Curl_nghttp2_free(void *ptr, void *user_data)
+{
+ (void)user_data;
+ Curl_cfree(ptr);
+}
+
+void *Curl_nghttp2_calloc(size_t nmemb, size_t size, void *user_data)
+{
+ (void)user_data;
+ return Curl_ccalloc(nmemb, size);
+}
+
+void *Curl_nghttp2_realloc(void *ptr, size_t size, void *user_data)
+{
+ (void)user_data;
+ return Curl_crealloc(ptr, size);
+}
+
#else /* !USE_NGHTTP2 */
/* Satisfy external references even if http2 is not compiled in. */
diff --git a/libs/libcurl/src/http2.h b/libs/libcurl/src/http2.h
index 3c6ffae278..b67a7e170d 100644
--- a/libs/libcurl/src/http2.h
+++ b/libs/libcurl/src/http2.h
@@ -60,6 +60,11 @@ CURLcode Curl_http2_upgrade(struct Curl_easy *data,
struct connectdata *conn, int sockindex,
const char *ptr, size_t nread);
+void *Curl_nghttp2_malloc(size_t size, void *user_data);
+void Curl_nghttp2_free(void *ptr, void *user_data);
+void *Curl_nghttp2_calloc(size_t nmemb, size_t size, void *user_data);
+void *Curl_nghttp2_realloc(void *ptr, size_t size, void *user_data);
+
extern struct Curl_cftype Curl_cft_nghttp2;
#else /* USE_NGHTTP2 */
diff --git a/libs/libcurl/src/http_negotiate.c b/libs/libcurl/src/http_negotiate.c
index 858a797d8b..d8b44abdd1 100644
--- a/libs/libcurl/src/http_negotiate.c
+++ b/libs/libcurl/src/http_negotiate.c
@@ -110,7 +110,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn,
/* Check if the connection is using SSL and get the channel binding data */
#if defined(USE_SSL) && defined(HAVE_GSSAPI)
if(conn->handler->flags & PROTOPT_SSL) {
- Curl_dyn_init(&neg_ctx->channel_binding_data, SSL_CB_MAX_SIZE);
+ Curl_dyn_init(&neg_ctx->channel_binding_data, SSL_CB_MAX_SIZE + 1);
result = Curl_ssl_get_channel_binding(
data, FIRSTSOCKET, &neg_ctx->channel_binding_data);
if(result) {
diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c
index c2c7ef6e37..684bd738b6 100644
--- a/libs/libcurl/src/http_proxy.c
+++ b/libs/libcurl/src/http_proxy.c
@@ -45,12 +45,155 @@
#include "vtls/vtls.h"
#include "transfer.h"
#include "multiif.h"
+#include "vauth/vauth.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"
+static bool hd_name_eq(const char *n1, size_t n1len,
+ const char *n2, size_t n2len)
+{
+ return (n1len == n2len) ? strncasecompare(n1, n2, n1len) : FALSE;
+}
+
+static CURLcode dynhds_add_custom(struct Curl_easy *data,
+ bool is_connect,
+ struct dynhds *hds)
+{
+ struct connectdata *conn = data->conn;
+ char *ptr;
+ struct curl_slist *h[2];
+ struct curl_slist *headers;
+ int numlists = 1; /* by default */
+ int i;
+
+ enum Curl_proxy_use proxy;
+
+ if(is_connect)
+ proxy = HEADER_CONNECT;
+ else
+ proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy ?
+ HEADER_PROXY : HEADER_SERVER;
+
+ switch(proxy) {
+ case HEADER_SERVER:
+ h[0] = data->set.headers;
+ break;
+ case HEADER_PROXY:
+ h[0] = data->set.headers;
+ if(data->set.sep_headers) {
+ h[1] = data->set.proxyheaders;
+ numlists++;
+ }
+ break;
+ case HEADER_CONNECT:
+ if(data->set.sep_headers)
+ h[0] = data->set.proxyheaders;
+ else
+ h[0] = data->set.headers;
+ break;
+ }
+
+ /* loop through one or two lists */
+ for(i = 0; i < numlists; i++) {
+ for(headers = h[i]; headers; headers = headers->next) {
+ const char *name, *value;
+ size_t namelen, valuelen;
+
+ /* There are 2 quirks in place for custom headers:
+ * 1. setting only 'name:' to suppress a header from being sent
+ * 2. setting only 'name;' to send an empty (illegal) header
+ */
+ ptr = strchr(headers->data, ':');
+ if(ptr) {
+ name = headers->data;
+ namelen = ptr - headers->data;
+ ptr++; /* pass the colon */
+ while(*ptr && ISSPACE(*ptr))
+ ptr++;
+ if(*ptr) {
+ value = ptr;
+ valuelen = strlen(value);
+ }
+ else {
+ /* quirk #1, suppress this header */
+ continue;
+ }
+ }
+ else {
+ ptr = strchr(headers->data, ';');
+
+ if(!ptr) {
+ /* neither : nor ; in provided header value. We seem
+ * to ignore this silently */
+ continue;
+ }
+
+ name = headers->data;
+ namelen = ptr - headers->data;
+ ptr++; /* pass the semicolon */
+ while(*ptr && ISSPACE(*ptr))
+ ptr++;
+ if(!*ptr) {
+ /* quirk #2, send an empty header */
+ value = "";
+ valuelen = 0;
+ }
+ else {
+ /* this may be used for something else in the future,
+ * ignore this for now */
+ continue;
+ }
+ }
+
+ DEBUGASSERT(name && value);
+ if(data->state.aptr.host &&
+ /* a Host: header was sent already, do not pass on any custom Host:
+ header as that will produce *two* in the same request! */
+ hd_name_eq(name, namelen, STRCONST("Host:")))
+ ;
+ else if(data->state.httpreq == HTTPREQ_POST_FORM &&
+ /* this header (extended by formdata.c) is sent later */
+ hd_name_eq(name, namelen, STRCONST("Content-Type:")))
+ ;
+ else if(data->state.httpreq == HTTPREQ_POST_MIME &&
+ /* this header is sent later */
+ hd_name_eq(name, namelen, STRCONST("Content-Type:")))
+ ;
+ else if(data->req.authneg &&
+ /* while doing auth neg, do not allow the custom length since
+ we will force length zero then */
+ hd_name_eq(name, namelen, STRCONST("Content-Length:")))
+ ;
+ else if(data->state.aptr.te &&
+ /* when asking for Transfer-Encoding, do not pass on a custom
+ Connection: */
+ hd_name_eq(name, namelen, STRCONST("Connection:")))
+ ;
+ else if((conn->httpversion >= 20) &&
+ hd_name_eq(name, namelen, STRCONST("Transfer-Encoding:")))
+ /* HTTP/2 does not support chunked requests */
+ ;
+ else if((hd_name_eq(name, namelen, STRCONST("Authorization:")) ||
+ hd_name_eq(name, namelen, STRCONST("Cookie:"))) &&
+ /* be careful of sending this potentially sensitive header to
+ other hosts */
+ !Curl_auth_allowed_to_host(data))
+ ;
+ else {
+ CURLcode result;
+
+ result = Curl_dynhds_add(hds, name, namelen, value, valuelen);
+ if(result)
+ return result;
+ }
+ }
+ }
+
+ return CURLE_OK;
+}
CURLcode Curl_http_proxy_get_destination(struct Curl_cfilter *cf,
const char **phostname,
@@ -146,7 +289,7 @@ CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq,
goto out;
}
- result = Curl_dynhds_add_custom(data, TRUE, &req->headers);
+ result = dynhds_add_custom(data, TRUE, &req->headers);
out:
if(result && req) {
diff --git a/libs/libcurl/src/http_proxy.h b/libs/libcurl/src/http_proxy.h
index 5566a7c0bd..95f4c7522c 100644
--- a/libs/libcurl/src/http_proxy.h
+++ b/libs/libcurl/src/http_proxy.h
@@ -30,6 +30,12 @@
#include "urldata.h"
+enum Curl_proxy_use {
+ HEADER_SERVER, /* direct to server */
+ HEADER_PROXY, /* regular request to proxy */
+ HEADER_CONNECT /* sending CONNECT to a proxy */
+};
+
CURLcode Curl_http_proxy_get_destination(struct Curl_cfilter *cf,
const char **phostname,
int *pport, bool *pipv6_ip);
diff --git a/libs/libcurl/src/krb5.c b/libs/libcurl/src/krb5.c
index 22eef17139..bb1ea644a8 100644
--- a/libs/libcurl/src/krb5.c
+++ b/libs/libcurl/src/krb5.c
@@ -202,7 +202,8 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
data->set.str[STRING_SERVICE_NAME] :
"ftp";
const char *srv_host = "host";
- gss_buffer_desc input_buffer, output_buffer, _gssresp, *gssresp;
+ gss_buffer_desc input_buffer, output_buffer, *gssresp;
+ gss_buffer_desc _gssresp = GSS_C_EMPTY_BUFFER;
OM_uint32 maj, min;
gss_name_t gssname;
gss_ctx_id_t *context = app_data;
@@ -363,7 +364,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
free(_gssresp.value);
if(ret == AUTH_OK || service == srv_host)
- return ret;
+ break;
service = srv_host;
}
@@ -372,13 +373,13 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
static void krb5_end(void *app_data)
{
- OM_uint32 min;
- gss_ctx_id_t *context = app_data;
- if(*context != GSS_C_NO_CONTEXT) {
- OM_uint32 maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
- (void)maj;
- DEBUGASSERT(maj == GSS_S_COMPLETE);
- }
+ OM_uint32 min;
+ gss_ctx_id_t *context = app_data;
+ if(*context != GSS_C_NO_CONTEXT) {
+ OM_uint32 maj = gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
+ (void)maj;
+ DEBUGASSERT(maj == GSS_S_COMPLETE);
+ }
}
static const struct Curl_sec_client_mech Curl_krb5_client_mech = {
@@ -612,10 +613,10 @@ static ssize_t sec_recv(struct Curl_easy *data, int sockindex,
return total_read;
}
-/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
- and negotiating with the server. |from| can be NULL. */
+/* Send |length| bytes from |from| to the |sockindex| socket taking care of
+ encoding and negotiating with the server. |from| can be NULL. */
static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
- curl_socket_t fd, const char *from, int length)
+ int sockindex, const char *from, int length)
{
int bytes, htonl_bytes; /* 32-bit integers for htonl */
char *buffer = NULL;
@@ -649,12 +650,12 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
static const char *enc = "ENC ";
static const char *mic = "MIC ";
if(prot_level == PROT_PRIVATE)
- socket_write(data, fd, enc, 4);
+ socket_write(data, sockindex, enc, 4);
else
- socket_write(data, fd, mic, 4);
+ socket_write(data, sockindex, mic, 4);
- socket_write(data, fd, cmd_buffer, cmd_size);
- socket_write(data, fd, "\r\n", 2);
+ socket_write(data, sockindex, cmd_buffer, cmd_size);
+ socket_write(data, sockindex, "\r\n", 2);
infof(data, "Send: %s%s", prot_level == PROT_PRIVATE ? enc : mic,
cmd_buffer);
free(cmd_buffer);
@@ -662,14 +663,14 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn,
}
else {
htonl_bytes = (int)htonl((OM_uint32)bytes);
- socket_write(data, fd, &htonl_bytes, sizeof(htonl_bytes));
- socket_write(data, fd, buffer, curlx_sitouz(bytes));
+ socket_write(data, sockindex, &htonl_bytes, sizeof(htonl_bytes));
+ socket_write(data, sockindex, buffer, curlx_sitouz(bytes));
}
free(buffer);
}
static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn,
- curl_socket_t fd, const char *buffer, size_t length)
+ int sockindex, const char *buffer, size_t length)
{
ssize_t tx = 0, len = conn->buffer_size;
@@ -679,7 +680,7 @@ static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn,
if(length < (size_t)len)
len = length;
- do_sec_send(data, conn, fd, buffer, curlx_sztosi(len));
+ do_sec_send(data, conn, sockindex, buffer, curlx_sztosi(len));
length -= len;
buffer += len;
tx += len;
@@ -693,10 +694,9 @@ static ssize_t sec_send(struct Curl_easy *data, int sockindex,
CURLcode *err)
{
struct connectdata *conn = data->conn;
- curl_socket_t fd = conn->sock[sockindex];
(void)eos; /* unused */
*err = CURLE_OK;
- return sec_write(data, conn, fd, buffer, len);
+ return sec_write(data, conn, sockindex, buffer, len);
}
int Curl_sec_read_msg(struct Curl_easy *data, struct connectdata *conn,
diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c
index 6bc73526d7..4e73c241d8 100644
--- a/libs/libcurl/src/ldap.c
+++ b/libs/libcurl/src/ldap.c
@@ -825,8 +825,8 @@ static bool split_str(char *str, char ***out, size_t *count)
if(!res)
return FALSE;
- for(i = 0, s = strtok_r(str, ",", &lasts); s && i < items;
- s = strtok_r(NULL, ",", &lasts), i++)
+ for(i = 0, s = Curl_strtok_r(str, ",", &lasts); s && i < items;
+ s = Curl_strtok_r(NULL, ",", &lasts), i++)
res[i] = s;
*out = res;
diff --git a/libs/libcurl/src/md4.c b/libs/libcurl/src/md4.c
index cbeaa0ff55..f7e5865bae 100644
--- a/libs/libcurl/src/md4.c
+++ b/libs/libcurl/src/md4.c
@@ -115,6 +115,13 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
#elif defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4)
+#ifdef OPENSSL_COEXIST
+ #define MD4_CTX WOLFSSL_MD4_CTX
+ #define MD4_Init wolfSSL_MD4_Init
+ #define MD4_Update wolfSSL_MD4_Update
+ #define MD4_Final wolfSSL_MD4_Final
+#endif
+
#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
#elif defined(AN_APPLE_OS)
diff --git a/libs/libcurl/src/md5.c b/libs/libcurl/src/md5.c
index 2f7f913ad6..ed0f801aa2 100644
--- a/libs/libcurl/src/md5.c
+++ b/libs/libcurl/src/md5.c
@@ -106,7 +106,8 @@ static void my_md5_final(unsigned char *digest, void *ctx)
md5_digest(ctx, 16, digest);
}
-#elif defined(USE_OPENSSL_MD5) || defined(USE_WOLFSSL_MD5)
+#elif defined(USE_OPENSSL_MD5) || \
+ (defined(USE_WOLFSSL_MD5) && !defined(OPENSSL_COEXIST))
typedef MD5_CTX my_md5_ctx;
@@ -130,6 +131,30 @@ static void my_md5_final(unsigned char *digest, void *ctx)
(void)MD5_Final(digest, ctx);
}
+#elif defined(USE_WOLFSSL_MD5)
+
+typedef WOLFSSL_MD5_CTX my_md5_ctx;
+
+static CURLcode my_md5_init(void *ctx)
+{
+ if(!wolfSSL_MD5_Init(ctx))
+ return CURLE_OUT_OF_MEMORY;
+
+ return CURLE_OK;
+}
+
+static void my_md5_update(void *ctx,
+ const unsigned char *input,
+ unsigned int len)
+{
+ (void)wolfSSL_MD5_Update(ctx, input, len);
+}
+
+static void my_md5_final(unsigned char *digest, void *ctx)
+{
+ (void)wolfSSL_MD5_Final(digest, ctx);
+}
+
#elif defined(USE_MBEDTLS)
typedef mbedtls_md5_context my_md5_ctx;
diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c
index a07449888d..e9aba3488a 100644
--- a/libs/libcurl/src/mime.c
+++ b/libs/libcurl/src/mime.c
@@ -1926,6 +1926,7 @@ struct cr_mime_ctx {
curl_off_t total_len;
curl_off_t read_len;
CURLcode error_result;
+ struct bufq tmpbuf;
BIT(seen_eos);
BIT(errored);
};
@@ -1937,9 +1938,18 @@ static CURLcode cr_mime_init(struct Curl_easy *data,
(void)data;
ctx->total_len = -1;
ctx->read_len = 0;
+ Curl_bufq_init2(&ctx->tmpbuf, 1024, 1, BUFQ_OPT_NO_SPARES);
return CURLE_OK;
}
+static void cr_mime_close(struct Curl_easy *data,
+ struct Curl_creader *reader)
+{
+ struct cr_mime_ctx *ctx = reader->ctx;
+ (void)data;
+ Curl_bufq_free(&ctx->tmpbuf);
+}
+
/* Real client reader to installed client callbacks. */
static CURLcode cr_mime_read(struct Curl_easy *data,
struct Curl_creader *reader,
@@ -1948,6 +1958,7 @@ static CURLcode cr_mime_read(struct Curl_easy *data,
{
struct cr_mime_ctx *ctx = reader->ctx;
size_t nread;
+ char tmp[256];
/* Once we have errored, we will return the same error forever */
@@ -1973,18 +1984,46 @@ static CURLcode cr_mime_read(struct Curl_easy *data,
blen = (size_t)remain;
}
- if(blen <= 4) {
- /* TODO: Curl_mime_read() may go into an infinite loop when reading
- * such small lengths. Returning 0 bytes read is a fix that only works
- * as request upload buffers will get flushed eventually and larger
- * reads will happen again. */
- CURL_TRC_READ(data, "cr_mime_read(len=%zu), too small, return", blen);
- *pnread = 0;
- *peos = FALSE;
- goto out;
+ if(!Curl_bufq_is_empty(&ctx->tmpbuf)) {
+ CURLcode result = CURLE_OK;
+ ssize_t n = Curl_bufq_read(&ctx->tmpbuf, (unsigned char *)buf, blen,
+ &result);
+ if(n < 0) {
+ ctx->errored = TRUE;
+ ctx->error_result = result;
+ return result;
+ }
+ nread = (size_t)n;
+ }
+ else if(blen <= 4) {
+ /* Curl_mime_read() may go into an infinite loop when reading
+ * via a base64 encoder, as it stalls when the read buffer is too small
+ * to contain a complete 3 byte encoding. Read into a larger buffer
+ * and use that until empty. */
+ CURL_TRC_READ(data, "cr_mime_read(len=%zu), small read, using tmp", blen);
+ nread = Curl_mime_read(tmp, 1, sizeof(tmp), ctx->part);
+ if(nread <= sizeof(tmp)) {
+ CURLcode result = CURLE_OK;
+ ssize_t n = Curl_bufq_write(&ctx->tmpbuf, (unsigned char *)tmp, nread,
+ &result);
+ if(n < 0) {
+ ctx->errored = TRUE;
+ ctx->error_result = result;
+ return result;
+ }
+ /* stored it, read again */
+ n = Curl_bufq_read(&ctx->tmpbuf, (unsigned char *)buf, blen, &result);
+ if(n < 0) {
+ ctx->errored = TRUE;
+ ctx->error_result = result;
+ return result;
+ }
+ nread = (size_t)n;
+ }
}
+ else
+ nread = Curl_mime_read(buf, 1, blen, ctx->part);
- nread = Curl_mime_read(buf, 1, blen, ctx->part);
CURL_TRC_READ(data, "cr_mime_read(len=%zu), mime_read() -> %zd",
blen, nread);
@@ -2044,7 +2083,6 @@ static CURLcode cr_mime_read(struct Curl_easy *data,
break;
}
-out:
CURL_TRC_READ(data, "cr_mime_read(len=%zu, total=%" FMT_OFF_T
", read=%"FMT_OFF_T") -> %d, %zu, %d",
blen, ctx->total_len, ctx->read_len, CURLE_OK, *pnread, *peos);
@@ -2140,7 +2178,7 @@ static const struct Curl_crtype cr_mime = {
"cr-mime",
cr_mime_init,
cr_mime_read,
- Curl_creader_def_close,
+ cr_mime_close,
cr_mime_needs_rewind,
cr_mime_total_length,
cr_mime_resume_from,
diff --git a/libs/libcurl/src/mprintf.c b/libs/libcurl/src/mprintf.c
index 2e4a2580a3..5722c6d838 100644
--- a/libs/libcurl/src/mprintf.c
+++ b/libs/libcurl/src/mprintf.c
@@ -321,10 +321,10 @@ static int parsefmt(const char *format,
fmt++;
}
while(ISDIGIT(*fmt)) {
- if(precision > INT_MAX/10)
+ int n = *fmt - '0';
+ if(precision > (INT_MAX - n) / 10)
return PFMT_PREC;
- precision *= 10;
- precision += *fmt - '0';
+ precision = precision * 10 + n;
fmt++;
}
if(is_neg)
@@ -397,10 +397,10 @@ static int parsefmt(const char *format,
width = 0;
fmt--;
do {
- if(width > INT_MAX/10)
+ int n = *fmt - '0';
+ if(width > (INT_MAX - n) / 10)
return PFMT_WIDTH;
- width *= 10;
- width += *fmt - '0';
+ width = width * 10 + n;
fmt++;
} while(ISDIGIT(*fmt));
break;
diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c
index d89657e2f3..b79a577d9e 100644
--- a/libs/libcurl/src/multi.c
+++ b/libs/libcurl/src/multi.c
@@ -1541,6 +1541,9 @@ CURLMcode curl_multi_wakeup(CURLM *m)
if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) {
#ifdef USE_EVENTFD
buf = &val;
+ /* eventfd has a stringent rule of requiring the 8-byte buffer when
+ calling write(2) on it, which makes the sizeof(buf) below fine since
+ this is only used on 64-bit systems and then the pointer is 64-bit */
#else
buf[0] = 1;
#endif
@@ -3586,6 +3589,14 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
}
}
}
+ else {
+ /* Asked to run due to time-out. Clear the 'last_expire_ts' variable to
+ force Curl_update_timer() to trigger a callback to the app again even
+ if the same timeout is still the one to run after this call. That
+ handles the case when the application asks libcurl to run the timeout
+ prematurely. */
+ memset(&multi->last_expire_ts, 0, sizeof(multi->last_expire_ts));
+ }
result = multi_run_expired(&mrc);
if(result)
diff --git a/libs/libcurl/src/netrc.c b/libs/libcurl/src/netrc.c
index 59759fe4a9..fed826a12d 100644
--- a/libs/libcurl/src/netrc.c
+++ b/libs/libcurl/src/netrc.c
@@ -54,13 +54,16 @@ enum found_state {
PASSWORD
};
+#define FOUND_LOGIN 1
+#define FOUND_PASSWORD 2
+
#define NETRC_FILE_MISSING 1
#define NETRC_FAILED -1
#define NETRC_SUCCESS 0
-#define MAX_NETRC_LINE 4096
-#define MAX_NETRC_FILE (64*1024)
-#define MAX_NETRC_TOKEN 128
+#define MAX_NETRC_LINE 16384
+#define MAX_NETRC_FILE (128*1024)
+#define MAX_NETRC_TOKEN 4096
static CURLcode file2memory(const char *filename, struct dynbuf *filebuf)
{
@@ -94,24 +97,24 @@ done:
*/
static int parsenetrc(struct store_netrc *store,
const char *host,
- char **loginp,
+ char **loginp, /* might point to a username */
char **passwordp,
const char *netrcfile)
{
int retcode = NETRC_FILE_MISSING;
char *login = *loginp;
- char *password = *passwordp;
- bool specific_login = (login && *login != 0);
- bool login_alloc = FALSE;
- bool password_alloc = FALSE;
+ char *password = NULL;
+ bool specific_login = !!login; /* points to something */
enum host_lookup_state state = NOTHING;
- enum found_state found = NONE;
- bool our_login = TRUE; /* With specific_login, found *our* login name (or
- login-less line) */
+ enum found_state keyword = NONE;
+ unsigned char found = 0; /* login + password found bits, as they can come in
+ any order */
+ bool our_login = FALSE; /* found our login name */
bool done = FALSE;
char *netrcbuffer;
struct dynbuf token;
struct dynbuf *filebuf = &store->filebuf;
+ DEBUGASSERT(!*passwordp);
Curl_dyn_init(&token, MAX_NETRC_TOKEN);
if(!store->loaded) {
@@ -124,7 +127,7 @@ static int parsenetrc(struct store_netrc *store,
while(!done) {
char *tok = netrcbuffer;
- while(tok) {
+ while(tok && !done) {
char *tok_end;
bool quoted;
Curl_dyn_reset(&token);
@@ -198,11 +201,6 @@ static int parsenetrc(struct store_netrc *store,
}
}
- if((login && *login) && (password && *password)) {
- done = TRUE;
- break;
- }
-
tok = Curl_dyn_ptr(&token);
switch(state) {
@@ -212,11 +210,18 @@ static int parsenetrc(struct store_netrc *store,
contents begin with the next .netrc line and continue until a
null line (consecutive new-line characters) is encountered. */
state = MACDEF;
- else if(strcasecompare("machine", tok))
+ else if(strcasecompare("machine", tok)) {
/* the next tok is the machine name, this is in itself the delimiter
that starts the stuff entered for this machine, after this we
need to search for 'login' and 'password'. */
state = HOSTFOUND;
+ keyword = NONE;
+ found = 0;
+ our_login = FALSE;
+ Curl_safefree(password);
+ if(!specific_login)
+ Curl_safefree(login);
+ }
else if(strcasecompare("default", tok)) {
state = HOSTVALID;
retcode = NETRC_SUCCESS; /* we did find our host */
@@ -238,44 +243,54 @@ static int parsenetrc(struct store_netrc *store,
break;
case HOSTVALID:
/* we are now parsing sub-keywords concerning "our" host */
- if(found == LOGIN) {
- if(specific_login) {
+ if(keyword == LOGIN) {
+ if(specific_login)
our_login = !Curl_timestrcmp(login, tok);
- }
- else if(!login || Curl_timestrcmp(login, tok)) {
- if(login_alloc)
- free(login);
+ else {
+ our_login = TRUE;
+ free(login);
login = strdup(tok);
if(!login) {
retcode = NETRC_FAILED; /* allocation failed */
goto out;
}
- login_alloc = TRUE;
}
- found = NONE;
+ found |= FOUND_LOGIN;
+ keyword = NONE;
}
- else if(found == PASSWORD) {
- if((our_login || !specific_login) &&
- (!password || Curl_timestrcmp(password, tok))) {
- if(password_alloc)
- free(password);
- password = strdup(tok);
- if(!password) {
- retcode = NETRC_FAILED; /* allocation failed */
- goto out;
- }
- password_alloc = TRUE;
+ else if(keyword == PASSWORD) {
+ free(password);
+ password = strdup(tok);
+ if(!password) {
+ retcode = NETRC_FAILED; /* allocation failed */
+ goto out;
}
- found = NONE;
+ found |= FOUND_PASSWORD;
+ keyword = NONE;
}
else if(strcasecompare("login", tok))
- found = LOGIN;
+ keyword = LOGIN;
else if(strcasecompare("password", tok))
- found = PASSWORD;
+ keyword = PASSWORD;
else if(strcasecompare("machine", tok)) {
- /* ok, there is machine here go => */
+ /* a new machine here */
state = HOSTFOUND;
- found = NONE;
+ keyword = NONE;
+ found = 0;
+ Curl_safefree(password);
+ if(!specific_login)
+ Curl_safefree(login);
+ }
+ else if(strcasecompare("default", tok)) {
+ state = HOSTVALID;
+ retcode = NETRC_SUCCESS; /* we did find our host */
+ Curl_safefree(password);
+ if(!specific_login)
+ Curl_safefree(login);
+ }
+ if((found == (FOUND_PASSWORD|FOUND_LOGIN)) && our_login) {
+ done = TRUE;
+ break;
}
break;
} /* switch (state) */
@@ -294,23 +309,23 @@ static int parsenetrc(struct store_netrc *store,
out:
Curl_dyn_free(&token);
+ if(!retcode && !password && our_login) {
+ /* success without a password, set a blank one */
+ password = strdup("");
+ if(!password)
+ retcode = 1; /* out of memory */
+ }
if(!retcode) {
/* success */
- if(login_alloc) {
- free(*loginp);
+ if(!specific_login)
*loginp = login;
- }
- if(password_alloc) {
- free(*passwordp);
- *passwordp = password;
- }
+ *passwordp = password;
}
else {
Curl_dyn_free(filebuf);
- if(login_alloc)
+ if(!specific_login)
free(login);
- if(password_alloc)
- free(password);
+ free(password);
}
return retcode;
diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c
index 0aff2d4bb8..356515a3f4 100644
--- a/libs/libcurl/src/rtsp.c
+++ b/libs/libcurl/src/rtsp.c
@@ -213,6 +213,11 @@ static CURLcode rtsp_done(struct Curl_easy *data,
(data->conn->proto.rtspc.rtp_channel == -1)) {
infof(data, "Got an RTP Receive with a CSeq of %ld", CSeq_recv);
}
+ if(data->set.rtspreq == RTSPREQ_RECEIVE &&
+ data->req.eos_written) {
+ failf(data, "Server prematurely closed the RTSP connection.");
+ return CURLE_RECV_ERROR;
+ }
}
return httpStatus;
diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c
index d02fca6c8f..13a4754da3 100644
--- a/libs/libcurl/src/setopt.c
+++ b/libs/libcurl/src/setopt.c
@@ -1146,7 +1146,7 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
/*
* raw data passed to the application when content encoding is used
*/
- data->set.http_ce_skip = enabled;
+ data->set.http_ce_skip = !enabled; /* reversed */
break;
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH)
@@ -1768,6 +1768,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option,
Curl_safefree(data->set.str[STRING_COPYPOSTFIELDS]);
data->set.method = HTTPREQ_POST;
break;
+#endif /* ! CURL_DISABLE_HTTP || ! CURL_DISABLE_MQTT */
#ifndef CURL_DISABLE_HTTP
case CURLOPT_ACCEPT_ENCODING:
@@ -2186,7 +2187,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option,
* proxy exception list
*/
return Curl_setstropt(&data->set.str[STRING_NOPROXY], ptr);
-#endif
+#endif /* ! CURL_DISABLE_PROXY */
case CURLOPT_RANGE:
/*
@@ -2194,7 +2195,6 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option,
*/
return Curl_setstropt(&data->set.str[STRING_SET_RANGE], ptr);
-#endif /* ! CURL_DISABLE_PROXY */
case CURLOPT_CURLU:
/*
* pass CURLU to set URL
diff --git a/libs/libcurl/src/smb.c b/libs/libcurl/src/smb.c
index b99064820b..34439a6510 100644
--- a/libs/libcurl/src/smb.c
+++ b/libs/libcurl/src/smb.c
@@ -27,12 +27,6 @@
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE)
-#ifdef _WIN32
-#define Curl_getpid() ((unsigned int)GetCurrentProcessId())
-#else
-#define Curl_getpid() ((unsigned int)getpid())
-#endif
-
#include "smb.h"
#include "urldata.h"
#include "sendf.h"
@@ -548,7 +542,7 @@ static void smb_format_message(struct Curl_easy *data, struct smb_header *h,
h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME);
h->uid = smb_swap16(smbc->uid);
h->tid = smb_swap16(req->tid);
- pid = Curl_getpid();
+ pid = (unsigned int)Curl_getpid();
h->pid_high = smb_swap16((unsigned short)(pid >> 16));
h->pid = smb_swap16((unsigned short) pid);
}
diff --git a/libs/libcurl/src/socketpair.h b/libs/libcurl/src/socketpair.h
index d3fa60c135..a8a011d753 100644
--- a/libs/libcurl/src/socketpair.h
+++ b/libs/libcurl/src/socketpair.h
@@ -27,14 +27,14 @@
#include "curl_setup.h"
#if defined(HAVE_EVENTFD) && \
- defined(__x86_64__) && \
- defined(__aarch64__) && \
- defined(__ia64__) && \
- defined(__ppc64__) && \
- defined(__mips64) && \
- defined(__sparc64__) && \
- defined(__riscv_64e) && \
- defined(__s390x__)
+ (defined(__x86_64__) || \
+ defined(__aarch64__) || \
+ defined(__ia64__) || \
+ defined(__ppc64__) || \
+ defined(__mips64) || \
+ defined(__sparc64__) || \
+ defined(__riscv_64e) || \
+ defined(__s390x__))
/* Use eventfd only with 64-bit CPU architectures because eventfd has a
* stringent rule of requiring the 8-byte buffer when calling read(2) and
diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c
index 7b8d4876c8..41c8887f54 100644
--- a/libs/libcurl/src/strerror.c
+++ b/libs/libcurl/src/strerror.c
@@ -151,9 +151,6 @@ curl_easy_strerror(CURLcode error)
case CURLE_RANGE_ERROR:
return "Requested range was not delivered by the server";
- case CURLE_HTTP_POST_ERROR:
- return "Internal problem setting up the POST";
-
case CURLE_SSL_CONNECT_ERROR:
return "SSL connect error";
@@ -169,9 +166,6 @@ curl_easy_strerror(CURLcode error)
case CURLE_LDAP_SEARCH_FAILED:
return "LDAP: search failed";
- case CURLE_FUNCTION_NOT_FOUND:
- return "A required function in the library was not found";
-
case CURLE_ABORTED_BY_CALLBACK:
return "Operation was aborted by an application callback";
@@ -330,7 +324,9 @@ curl_easy_strerror(CURLcode error)
case CURLE_OBSOLETE24:
case CURLE_OBSOLETE29:
case CURLE_OBSOLETE32:
+ case CURLE_OBSOLETE34:
case CURLE_OBSOLETE40:
+ case CURLE_OBSOLETE41:
case CURLE_OBSOLETE44:
case CURLE_OBSOLETE46:
case CURLE_OBSOLETE50:
diff --git a/libs/libcurl/src/strtok.h b/libs/libcurl/src/strtok.h
index 0cff3213ab..9890090b56 100644
--- a/libs/libcurl/src/strtok.h
+++ b/libs/libcurl/src/strtok.h
@@ -26,11 +26,11 @@
#include "curl_setup.h"
#include <stddef.h>
-#ifndef HAVE_STRTOK_R
-char *Curl_strtok_r(char *s, const char *delim, char **last);
-#define strtok_r Curl_strtok_r
-#else
+#ifdef HAVE_STRTOK_R
#include <string.h>
+#define Curl_strtok_r strtok_r
+#else
+char *Curl_strtok_r(char *s, const char *delim, char **last);
#endif
#endif /* HEADER_CURL_STRTOK_H */
diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c
index 28c37019ea..dcb3e2ab2b 100644
--- a/libs/libcurl/src/url.c
+++ b/libs/libcurl/src/url.c
@@ -2651,6 +2651,17 @@ static CURLcode parse_remote_port(struct Curl_easy *data,
return CURLE_OK;
}
+static bool str_has_ctrl(const char *input)
+{
+ const unsigned char *str = (const unsigned char *)input;
+ while(*str) {
+ if(*str < 0x20)
+ return TRUE;
+ str++;
+ }
+ return FALSE;
+}
+
/*
* Override the login details from the URL with that in the CURLOPT_USERPWD
* option or a .netrc file, if applicable.
@@ -2682,29 +2693,40 @@ static CURLcode override_login(struct Curl_easy *data,
if(data->state.aptr.user &&
(data->state.creds_from != CREDS_NETRC)) {
- /* there was a username in the URL. Use the URL decoded version */
+ /* there was a username with a length in the URL. Use the URL decoded
+ version */
userp = &data->state.aptr.user;
url_provided = TRUE;
}
- ret = Curl_parsenetrc(&data->state.netrc, conn->host.name,
- userp, passwdp,
- data->set.str[STRING_NETRC_FILE]);
- if(ret > 0) {
- infof(data, "Couldn't find host %s in the %s file; using defaults",
- conn->host.name,
- (data->set.str[STRING_NETRC_FILE] ?
- data->set.str[STRING_NETRC_FILE] : ".netrc"));
- }
- else if(ret < 0) {
- failf(data, ".netrc parser error");
- return CURLE_READ_ERROR;
- }
- else {
- /* set bits.netrc TRUE to remember that we got the name from a .netrc
- file, so that it is safe to use even if we followed a Location: to a
- different host or similar. */
- conn->bits.netrc = TRUE;
+ if(!*passwdp) {
+ ret = Curl_parsenetrc(&data->state.netrc, conn->host.name,
+ userp, passwdp,
+ data->set.str[STRING_NETRC_FILE]);
+ if(ret > 0) {
+ infof(data, "Couldn't find host %s in the %s file; using defaults",
+ conn->host.name,
+ (data->set.str[STRING_NETRC_FILE] ?
+ data->set.str[STRING_NETRC_FILE] : ".netrc"));
+ }
+ else if(ret < 0) {
+ failf(data, ".netrc parser error");
+ return CURLE_READ_ERROR;
+ }
+ else {
+ if(!(conn->handler->flags&PROTOPT_USERPWDCTRL)) {
+ /* if the protocol can't handle control codes in credentials, make
+ sure there are none */
+ if(str_has_ctrl(*userp) || str_has_ctrl(*passwdp)) {
+ failf(data, "control code detected in .netrc credentials");
+ return CURLE_READ_ERROR;
+ }
+ }
+ /* set bits.netrc TRUE to remember that we got the name from a .netrc
+ file, so that it is safe to use even if we followed a Location: to a
+ different host or similar. */
+ conn->bits.netrc = TRUE;
+ }
}
if(url_provided) {
Curl_safefree(conn->user);
diff --git a/libs/libcurl/src/vauth/digest.c b/libs/libcurl/src/vauth/digest.c
index 84a706afc5..98e32900db 100644
--- a/libs/libcurl/src/vauth/digest.c
+++ b/libs/libcurl/src/vauth/digest.c
@@ -227,12 +227,12 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value)
*value = 0;
/* Tokenise the list of qop values. Use a temporary clone of the buffer since
- strtok_r() ruins it. */
+ Curl_strtok_r() ruins it. */
tmp = strdup(options);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
- token = strtok_r(tmp, ",", &tok_buf);
+ token = Curl_strtok_r(tmp, ",", &tok_buf);
while(token) {
if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH))
*value |= DIGEST_QOP_VALUE_AUTH;
@@ -241,7 +241,7 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value)
else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
*value |= DIGEST_QOP_VALUE_AUTH_CONF;
- token = strtok_r(NULL, ",", &tok_buf);
+ token = Curl_strtok_r(NULL, ",", &tok_buf);
}
free(tmp);
@@ -553,12 +553,12 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
else if(strcasecompare(value, "qop")) {
char *tok_buf = NULL;
/* Tokenize the list and choose auth if possible, use a temporary
- clone of the buffer since strtok_r() ruins it */
+ clone of the buffer since Curl_strtok_r() ruins it */
tmp = strdup(content);
if(!tmp)
return CURLE_OUT_OF_MEMORY;
- token = strtok_r(tmp, ",", &tok_buf);
+ token = Curl_strtok_r(tmp, ",", &tok_buf);
while(token) {
/* Pass additional spaces here */
while(*token && ISBLANK(*token))
@@ -569,7 +569,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
foundAuthInt = TRUE;
}
- token = strtok_r(NULL, ",", &tok_buf);
+ token = Curl_strtok_r(NULL, ",", &tok_buf);
}
free(tmp);
@@ -709,13 +709,17 @@ static CURLcode auth_create_digest_http_message(
digest->nc = 1;
if(!digest->cnonce) {
- char cnoncebuf[33];
- result = Curl_rand_hex(data, (unsigned char *)cnoncebuf,
- sizeof(cnoncebuf));
+ char cnoncebuf[12];
+ result = Curl_rand_bytes(data,
+#ifdef DEBUGBUILD
+ TRUE,
+#endif
+ (unsigned char *)cnoncebuf,
+ sizeof(cnoncebuf));
if(result)
return result;
- result = Curl_base64_encode(cnoncebuf, strlen(cnoncebuf),
+ result = Curl_base64_encode(cnoncebuf, sizeof(cnoncebuf),
&cnonce, &cnonce_sz);
if(result)
return result;
diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c
index 34eaa314f2..6e92c1c5ee 100644
--- a/libs/libcurl/src/version.c
+++ b/libs/libcurl/src/version.c
@@ -551,7 +551,7 @@ static const struct feat features_table[] = {
#ifdef HAVE_ZSTD
FEATURE("zstd", NULL, CURL_VERSION_ZSTD),
#endif
- {NULL, NULL, 0}
+ {NULL, NULL, 0}
};
static const char *feature_names[sizeof(features_table) /
diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c
index b1e9e79396..2e84fbeea8 100644
--- a/libs/libcurl/src/vssh/libssh.c
+++ b/libs/libcurl/src/vssh/libssh.c
@@ -1368,7 +1368,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
state machine to move on as soon as possible so we set a very short
timeout here */
Curl_expire(data, 0, EXPIRE_RUN_NOW);
-
+#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0)
+ sshc->sftp_send_state = 0;
+#endif
state(data, SSH_STOP);
break;
}
@@ -1772,6 +1774,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
/* during times we get here due to a broken transfer and then the
sftp_handle might not have been taken down so make sure that is done
before we proceed */
+ ssh_set_blocking(sshc->ssh_session, 0);
+#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0)
+ if(sshc->sftp_aio) {
+ sftp_aio_free(sshc->sftp_aio);
+ sshc->sftp_aio = NULL;
+ }
+#endif
if(sshc->sftp_file) {
sftp_close(sshc->sftp_file);
@@ -2191,7 +2200,14 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done)
return CURLE_FAILED_INIT;
}
- rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name);
+ if(conn->bits.ipv6_ip) {
+ char ipv6[MAX_IPADR_LEN];
+ msnprintf(ipv6, sizeof(ipv6), "[%s]", conn->host.name);
+ rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, ipv6);
+ }
+ else
+ rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_HOST, conn->host.name);
+
if(rc != SSH_OK) {
failf(data, "Could not set remote host");
return CURLE_FAILED_INIT;
@@ -2563,7 +2579,39 @@ static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
*/
if(len > 32768)
len = 32768;
-
+#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0)
+ switch(conn->proto.sshc.sftp_send_state) {
+ case 0:
+ sftp_file_set_nonblocking(conn->proto.sshc.sftp_file);
+ if(sftp_aio_begin_write(conn->proto.sshc.sftp_file, mem, len,
+ &conn->proto.sshc.sftp_aio) == SSH_ERROR) {
+ *err = CURLE_SEND_ERROR;
+ return -1;
+ }
+ conn->proto.sshc.sftp_send_state = 1;
+ FALLTHROUGH();
+ case 1:
+ nwrite = sftp_aio_wait_write(&conn->proto.sshc.sftp_aio);
+ myssh_block2waitfor(conn, (nwrite == SSH_AGAIN) ? TRUE : FALSE);
+ if(nwrite == SSH_AGAIN) {
+ *err = CURLE_AGAIN;
+ return 0;
+ }
+ else if(nwrite < 0) {
+ *err = CURLE_SEND_ERROR;
+ return -1;
+ }
+ if(conn->proto.sshc.sftp_aio) {
+ sftp_aio_free(conn->proto.sshc.sftp_aio);
+ conn->proto.sshc.sftp_aio = NULL;
+ }
+ conn->proto.sshc.sftp_send_state = 0;
+ return nwrite;
+ default:
+ /* we never reach here */
+ return -1;
+ }
+#else
nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
myssh_block2waitfor(conn, FALSE);
@@ -2581,6 +2629,7 @@ static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
}
return nwrite;
+#endif
}
/*
diff --git a/libs/libcurl/src/vssh/ssh.h b/libs/libcurl/src/vssh/ssh.h
index 192c1d7970..3178e305bd 100644
--- a/libs/libcurl/src/vssh/ssh.h
+++ b/libs/libcurl/src/vssh/ssh.h
@@ -177,6 +177,10 @@ struct ssh_conn {
sftp_dir sftp_dir;
unsigned sftp_recv_state; /* 0 or 1 */
+#if LIBSSH_VERSION_INT > SSH_VERSION_INT(0, 11, 0)
+ sftp_aio sftp_aio;
+ unsigned sftp_send_state; /* 0 or 1 */
+#endif
int sftp_file_index; /* for async read */
sftp_attributes readdir_attrs; /* used by the SFTP readdir actions */
sftp_attributes readdir_link_attrs; /* used by the SFTP readdir actions */
diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c
index 20226b74bd..ae2acdb0a0 100644
--- a/libs/libcurl/src/vtls/mbedtls.c
+++ b/libs/libcurl/src/vtls/mbedtls.c
@@ -54,7 +54,7 @@
# ifdef MBEDTLS_DEBUG
# include <mbedtls/debug.h>
# endif
-#endif
+#endif /* MBEDTLS_VERSION_MAJOR >= 2 */
#include "cipher_suite.h"
#include "strcase.h"
@@ -122,7 +122,7 @@ struct mbed_ssl_backend_data {
#define HAS_SESSION_TICKETS
#endif
-#if defined(THREADING_SUPPORT)
+#ifdef THREADING_SUPPORT
static mbedtls_entropy_context ts_entropy;
static int entropy_init_initialized = 0;
@@ -585,16 +585,6 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
return CURLE_NOT_BUILT_IN;
}
-#ifdef TLS13_SUPPORT
- ret = psa_crypto_init();
- if(ret != PSA_SUCCESS) {
- mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
- failf(data, "mbedTLS psa_crypto_init returned (-0x%04X) %s",
- -ret, errorbuf);
- return CURLE_SSL_CONNECT_ERROR;
- }
-#endif /* TLS13_SUPPORT */
-
#ifdef THREADING_SUPPORT
mbedtls_ctr_drbg_init(&backend->ctr_drbg);
@@ -1571,6 +1561,20 @@ static int mbedtls_init(void)
#ifdef THREADING_SUPPORT
entropy_init_mutex(&ts_entropy);
#endif
+#ifdef TLS13_SUPPORT
+ {
+ int ret;
+#ifdef THREADING_SUPPORT
+ Curl_mbedtlsthreadlock_lock_function(0);
+#endif
+ ret = psa_crypto_init();
+#ifdef THREADING_SUPPORT
+ Curl_mbedtlsthreadlock_unlock_function(0);
+#endif
+ if(ret != PSA_SUCCESS)
+ return 0;
+ }
+#endif /* TLS13_SUPPORT */
return 1;
}
diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c
index 86931089b1..ed4dd5df1f 100644
--- a/libs/libcurl/src/vtls/openssl.c
+++ b/libs/libcurl/src/vtls/openssl.c
@@ -83,7 +83,7 @@
#include <openssl/evp.h>
#ifdef USE_ECH
-# ifndef OPENSSL_IS_BORINGSSL
+# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
# include <openssl/ech.h>
# endif
# include "curl_base64.h"
@@ -1152,9 +1152,8 @@ static bool is_pkcs11_uri(const char *string)
static CURLcode ossl_set_engine(struct Curl_easy *data, const char *engine);
-static int
-SSL_CTX_use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob,
- int type, const char *key_passwd)
+static int use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob,
+ int type, const char *key_passwd)
{
int ret = 0;
X509 *x = NULL;
@@ -1190,9 +1189,8 @@ end:
return ret;
}
-static int
-SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob,
- int type, const char *key_passwd)
+static int use_privatekey_blob(SSL_CTX *ctx, const struct curl_blob *blob,
+ int type, const char *key_passwd)
{
int ret = 0;
EVP_PKEY *pkey = NULL;
@@ -1205,14 +1203,12 @@ SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob,
(void *)key_passwd);
else if(type == SSL_FILETYPE_ASN1)
pkey = d2i_PrivateKey_bio(in, NULL);
- else {
- ret = 0;
+ else
goto end;
- }
- if(!pkey) {
- ret = 0;
+
+ if(!pkey)
goto end;
- }
+
ret = SSL_CTX_use_PrivateKey(ctx, pkey);
EVP_PKEY_free(pkey);
end:
@@ -1221,8 +1217,8 @@ end:
}
static int
-SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob,
- const char *key_passwd)
+use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob,
+ const char *key_passwd)
{
/* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */
#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* OpenSSL 1.0.2 or later */ \
@@ -1239,11 +1235,8 @@ SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob,
x = PEM_read_bio_X509_AUX(in, NULL,
passwd_callback, (void *)key_passwd);
-
- if(!x) {
- ret = 0;
+ if(!x)
goto end;
- }
ret = SSL_CTX_use_certificate(ctx, x);
@@ -1324,7 +1317,7 @@ int cert_stuff(struct Curl_easy *data,
case SSL_FILETYPE_PEM:
/* SSL_CTX_use_certificate_chain_file() only works on PEM files */
cert_use_result = cert_blob ?
- SSL_CTX_use_certificate_chain_blob(ctx, cert_blob, key_passwd) :
+ use_certificate_chain_blob(ctx, cert_blob, key_passwd) :
SSL_CTX_use_certificate_chain_file(ctx, cert_file);
if(cert_use_result != 1) {
failf(data,
@@ -1344,8 +1337,7 @@ int cert_stuff(struct Curl_easy *data,
ASN1 files. */
cert_use_result = cert_blob ?
- SSL_CTX_use_certificate_blob(ctx, cert_blob,
- file_type, key_passwd) :
+ use_certificate_blob(ctx, cert_blob, file_type, key_passwd) :
SSL_CTX_use_certificate_file(ctx, cert_file, file_type);
if(cert_use_result != 1) {
failf(data,
@@ -1554,7 +1546,7 @@ fail:
FALLTHROUGH();
case SSL_FILETYPE_ASN1:
cert_use_result = key_blob ?
- SSL_CTX_use_PrivateKey_blob(ctx, key_blob, file_type, key_passwd) :
+ use_privatekey_blob(ctx, key_blob, file_type, key_passwd) :
SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type);
if(cert_use_result != 1) {
failf(data, "unable to set private key file: '%s' type %s",
@@ -3674,14 +3666,14 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
SSL_CTX_set_mode(octx->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif
-#ifdef HAS_ALPN
if(alpn && alpn_len) {
+#ifdef HAS_ALPN
if(SSL_CTX_set_alpn_protos(octx->ssl_ctx, alpn, (int)alpn_len)) {
failf(data, "Error setting ALPN");
return CURLE_SSL_CONNECT_ERROR;
}
- }
#endif
+ }
if(ssl_cert || ssl_cert_blob || ssl_cert_type) {
if(!result &&
@@ -3849,15 +3841,15 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
if(data->set.tls_ech & CURLECH_GREASE) {
infof(data, "ECH: will GREASE ClientHello");
-# ifdef OPENSSL_IS_BORINGSSL
+# if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
SSL_set_enable_ech_grease(octx->ssl, 1);
# else
SSL_set_options(octx->ssl, SSL_OP_ECH_GREASE);
# endif
}
else if(data->set.tls_ech & CURLECH_CLA_CFG) {
-# ifdef OPENSSL_IS_BORINGSSL
- /* have to do base64 decode here for boring */
+# if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+ /* have to do base64 decode here for BoringSSL */
const char *b64 = data->set.str[STRING_ECH_CONFIG];
if(!b64) {
@@ -3917,7 +3909,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
size_t elen = rinfo->echconfiglist_len;
infof(data, "ECH: ECHConfig from DoH HTTPS RR");
-# ifndef OPENSSL_IS_BORINGSSL
+# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
if(SSL_ech_set1_echconfig(octx->ssl, ecl, elen) != 1) {
infof(data, "ECH: SSL_ECH_set1_echconfig failed");
if(data->set.tls_ech & CURLECH_HARD)
@@ -3925,7 +3917,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
}
# else
if(SSL_set1_ech_config_list(octx->ssl, ecl, elen) != 1) {
- infof(data, "ECH: SSL_set1_ech_config_list failed (boring)");
+ infof(data, "ECH: SSL_set1_ech_config_list failed (BoringSSL)");
if(data->set.tls_ech & CURLECH_HARD)
return CURLE_SSL_CONNECT_ERROR;
}
@@ -3943,7 +3935,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
Curl_resolv_unlink(data, &dns);
}
}
-# ifdef OPENSSL_IS_BORINGSSL
+# if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
if(trying_ech_now && outername) {
infof(data, "ECH: setting public_name not supported with BoringSSL");
return CURLE_SSL_CONNECT_ERROR;
@@ -3960,7 +3952,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
return CURLE_SSL_CONNECT_ERROR;
}
}
-# endif /* not BORING */
+# endif /* OPENSSL_IS_BORINGSSL || OPENSSL_IS_AWSLC */
if(trying_ech_now
&& SSL_set_min_proto_version(octx->ssl, TLS1_3_VERSION) != 1) {
infof(data, "ECH: cannot force TLSv1.3 [ERROR]");
@@ -4071,7 +4063,7 @@ static void ossl_trace_ech_retry_configs(struct Curl_easy *data, SSL* ssl,
CURLcode result = CURLE_OK;
size_t rcl = 0;
int rv = 1;
-# ifndef OPENSSL_IS_BORINGSSL
+# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
char *inner = NULL;
unsigned char *rcs = NULL;
char *outer = NULL;
@@ -4086,7 +4078,7 @@ static void ossl_trace_ech_retry_configs(struct Curl_easy *data, SSL* ssl,
/* nothing to trace if not doing ECH */
if(!ECH_ENABLED(data))
return;
-# ifndef OPENSSL_IS_BORINGSSL
+# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
rv = SSL_ech_get_retry_config(ssl, &rcs, &rcl);
# else
SSL_get0_ech_retry_configs(ssl, &rcs, &rcl);
@@ -4103,23 +4095,23 @@ static void ossl_trace_ech_retry_configs(struct Curl_easy *data, SSL* ssl,
if(!result && b64str)
infof(data, "ECH: retry_configs %s", b64str);
free(b64str);
-# ifndef OPENSSL_IS_BORINGSSL
+# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
rv = SSL_ech_get_status(ssl, &inner, &outer);
infof(data, "ECH: retry_configs for %s from %s, %d %d",
inner ? inner : "NULL", outer ? outer : "NULL", reason, rv);
-#else
+# else
rv = SSL_ech_accepted(ssl);
servername_type = SSL_get_servername_type(ssl);
inner = SSL_get_servername(ssl, servername_type);
SSL_get0_ech_name_override(ssl, &outer, &out_name_len);
- /* TODO: get the inner from boring */
+ /* TODO: get the inner from BoringSSL */
infof(data, "ECH: retry_configs for %s from %s, %d %d",
inner ? inner : "NULL", outer ? outer : "NULL", reason, rv);
-#endif
+# endif
}
else
infof(data, "ECH: no retry_configs (rv = %d)", rv);
-# ifndef OPENSSL_IS_BORINGSSL
+# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
OPENSSL_free((void *)rcs);
# endif
return;
@@ -4220,14 +4212,11 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
lerr = SSL_get_verify_result(octx->ssl);
if(lerr != X509_V_OK) {
ssl_config->certverifyresult = lerr;
- msnprintf(error_buffer, sizeof(error_buffer),
- "SSL certificate problem: %s",
- X509_verify_cert_error_string(lerr));
+ failf(data, "SSL certificate problem: %s",
+ X509_verify_cert_error_string(lerr));
}
- else {
+ else
failf(data, "%s", "SSL certificate verification failed");
- return result;
- }
}
#if defined(SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)
/* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on
@@ -4243,7 +4232,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
#endif
#ifdef USE_ECH
else if((lib == ERR_LIB_SSL) &&
-# ifndef OPENSSL_IS_BORINGSSL
+# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
(reason == SSL_R_ECH_REQUIRED)) {
# else
(reason == SSL_R_ECH_REJECTED)) {
@@ -4278,7 +4267,6 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%d ",
extramsg[0] ? extramsg : SSL_ERROR_to_str(detail),
connssl->peer.hostname, connssl->peer.port);
- return result;
}
return result;
@@ -4309,7 +4297,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
OBJ_nid2sn(psigtype_nid));
#ifdef USE_ECH
-# ifndef OPENSSL_IS_BORINGSSL
+# if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
if(ECH_ENABLED(data)) {
char *inner = NULL, *outer = NULL;
const char *status = NULL;
@@ -4367,7 +4355,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf,
else {
infof(data, "ECH: result: status is not attempted");
}
-# endif /* BORING */
+# endif /* !OPENSSL_IS_BORINGSSL && !OPENSSL_IS_AWSLC */
#endif /* USE_ECH */
#ifdef HAS_ALPN
diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c
index 85d018d322..1c9ecc673a 100644
--- a/libs/libcurl/src/vtls/schannel.c
+++ b/libs/libcurl/src/vtls/schannel.c
@@ -451,11 +451,6 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,
}
#endif
-static bool algo(const char *check, char *namep, size_t nlen)
-{
- return (strlen(check) == nlen) && !strncmp(check, namep, nlen);
-}
-
static CURLcode
schannel_acquire_credential_handle(struct Curl_cfilter *cf,
struct Curl_easy *data)
@@ -781,187 +776,14 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
curlx_verify_windows_version(10, 0, 17763, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
- char *ciphers13 = 0;
-
- bool disable_aes_gcm_sha384 = FALSE;
- bool disable_aes_gcm_sha256 = FALSE;
- bool disable_chacha_poly = FALSE;
- bool disable_aes_ccm_8_sha256 = FALSE;
- bool disable_aes_ccm_sha256 = FALSE;
-
SCH_CREDENTIALS credentials = { 0 };
TLS_PARAMETERS tls_parameters = { 0 };
- CRYPTO_SETTINGS crypto_settings[4] = { { 0 } };
- UNICODE_STRING blocked_ccm_modes[1] = { { 0 } };
- UNICODE_STRING blocked_gcm_modes[1] = { { 0 } };
-
- int crypto_settings_idx = 0;
-
-
- /* If TLS 1.3 ciphers are explicitly listed, then
- * disable all the ciphers and re-enable which
- * ciphers the user has provided.
- */
- ciphers13 = conn_config->cipher_list13;
- if(ciphers13) {
- const int remaining_ciphers = 5;
-
- /* detect which remaining ciphers to enable
- and then disable everything else.
- */
-
- char *startCur = ciphers13;
- int algCount = 0;
- char *nameEnd;
-
- disable_aes_gcm_sha384 = TRUE;
- disable_aes_gcm_sha256 = TRUE;
- disable_chacha_poly = TRUE;
- disable_aes_ccm_8_sha256 = TRUE;
- disable_aes_ccm_sha256 = TRUE;
-
- while(startCur && (0 != *startCur) && (algCount < remaining_ciphers)) {
- size_t n;
- char *namep;
- nameEnd = strchr(startCur, ':');
- n = nameEnd ? (size_t)(nameEnd - startCur) : strlen(startCur);
- namep = startCur;
-
- if(disable_aes_gcm_sha384 &&
- algo("TLS_AES_256_GCM_SHA384", namep, n)) {
- disable_aes_gcm_sha384 = FALSE;
- }
- else if(disable_aes_gcm_sha256
- && algo("TLS_AES_128_GCM_SHA256", namep, n)) {
- disable_aes_gcm_sha256 = FALSE;
- }
- else if(disable_chacha_poly
- && algo("TLS_CHACHA20_POLY1305_SHA256", namep, n)) {
- disable_chacha_poly = FALSE;
- }
- else if(disable_aes_ccm_8_sha256
- && algo("TLS_AES_128_CCM_8_SHA256", namep, n)) {
- disable_aes_ccm_8_sha256 = FALSE;
- }
- else if(disable_aes_ccm_sha256
- && algo("TLS_AES_128_CCM_SHA256", namep, n)) {
- disable_aes_ccm_sha256 = FALSE;
- }
- else {
- failf(data, "schannel: Unknown TLS 1.3 cipher: %.*s", (int)n, namep);
- return CURLE_SSL_CIPHER;
- }
-
- startCur = nameEnd;
- if(startCur)
- startCur++;
-
- algCount++;
- }
- }
-
- if(disable_aes_gcm_sha384 && disable_aes_gcm_sha256
- && disable_chacha_poly && disable_aes_ccm_8_sha256
- && disable_aes_ccm_sha256) {
- failf(data, "schannel: All available TLS 1.3 ciphers were disabled");
- return CURLE_SSL_CIPHER;
- }
-
- /* Disable TLS_AES_128_CCM_8_SHA256 and/or TLS_AES_128_CCM_SHA256 */
- if(disable_aes_ccm_8_sha256 || disable_aes_ccm_sha256) {
- /*
- Disallow AES_CCM algorithm.
- */
- blocked_ccm_modes[0].Length = sizeof(BCRYPT_CHAIN_MODE_CCM);
- blocked_ccm_modes[0].MaximumLength = sizeof(BCRYPT_CHAIN_MODE_CCM);
- blocked_ccm_modes[0].Buffer = (PWSTR)BCRYPT_CHAIN_MODE_CCM;
-
- crypto_settings[crypto_settings_idx].eAlgorithmUsage =
- TlsParametersCngAlgUsageCipher;
- crypto_settings[crypto_settings_idx].rgstrChainingModes =
- blocked_ccm_modes;
- crypto_settings[crypto_settings_idx].cChainingModes =
- ARRAYSIZE(blocked_ccm_modes);
- crypto_settings[crypto_settings_idx].strCngAlgId.Length =
- sizeof(BCRYPT_AES_ALGORITHM);
- crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength =
- sizeof(BCRYPT_AES_ALGORITHM);
- crypto_settings[crypto_settings_idx].strCngAlgId.Buffer =
- (PWSTR)BCRYPT_AES_ALGORITHM;
-
- /* only disabling one of the CCM modes */
- if(disable_aes_ccm_8_sha256 != disable_aes_ccm_sha256) {
- if(disable_aes_ccm_8_sha256)
- crypto_settings[crypto_settings_idx].dwMinBitLength = 128;
- else /* disable_aes_ccm_sha256 */
- crypto_settings[crypto_settings_idx].dwMaxBitLength = 64;
- }
-
- crypto_settings_idx++;
- }
-
- /* Disable TLS_AES_256_GCM_SHA384 and/or TLS_AES_128_GCM_SHA256 */
- if(disable_aes_gcm_sha384 || disable_aes_gcm_sha256) {
-
- /*
- Disallow AES_GCM algorithm
- */
- blocked_gcm_modes[0].Length = sizeof(BCRYPT_CHAIN_MODE_GCM);
- blocked_gcm_modes[0].MaximumLength = sizeof(BCRYPT_CHAIN_MODE_GCM);
- blocked_gcm_modes[0].Buffer = (PWSTR)BCRYPT_CHAIN_MODE_GCM;
-
- /* if only one is disabled, then explicitly disable the
- digest cipher suite (sha384 or sha256) */
- if(disable_aes_gcm_sha384 != disable_aes_gcm_sha256) {
- crypto_settings[crypto_settings_idx].eAlgorithmUsage =
- TlsParametersCngAlgUsageDigest;
- crypto_settings[crypto_settings_idx].strCngAlgId.Length =
- sizeof(disable_aes_gcm_sha384 ?
- BCRYPT_SHA384_ALGORITHM : BCRYPT_SHA256_ALGORITHM);
- crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength =
- sizeof(disable_aes_gcm_sha384 ?
- BCRYPT_SHA384_ALGORITHM : BCRYPT_SHA256_ALGORITHM);
- crypto_settings[crypto_settings_idx].strCngAlgId.Buffer =
- (PWSTR)(disable_aes_gcm_sha384 ?
- BCRYPT_SHA384_ALGORITHM : BCRYPT_SHA256_ALGORITHM);
- }
- else { /* Disable both AES_GCM ciphers */
- crypto_settings[crypto_settings_idx].eAlgorithmUsage =
- TlsParametersCngAlgUsageCipher;
- crypto_settings[crypto_settings_idx].strCngAlgId.Length =
- sizeof(BCRYPT_AES_ALGORITHM);
- crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength =
- sizeof(BCRYPT_AES_ALGORITHM);
- crypto_settings[crypto_settings_idx].strCngAlgId.Buffer =
- (PWSTR)BCRYPT_AES_ALGORITHM;
- }
-
- crypto_settings[crypto_settings_idx].rgstrChainingModes =
- blocked_gcm_modes;
- crypto_settings[crypto_settings_idx].cChainingModes = 1;
-
- crypto_settings_idx++;
- }
-
- /*
- Disable ChaCha20-Poly1305.
- */
- if(disable_chacha_poly) {
- crypto_settings[crypto_settings_idx].eAlgorithmUsage =
- TlsParametersCngAlgUsageCipher;
- crypto_settings[crypto_settings_idx].strCngAlgId.Length =
- sizeof(BCRYPT_CHACHA20_POLY1305_ALGORITHM);
- crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength =
- sizeof(BCRYPT_CHACHA20_POLY1305_ALGORITHM);
- crypto_settings[crypto_settings_idx].strCngAlgId.Buffer =
- (PWSTR)BCRYPT_CHACHA20_POLY1305_ALGORITHM;
- crypto_settings_idx++;
- }
+ CRYPTO_SETTINGS crypto_settings[1] = { { 0 } };
tls_parameters.pDisabledCrypto = crypto_settings;
/* The number of blocked suites */
- tls_parameters.cDisabledCrypto = (DWORD)crypto_settings_idx;
+ tls_parameters.cDisabledCrypto = (DWORD)0;
credentials.pTlsParameters = &tls_parameters;
credentials.cTlsParameters = 1;
@@ -986,9 +808,8 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
&backend->cred->time_stamp);
}
else {
- /* Pre-Windows 10 1809 or the user set a legacy algorithm list. Although MS
- does not document it, currently Schannel will not negotiate TLS 1.3 when
- SCHANNEL_CRED is used. */
+ /* Pre-Windows 10 1809 or the user set a legacy algorithm list.
+ Schannel will not negotiate TLS 1.3 when SCHANNEL_CRED is used. */
ALG_ID algIds[NUM_CIPHERS];
char *ciphers = conn_config->cipher_list;
SCHANNEL_CRED schannel_cred = { 0 };
@@ -998,16 +819,10 @@ schannel_acquire_credential_handle(struct Curl_cfilter *cf,
if(ciphers) {
if((enabled_protocols & SP_PROT_TLS1_3_CLIENT)) {
- infof(data, "schannel: WARNING: This version of Schannel may "
- "negotiate a less-secure TLS version than TLS 1.3 because the "
+ infof(data, "schannel: WARNING: This version of Schannel "
+ "negotiates a less-secure TLS version than TLS 1.3 because the "
"user set an algorithm cipher list.");
}
- if(conn_config->cipher_list13) {
- failf(data, "schannel: This version of Schannel does not support "
- "setting an algorithm cipher list and TLS 1.3 cipher list at "
- "the same time");
- return CURLE_SSL_CIPHER;
- }
result = set_ssl_ciphers(&schannel_cred, ciphers, algIds);
if(CURLE_OK != result) {
failf(data, "schannel: Failed setting algorithm cipher list");
@@ -2974,7 +2789,6 @@ const struct Curl_ssl Curl_ssl_schannel = {
#ifndef CURL_WINDOWS_UWP
SSLSUPP_PINNEDPUBKEY |
#endif
- SSLSUPP_TLS13_CIPHERSUITES |
SSLSUPP_CA_CACHE |
SSLSUPP_HTTPS_PROXY |
SSLSUPP_CIPHER_LIST,
diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c
index ee960ed2c5..42f7f517e4 100644
--- a/libs/libcurl/src/vtls/schannel_verify.c
+++ b/libs/libcurl/src/vtls/schannel_verify.c
@@ -554,7 +554,7 @@ CURLcode Curl_verify_host(struct Curl_cfilter *cf,
}
}
- if(p->size) {
+ if(p->size && alt_name_info) {
for(i = 0; i < alt_name_info->cAltEntry; ++i) {
PCERT_ALT_NAME_ENTRY entry = &alt_name_info->rgAltEntry[i];
if(entry->dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS) {
@@ -571,7 +571,6 @@ CURLcode Curl_verify_host(struct Curl_cfilter *cf,
}
}
}
-
else {
/* Determine the size of the string needed for the cert hostname */
len = cert_get_name_string(data, pCertContextServer,
diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c
index bf1d44dbdf..765ce36d92 100644
--- a/libs/libcurl/src/vtls/sectransp.c
+++ b/libs/libcurl/src/vtls/sectransp.c
@@ -354,8 +354,8 @@ CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
}
/* Parse the version: */
- os_version_major = strtok_r(os_version, ".", &tok_buf);
- os_version_minor = strtok_r(NULL, ".", &tok_buf);
+ os_version_major = Curl_strtok_r(os_version, ".", &tok_buf);
+ os_version_minor = Curl_strtok_r(NULL, ".", &tok_buf);
*major = atoi(os_version_major);
*minor = atoi(os_version_minor);
free(os_version);
diff --git a/libs/libcurl/src/vtls/wolfssl.c b/libs/libcurl/src/vtls/wolfssl.c
index 9a05f82946..a624d3ff0c 100644
--- a/libs/libcurl/src/vtls/wolfssl.c
+++ b/libs/libcurl/src/vtls/wolfssl.c
@@ -33,8 +33,8 @@
#ifdef USE_WOLFSSL
#define WOLFSSL_OPTIONS_IGNORE_SYS
-#include <wolfssl/version.h>
#include <wolfssl/options.h>
+#include <wolfssl/version.h>
#if LIBWOLFSSL_VERSION_HEX < 0x03004006 /* wolfSSL 3.4.6 (2015) */
#error "wolfSSL version should be at least 3.4.6"