mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-30 18:29:37 -06:00
Merge branch 'upstream-curl' into update-curl
* upstream-curl: curl 2024-07-31 (83bedbd7)
This commit is contained in:
75
Utilities/cmcurl/CMake/FindNettle.cmake
Normal file
75
Utilities/cmcurl/CMake/FindNettle.cmake
Normal file
@@ -0,0 +1,75 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
# - Try to find the nettle library
|
||||
# Once done this will define
|
||||
#
|
||||
# NETTLE_FOUND - system has nettle
|
||||
# NETTLE_INCLUDE_DIRS - nettle include directories
|
||||
# NETTLE_LIBRARIES - nettle library names
|
||||
|
||||
if(UNIX)
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(NETTLE "nettle")
|
||||
endif()
|
||||
|
||||
if(NETTLE_FOUND)
|
||||
set(NETTLE_LIBRARIES ${NETTLE_LINK_LIBRARIES})
|
||||
else()
|
||||
find_path(NETTLE_INCLUDE_DIR NAMES "nettle/sha2.h")
|
||||
find_library(NETTLE_LIBRARY NAMES "nettle")
|
||||
|
||||
if(NETTLE_INCLUDE_DIR)
|
||||
if(EXISTS "${NETTLE_INCLUDE_DIR}/nettle/version.h")
|
||||
set(_version_regex_major "^#define[ \t]+NETTLE_VERSION_MAJOR[ \t]+([0-9]+).*")
|
||||
set(_version_regex_minor "^#define[ \t]+NETTLE_VERSION_MINOR[ \t]+([0-9]+).*")
|
||||
file(STRINGS "${NETTLE_INCLUDE_DIR}/nettle/version.h"
|
||||
_version_major REGEX "${_version_regex_major}")
|
||||
file(STRINGS "${NETTLE_INCLUDE_DIR}/nettle/version.h"
|
||||
_version_minor REGEX "${_version_regex_minor}")
|
||||
string(REGEX REPLACE "${_version_regex_major}" "\\1" _version_major "${_version_major}")
|
||||
string(REGEX REPLACE "${_version_regex_minor}" "\\1" _version_minor "${_version_minor}")
|
||||
unset(_version_regex_major)
|
||||
unset(_version_regex_minor)
|
||||
set(NETTLE_VERSION "${_version_major}.${_version_minor}")
|
||||
unset(_version_major)
|
||||
unset(_version_minor)
|
||||
else()
|
||||
set(NETTLE_VERSION "0.0")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args("nettle"
|
||||
REQUIRED_VARS
|
||||
NETTLE_INCLUDE_DIR
|
||||
NETTLE_LIBRARY
|
||||
VERSION_VAR NETTLE_VERSION)
|
||||
|
||||
if(NETTLE_FOUND)
|
||||
set(NETTLE_INCLUDE_DIRS ${NETTLE_INCLUDE_DIR})
|
||||
set(NETTLE_LIBRARIES ${NETTLE_LIBRARY})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(NETTLE_INCLUDE_DIR NETTLE_LIBRARY)
|
||||
endif()
|
||||
@@ -723,11 +723,12 @@ endif()
|
||||
|
||||
if(CURL_USE_GNUTLS)
|
||||
find_package(GnuTLS REQUIRED)
|
||||
find_package(nettle REQUIRED)
|
||||
set(SSL_ENABLED ON)
|
||||
set(USE_GNUTLS ON)
|
||||
list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES} "nettle")
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "gnutls")
|
||||
include_directories(${GNUTLS_INCLUDE_DIRS})
|
||||
list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES} ${NETTLE_LIBRARIES})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "gnutls" "nettle")
|
||||
include_directories(${GNUTLS_INCLUDE_DIRS} ${NETTLE_INCLUDE_DIRS})
|
||||
|
||||
if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "gnutls")
|
||||
set(valid_default_ssl_backend TRUE)
|
||||
@@ -1183,11 +1184,21 @@ endif()
|
||||
option(CURL_USE_LIBSSH "Use libssh" OFF)
|
||||
mark_as_advanced(CURL_USE_LIBSSH)
|
||||
if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH)
|
||||
find_package(libssh CONFIG)
|
||||
find_package(libssh CONFIG QUIET)
|
||||
if(libssh_FOUND)
|
||||
message(STATUS "Found libssh ${libssh_VERSION}")
|
||||
# Use imported target for include and library paths.
|
||||
list(APPEND CURL_LIBS ssh)
|
||||
else()
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(LIBSSH "libssh")
|
||||
if(LIBSSH_FOUND)
|
||||
include_directories(${LIBSSH_INCLUDE_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
if(libssh_FOUND OR LIBSSH_FOUND)
|
||||
if(NOT DEFINED LIBSSH_LINK_LIBRARIES)
|
||||
set(LIBSSH_LINK_LIBRARIES "ssh") # for find_package() with broken pkg-config (e.g. linux-old CI workflow)
|
||||
endif()
|
||||
list(APPEND CURL_LIBS ${LIBSSH_LINK_LIBRARIES})
|
||||
list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "libssh")
|
||||
set(USE_LIBSSH ON)
|
||||
endif()
|
||||
|
||||
@@ -2133,7 +2133,7 @@ typedef enum {
|
||||
|
||||
/* the EC curves requested by the TLS client (RFC 8422, 5.1);
|
||||
* OpenSSL support via 'set_groups'/'set_curves':
|
||||
* https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
|
||||
* https://docs.openssl.org/master/man3/SSL_CTX_set1_curves/
|
||||
*/
|
||||
CURLOPT(CURLOPT_SSL_EC_CURVES, CURLOPTTYPE_STRINGPOINT, 298),
|
||||
|
||||
|
||||
@@ -32,13 +32,13 @@
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "8.9.0"
|
||||
#define LIBCURL_VERSION "8.9.1"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 8
|
||||
#define LIBCURL_VERSION_MINOR 9
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
|
||||
@@ -59,7 +59,7 @@
|
||||
CURL_VERSION_BITS() macro since curl's own configure script greps for it
|
||||
and needs it to contain the full number.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x080900
|
||||
#define LIBCURL_VERSION_NUM 0x080901
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
||||
@@ -584,15 +584,15 @@ static void connc_close_all(struct conncache *connc)
|
||||
return;
|
||||
|
||||
/* Move all connections to the shutdown list */
|
||||
sigpipe_init(&pipe_st);
|
||||
conn = connc_find_first_connection(connc);
|
||||
while(conn) {
|
||||
connc_remove_conn(connc, conn);
|
||||
sigpipe_ignore(data, &pipe_st);
|
||||
sigpipe_apply(data, &pipe_st);
|
||||
/* This will remove the connection from the cache */
|
||||
connclose(conn, "kill all");
|
||||
Curl_conncache_remove_conn(connc->closure_handle, conn, TRUE);
|
||||
connc_discard_conn(connc, connc->closure_handle, conn, FALSE);
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
conn = connc_find_first_connection(connc);
|
||||
}
|
||||
@@ -613,7 +613,7 @@ static void connc_close_all(struct conncache *connc)
|
||||
/* discard all connections in the shutdown list */
|
||||
connc_shutdown_discard_all(connc);
|
||||
|
||||
sigpipe_ignore(data, &pipe_st);
|
||||
sigpipe_apply(data, &pipe_st);
|
||||
Curl_hostcache_clean(data, data->dns.hostcache);
|
||||
Curl_close(&data);
|
||||
sigpipe_restore(&pipe_st);
|
||||
@@ -628,7 +628,6 @@ static void connc_shutdown_discard_oldest(struct conncache *connc)
|
||||
{
|
||||
struct Curl_llist_element *e;
|
||||
struct connectdata *conn;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
DEBUGASSERT(!connc->shutdowns.iter_locked);
|
||||
if(connc->shutdowns.iter_locked)
|
||||
@@ -636,9 +635,11 @@ static void connc_shutdown_discard_oldest(struct conncache *connc)
|
||||
|
||||
e = connc->shutdowns.conn_list.head;
|
||||
if(e) {
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
conn = e->ptr;
|
||||
Curl_llist_remove(&connc->shutdowns.conn_list, e, NULL);
|
||||
sigpipe_ignore(connc->closure_handle, &pipe_st);
|
||||
sigpipe_init(&pipe_st);
|
||||
sigpipe_apply(connc->closure_handle, &pipe_st);
|
||||
connc_disconnect(NULL, conn, connc, FALSE);
|
||||
sigpipe_restore(&pipe_st);
|
||||
}
|
||||
@@ -900,6 +901,9 @@ static void connc_perform(struct conncache *connc)
|
||||
struct Curl_llist_element *e = connc->shutdowns.conn_list.head;
|
||||
struct Curl_llist_element *enext;
|
||||
struct connectdata *conn;
|
||||
struct curltime *nowp = NULL;
|
||||
struct curltime now;
|
||||
timediff_t next_from_now_ms = 0, ms;
|
||||
bool done;
|
||||
|
||||
if(!e)
|
||||
@@ -922,9 +926,22 @@ static void connc_perform(struct conncache *connc)
|
||||
Curl_llist_remove(&connc->shutdowns.conn_list, e, NULL);
|
||||
connc_disconnect(NULL, conn, connc, FALSE);
|
||||
}
|
||||
else {
|
||||
/* Not done, when does this connection time out? */
|
||||
if(!nowp) {
|
||||
now = Curl_now();
|
||||
nowp = &now;
|
||||
}
|
||||
ms = Curl_conn_shutdown_timeleft(conn, nowp);
|
||||
if(ms && ms < next_from_now_ms)
|
||||
next_from_now_ms = ms;
|
||||
}
|
||||
e = enext;
|
||||
}
|
||||
connc->shutdowns.iter_locked = FALSE;
|
||||
|
||||
if(next_from_now_ms)
|
||||
Curl_expire(data, next_from_now_ms, EXPIRE_RUN_NOW);
|
||||
}
|
||||
|
||||
void Curl_conncache_multi_perform(struct Curl_multi *multi)
|
||||
|
||||
@@ -161,6 +161,7 @@ timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex,
|
||||
struct curltime *nowp)
|
||||
{
|
||||
struct curltime now;
|
||||
timediff_t left_ms;
|
||||
|
||||
if(!conn->shutdown.start[sockindex].tv_sec || !conn->shutdown.timeout_ms)
|
||||
return 0; /* not started or no limits */
|
||||
@@ -169,8 +170,30 @@ timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex,
|
||||
now = Curl_now();
|
||||
nowp = &now;
|
||||
}
|
||||
return conn->shutdown.timeout_ms -
|
||||
Curl_timediff(*nowp, conn->shutdown.start[sockindex]);
|
||||
left_ms = conn->shutdown.timeout_ms -
|
||||
Curl_timediff(*nowp, conn->shutdown.start[sockindex]);
|
||||
return left_ms? left_ms : -1;
|
||||
}
|
||||
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct connectdata *conn,
|
||||
struct curltime *nowp)
|
||||
{
|
||||
timediff_t left_ms = 0, ms;
|
||||
struct curltime now;
|
||||
int i;
|
||||
|
||||
for(i = 0; conn->shutdown.timeout_ms && (i < 2); ++i) {
|
||||
if(!conn->shutdown.start[i].tv_sec)
|
||||
continue;
|
||||
if(!nowp) {
|
||||
now = Curl_now();
|
||||
nowp = &now;
|
||||
}
|
||||
ms = Curl_shutdown_timeleft(conn, i, nowp);
|
||||
if(ms && (!left_ms || ms < left_ms))
|
||||
left_ms = ms;
|
||||
}
|
||||
return left_ms;
|
||||
}
|
||||
|
||||
void Curl_shutdown_clear(struct Curl_easy *data, int sockindex)
|
||||
|
||||
@@ -46,10 +46,15 @@ void Curl_shutdown_start(struct Curl_easy *data, int sockindex,
|
||||
struct curltime *nowp);
|
||||
|
||||
/* return how much time there is left to shutdown the connection at
|
||||
* sockindex. */
|
||||
* sockindex. Returns 0 if there is no limit or shutdown has not started. */
|
||||
timediff_t Curl_shutdown_timeleft(struct connectdata *conn, int sockindex,
|
||||
struct curltime *nowp);
|
||||
|
||||
/* return how much time there is left to shutdown the connection.
|
||||
* Returns 0 if there is no limit or shutdown has not started. */
|
||||
timediff_t Curl_conn_shutdown_timeleft(struct connectdata *conn,
|
||||
struct curltime *nowp);
|
||||
|
||||
void Curl_shutdown_clear(struct Curl_easy *data, int sockindex);
|
||||
|
||||
/* TRUE iff shutdown has been started */
|
||||
|
||||
@@ -71,7 +71,9 @@
|
||||
the necessary dynamic detection features, so the SDK falls back to
|
||||
a codepath that sets both the old and new macro to 1. */
|
||||
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC && \
|
||||
defined(TARGET_OS_OSX) && !TARGET_OS_OSX
|
||||
defined(TARGET_OS_OSX) && !TARGET_OS_OSX && \
|
||||
(!defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE) && \
|
||||
(!defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR)
|
||||
#undef TARGET_OS_OSX
|
||||
#define TARGET_OS_OSX TARGET_OS_MAC
|
||||
#endif
|
||||
|
||||
@@ -764,7 +764,8 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events)
|
||||
/* assign this after curl_multi_add_handle() */
|
||||
data->multi_easy = multi;
|
||||
|
||||
sigpipe_ignore(data, &pipe_st);
|
||||
sigpipe_init(&pipe_st);
|
||||
sigpipe_apply(data, &pipe_st);
|
||||
|
||||
/* run the transfer */
|
||||
result = events ? easy_events(multi) : easy_transfer(multi);
|
||||
|
||||
@@ -60,7 +60,7 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string,
|
||||
struct dynbuf d;
|
||||
(void)data;
|
||||
|
||||
if(inlength < 0)
|
||||
if(!string || (inlength < 0))
|
||||
return NULL;
|
||||
|
||||
Curl_dyn_init(&d, CURL_MAX_INPUT_LENGTH * 3);
|
||||
@@ -181,7 +181,7 @@ char *curl_easy_unescape(struct Curl_easy *data, const char *string,
|
||||
{
|
||||
char *str = NULL;
|
||||
(void)data;
|
||||
if(length >= 0) {
|
||||
if(string && (length >= 0)) {
|
||||
size_t inputlen = (size_t)length;
|
||||
size_t outputlen;
|
||||
CURLcode res = Curl_urldecode(string, inputlen, &str, &outputlen,
|
||||
|
||||
@@ -2714,6 +2714,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
||||
CURLMcode returncode = CURLM_OK;
|
||||
struct Curl_tree *t;
|
||||
struct curltime now = Curl_now();
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
if(!GOOD_MULTI_HANDLE(multi))
|
||||
return CURLM_BAD_HANDLE;
|
||||
@@ -2721,12 +2722,10 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
||||
if(multi->in_callback)
|
||||
return CURLM_RECURSIVE_API_CALL;
|
||||
|
||||
sigpipe_init(&pipe_st);
|
||||
data = multi->easyp;
|
||||
if(data) {
|
||||
CURLMcode result;
|
||||
bool nosig = data->set.no_signal;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
sigpipe_ignore(data, &pipe_st);
|
||||
/* Do the loop and only alter the signal ignore state if the next handle
|
||||
has a different NO_SIGNAL state than the previous */
|
||||
do {
|
||||
@@ -2734,22 +2733,23 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
||||
pointer now */
|
||||
struct Curl_easy *datanext = data->next;
|
||||
|
||||
if(data->set.no_signal != nosig) {
|
||||
sigpipe_restore(&pipe_st);
|
||||
sigpipe_ignore(data, &pipe_st);
|
||||
nosig = data->set.no_signal;
|
||||
if(data != multi->conn_cache.closure_handle) {
|
||||
/* connection cache handle is processed below */
|
||||
sigpipe_apply(data, &pipe_st);
|
||||
result = multi_runsingle(multi, &now, data);
|
||||
if(result)
|
||||
returncode = result;
|
||||
}
|
||||
result = multi_runsingle(multi, &now, data);
|
||||
if(result)
|
||||
returncode = result;
|
||||
|
||||
data = datanext; /* operate on next handle */
|
||||
} while(data);
|
||||
sigpipe_restore(&pipe_st);
|
||||
}
|
||||
|
||||
sigpipe_apply(multi->conn_cache.closure_handle, &pipe_st);
|
||||
Curl_conncache_multi_perform(multi);
|
||||
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
/*
|
||||
* Simply remove all expired timers from the splay since handles are dealt
|
||||
* with unconditionally by this function and curl_multi_timeout() requires
|
||||
@@ -2778,7 +2778,8 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
||||
}
|
||||
} while(t);
|
||||
|
||||
*running_handles = (int)multi->num_alive;
|
||||
if(running_handles)
|
||||
*running_handles = (int)multi->num_alive;
|
||||
|
||||
if(CURLM_OK >= returncode)
|
||||
returncode = Curl_update_timer(multi);
|
||||
@@ -3188,8 +3189,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
||||
struct Curl_easy *data = NULL;
|
||||
struct Curl_tree *t;
|
||||
struct curltime now = Curl_now();
|
||||
bool first = FALSE;
|
||||
bool nosig = FALSE;
|
||||
bool run_conn_cache = FALSE;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
if(checkall) {
|
||||
@@ -3234,11 +3234,15 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
||||
DEBUGASSERT(data);
|
||||
DEBUGASSERT(data->magic == CURLEASY_MAGIC_NUMBER);
|
||||
|
||||
if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
|
||||
/* set socket event bitmask if they are not locked */
|
||||
data->state.select_bits |= (unsigned char)ev_bitmask;
|
||||
if(data == multi->conn_cache.closure_handle)
|
||||
run_conn_cache = TRUE;
|
||||
else {
|
||||
if(data->conn && !(data->conn->handler->flags & PROTOPT_DIRLOCK))
|
||||
/* set socket event bitmask if they are not locked */
|
||||
data->state.select_bits |= (unsigned char)ev_bitmask;
|
||||
|
||||
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
||||
Curl_expire(data, 0, EXPIRE_RUN_NOW);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we fall-through and do the timer-based stuff, since we do not want
|
||||
@@ -3265,19 +3269,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
||||
* to process in the splay and 'data' will be re-assigned for every expired
|
||||
* handle we deal with.
|
||||
*/
|
||||
sigpipe_init(&pipe_st);
|
||||
do {
|
||||
if(data == multi->conn_cache.closure_handle)
|
||||
run_conn_cache = TRUE;
|
||||
/* the first loop lap 'data' can be NULL */
|
||||
if(data) {
|
||||
if(!first) {
|
||||
first = TRUE;
|
||||
nosig = data->set.no_signal; /* initial state */
|
||||
sigpipe_ignore(data, &pipe_st);
|
||||
}
|
||||
else if(data->set.no_signal != nosig) {
|
||||
sigpipe_restore(&pipe_st);
|
||||
sigpipe_ignore(data, &pipe_st);
|
||||
nosig = data->set.no_signal; /* remember new state */
|
||||
}
|
||||
else if(data) {
|
||||
sigpipe_apply(data, &pipe_st);
|
||||
result = multi_runsingle(multi, &now, data);
|
||||
|
||||
if(CURLM_OK >= result) {
|
||||
@@ -3299,10 +3297,16 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
||||
}
|
||||
|
||||
} while(t);
|
||||
if(first)
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
*running_handles = (int)multi->num_alive;
|
||||
if(run_conn_cache) {
|
||||
sigpipe_apply(multi->conn_cache.closure_handle, &pipe_st);
|
||||
Curl_conncache_multi_perform(multi);
|
||||
}
|
||||
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
if(running_handles)
|
||||
*running_handles = (int)multi->num_alive;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,15 @@ typedef unsigned long u_int32_t;
|
||||
#define isatty(fd) 0
|
||||
|
||||
|
||||
/* Workaround bug in IBM QADRT runtime library:
|
||||
* function puts() does not output the implicit trailing newline.
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* Be sure it is loaded. */
|
||||
#undef puts
|
||||
#define puts(s) (fputs((s), stdout) == EOF? EOF: putchar('\n'))
|
||||
|
||||
|
||||
/* System API wrapper prototypes & definitions to support ASCII parameters. */
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
@@ -36,6 +36,11 @@ struct sigpipe_ignore {
|
||||
|
||||
#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x
|
||||
|
||||
static void sigpipe_init(struct sigpipe_ignore *ig)
|
||||
{
|
||||
memset(ig, 0, sizeof(*ig));
|
||||
}
|
||||
|
||||
/*
|
||||
* sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl
|
||||
* internals, and then sigpipe_restore() will restore the situation when we
|
||||
@@ -70,9 +75,20 @@ static void sigpipe_restore(struct sigpipe_ignore *ig)
|
||||
sigaction(SIGPIPE, &ig->old_pipe_act, NULL);
|
||||
}
|
||||
|
||||
static void sigpipe_apply(struct Curl_easy *data,
|
||||
struct sigpipe_ignore *ig)
|
||||
{
|
||||
if(data->set.no_signal != ig->no_signal) {
|
||||
sigpipe_restore(ig);
|
||||
sigpipe_ignore(data, ig);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* for systems without sigaction */
|
||||
#define sigpipe_ignore(x,y) Curl_nop_stmt
|
||||
#define sigpipe_apply(x,y) Curl_nop_stmt
|
||||
#define sigpipe_init(x) Curl_nop_stmt
|
||||
#define sigpipe_restore(x) Curl_nop_stmt
|
||||
#define SIGPIPE_VARIABLE(x)
|
||||
#endif
|
||||
|
||||
@@ -281,13 +281,13 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
buf = xfer_buf;
|
||||
bytestoread = xfer_blen;
|
||||
|
||||
if(bytestoread && data->set.max_recv_speed) {
|
||||
if(bytestoread && data->set.max_recv_speed > 0) {
|
||||
/* In case of speed limit on receiving: if this loop already got
|
||||
* data, break out. If not, limit the amount of bytes to receive.
|
||||
* The overall, timed, speed limiting is done in multi.c */
|
||||
if(total_received)
|
||||
break;
|
||||
if((size_t)data->set.max_recv_speed < bytestoread)
|
||||
if(data->set.max_recv_speed < (curl_off_t)bytestoread)
|
||||
bytestoread = (size_t)data->set.max_recv_speed;
|
||||
}
|
||||
|
||||
|
||||
@@ -249,8 +249,8 @@ static const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
|
||||
1024, /* RSA min key len */
|
||||
};
|
||||
|
||||
/* See https://tls.mbed.org/discussions/generic/
|
||||
howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
|
||||
/* See https://web.archive.org/web/20200921194007/tls.mbed.org/discussions/
|
||||
generic/howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
|
||||
*/
|
||||
#define RSA_PUB_DER_MAX_BYTES (38 + 2 * MBEDTLS_MPI_MAX_SIZE)
|
||||
#define ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES)
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
/*
|
||||
* Whether SSL_CTX_set1_curves_list is available.
|
||||
* OpenSSL: supported since 1.0.2, see
|
||||
* https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
|
||||
* https://docs.openssl.org/master/man3/SSL_CTX_set1_curves/
|
||||
* BoringSSL: supported since 5fd1807d95f7 (committed 2016-09-30)
|
||||
* LibreSSL: since 2.5.3 (April 12, 2017)
|
||||
*/
|
||||
@@ -3260,7 +3260,8 @@ static CURLcode populate_x509_store(struct Curl_cfilter *cf,
|
||||
problems with server-sent legacy intermediates. Newer versions of
|
||||
OpenSSL do alternate chain checking by default but we do not know how to
|
||||
determine that in a reliable manner.
|
||||
https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
|
||||
https://web.archive.org/web/20190422050538/
|
||||
rt.openssl.org/Ticket/Display.html?id=3621
|
||||
*/
|
||||
#if defined(X509_V_FLAG_TRUSTED_FIRST)
|
||||
X509_STORE_set_flags(store, X509_V_FLAG_TRUSTED_FIRST);
|
||||
@@ -3583,12 +3584,12 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx,
|
||||
CVE-2010-4180 when using previous OpenSSL versions we no longer enable
|
||||
this option regardless of OpenSSL version and SSL_OP_ALL definition.
|
||||
|
||||
OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability
|
||||
(https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to
|
||||
SSL_OP_ALL that _disables_ that work-around despite the fact that
|
||||
SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to
|
||||
keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit
|
||||
must not be set.
|
||||
OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability:
|
||||
https://web.archive.org/web/20240114184648/openssl.org/~bodo/tls-cbc.txt.
|
||||
In 0.9.6e they added a bit to SSL_OP_ALL that _disables_ that work-around
|
||||
despite the fact that SSL_OP_ALL is documented to do "rather harmless"
|
||||
workarounds. In order to keep the secure work-around, the
|
||||
SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit must not be set.
|
||||
*/
|
||||
|
||||
ctx_options = SSL_OP_ALL;
|
||||
@@ -4379,7 +4380,7 @@ static CURLcode ossl_pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
|
||||
if(!buff1)
|
||||
break; /* failed */
|
||||
|
||||
/* https://www.openssl.org/docs/crypto/d2i_X509.html */
|
||||
/* https://docs.openssl.org/master/man3/d2i_X509/ */
|
||||
len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp);
|
||||
|
||||
/*
|
||||
@@ -4991,7 +4992,7 @@ static ssize_t ossl_recv(struct Curl_cfilter *cf,
|
||||
default:
|
||||
/* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
|
||||
value/errno" */
|
||||
/* https://www.openssl.org/docs/crypto/ERR_get_error.html */
|
||||
/* https://docs.openssl.org/master/man3/ERR_get_error/ */
|
||||
if(octx->io_result == CURLE_AGAIN) {
|
||||
*curlcode = CURLE_AGAIN;
|
||||
nread = -1;
|
||||
|
||||
@@ -413,23 +413,6 @@ int Curl_ssl_init(void)
|
||||
return Curl_ssl->init();
|
||||
}
|
||||
|
||||
#if defined(CURL_WITH_MULTI_SSL)
|
||||
static const struct Curl_ssl Curl_ssl_multi;
|
||||
#endif
|
||||
|
||||
/* Global cleanup */
|
||||
void Curl_ssl_cleanup(void)
|
||||
{
|
||||
if(init_ssl) {
|
||||
/* only cleanup if we did a previous init */
|
||||
Curl_ssl->cleanup();
|
||||
#if defined(CURL_WITH_MULTI_SSL)
|
||||
Curl_ssl = &Curl_ssl_multi;
|
||||
#endif
|
||||
init_ssl = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ssl_prefs_check(struct Curl_easy *data)
|
||||
{
|
||||
/* check for CURLOPT_SSLVERSION invalid parameter value */
|
||||
@@ -1404,6 +1387,19 @@ static const struct Curl_ssl *available_backends[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Global cleanup */
|
||||
void Curl_ssl_cleanup(void)
|
||||
{
|
||||
if(init_ssl) {
|
||||
/* only cleanup if we did a previous init */
|
||||
Curl_ssl->cleanup();
|
||||
#if defined(CURL_WITH_MULTI_SSL)
|
||||
Curl_ssl = &Curl_ssl_multi;
|
||||
#endif
|
||||
init_ssl = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t multissl_version(char *buffer, size_t size)
|
||||
{
|
||||
static const struct Curl_ssl *selected;
|
||||
|
||||
@@ -212,7 +212,7 @@ static int do_file_type(const char *type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBOQS
|
||||
#ifdef WOLFSSL_HAVE_KYBER
|
||||
struct group_name_map {
|
||||
const word16 group;
|
||||
const char *name;
|
||||
@@ -434,10 +434,10 @@ static CURLcode populate_x509_store(struct Curl_cfilter *cf,
|
||||
}
|
||||
infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
|
||||
infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
|
||||
wssl->x509_store_setup = TRUE;
|
||||
}
|
||||
#endif
|
||||
(void)store;
|
||||
wssl->x509_store_setup = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@@ -571,7 +571,7 @@ CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf,
|
||||
bool cache_criteria_met;
|
||||
|
||||
/* Consider the X509 store cacheable if it comes exclusively from a CAfile,
|
||||
or no source is provided and we are falling back to OpenSSL's built-in
|
||||
or no source is provided and we are falling back to wolfSSL's built-in
|
||||
default. */
|
||||
cache_criteria_met = (data->set.general_ssl.ca_cache_timeout != 0) &&
|
||||
conn_config->verifypeer &&
|
||||
@@ -580,19 +580,30 @@ CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf,
|
||||
!ssl_config->primary.CRLfile &&
|
||||
!ssl_config->native_ca_store;
|
||||
|
||||
cached_store = get_cached_x509_store(cf, data);
|
||||
if(cached_store && cache_criteria_met
|
||||
&& wolfSSL_X509_STORE_up_ref(cached_store)) {
|
||||
cached_store = cache_criteria_met ? get_cached_x509_store(cf, data) : NULL;
|
||||
if(cached_store && wolfSSL_X509_STORE_up_ref(cached_store)) {
|
||||
wolfSSL_CTX_set_cert_store(wssl->ctx, cached_store);
|
||||
}
|
||||
else {
|
||||
X509_STORE *store = wolfSSL_CTX_get_cert_store(wssl->ctx);
|
||||
else if(cache_criteria_met) {
|
||||
/* wolfSSL's initial store in CTX is not shareable by default.
|
||||
* Make a new one, suitable for adding to the cache. See #14278 */
|
||||
X509_STORE *store = wolfSSL_X509_STORE_new();
|
||||
if(!store) {
|
||||
failf(data, "SSL: could not create a X509 store");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
wolfSSL_CTX_set_cert_store(wssl->ctx, store);
|
||||
|
||||
result = populate_x509_store(cf, data, store, wssl);
|
||||
if(result == CURLE_OK && cache_criteria_met) {
|
||||
if(!result) {
|
||||
set_cached_x509_store(cf, data, store);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* We never share the CTX's store, use it. */
|
||||
X509_STORE *store = wolfSSL_CTX_get_cert_store(wssl->ctx);
|
||||
result = populate_x509_store(cf, data, store, wssl);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -611,8 +622,8 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf);
|
||||
const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
|
||||
WOLFSSL_METHOD* req_method = NULL;
|
||||
#ifdef HAVE_LIBOQS
|
||||
word16 oqsAlg = 0;
|
||||
#ifdef WOLFSSL_HAVE_KYBER
|
||||
word16 pqkem = 0;
|
||||
size_t idx = 0;
|
||||
#endif
|
||||
#ifdef HAVE_SNI
|
||||
@@ -739,15 +750,15 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
curves = conn_config->curves;
|
||||
if(curves) {
|
||||
|
||||
#ifdef HAVE_LIBOQS
|
||||
#ifdef WOLFSSL_HAVE_KYBER
|
||||
for(idx = 0; gnm[idx].name != NULL; idx++) {
|
||||
if(strncmp(curves, gnm[idx].name, strlen(gnm[idx].name)) == 0) {
|
||||
oqsAlg = gnm[idx].group;
|
||||
pqkem = gnm[idx].group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(oqsAlg == 0)
|
||||
if(pqkem == 0)
|
||||
#endif
|
||||
{
|
||||
if(!SSL_CTX_set1_curves_list(backend->ctx, curves)) {
|
||||
@@ -821,8 +832,14 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
|
||||
/* give application a chance to interfere with SSL set up. */
|
||||
if(data->set.ssl.fsslctx) {
|
||||
CURLcode result = (*data->set.ssl.fsslctx)(data, backend->ctx,
|
||||
data->set.ssl.fsslctxp);
|
||||
CURLcode result;
|
||||
if(!backend->x509_store_setup) {
|
||||
result = Curl_wssl_setup_x509_store(cf, data, backend);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
result = (*data->set.ssl.fsslctx)(data, backend->ctx,
|
||||
data->set.ssl.fsslctxp);
|
||||
if(result) {
|
||||
failf(data, "error signaled by ssl ctx callback");
|
||||
return result;
|
||||
@@ -847,10 +864,10 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBOQS
|
||||
if(oqsAlg) {
|
||||
if(wolfSSL_UseKeyShare(backend->handle, oqsAlg) != WOLFSSL_SUCCESS) {
|
||||
failf(data, "unable to use oqs KEM");
|
||||
#ifdef WOLFSSL_HAVE_KYBER
|
||||
if(pqkem) {
|
||||
if(wolfSSL_UseKeyShare(backend->handle, pqkem) != WOLFSSL_SUCCESS) {
|
||||
failf(data, "unable to use PQ KEM");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1059,15 +1076,9 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
|
||||
/* After having send off the ClientHello, we prepare the x509
|
||||
* store to verify the coming certificate from the server */
|
||||
CURLcode result;
|
||||
struct wolfssl_ctx wssl;
|
||||
wssl.ctx = backend->ctx;
|
||||
wssl.handle = backend->handle;
|
||||
wssl.io_result = CURLE_OK;
|
||||
wssl.x509_store_setup = FALSE;
|
||||
result = Curl_wssl_setup_x509_store(cf, data, &wssl);
|
||||
result = Curl_wssl_setup_x509_store(cf, data, backend);
|
||||
if(result)
|
||||
return result;
|
||||
backend->x509_store_setup = wssl.x509_store_setup;
|
||||
}
|
||||
|
||||
connssl->io_need = CURL_SSL_IO_NEED_NONE;
|
||||
|
||||
@@ -494,7 +494,7 @@ static CURLcode GTime2str(struct dynbuf *store,
|
||||
/* Convert an ASN.1 Generalized time to a printable string.
|
||||
Return the dynamically allocated string, or NULL if an error occurs. */
|
||||
|
||||
for(fracp = beg; fracp < end && *fracp >= '0' && *fracp <= '9'; fracp++)
|
||||
for(fracp = beg; fracp < end && ISDIGIT(*fracp); fracp++)
|
||||
;
|
||||
|
||||
/* Get seconds digits. */
|
||||
@@ -513,32 +513,44 @@ static CURLcode GTime2str(struct dynbuf *store,
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
/* Scan for timezone, measure fractional seconds. */
|
||||
/* timezone follows optional fractional seconds. */
|
||||
tzp = fracp;
|
||||
fracl = 0;
|
||||
fracl = 0; /* no fractional seconds detected so far */
|
||||
if(fracp < end && (*fracp == '.' || *fracp == ',')) {
|
||||
fracp++;
|
||||
do
|
||||
/* Have fractional seconds, e.g. "[.,]\d+". How many? */
|
||||
fracp++; /* should be a digit char or BAD ARGUMENT */
|
||||
tzp = fracp;
|
||||
while(tzp < end && ISDIGIT(*tzp))
|
||||
tzp++;
|
||||
while(tzp < end && *tzp >= '0' && *tzp <= '9');
|
||||
/* Strip leading zeroes in fractional seconds. */
|
||||
for(fracl = tzp - fracp - 1; fracl && fracp[fracl - 1] == '0'; fracl--)
|
||||
;
|
||||
if(tzp == fracp) /* never looped, no digit after [.,] */
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
fracl = tzp - fracp; /* number of fractional sec digits */
|
||||
DEBUGASSERT(fracl > 0);
|
||||
/* Strip trailing zeroes in fractional seconds.
|
||||
* May reduce fracl to 0 if only '0's are present. */
|
||||
while(fracl && fracp[fracl - 1] == '0')
|
||||
fracl--;
|
||||
}
|
||||
|
||||
/* Process timezone. */
|
||||
if(tzp >= end)
|
||||
; /* Nothing to do. */
|
||||
if(tzp >= end) {
|
||||
tzp = "";
|
||||
tzl = 0;
|
||||
}
|
||||
else if(*tzp == 'Z') {
|
||||
tzp = " GMT";
|
||||
end = tzp + 4;
|
||||
sep = " ";
|
||||
tzp = "GMT";
|
||||
tzl = 3;
|
||||
}
|
||||
else if((*tzp == '+') || (*tzp == '-')) {
|
||||
sep = " UTC";
|
||||
tzl = end - tzp;
|
||||
}
|
||||
else {
|
||||
sep = " ";
|
||||
tzp++;
|
||||
tzl = end - tzp;
|
||||
}
|
||||
|
||||
tzl = end - tzp;
|
||||
return Curl_dyn_addf(store,
|
||||
"%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s",
|
||||
beg, beg + 4, beg + 6,
|
||||
@@ -547,6 +559,15 @@ static CURLcode GTime2str(struct dynbuf *store,
|
||||
sep, (int)tzl, tzp);
|
||||
}
|
||||
|
||||
#ifdef UNITTESTS
|
||||
/* used by unit1656.c */
|
||||
CURLcode Curl_x509_GTime2str(struct dynbuf *store,
|
||||
const char *beg, const char *end)
|
||||
{
|
||||
return GTime2str(store, beg, end);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert an ASN.1 UTC time to a printable string.
|
||||
*
|
||||
|
||||
@@ -77,5 +77,16 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, int certnum,
|
||||
const char *beg, const char *end);
|
||||
CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
const char *beg, const char *end);
|
||||
|
||||
#ifdef UNITTESTS
|
||||
#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \
|
||||
defined(USE_MBEDTLS)
|
||||
|
||||
/* used by unit1656.c */
|
||||
CURLcode Curl_x509_GTime2str(struct dynbuf *store,
|
||||
const char *beg, const char *end);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP */
|
||||
#endif /* HEADER_CURL_X509ASN1_H */
|
||||
|
||||
Reference in New Issue
Block a user