From 1865f86e282d9e51d00c0cb744b1a43dbc8e0ad7 Mon Sep 17 00:00:00 2001 From: Curl Upstream Date: Thu, 13 Feb 2025 08:14:17 +0100 Subject: curl 2025-02-13 (57495c64) Code extracted from: https://github.com/curl/curl.git at commit 57495c64871d18905a0941db9196ef90bafe9a29 (curl-8_12_1). --- CMake/CurlTests.c | 4 +- CMake/FindBrotli.cmake | 1 + CMake/FindCares.cmake | 1 + CMake/FindLibgsasl.cmake | 1 + CMake/FindLibidn2.cmake | 1 + CMake/FindLibpsl.cmake | 1 + CMake/FindLibrtmp.cmake | 1 + CMake/FindLibssh.cmake | 1 + CMake/FindLibssh2.cmake | 1 + CMake/FindLibuv.cmake | 1 + CMake/FindMbedTLS.cmake | 1 + CMake/FindNettle.cmake | 1 + CMake/FindQuiche.cmake | 1 + CMake/FindRustls.cmake | 1 + CMake/FindWolfSSL.cmake | 1 + CMake/FindZstd.cmake | 1 + CMake/Macros.cmake | 3 + CMake/OtherTests.cmake | 3 + CMake/PickyWarnings.cmake | 2 +- CMake/Utilities.cmake | 2 +- CMake/win32-cache.cmake | 6 +- CMakeLists.txt | 273 ++++++++++++++++++++++++---------------------- include/curl/curlver.h | 6 +- lib/CMakeLists.txt | 10 ++ lib/asyn-ares.c | 3 + lib/asyn-thread.c | 47 ++++---- lib/asyn.h | 7 +- lib/cf-h1-proxy.c | 1 - lib/cf-h2-proxy.c | 2 +- lib/cf-https-connect.c | 16 +-- lib/cf-socket.c | 7 +- lib/cfilters.c | 6 +- lib/conncache.c | 11 +- lib/connect.c | 32 +++--- lib/content_encoding.c | 19 ++-- lib/cookie.c | 2 +- lib/curl_config.h.cmake | 3 + lib/curl_setup.h | 12 +- lib/curl_trc.c | 12 +- lib/ftp.c | 12 +- lib/http.c | 10 +- lib/http1.c | 2 - lib/imap.c | 58 +++++----- lib/inet_ntop.h | 6 + lib/inet_pton.h | 6 + lib/ldap.c | 54 +-------- lib/mime.c | 4 +- lib/multi.c | 20 +--- lib/netrc.c | 105 +++++++++++------- lib/netrc.h | 15 ++- lib/pop3.c | 68 +++++------- lib/setopt.c | 15 +-- lib/smb.c | 9 ++ lib/smtp.c | 53 ++++----- lib/telnet.c | 16 +-- lib/transfer.c | 6 - lib/url.c | 28 ++--- lib/urlapi.c | 2 +- lib/urldata.h | 2 - lib/vquic/curl_msh3.c | 18 +-- lib/vquic/curl_ngtcp2.c | 8 +- lib/vquic/curl_osslq.c | 10 +- lib/vquic/curl_quiche.c | 8 +- lib/vquic/vquic-tls.c | 4 - lib/vquic/vquic.c | 2 +- lib/vssh/libssh.c | 37 +------ lib/vssh/libssh2.c | 122 ++++----------------- lib/vssh/ssh.h | 52 ++------- lib/vtls/gtls.c | 6 +- lib/vtls/mbedtls.c | 14 +-- lib/vtls/openssl.c | 38 +++---- lib/vtls/schannel.c | 15 ++- lib/vtls/vtls.c | 8 +- lib/vtls/vtls_scache.c | 61 +++++++++-- lib/vtls/wolfssl.c | 2 +- 75 files changed, 618 insertions(+), 782 deletions(-) diff --git a/CMake/CurlTests.c b/CMake/CurlTests.c index 1428238..c5a5257 100644 --- a/CMake/CurlTests.c +++ b/CMake/CurlTests.c @@ -70,7 +70,7 @@ int main(void) #include int main(void) { - char *address = "example.com"; + const char *address = "example.com"; int length = 0; int type = 0; struct hostent h; @@ -167,7 +167,7 @@ int main(void) { return 0; } int main(void) { /* ioctlsocket source code */ - int socket; + int socket = -1; unsigned long flags = ioctlsocket(socket, FIONBIO, &flags); ; return 0; diff --git a/CMake/FindBrotli.cmake b/CMake/FindBrotli.cmake index 8a692bd..b72f190 100644 --- a/CMake/FindBrotli.cmake +++ b/CMake/FindBrotli.cmake @@ -51,6 +51,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(BROTLI_FOUND AND BROTLIDEC_FOUND) + set(Brotli_FOUND TRUE) list(APPEND BROTLIDEC_LIBRARIES ${BROTLI_LIBRARIES}) # order is significant: brotlidec then brotlicommon list(REVERSE BROTLIDEC_LIBRARIES) list(REMOVE_DUPLICATES BROTLIDEC_LIBRARIES) diff --git a/CMake/FindCares.cmake b/CMake/FindCares.cmake index 67dec09..cc47e2d 100644 --- a/CMake/FindCares.cmake +++ b/CMake/FindCares.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(CARES_FOUND) + set(Cares_FOUND TRUE) string(REPLACE ";" " " CARES_CFLAGS "${CARES_CFLAGS}") message(STATUS "Found Cares (via pkg-config): ${CARES_INCLUDE_DIRS} (found version \"${CARES_VERSION}\")") else() diff --git a/CMake/FindLibgsasl.cmake b/CMake/FindLibgsasl.cmake index c0ce673..c726ce1 100644 --- a/CMake/FindLibgsasl.cmake +++ b/CMake/FindLibgsasl.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(LIBGSASL_FOUND) + set(Libgsasl_FOUND TRUE) string(REPLACE ";" " " LIBGSASL_CFLAGS "${LIBGSASL_CFLAGS}") message(STATUS "Found Libgsasl (via pkg-config): ${LIBGSASL_INCLUDE_DIRS} (found version \"${LIBGSASL_VERSION}\")") else() diff --git a/CMake/FindLibidn2.cmake b/CMake/FindLibidn2.cmake index a8887e8..f8f00f0 100644 --- a/CMake/FindLibidn2.cmake +++ b/CMake/FindLibidn2.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(LIBIDN2_FOUND) + set(Libidn2_FOUND TRUE) string(REPLACE ";" " " LIBIDN2_CFLAGS "${LIBIDN2_CFLAGS}") message(STATUS "Found Libidn2 (via pkg-config): ${LIBIDN2_INCLUDE_DIRS} (found version \"${LIBIDN2_VERSION}\")") else() diff --git a/CMake/FindLibpsl.cmake b/CMake/FindLibpsl.cmake index 0d96995..d6fde4b 100644 --- a/CMake/FindLibpsl.cmake +++ b/CMake/FindLibpsl.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(LIBPSL_FOUND AND LIBPSL_INCLUDE_DIRS) + set(Libpsl_FOUND TRUE) string(REPLACE ";" " " LIBPSL_CFLAGS "${LIBPSL_CFLAGS}") message(STATUS "Found Libpsl (via pkg-config): ${LIBPSL_INCLUDE_DIRS} (found version \"${LIBPSL_VERSION}\")") else() diff --git a/CMake/FindLibrtmp.cmake b/CMake/FindLibrtmp.cmake index dd3fb9e..50fc969 100644 --- a/CMake/FindLibrtmp.cmake +++ b/CMake/FindLibrtmp.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(LIBRTMP_FOUND AND LIBRTMP_INCLUDE_DIRS) + set(Librtmp_FOUND TRUE) string(REPLACE ";" " " LIBRTMP_CFLAGS "${LIBRTMP_CFLAGS}") message(STATUS "Found Librtmp (via pkg-config): ${LIBRTMP_INCLUDE_DIRS} (found version \"${LIBRTMP_VERSION}\")") else() diff --git a/CMake/FindLibssh.cmake b/CMake/FindLibssh.cmake index b8b4a51..e2b27d9 100644 --- a/CMake/FindLibssh.cmake +++ b/CMake/FindLibssh.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(LIBSSH_FOUND) + set(Libssh_FOUND TRUE) string(REPLACE ";" " " LIBSSH_CFLAGS "${LIBSSH_CFLAGS}") message(STATUS "Found Libssh (via pkg-config): ${LIBSSH_INCLUDE_DIRS} (found version \"${LIBSSH_VERSION}\")") else() diff --git a/CMake/FindLibssh2.cmake b/CMake/FindLibssh2.cmake index dfb0582..0b81ecb 100644 --- a/CMake/FindLibssh2.cmake +++ b/CMake/FindLibssh2.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(LIBSSH2_FOUND AND LIBSSH2_INCLUDE_DIRS) + set(Libssh2_FOUND TRUE) string(REPLACE ";" " " LIBSSH2_CFLAGS "${LIBSSH2_CFLAGS}") message(STATUS "Found Libssh2 (via pkg-config): ${LIBSSH2_INCLUDE_DIRS} (found version \"${LIBSSH2_VERSION}\")") else() diff --git a/CMake/FindLibuv.cmake b/CMake/FindLibuv.cmake index 8255eaa..b16b355 100644 --- a/CMake/FindLibuv.cmake +++ b/CMake/FindLibuv.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(LIBUV_FOUND) + set(Libuv_FOUND TRUE) string(REPLACE ";" " " LIBUV_CFLAGS "${LIBUV_CFLAGS}") message(STATUS "Found Libuv (via pkg-config): ${LIBUV_INCLUDE_DIRS} (found version \"${LIBUV_VERSION}\")") else() diff --git a/CMake/FindMbedTLS.cmake b/CMake/FindMbedTLS.cmake index c3ba27d..83f1371 100644 --- a/CMake/FindMbedTLS.cmake +++ b/CMake/FindMbedTLS.cmake @@ -60,6 +60,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(MBEDTLS_FOUND AND MBEDX509_FOUND AND MBEDCRYPTO_FOUND) + set(MbedTLS_FOUND TRUE) list(APPEND MBEDTLS_LIBRARIES ${MBEDX509_LIBRARIES} ${MBEDCRYPTO_LIBRARIES}) list(REVERSE MBEDTLS_LIBRARIES) list(REMOVE_DUPLICATES MBEDTLS_LIBRARIES) diff --git a/CMake/FindNettle.cmake b/CMake/FindNettle.cmake index 753633a..c2decf6 100644 --- a/CMake/FindNettle.cmake +++ b/CMake/FindNettle.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(NETTLE_FOUND) + set(Nettle_FOUND TRUE) string(REPLACE ";" " " NETTLE_CFLAGS "${NETTLE_CFLAGS}") message(STATUS "Found Nettle (via pkg-config): ${NETTLE_INCLUDE_DIRS} (found version \"${NETTLE_VERSION}\")") else() diff --git a/CMake/FindQuiche.cmake b/CMake/FindQuiche.cmake index 092aff8..6939c64 100644 --- a/CMake/FindQuiche.cmake +++ b/CMake/FindQuiche.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(QUICHE_FOUND) + set(Quiche_FOUND TRUE) string(REPLACE ";" " " QUICHE_CFLAGS "${QUICHE_CFLAGS}") message(STATUS "Found Quiche (via pkg-config): ${QUICHE_INCLUDE_DIRS} (found version \"${QUICHE_VERSION}\")") else() diff --git a/CMake/FindRustls.cmake b/CMake/FindRustls.cmake index 51f4506..564b08c 100644 --- a/CMake/FindRustls.cmake +++ b/CMake/FindRustls.cmake @@ -48,6 +48,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(RUSTLS_FOUND) + set(Rustls_FOUND TRUE) string(REPLACE ";" " " RUSTLS_CFLAGS "${RUSTLS_CFLAGS}") message(STATUS "Found Rustls (via pkg-config): ${RUSTLS_INCLUDE_DIRS} (found version \"${RUSTLS_VERSION}\")") else() diff --git a/CMake/FindWolfSSL.cmake b/CMake/FindWolfSSL.cmake index 3163fee..e33fef8 100644 --- a/CMake/FindWolfSSL.cmake +++ b/CMake/FindWolfSSL.cmake @@ -57,6 +57,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(WOLFSSL_FOUND) + set(WolfSSL_FOUND TRUE) string(REPLACE ";" " " WOLFSSL_CFLAGS "${WOLFSSL_CFLAGS}") message(STATUS "Found WolfSSL (via pkg-config): ${WOLFSSL_INCLUDE_DIRS} (found version \"${WOLFSSL_VERSION}\")") else() diff --git a/CMake/FindZstd.cmake b/CMake/FindZstd.cmake index dbfede7..0ea1fef 100644 --- a/CMake/FindZstd.cmake +++ b/CMake/FindZstd.cmake @@ -57,6 +57,7 @@ if(CURL_USE_PKGCONFIG AND endif() if(ZSTD_FOUND) + set(Zstd_FOUND TRUE) string(REPLACE ";" " " ZSTD_CFLAGS "${ZSTD_CFLAGS}") message(STATUS "Found Zstd (via pkg-config): ${ZSTD_INCLUDE_DIRS} (found version \"${ZSTD_VERSION}\")") else() diff --git a/CMake/Macros.cmake b/CMake/Macros.cmake index ad0df18..8653f36 100644 --- a/CMake/Macros.cmake +++ b/CMake/Macros.cmake @@ -34,11 +34,14 @@ macro(check_include_file_concat_curl _file _variable) endif() endmacro() +set(CURL_TEST_DEFINES "") # Initialize global variable + # For other curl specific tests, use this macro. # Return result in variable: CURL_TEST_OUTPUT macro(curl_internal_test _curl_test) if(NOT DEFINED "${_curl_test}") string(REPLACE ";" " " _cmake_required_definitions "${CMAKE_REQUIRED_DEFINITIONS}") + set(_curl_test_add_libraries "") if(CMAKE_REQUIRED_LIBRARIES) set(_curl_test_add_libraries "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") diff --git a/CMake/OtherTests.cmake b/CMake/OtherTests.cmake index 0188538..8a7faaf 100644 --- a/CMake/OtherTests.cmake +++ b/CMake/OtherTests.cmake @@ -65,6 +65,9 @@ endif() set(_source_epilogue "#undef inline") curl_add_header_include(HAVE_SYS_TIME_H "sys/time.h") check_c_source_compiles("${_source_epilogue} + #ifdef _MSC_VER + #include + #endif #include int main(void) { diff --git a/CMake/PickyWarnings.cmake b/CMake/PickyWarnings.cmake index 23341c4..15f771b 100644 --- a/CMake/PickyWarnings.cmake +++ b/CMake/PickyWarnings.cmake @@ -274,6 +274,6 @@ endif() if(_picky) string(REPLACE ";" " " _picky "${_picky}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_picky}") + string(APPEND CMAKE_C_FLAGS " ${_picky}") message(STATUS "Picky compiler options: ${_picky}") endif() diff --git a/CMake/Utilities.cmake b/CMake/Utilities.cmake index 869d591..ff2173f 100644 --- a/CMake/Utilities.cmake +++ b/CMake/Utilities.cmake @@ -47,7 +47,7 @@ function(curl_dumpvars) if(_var_advanced) set(_var_advanced " [adv]") endif() - message("${_var}${_var_type}${_var_advanced} = ${${_var}}") + message("${_var}${_var_type}${_var_advanced} = '${${_var}}'") endforeach() message("::endgroup::") endfunction() diff --git a/CMake/win32-cache.cmake b/CMake/win32-cache.cmake index 9d46736..272f513 100644 --- a/CMake/win32-cache.cmake +++ b/CMake/win32-cache.cmake @@ -74,12 +74,12 @@ else() set(HAVE_UNISTD_H 0) set(HAVE_STDDEF_H 1) # detected by CMake internally in check_type_size() set(HAVE_STDATOMIC_H 0) - if(NOT MSVC_VERSION LESS 1600) + if(MSVC_VERSION GREATER_EQUAL 1600) set(HAVE_STDINT_H 1) # detected by CMake internally in check_type_size() else() set(HAVE_STDINT_H 0) # detected by CMake internally in check_type_size() endif() - if(NOT MSVC_VERSION LESS 1800) + if(MSVC_VERSION GREATER_EQUAL 1800) set(HAVE_STDBOOL_H 1) set(HAVE_STRTOLL 1) else() @@ -87,7 +87,7 @@ else() set(HAVE_STRTOLL 0) endif() set(HAVE_BOOL_T "${HAVE_STDBOOL_H}") - if(NOT MSVC_VERSION LESS 1900) + if(MSVC_VERSION GREATER_EQUAL 1900) set(HAVE_SNPRINTF 1) else() set(HAVE_SNPRINTF 0) diff --git a/CMakeLists.txt b/CMakeLists.txt index 30c0154..566863e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,12 +61,12 @@ if(NOT "$ENV{CURL_BUILDINFO}$ENV{CURL_CI}$ENV{CI}" STREQUAL "") else() set(_cache_var_type ":${_cache_var_type}") endif() - set(_cmake_args "${_cmake_args} -D${_cache_var}${_cache_var_type}=\"${_cache_var_value}\"") + string(APPEND _cmake_args " -D${_cache_var}${_cache_var_type}=\"${_cache_var_value}\"") endif() endforeach() endif() -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}") +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) include(Utilities) include(Macros) include(CMakeDependentOption) @@ -105,49 +105,49 @@ endif() set(_target_flags "") if(APPLE) - set(_target_flags "${_target_flags} APPLE") + string(APPEND _target_flags " APPLE") endif() if(UNIX) - set(_target_flags "${_target_flags} UNIX") + string(APPEND _target_flags " UNIX") endif() if(BSD) - set(_target_flags "${_target_flags} BSD") + string(APPEND _target_flags " BSD") endif() if(ANDROID) - set(_target_flags "${_target_flags} ANDROID-${ANDROID_PLATFORM_LEVEL}") + string(APPEND _target_flags " ANDROID-${ANDROID_PLATFORM_LEVEL}") endif() if(WIN32) - set(_target_flags "${_target_flags} WIN32") + string(APPEND _target_flags " WIN32") endif() if(WINDOWS_STORE) - set(_target_flags "${_target_flags} UWP") + string(APPEND _target_flags " UWP") endif() if(CYGWIN) - set(_target_flags "${_target_flags} CYGWIN") + string(APPEND _target_flags " CYGWIN") endif() if(MSYS) - set(_target_flags "${_target_flags} MSYS") + string(APPEND _target_flags " MSYS") endif() if(DOS) - set(_target_flags "${_target_flags} DOS") + string(APPEND _target_flags " DOS") endif() if(AMIGA) - set(_target_flags "${_target_flags} AMIGA") + string(APPEND _target_flags " AMIGA") endif() if(CMAKE_COMPILER_IS_GNUCC) - set(_target_flags "${_target_flags} GCC") + string(APPEND _target_flags " GCC") endif() if(MINGW) - set(_target_flags "${_target_flags} MINGW") + string(APPEND _target_flags " MINGW") endif() if(MSVC) - set(_target_flags "${_target_flags} MSVC-${MSVC_VERSION}") + string(APPEND _target_flags " MSVC-${MSVC_VERSION}") endif() if(VCPKG_TOOLCHAIN) - set(_target_flags "${_target_flags} VCPKG") + string(APPEND _target_flags " VCPKG") endif() if(CMAKE_CROSSCOMPILING) - set(_target_flags "${_target_flags} CROSS") + string(APPEND _target_flags " CROSS") endif() message(STATUS "CMake platform flags:${_target_flags}") @@ -193,8 +193,8 @@ if(WIN32) option(CURL_STATIC_CRT "Build libcurl with static CRT with MSVC (/MT)" OFF) if(CURL_STATIC_CRT AND MSVC) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -MT") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -MTd") + string(APPEND CMAKE_C_FLAGS_RELEASE " -MT") + string(APPEND CMAKE_C_FLAGS_DEBUG " -MTd") endif() option(ENABLE_UNICODE "Use the Unicode version of the Windows API functions" OFF) @@ -208,7 +208,11 @@ if(WIN32) endif() endif() - list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN") # Apply to all feature checks + # Apply to all feature checks + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DWIN32_LEAN_AND_MEAN") + if(MSVC) + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D_CRT_NONSTDC_NO_DEPRECATE") # for strdup() detection + endif() set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string") if(CURL_TARGET_WINDOWS_VERSION) @@ -256,7 +260,7 @@ endif() include(PickyWarnings) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE") # Required for sendmmsg() + string(APPEND CMAKE_C_FLAGS " -D_GNU_SOURCE") # Required for sendmmsg() endif() option(ENABLE_DEBUG "Enable curl debug features (for developing curl itself)" OFF) @@ -265,10 +269,6 @@ if(ENABLE_DEBUG) endif() option(ENABLE_CURLDEBUG "Enable TrackMemory debug feature" ${ENABLE_DEBUG}) -if(MSVC) - set(ENABLE_CURLDEBUG OFF) # FIXME: TrackMemory + MSVC fails test 558 and 1330. Tested with static build, Debug mode. -endif() - if(ENABLE_DEBUG) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "DEBUGBUILD") endif() @@ -350,7 +350,7 @@ if(ENABLE_ARES) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${CARES_PC_REQUIRES}) link_directories(${CARES_LIBRARY_DIRS}) if(CARES_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CARES_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${CARES_CFLAGS}") endif() endif() @@ -483,35 +483,6 @@ if(WINDOWS_STORE) set(CURL_DISABLE_TELNET ON) # telnet code needs fixing to compile for UWP. endif() -option(ENABLE_IPV6 "Enable IPv6 support" ON) -mark_as_advanced(ENABLE_IPV6) -if(ENABLE_IPV6 AND NOT WIN32) - include(CheckStructHasMember) - check_struct_has_member("struct sockaddr_in6" "sin6_addr" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_ADDR) - check_struct_has_member("struct sockaddr_in6" "sin6_scope_id" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) - if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR) - if(NOT DOS AND NOT AMIGA) - message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support") - endif() - # Force the feature off as this name is used as guard macro... - set(ENABLE_IPV6 OFF CACHE BOOL "Enable IPv6 support" FORCE) - endif() - - if(APPLE AND NOT ENABLE_ARES) - set(_use_core_foundation_and_core_services ON) - - find_library(SYSTEMCONFIGURATION_FRAMEWORK NAMES "SystemConfiguration") - mark_as_advanced(SYSTEMCONFIGURATION_FRAMEWORK) - if(NOT SYSTEMCONFIGURATION_FRAMEWORK) - message(FATAL_ERROR "SystemConfiguration framework not found") - endif() - list(APPEND CURL_LIBS "-framework SystemConfiguration") - endif() -endif() -if(ENABLE_IPV6) - set(USE_IPV6 ON) -endif() - find_package(Perl) if(PERL_EXECUTABLE) @@ -542,7 +513,7 @@ endif() # Disable warnings on Borland to avoid changing 3rd party code. if(BORLAND) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-") + string(APPEND CMAKE_C_FLAGS " -w-") endif() # If we are on AIX, do the _ALL_SOURCE magic @@ -568,15 +539,18 @@ include(CheckSymbolExists) include(CheckTypeSize) include(CheckCSourceCompiles) -if(WIN32) - # Preload settings on Windows - include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/win32-cache.cmake") -elseif(APPLE) - # Fast-track predictable feature detections - set(HAVE_EVENTFD 0) - set(HAVE_GETPASS_R 0) - set(HAVE_SENDMMSG 0) -elseif(AMIGA) +option(_CURL_QUICK_DETECT "Fast-track known feature detection results (Windows, some Apple)" ON) +if(_CURL_QUICK_DETECT) + if(WIN32) + include("${CMAKE_CURRENT_SOURCE_DIR}/CMake/win32-cache.cmake") + elseif(APPLE) + set(HAVE_EVENTFD 0) + set(HAVE_GETPASS_R 0) + set(HAVE_SENDMMSG 0) + endif() +endif() + +if(AMIGA) set(HAVE_GETADDRINFO 0) # Breaks the build when detected and used. endif() if(DOS OR AMIGA) @@ -619,12 +593,40 @@ elseif(AMIGA) elseif(NOT WIN32 AND NOT APPLE) check_library_exists("socket" "connect" "" HAVE_LIBSOCKET) if(HAVE_LIBSOCKET) - set(CURL_LIBS "socket;${CURL_LIBS}") + set(CURL_LIBS "socket" ${CURL_LIBS}) endif() endif() -if(WIN32) - list(APPEND CURL_LIBS "ws2_32" "bcrypt") +option(ENABLE_IPV6 "Enable IPv6 support" ON) +mark_as_advanced(ENABLE_IPV6) +if(ENABLE_IPV6) + include(CheckStructHasMember) + if(WIN32) + check_struct_has_member("struct sockaddr_in6" "sin6_scope_id" "winsock2.h;ws2tcpip.h" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) + else() + check_struct_has_member("struct sockaddr_in6" "sin6_addr" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_ADDR) + check_struct_has_member("struct sockaddr_in6" "sin6_scope_id" "netinet/in.h" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) + if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR) + if(NOT DOS AND NOT AMIGA) + message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support") + endif() + set(ENABLE_IPV6 OFF CACHE BOOL "Enable IPv6 support" FORCE) # Force the feature off as we use this name as guard macro + endif() + + if(APPLE AND NOT ENABLE_ARES) + set(_use_core_foundation_and_core_services ON) + + find_library(SYSTEMCONFIGURATION_FRAMEWORK NAMES "SystemConfiguration") + mark_as_advanced(SYSTEMCONFIGURATION_FRAMEWORK) + if(NOT SYSTEMCONFIGURATION_FRAMEWORK) + message(FATAL_ERROR "SystemConfiguration framework not found") + endif() + list(APPEND CURL_LIBS "-framework SystemConfiguration") + endif() + endif() +endif() +if(ENABLE_IPV6) + set(USE_IPV6 ON) endif() # Check SSL libraries @@ -748,7 +750,7 @@ if(CURL_USE_OPENSSL) set(_curl_ca_bundle_supported TRUE) cmake_push_check_state() - list(APPEND CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) + list(APPEND CMAKE_REQUIRED_LIBRARIES OpenSSL::SSL OpenSSL::Crypto) if(NOT DEFINED HAVE_BORINGSSL) check_symbol_exists("OPENSSL_IS_BORINGSSL" "openssl/base.h" HAVE_BORINGSSL) endif() @@ -793,7 +795,7 @@ if(CURL_USE_MBEDTLS) include_directories(SYSTEM ${MBEDTLS_INCLUDE_DIRS}) link_directories(${MBEDTLS_LIBRARY_DIRS}) if(MBEDTLS_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MBEDTLS_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${MBEDTLS_CFLAGS}") endif() if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "mbedtls") @@ -827,7 +829,7 @@ if(CURL_USE_WOLFSSL) include_directories(SYSTEM ${WOLFSSL_INCLUDE_DIRS}) link_directories(${WOLFSSL_LIBRARY_DIRS}) if(WOLFSSL_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WOLFSSL_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${WOLFSSL_CFLAGS}") endif() if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "wolfssl") @@ -842,6 +844,10 @@ if(CURL_USE_GNUTLS) pkg_check_modules(GNUTLS "gnutls") if(GNUTLS_FOUND) set(GNUTLS_LIBRARIES ${GNUTLS_LINK_LIBRARIES}) + string(REPLACE ";" " " GNUTLS_CFLAGS "${GNUTLS_CFLAGS}") + if(GNUTLS_CFLAGS) + string(APPEND CMAKE_C_FLAGS " ${GNUTLS_CFLAGS}") + endif() endif() endif() if(NOT GNUTLS_FOUND) @@ -851,12 +857,12 @@ if(CURL_USE_GNUTLS) set(_ssl_enabled ON) set(USE_GNUTLS ON) list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES} ${NETTLE_LIBRARIES}) - list(APPEND CURL_LIBDIRS ${NETTLE_LIBRARY_DIRS}) + list(APPEND CURL_LIBDIRS ${GNUTLS_LIBRARY_DIRS} ${NETTLE_LIBRARY_DIRS}) list(APPEND LIBCURL_PC_REQUIRES_PRIVATE "gnutls" ${NETTLE_PC_REQUIRES}) include_directories(SYSTEM ${GNUTLS_INCLUDE_DIRS} ${NETTLE_INCLUDE_DIRS}) link_directories(${NETTLE_LIBRARY_DIRS}) if(NETTLE_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NETTLE_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${NETTLE_CFLAGS}") endif() if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "gnutls") @@ -883,7 +889,7 @@ if(CURL_USE_RUSTLS) include_directories(SYSTEM ${RUSTLS_INCLUDE_DIRS}) link_directories(${RUSTLS_LIBRARY_DIRS}) if(RUSTLS_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${RUSTLS_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${RUSTLS_CFLAGS}") endif() if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "rustls") @@ -919,7 +925,7 @@ if(BROTLI_FOUND) include_directories(SYSTEM ${BROTLI_INCLUDE_DIRS}) link_directories(${BROTLI_LIBRARY_DIRS}) if(BROTLI_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${BROTLI_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${BROTLI_CFLAGS}") endif() endif() @@ -934,7 +940,7 @@ if(ZSTD_FOUND) include_directories(SYSTEM ${ZSTD_INCLUDE_DIRS}) link_directories(${ZSTD_LIBRARY_DIRS}) if(ZSTD_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ZSTD_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${ZSTD_CFLAGS}") endif() else() message(WARNING "zstd v1.0.0 or newer is required, disabling zstd support.") @@ -945,10 +951,10 @@ endif() macro(curl_openssl_check_symbol_exists _symbol _files _variable) cmake_push_check_state() if(USE_OPENSSL) - list(APPEND CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}") - list(APPEND CMAKE_REQUIRED_LIBRARIES "${OPENSSL_LIBRARIES}") + list(APPEND CMAKE_REQUIRED_LIBRARIES OpenSSL::SSL OpenSSL::Crypto) + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DOPENSSL_SUPPRESS_DEPRECATED") # for SSL_CTX_set_srp_username deprecated since 3.0.0 if(HAVE_LIBZ) - list(APPEND CMAKE_REQUIRED_LIBRARIES "${ZLIB_LIBRARIES}") + list(APPEND CMAKE_REQUIRED_LIBRARIES ZLIB::ZLIB) endif() if(WIN32) list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32") @@ -960,8 +966,7 @@ macro(curl_openssl_check_symbol_exists _symbol _files _variable) list(APPEND CMAKE_REQUIRED_LIBRARIES "${WOLFSSL_LIBRARIES}") curl_required_libpaths("${WOLFSSL_LIBRARY_DIRS}") if(HAVE_LIBZ) - list(APPEND CMAKE_REQUIRED_INCLUDES "${ZLIB_INCLUDE_DIRS}") # Public wolfSSL headers require zlib headers - list(APPEND CMAKE_REQUIRED_LIBRARIES "${ZLIB_LIBRARIES}") + list(APPEND CMAKE_REQUIRED_LIBRARIES ZLIB::ZLIB) # Public wolfSSL headers also require zlib headers endif() if(WIN32) list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32" "crypt32") @@ -1053,7 +1058,7 @@ if(USE_NGHTTP2) include_directories(SYSTEM ${NGHTTP2_INCLUDE_DIRS}) link_directories(${NGHTTP2_LIBRARY_DIRS}) if(NGHTTP2_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NGHTTP2_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${NGHTTP2_CFLAGS}") endif() else() set(USE_NGHTTP2 OFF) @@ -1085,7 +1090,7 @@ if(USE_NGTCP2) include_directories(SYSTEM ${NGTCP2_INCLUDE_DIRS}) link_directories(${NGTCP2_LIBRARY_DIRS}) if(NGTCP2_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NGTCP2_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${NGTCP2_CFLAGS}") endif() find_package(NGHTTP3 REQUIRED) @@ -1096,7 +1101,7 @@ if(USE_NGTCP2) include_directories(SYSTEM ${NGHTTP3_INCLUDE_DIRS}) link_directories(${NGHTTP3_LIBRARY_DIRS}) if(NGHTTP3_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NGHTTP3_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${NGHTTP3_CFLAGS}") endif() endif() @@ -1116,7 +1121,7 @@ if(USE_QUICHE) include_directories(SYSTEM ${QUICHE_INCLUDE_DIRS}) link_directories(${QUICHE_LIBRARY_DIRS}) if(QUICHE_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${QUICHE_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${QUICHE_CFLAGS}") endif() if(NOT DEFINED HAVE_QUICHE_CONN_SET_QLOG_FD) cmake_push_check_state() @@ -1145,7 +1150,7 @@ if(USE_MSH3) include_directories(SYSTEM ${MSH3_INCLUDE_DIRS}) link_directories(${MSH3_LIBRARY_DIRS}) if(MSH3_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MSH3_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${MSH3_CFLAGS}") endif() endif() @@ -1186,20 +1191,20 @@ if(NOT CURL_DISABLE_LDAP) # Check for LDAP cmake_push_check_state() if(USE_OPENSSL) - list(APPEND CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) + list(APPEND CMAKE_REQUIRED_LIBRARIES OpenSSL::SSL OpenSSL::Crypto) endif() find_package(LDAP) if(LDAP_FOUND) set(HAVE_LBER_H 1) - set(CURL_LIBS "${LDAP_LIBRARIES};${CURL_LIBS}") + set(CURL_LIBS ${LDAP_LIBRARIES} ${CURL_LIBS}) list(APPEND CURL_LIBDIRS ${LDAP_LIBRARY_DIRS}) if(LDAP_PC_REQUIRES) - set(LIBCURL_PC_REQUIRES_PRIVATE "${LDAP_PC_REQUIRES};${LIBCURL_PC_REQUIRES_PRIVATE}") + set(LIBCURL_PC_REQUIRES_PRIVATE ${LDAP_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE}) endif() include_directories(SYSTEM ${LDAP_INCLUDE_DIRS}) link_directories(${LDAP_LIBRARY_DIRS}) if(LDAP_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LDAP_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${LDAP_CFLAGS}") endif() # LDAP feature checks @@ -1215,7 +1220,6 @@ if(NOT CURL_DISABLE_LDAP) if(HAVE_LDAP_INIT_FD) set(USE_OPENLDAP ON) - add_definitions("-DLDAP_DEPRECATED=1") endif() if(NOT CURL_DISABLE_LDAPS) set(HAVE_LDAP_SSL ON) @@ -1269,13 +1273,13 @@ set(HAVE_LIBIDN2 OFF) if(USE_LIBIDN2 AND NOT USE_APPLE_IDN AND NOT USE_WIN32_IDN) find_package(Libidn2) if(LIBIDN2_FOUND) - set(CURL_LIBS "${LIBIDN2_LIBRARIES};${CURL_LIBS}") + set(CURL_LIBS ${LIBIDN2_LIBRARIES} ${CURL_LIBS}) list(APPEND CURL_LIBDIRS ${LIBIDN2_LIBRARY_DIRS}) - set(LIBCURL_PC_REQUIRES_PRIVATE "${LIBIDN2_PC_REQUIRES};${LIBCURL_PC_REQUIRES_PRIVATE}") + set(LIBCURL_PC_REQUIRES_PRIVATE ${LIBIDN2_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE}) include_directories(SYSTEM ${LIBIDN2_INCLUDE_DIRS}) link_directories(${LIBIDN2_LIBRARY_DIRS}) if(LIBIDN2_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBIDN2_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${LIBIDN2_CFLAGS}") endif() set(HAVE_IDN2_H 1) set(HAVE_LIBIDN2 1) @@ -1295,7 +1299,7 @@ if(CURL_USE_LIBPSL) include_directories(SYSTEM ${LIBPSL_INCLUDE_DIRS}) link_directories(${LIBPSL_LIBRARY_DIRS}) if(LIBPSL_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBPSL_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${LIBPSL_CFLAGS}") endif() set(USE_LIBPSL ON) endif() @@ -1308,13 +1312,13 @@ set(USE_LIBSSH2 OFF) if(CURL_USE_LIBSSH2) find_package(Libssh2) if(LIBSSH2_FOUND) - list(APPEND CURL_LIBS ${LIBSSH2_LIBRARIES}) + set(CURL_LIBS ${LIBSSH2_LIBRARIES} ${CURL_LIBS}) # keep it before TLS-crypto, compression list(APPEND CURL_LIBDIRS ${LIBSSH2_LIBRARY_DIRS}) - list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH2_PC_REQUIRES}) + set(LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH2_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE}) include_directories(SYSTEM ${LIBSSH2_INCLUDE_DIRS}) link_directories(${LIBSSH2_LIBRARY_DIRS}) if(LIBSSH2_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBSSH2_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${LIBSSH2_CFLAGS}") endif() set(USE_LIBSSH2 ON) endif() @@ -1325,13 +1329,13 @@ option(CURL_USE_LIBSSH "Use libssh" OFF) mark_as_advanced(CURL_USE_LIBSSH) if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH) find_package(Libssh REQUIRED) - list(APPEND CURL_LIBS ${LIBSSH_LIBRARIES}) + set(CURL_LIBS ${LIBSSH_LIBRARIES} ${CURL_LIBS}) # keep it before TLS-crypto, compression list(APPEND CURL_LIBDIRS ${LIBSSH_LIBRARY_DIRS}) - list(APPEND LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH_PC_REQUIRES}) + set(LIBCURL_PC_REQUIRES_PRIVATE ${LIBSSH_PC_REQUIRES} ${LIBCURL_PC_REQUIRES_PRIVATE}) include_directories(SYSTEM ${LIBSSH_INCLUDE_DIRS}) link_directories(${LIBSSH_LIBRARY_DIRS}) if(LIBSSH_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBSSH_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${LIBSSH_CFLAGS}") endif() set(USE_LIBSSH ON) endif() @@ -1344,7 +1348,7 @@ if(NOT USE_LIBSSH2 AND NOT USE_LIBSSH AND CURL_USE_WOLFSSH) if(USE_WOLFSSL) find_package(WolfSSH) if(WOLFSSH_FOUND) - list(APPEND CURL_LIBS ${WOLFSSH_LIBRARIES}) + set(CURL_LIBS ${WOLFSSH_LIBRARIES} ${CURL_LIBS}) # keep it before TLS-crypto, compression include_directories(SYSTEM ${WOLFSSH_INCLUDE_DIRS}) set(USE_WOLFSSH ON) endif() @@ -1363,7 +1367,7 @@ if(CURL_USE_GSASL) include_directories(SYSTEM ${LIBGSASL_INCLUDE_DIRS}) link_directories(${LIBGSASL_LIBRARY_DIRS}) if(LIBGSASL_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBGSASL_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${LIBGSASL_CFLAGS}") endif() set(USE_GSASL ON) endif() @@ -1382,7 +1386,7 @@ if(CURL_USE_GSSAPI) include_directories(SYSTEM ${GSS_INCLUDE_DIRS}) link_directories(${GSS_LIBRARY_DIRS}) if(GSS_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${GSS_CFLAGS}") endif() if(GSS_FLAVOUR STREQUAL "GNU") @@ -1408,7 +1412,7 @@ if(CURL_USE_GSSAPI) endif() if(NOT DEFINED HAVE_GSS_C_NT_HOSTBASED_SERVICE) - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${GSS_CFLAGS}") + string(APPEND CMAKE_REQUIRED_FLAGS " ${GSS_CFLAGS}") list(APPEND CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES}) curl_required_libpaths("${GSS_LIBRARY_DIRS}") check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" "${_include_list}" HAVE_GSS_C_NT_HOSTBASED_SERVICE) @@ -1438,7 +1442,7 @@ if(CURL_USE_LIBUV) include_directories(SYSTEM ${LIBUV_INCLUDE_DIRS}) link_directories(${LIBUV_LIBRARY_DIRS}) if(LIBUV_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUV_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${LIBUV_CFLAGS}") endif() set(USE_LIBUV ON) set(HAVE_UV_H ON) @@ -1453,7 +1457,7 @@ if(USE_LIBRTMP) include_directories(SYSTEM ${LIBRTMP_INCLUDE_DIRS}) link_directories(${LIBRTMP_LIBRARY_DIRS}) if(LIBRTMP_CFLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBRTMP_CFLAGS}") + string(APPEND CMAKE_C_FLAGS " ${LIBRTMP_CFLAGS}") endif() endif() @@ -1650,7 +1654,7 @@ foreach(_variable IN ITEMS HAVE_UNISTD_H ) if(${_variable}) - set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${_variable}") + string(APPEND CURL_TEST_DEFINES " -D${_variable}") endif() endforeach() @@ -1735,14 +1739,15 @@ check_function_exists("eventfd" HAVE_EVENTFD) check_symbol_exists("ftruncate" "unistd.h" HAVE_FTRUNCATE) check_symbol_exists("getpeername" "${CURL_INCLUDES}" HAVE_GETPEERNAME) # winsock2.h unistd.h proto/bsdsocket.h check_symbol_exists("getsockname" "${CURL_INCLUDES}" HAVE_GETSOCKNAME) # winsock2.h unistd.h proto/bsdsocket.h -check_function_exists("if_nametoindex" HAVE_IF_NAMETOINDEX) # winsock2.h net/if.h check_function_exists("getrlimit" HAVE_GETRLIMIT) check_function_exists("setlocale" HAVE_SETLOCALE) check_function_exists("setmode" HAVE_SETMODE) check_function_exists("setrlimit" HAVE_SETRLIMIT) if(NOT WIN32) - check_function_exists("sched_yield" HAVE_SCHED_YIELD) + check_function_exists("if_nametoindex" HAVE_IF_NAMETOINDEX) # iphlpapi.h (Windows non-UWP), net/if.h + check_function_exists("realpath" HAVE_REALPATH) + check_function_exists("sched_yield" HAVE_SCHED_YIELD) check_symbol_exists("strcasecmp" "string.h" HAVE_STRCASECMP) check_symbol_exists("stricmp" "string.h" HAVE_STRICMP) check_symbol_exists("strcmpi" "string.h" HAVE_STRCMPI) @@ -1760,15 +1765,16 @@ if(NOT _ssl_enabled) check_symbol_exists("arc4random" "${CURL_INCLUDES};stdlib.h" HAVE_ARC4RANDOM) endif() -if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1900)) - # Earlier MSVC compilers had faulty snprintf implementations - check_function_exists("snprintf" HAVE_SNPRINTF) +if(NOT MSVC) + check_function_exists("snprintf" HAVE_SNPRINTF) # to match detection method in ./configure +elseif(MSVC_VERSION GREATER_EQUAL 1900) # Earlier MSVC compilers had faulty snprintf implementations + check_symbol_exists("snprintf" "stdio.h" HAVE_SNPRINTF) # snprintf may be a compatibility macro, not an exported function endif() if(APPLE) check_function_exists("mach_absolute_time" HAVE_MACH_ABSOLUTE_TIME) endif() -check_symbol_exists("inet_ntop" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP) # arpa/inet.h -check_symbol_exists("inet_pton" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON) # arpa/inet.h +check_symbol_exists("inet_ntop" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP) # arpa/inet.h netinet/in.h sys/socket.h +check_symbol_exists("inet_pton" "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON) # arpa/inet.h netinet/in.h sys/socket.h check_symbol_exists("fsetxattr" "sys/xattr.h" HAVE_FSETXATTR) if(HAVE_FSETXATTR) @@ -1911,7 +1917,7 @@ if(CMAKE_COMPILER_IS_GNUCC AND APPLE) # The Mac version of GCC warns about use of long double. Disable it. get_source_file_property(_mprintf_compile_flags "mprintf.c" COMPILE_FLAGS) if(_mprintf_compile_flags) - set(_mprintf_compile_flags "${_mprintf_compile_flags} -Wno-long-double") + string(APPEND _mprintf_compile_flags " -Wno-long-double") else() set(_mprintf_compile_flags "-Wno-long-double") endif() @@ -1930,13 +1936,15 @@ include(CMake/OtherTests.cmake) add_definitions("-DHAVE_CONFIG_H") if(WIN32) + list(APPEND CURL_LIBS "ws2_32" "bcrypt") + # _fseeki64() requires VS2005 if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1400)) set(USE_WIN32_LARGE_FILES ON) endif() # Use the manifest embedded in the Windows Resource - set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DCURL_EMBED_MANIFEST") + string(APPEND CMAKE_RC_FLAGS " -DCURL_EMBED_MANIFEST") # We use crypto functions that are not available for UWP apps if(NOT WINDOWS_STORE) @@ -1951,26 +1959,25 @@ endif() if(MSVC) # Disable default manifest added by CMake - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -MANIFEST:NO") + string(APPEND CMAKE_EXE_LINKER_FLAGS " -MANIFEST:NO") if(CMAKE_C_FLAGS MATCHES "[/-]W[0-4]") string(REGEX REPLACE "[/-]W[0-4]" "-W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W4") + string(APPEND CMAKE_C_FLAGS " -W4") endif() # Use multithreaded compilation on VS2008+ if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION GREATER_EQUAL 1500) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MP") + string(APPEND CMAKE_C_FLAGS " -MP") endif() endif() if(CURL_WERROR) if(MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -WX") + string(APPEND CMAKE_C_FLAGS " -WX") else() - # This assumes clang or gcc style options - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + string(APPEND CMAKE_C_FLAGS " -Werror") # This assumes clang or gcc style options endif() endif() @@ -2122,7 +2129,7 @@ curl_add_if("brotli" HAVE_BROTLI) curl_add_if("gsasl" USE_GSASL) curl_add_if("zstd" HAVE_ZSTD) curl_add_if("AsynchDNS" USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32) -curl_add_if("asyn-rr" USE_ARES AND ENABLE_THREADED_RESOLVER) +curl_add_if("asyn-rr" USE_ARES AND ENABLE_THREADED_RESOLVER AND USE_HTTPSRR) curl_add_if("IDN" (HAVE_LIBIDN2 AND HAVE_IDN2_H) OR USE_WIN32_IDN OR USE_APPLE_IDN) @@ -2197,7 +2204,6 @@ if(NOT CURL_DISABLE_INSTALL) # curl-config needs the following options to be set. set(CC "${CMAKE_C_COMPILER}") - # TODO: probably put a -D... options here? set(CONFIGURE_OPTIONS "") set(CURLVERSION "${_curl_version}") set(VERSIONNUM "${_curl_version_num}") @@ -2241,18 +2247,18 @@ if(NOT CURL_DISABLE_INSTALL) endforeach() # Avoid getting unnecessary -L options for known system directories. - set(_sys_libdirs "") + set(_sys_libdirs "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}") foreach(_libdir IN LISTS CMAKE_SYSTEM_PREFIX_PATH) if(_libdir MATCHES "/$") - set(_libdir "${_libdir}lib") + string(APPEND _libdir "lib") else() - set(_libdir "${_libdir}/lib") + string(APPEND _libdir "/lib") endif() if(IS_DIRECTORY "${_libdir}") list(APPEND _sys_libdirs "${_libdir}") endif() if(DEFINED CMAKE_LIBRARY_ARCHITECTURE) - set(_libdir "${_libdir}/${CMAKE_LIBRARY_ARCHITECTURE}") + string(APPEND _libdir "/${CMAKE_LIBRARY_ARCHITECTURE}") if(IS_DIRECTORY "${_libdir}") list(APPEND _sys_libdirs "${_libdir}") endif() @@ -2260,6 +2266,9 @@ if(NOT CURL_DISABLE_INSTALL) endforeach() foreach(_libdir IN LISTS _custom_libdirs CURL_LIBDIRS) + if(NOT CMAKE_VERSION VERSION_LESS 3.20) + cmake_path(SET _libdir NORMALIZE "${_libdir}") + endif() list(FIND _sys_libdirs "${_libdir}" _libdir_index) if(_libdir_index LESS 0) list(APPEND _ldflags "-L${_libdir}") @@ -2268,7 +2277,7 @@ if(NOT CURL_DISABLE_INSTALL) set(_implicit_libs "") if(NOT MINGW AND NOT UNIX) - set(_implicit_libs ${CMAKE_C_IMPLICIT_LINK_LIBRARIES}) + set(_implicit_libs "${CMAKE_C_IMPLICIT_LINK_LIBRARIES}") endif() foreach(_lib IN LISTS _implicit_libs _custom_libs CURL_LIBS) @@ -2294,6 +2303,9 @@ if(NOT CURL_DISABLE_INSTALL) get_filename_component(_libdir ${_lib} DIRECTORY) get_filename_component(_libname ${_lib} NAME_WE) if(_libname MATCHES "^lib") + if(NOT CMAKE_VERSION VERSION_LESS 3.20) + cmake_path(SET _libdir NORMALIZE "${_libdir}") + endif() list(FIND _sys_libdirs "${_libdir}" _libdir_index) if(_libdir_index LESS 0) list(APPEND _ldflags "-L${_libdir}") @@ -2464,6 +2476,7 @@ if(NOT CURL_DISABLE_INSTALL) endif() # Save build info for test runner to pick up and log +set(_cmake_sysroot "") if(CMAKE_OSX_SYSROOT) set(_cmake_sysroot ${CMAKE_OSX_SYSROOT}) elseif(CMAKE_SYSROOT) diff --git a/include/curl/curlver.h b/include/curl/curlver.h index 376272e..8403e7c 100644 --- a/include/curl/curlver.h +++ b/include/curl/curlver.h @@ -32,13 +32,13 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "8.12.0-DEV" +#define LIBCURL_VERSION "8.12.1-DEV" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 8 #define LIBCURL_VERSION_MINOR 12 -#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 0x080c00 +#define LIBCURL_VERSION_NUM 0x080c01 /* * This is the date and time when the full source package was created. The diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index c1863b0..5f1b395 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -55,6 +55,9 @@ if(CURL_BUILD_TESTING) ) target_compile_definitions(curlu PUBLIC "UNITTESTS" "CURL_STATICLIB") target_link_libraries(curlu PRIVATE ${CURL_LIBS}) + # There is plenty of parallelism when building the testdeps target. + # Override the curlu batch size with the maximum to optimize performance. + set_target_properties(curlu PROPERTIES UNITY_BUILD_BATCH_SIZE 0) endif() if(ENABLE_CURLDEBUG) @@ -65,6 +68,13 @@ endif() ## Library definition +if(NOT DEFINED IMPORT_LIB_SUFFIX) + set(IMPORT_LIB_SUFFIX "") +endif() +if(NOT DEFINED STATIC_LIB_SUFFIX) + set(STATIC_LIB_SUFFIX "") +endif() + # Add "_imp" as a suffix before the extension to avoid conflicting with # the statically linked "libcurl.lib" (typically with MSVC) if(WIN32 AND diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index 38dc729..640c8a9 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -109,6 +109,9 @@ int Curl_ares_perform(ares_channel channel, int i; int num = 0; + if(!channel) + return 0; + bitmask = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM); for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) { diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index b8c3049..f989415 100644 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -138,14 +138,14 @@ CURLcode Curl_resolver_duphandle(struct Curl_easy *easy, void **to, void *from) return Curl_resolver_init(easy, to); } -static void destroy_async_data(struct Curl_async *); +static void destroy_async_data(struct Curl_easy *); /* * Cancel all possibly still on-going resolves for this connection. */ void Curl_resolver_cancel(struct Curl_easy *data) { - destroy_async_data(&data->state.async); + destroy_async_data(data); } /* This function is used to init a threaded resolve */ @@ -282,14 +282,6 @@ CURL_STDCALL getaddrinfo_thread(void *arg) struct thread_data *td = tsd->td; char service[12]; int rc; -#ifndef CURL_DISABLE_SOCKETPAIR -#ifdef USE_EVENTFD - const void *buf; - const uint64_t val = 1; -#else - char buf[1]; -#endif -#endif msnprintf(service, sizeof(service), "%d", tsd->port); @@ -315,9 +307,9 @@ CURL_STDCALL getaddrinfo_thread(void *arg) #ifndef CURL_DISABLE_SOCKETPAIR if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { #ifdef USE_EVENTFD - buf = &val; + const uint64_t buf[1] = { 1 }; #else - buf[0] = 1; + const char buf[1] = { 1 }; #endif /* DNS has been resolved, signal client task */ if(wakeup_write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { @@ -377,18 +369,22 @@ CURL_STDCALL gethostbyname_thread(void *arg) /* * destroy_async_data() cleans up async resolver data and thread handle. */ -static void destroy_async_data(struct Curl_async *async) +static void destroy_async_data(struct Curl_easy *data) { + struct Curl_async *async; + DEBUGASSERT(data); + async = &data->state.async; + DEBUGASSERT(async); if(async->tdata) { struct thread_data *td = async->tdata; bool done; #ifndef CURL_DISABLE_SOCKETPAIR curl_socket_t sock_rd = td->tsd.sock_pair[0]; - struct Curl_easy *data = td->tsd.data; #endif #ifdef USE_HTTPSRR_ARES - ares_destroy(data->state.async.tdata->channel); + if(data->state.async.tdata->channel) + ares_destroy(data->state.async.tdata->channel); #endif /* * if the thread is still blocking in the resolve syscall, detach it and @@ -495,12 +491,12 @@ static bool init_resolve_thread(struct Curl_easy *data, } #ifdef USE_HTTPSRR_ARES if(resolve_httpsrr(data, asp)) - goto err_exit; + infof(data, "Failed HTTPS RR operation"); #endif return TRUE; err_exit: - destroy_async_data(asp); + destroy_async_data(data); errno_exit: errno = err; @@ -539,7 +535,7 @@ static CURLcode thread_wait_resolv(struct Curl_easy *data, /* a name was not resolved, report error */ result = Curl_resolver_error(data); - destroy_async_data(&data->state.async); + destroy_async_data(data); if(!data->state.async.dns && report) connclose(data->conn, "asynch resolve failed"); @@ -617,7 +613,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, if(!data->state.async.dns) { CURLcode result = Curl_resolver_error(data); - destroy_async_data(&data->state.async); + destroy_async_data(data); return result; } #ifdef USE_HTTPSRR_ARES @@ -625,13 +621,13 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, struct Curl_https_rrinfo *lhrr = Curl_memdup(&td->hinfo, sizeof(struct Curl_https_rrinfo)); if(!lhrr) { - destroy_async_data(&data->state.async); + destroy_async_data(data); return CURLE_OUT_OF_MEMORY; } data->state.async.dns->hinfo = lhrr; } #endif - destroy_async_data(&data->state.async); + destroy_async_data(data); *entry = data->state.async.dns; } else { @@ -665,15 +661,17 @@ int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks) timediff_t milli; timediff_t ms; struct resdata *reslv = (struct resdata *)data->state.async.resolver; - int socketi = 0; #ifndef CURL_DISABLE_SOCKETPAIR struct thread_data *td = data->state.async.tdata; +#endif +#if !defined(CURL_DISABLE_SOCKETPAIR) || defined(USE_HTTPSRR_ARES) + int socketi = 0; #else (void)socks; #endif #ifdef USE_HTTPSRR_ARES - if(data->state.async.tdata) { + if(data->state.async.tdata && data->state.async.tdata->channel) { ret_val = Curl_ares_getsock(data, data->state.async.tdata->channel, socks); for(socketi = 0; socketi < (MAX_SOCKSPEREASYHANDLE - 1); socketi++) if(!ARES_GETSOCK_READABLE(ret_val, socketi) && @@ -685,8 +683,7 @@ int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks) if(td) { /* return read fd to client for polling the DNS resolution status */ socks[socketi] = td->tsd.sock_pair[0]; - td->tsd.data = data; - ret_val = GETSOCK_READSOCK(socketi); + ret_val |= GETSOCK_READSOCK(socketi); } else { #endif diff --git a/lib/asyn.h b/lib/asyn.h index c674541..5a21329 100644 --- a/lib/asyn.h +++ b/lib/asyn.h @@ -40,20 +40,19 @@ struct Curl_dns_entry; /* Data for synchronization between resolver thread and its parent */ struct thread_sync_data { curl_mutex_t *mtx; - bool done; - int port; char *hostname; /* hostname to resolve, Curl_async.hostname duplicate */ #ifndef CURL_DISABLE_SOCKETPAIR - struct Curl_easy *data; curl_socket_t sock_pair[2]; /* eventfd/pipes/socket pair */ #endif - int sock_error; struct Curl_addrinfo *res; #ifdef HAVE_GETADDRINFO struct addrinfo hints; #endif struct thread_data *td; /* for thread-self cleanup */ + int port; + int sock_error; + bool done; }; struct thread_data { diff --git a/lib/cf-h1-proxy.c b/lib/cf-h1-proxy.c index 2e13f39..9b75d08 100644 --- a/lib/cf-h1-proxy.c +++ b/lib/cf-h1-proxy.c @@ -660,7 +660,6 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf, cf->ctx = ts; } - /* TODO: can we do blocking? */ /* We want "seamless" operations through HTTP proxy tunnel */ result = H1_CONNECT(cf, data, ts); diff --git a/lib/cf-h2-proxy.c b/lib/cf-h2-proxy.c index 771ecc1..d8b9128 100644 --- a/lib/cf-h2-proxy.c +++ b/lib/cf-h2-proxy.c @@ -1408,7 +1408,7 @@ static ssize_t cf_h2_proxy_send(struct Curl_cfilter *cf, ssize_t nwritten; CURLcode result; - (void)eos; /* TODO, maybe useful for blocks? */ + (void)eos; if(ctx->tunnel.state != H2_TUNNEL_ESTABLISHED) { *err = CURLE_SEND_ERROR; return -1; diff --git a/lib/cf-https-connect.c b/lib/cf-https-connect.c index 2b39e98..f073647 100644 --- a/lib/cf-https-connect.c +++ b/lib/cf-https-connect.c @@ -42,11 +42,6 @@ #include "curl_memory.h" #include "memdebug.h" - -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - typedef enum { CF_HC_INIT, CF_HC_CONNECT, @@ -592,8 +587,8 @@ static CURLcode cf_hc_create(struct Curl_cfilter **pcf, DEBUGASSERT(alpnids); DEBUGASSERT(alpn_count); - DEBUGASSERT(alpn_count <= ARRAYSIZE(ctx->ballers)); - if(!alpn_count || (alpn_count > ARRAYSIZE(ctx->ballers))) { + DEBUGASSERT(alpn_count <= CURL_ARRAYSIZE(ctx->ballers)); + if(!alpn_count || (alpn_count > CURL_ARRAYSIZE(ctx->ballers))) { failf(data, "https-connect filter create with unsupported %zu ALPN ids", alpn_count); return CURLE_FAILED_INIT; @@ -607,7 +602,7 @@ static CURLcode cf_hc_create(struct Curl_cfilter **pcf, ctx->remotehost = remotehost; for(i = 0; i < alpn_count; ++i) cf_hc_baller_assign(&ctx->ballers[i], alpnids[i]); - for(; i < ARRAYSIZE(ctx->ballers); ++i) + for(; i < CURL_ARRAYSIZE(ctx->ballers); ++i) ctx->ballers[i].alpn_id = ALPN_none; ctx->baller_count = alpn_count; @@ -663,8 +658,8 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data, if(conn->dns_entry && conn->dns_entry->hinfo && !conn->dns_entry->hinfo->no_def_alpn) { size_t i, j; - for(i = 0; i < ARRAYSIZE(conn->dns_entry->hinfo->alpns) && - alpn_count < ARRAYSIZE(alpn_ids); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(conn->dns_entry->hinfo->alpns) && + alpn_count < CURL_ARRAYSIZE(alpn_ids); ++i) { bool present = FALSE; enum alpnid alpn = conn->dns_entry->hinfo->alpns[i]; for(j = 0; j < alpn_count; ++j) { @@ -701,7 +696,6 @@ CURLcode Curl_cf_https_setup(struct Curl_easy *data, break; case CURL_HTTP_VERSION_3: /* We assume that silently not even trying H3 is ok here */ - /* TODO: should we fail instead? */ if(Curl_conn_may_http3(data, conn) == CURLE_OK) alpn_ids[alpn_count++] = ALPN_h3; alpn_ids[alpn_count++] = ALPN_h2; diff --git a/lib/cf-socket.c b/lib/cf-socket.c index edda348..a6f9888 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -1325,7 +1325,6 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf, return CURLE_OK; } - /* TODO: need to support blocking connect? */ if(blocking) return CURLE_UNSUPPORTED_PROTOCOL; @@ -1432,7 +1431,7 @@ static void cf_socket_adjust_pollset(struct Curl_cfilter *cf, /* A listening socket filter needs to be connected before the accept * for some weird FTP interaction. This should be rewritten, so that * FTP no longer does the socket checks and accept calls and delegates - * all that to the filter. TODO. */ + * all that to the filter. */ if(ctx->listening) { Curl_pollset_set_in_only(data, ps, ctx->sock); CURL_TRC_CF(data, cf, "adjust_pollset, listening, POLLIN fd=%" @@ -1850,7 +1849,7 @@ static CURLcode cf_udp_setup_quic(struct Curl_cfilter *cf, /* QUIC needs a connected socket, nonblocking */ DEBUGASSERT(ctx->sock != CURL_SOCKET_BAD); - rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, /* NOLINT FIXME */ + rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, /* NOLINT */ (curl_socklen_t)ctx->addr.addrlen); if(-1 == rc) { return socket_connect_result(data, ctx->ip.remote_ip, SOCKERRNO); @@ -2213,7 +2212,7 @@ struct Curl_cftype Curl_cft_tcp_accept = { cf_tcp_accept_connect, cf_socket_close, cf_socket_shutdown, - cf_socket_get_host, /* TODO: not accurate */ + cf_socket_get_host, cf_socket_adjust_pollset, cf_socket_data_pending, cf_socket_send, diff --git a/lib/cfilters.c b/lib/cfilters.c index 3be0840..6a894e8 100644 --- a/lib/cfilters.c +++ b/lib/cfilters.c @@ -41,10 +41,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - static void cf_cntrl_update_info(struct Curl_easy *data, struct connectdata *conn); @@ -724,7 +720,7 @@ static CURLcode cf_cntrl_all(struct connectdata *conn, CURLcode result = CURLE_OK; size_t i; - for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(conn->cfilter); ++i) { result = Curl_conn_cf_cntrl(conn->cfilter[i], data, ignore_result, event, arg1, arg2); if(!ignore_result && result) diff --git a/lib/conncache.c b/lib/conncache.c index 85435bf..b8a0515 100644 --- a/lib/conncache.c +++ b/lib/conncache.c @@ -166,11 +166,11 @@ int Curl_cpool_init(struct cpool *cpool, if(!cpool->idata) return 1; /* bad */ cpool->idata->state.internal = TRUE; - /* TODO: this is quirky. We need an internal handle for certain - * operations, but we do not add it to the multi (if there is one). - * But we give it the multi so that socket event operations can work. - * Probably better to have an internal handle owned by the multi that - * can be used for cpool operations. */ + /* This is quirky. We need an internal handle for certain operations, but we + * do not add it to the multi (if there is one). We give it the multi so + * that socket event operations can work. Probably better to have an + * internal handle owned by the multi that can be used for cpool + * operations. */ cpool->idata->multi = multi; #ifdef DEBUGBUILD if(getenv("CURL_DEBUG")) @@ -1302,7 +1302,6 @@ static int conn_upkeep(struct Curl_easy *data, void *param) { struct curltime *now = param; - /* TODO, shall we reap connections that return an error here? */ Curl_conn_upkeep(data, conn, now); return 0; /* continue iteration */ } diff --git a/lib/connect.c b/lib/connect.c index 05aabff..67cdb54 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -85,10 +85,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - #if !defined(CURL_DISABLE_ALTSVC) || defined(USE_HTTPSRR) enum alpnid Curl_alpn2alpnid(char *name, size_t len) @@ -644,7 +640,7 @@ evaluate: *connected = FALSE; /* a negative world view is best */ now = Curl_now(); ongoing = not_started = 0; - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; if(!baller || baller->is_done) @@ -705,7 +701,7 @@ evaluate: if(not_started > 0) { int added = 0; - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; if(!baller || baller->has_started) @@ -739,7 +735,7 @@ evaluate: /* all ballers have failed to connect. */ CURL_TRC_CF(data, cf, "all eyeballers failed"); result = CURLE_COULDNT_CONNECT; - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; if(!baller) continue; @@ -884,7 +880,7 @@ static void cf_he_ctx_clear(struct Curl_cfilter *cf, struct Curl_easy *data) DEBUGASSERT(ctx); DEBUGASSERT(data); - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { baller_free(ctx->baller[i], data); ctx->baller[i] = NULL; } @@ -907,7 +903,7 @@ static CURLcode cf_he_shutdown(struct Curl_cfilter *cf, /* shutdown all ballers that have not done so already. If one fails, * continue shutting down others until all are shutdown. */ - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; bool bdone = FALSE; if(!baller || !baller->cf || baller->shutdown) @@ -918,12 +914,12 @@ static CURLcode cf_he_shutdown(struct Curl_cfilter *cf, } *done = TRUE; - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { if(ctx->baller[i] && !ctx->baller[i]->shutdown) *done = FALSE; } if(*done) { - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { if(ctx->baller[i] && ctx->baller[i]->result) result = ctx->baller[i]->result; } @@ -940,7 +936,7 @@ static void cf_he_adjust_pollset(struct Curl_cfilter *cf, size_t i; if(!cf->connected) { - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; if(!baller || !baller->cf) continue; @@ -962,7 +958,7 @@ static CURLcode cf_he_connect(struct Curl_cfilter *cf, return CURLE_OK; } - (void)blocking; /* TODO: do we want to support this? */ + (void)blocking; DEBUGASSERT(ctx); *done = FALSE; @@ -1037,7 +1033,7 @@ static bool cf_he_data_pending(struct Curl_cfilter *cf, if(cf->connected) return cf->next->cft->has_data_pending(cf->next, data); - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; if(!baller || !baller->cf) continue; @@ -1056,7 +1052,7 @@ static struct curltime get_max_baller_time(struct Curl_cfilter *cf, size_t i; memset(&tmax, 0, sizeof(tmax)); - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; memset(&t, 0, sizeof(t)); @@ -1081,7 +1077,7 @@ static CURLcode cf_he_query(struct Curl_cfilter *cf, int reply_ms = -1; size_t i; - for(i = 0; i < ARRAYSIZE(ctx->baller); i++) { + for(i = 0; i < CURL_ARRAYSIZE(ctx->baller); i++) { struct eyeballer *baller = ctx->baller[i]; int breply_ms; @@ -1215,7 +1211,7 @@ struct transport_provider transport_providers[] = { static cf_ip_connect_create *get_cf_create(int transport) { size_t i; - for(i = 0; i < ARRAYSIZE(transport_providers); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) { if(transport == transport_providers[i].transport) return transport_providers[i].cf_create; } @@ -1469,7 +1465,7 @@ void Curl_debug_set_transport_provider(int transport, cf_ip_connect_create *cf_create) { size_t i; - for(i = 0; i < ARRAYSIZE(transport_providers); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(transport_providers); ++i) { if(transport == transport_providers[i].transport) { transport_providers[i].cf_create = cf_create; return; diff --git a/lib/content_encoding.c b/lib/content_encoding.c index d23f8cd..e365af6 100644 --- a/lib/content_encoding.c +++ b/lib/content_encoding.c @@ -69,6 +69,10 @@ #ifdef HAVE_LIBZ +#if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204) +#error "requires zlib 1.2.0.4 or newer" +#endif + typedef enum { ZLIB_UNINIT, /* uninitialized */ ZLIB_INIT, /* initialized */ @@ -309,24 +313,15 @@ static CURLcode gzip_do_init(struct Curl_easy *data, { struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ - const char *v = zlibVersion(); /* Initialize zlib */ z->zalloc = (alloc_func) zalloc_cb; z->zfree = (free_func) zfree_cb; - if(strcmp(v, "1.2.0.4") >= 0) { - /* zlib version >= 1.2.0.4 supports transparent gzip decompressing */ - if(inflateInit2(z, MAX_WBITS + 32) != Z_OK) { - return process_zlib_error(data, z); - } - zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ - } - else { - failf(data, "too old zlib version: %s", v); - return CURLE_FAILED_INIT; - } + if(inflateInit2(z, MAX_WBITS + 32) != Z_OK) + return process_zlib_error(data, z); + zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ return CURLE_OK; } diff --git a/lib/cookie.c b/lib/cookie.c index 6fe949b..9819768 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -879,7 +879,7 @@ parse_netscape(struct Cookie *co, /* * flag: A TRUE/FALSE value indicating if all machines within a given * domain can access the variable. Set TRUE when the cookie says - * .domain.com and to false when the domain is complete www.domain.com + * .example.com and to false when the domain is complete www.example.com */ co->tailmatch = !!strncasecompare(ptr, "TRUE", len); break; diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake index a41af0c..f4f3a18 100644 --- a/lib/curl_config.h.cmake +++ b/lib/curl_config.h.cmake @@ -433,6 +433,9 @@ /* If you have poll */ #cmakedefine HAVE_POLL 1 +/* If you have realpath */ +#cmakedefine HAVE_REALPATH 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_POLL_H 1 diff --git a/lib/curl_setup.h b/lib/curl_setup.h index f4e5400..7a6ef10 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -933,6 +933,8 @@ endings either CRLF or LF so 't' is appropriate. as their argument */ #define STRCONST(x) x,sizeof(x)-1 +#define CURL_ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) + /* Some versions of the Android NDK is missing the declaration */ #if defined(HAVE_GETPWUID_R) && \ defined(__ANDROID_API__) && (__ANDROID_API__ < 21) @@ -983,10 +985,16 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, # endif #endif +#ifdef USE_OPENSSL /* OpenSSLv3 marks DES, MD5 and ENGINE functions deprecated but we have no replacements (yet) so tell the compiler to not warn for them. */ -#ifdef USE_OPENSSL -#define OPENSSL_SUPPRESS_DEPRECATED +# define OPENSSL_SUPPRESS_DEPRECATED +# ifdef _WIN32 +/* Silence LibreSSL warnings about wincrypt.h collision. Works in 3.8.2+ */ +# ifndef LIBRESSL_DISABLE_OVERRIDE_WINCRYPT_DEFINES_WARNING +# define LIBRESSL_DISABLE_OVERRIDE_WINCRYPT_DEFINES_WARNING +# endif +# endif #endif #if defined(CURL_INLINE) diff --git a/lib/curl_trc.c b/lib/curl_trc.c index e773e4f..07137c1 100644 --- a/lib/curl_trc.c +++ b/lib/curl_trc.c @@ -53,10 +53,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - void Curl_debug(struct Curl_easy *data, curl_infotype type, char *ptr, size_t size) { @@ -349,13 +345,13 @@ static void trc_apply_level_by_name(const char * const token, int lvl) { size_t i; - for(i = 0; i < ARRAYSIZE(trc_cfts); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) { if(strcasecompare(token, trc_cfts[i].cft->name)) { trc_cfts[i].cft->log_level = lvl; break; } } - for(i = 0; i < ARRAYSIZE(trc_feats); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) { if(strcasecompare(token, trc_feats[i].feat->name)) { trc_feats[i].feat->log_level = lvl; break; @@ -367,11 +363,11 @@ static void trc_apply_level_by_category(int category, int lvl) { size_t i; - for(i = 0; i < ARRAYSIZE(trc_cfts); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(trc_cfts); ++i) { if(!category || (trc_cfts[i].category & category)) trc_cfts[i].cft->log_level = lvl; } - for(i = 0; i < ARRAYSIZE(trc_feats); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(trc_feats); ++i) { if(!category || (trc_feats[i].category & category)) trc_feats[i].feat->log_level = lvl; } diff --git a/lib/ftp.c b/lib/ftp.c index cb0fada..6c6a207 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -4107,11 +4107,6 @@ static CURLcode ftp_disconnect(struct Curl_easy *data, return CURLE_OK; } -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4706) /* assignment within conditional expression */ -#endif - /*********************************************************************** * * ftp_parse_url_path() @@ -4202,7 +4197,8 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data) } /* parse the URL path into separate path components */ - while((slashPos = strchr(curPos, '/'))) { + /* !checksrc! disable EQUALSNULL 1 */ + while((slashPos = strchr(curPos, '/')) != NULL) { size_t compLen = slashPos - curPos; /* path starts with a slash: add that as a directory */ @@ -4266,10 +4262,6 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data) return CURLE_OK; } -#ifdef _MSC_VER -#pragma warning(pop) -#endif - /* call this when the DO phase has completed */ static CURLcode ftp_dophase_done(struct Curl_easy *data, bool connected) { diff --git a/lib/http.c b/lib/http.c index 1fe0904..5bd2bd4 100644 --- a/lib/http.c +++ b/lib/http.c @@ -495,7 +495,6 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data, ongoing_auth ? " send, " : ""); /* We decided to abort the ongoing transfer */ streamclose(conn, "Mid-auth HTTP and much data left to send"); - /* FIXME: questionable manipulation here, can we do this differently? */ data->req.size = 0; /* do not download any more than 0 bytes */ } return CURLE_OK; @@ -2477,7 +2476,7 @@ static CURLcode http_range(struct Curl_easy *data, } else if(data->state.resume_from) { /* This is because "resume" was selected */ - /* TODO: not sure if we want to send this header during authentication + /* Not sure if we want to send this header during authentication * negotiation, but test1084 checks for it. In which case we have a * "null" client reader installed that gives an unexpected length. */ curl_off_t total_len = data->req.authneg ? @@ -3597,10 +3596,9 @@ static CURLcode http_on_response(struct Curl_easy *data, } #endif else { - /* We silently accept this as the final response. - * TODO: this looks, uhm, wrong. What are we switching to if we - * did not ask for an Upgrade? Maybe the application provided an - * `Upgrade: xxx` header? */ + /* We silently accept this as the final response. What are we + * switching to if we did not ask for an Upgrade? Maybe the + * application provided an `Upgrade: xxx` header? */ k->header = FALSE; } break; diff --git a/lib/http1.c b/lib/http1.c index f135b20..9d2461e 100644 --- a/lib/http1.c +++ b/lib/http1.c @@ -167,8 +167,6 @@ static CURLcode start_req(struct h1_req_parser *parser, if(!target_len || !hv_len) goto out; - /* TODO: we do not check HTTP_VERSION for conformity, should - + do that when STRICT option is supplied. */ (void)hv; /* The TARGET can be (rfc 9112, ch. 3.2): diff --git a/lib/imap.c b/lib/imap.c index e5ee401..49abaf4 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -193,19 +193,6 @@ static const struct SASLproto saslimap = { }; -#ifdef USE_SSL -static void imap_to_imaps(struct connectdata *conn) -{ - /* Change the connection handler */ - conn->handler = &Curl_handler_imaps; - - /* Set the connection's upgraded to TLS flag */ - conn->bits.tls_upgraded = TRUE; -} -#else -#define imap_to_imaps(x) Curl_nop_stmt -#endif - /*********************************************************************** * * imap_matchresp() @@ -474,6 +461,7 @@ static CURLcode imap_perform_starttls(struct Curl_easy *data) static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data, struct connectdata *conn) { +#ifdef USE_SSL /* Start the SSL connection */ struct imap_conn *imapc = &conn->proto.imapc; CURLcode result; @@ -483,21 +471,27 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data, result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); if(result) goto out; + /* Change the connection handler */ + conn->handler = &Curl_handler_imaps; + conn->bits.tls_upgraded = TRUE; } + DEBUGASSERT(!imapc->ssldone); result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - if(!result) { + DEBUGF(infof(data, "imap_perform_upgrade_tls, connect -> %d, %d", + result, ssldone)); + if(!result && ssldone) { imapc->ssldone = ssldone; - if(imapc->state != IMAP_UPGRADETLS) - imap_state(data, IMAP_UPGRADETLS); - - if(imapc->ssldone) { - imap_to_imaps(conn); - result = imap_perform_capability(data, conn); - } + /* perform CAPA now, changes imapc->state out of IMAP_UPGRADETLS */ + result = imap_perform_capability(data, conn); } out: return result; +#else + (void)data; + (void)conn; + return CURLE_NOT_BUILT_IN; +#endif } /*********************************************************************** @@ -998,7 +992,7 @@ static CURLcode imap_state_starttls_resp(struct Curl_easy *data, result = imap_perform_authentication(data, conn); } else - result = imap_perform_upgrade_tls(data, conn); + imap_state(data, IMAP_UPGRADETLS); return result; } @@ -1307,8 +1301,12 @@ static CURLcode imap_statemachine(struct Curl_easy *data, (void)data; /* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */ - if(imapc->state == IMAP_UPGRADETLS) - return imap_perform_upgrade_tls(data, conn); +upgrade_tls: + if(imapc->state == IMAP_UPGRADETLS) { + result = imap_perform_upgrade_tls(data, conn); + if(result || (imapc->state == IMAP_UPGRADETLS)) + return result; + } /* Flush any data that needs to be sent */ if(pp->sendleft) @@ -1339,6 +1337,10 @@ static CURLcode imap_statemachine(struct Curl_easy *data, case IMAP_STARTTLS: result = imap_state_starttls_resp(data, imapcode, imapc->state); + /* During UPGRADETLS, leave the read loop as we need to connect + * (e.g. TLS handshake) before we continue sending/receiving. */ + if(!result && (imapc->state == IMAP_UPGRADETLS)) + goto upgrade_tls; break; case IMAP_AUTHENTICATE: @@ -1392,14 +1394,6 @@ static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done) struct connectdata *conn = data->conn; struct imap_conn *imapc = &conn->proto.imapc; - if(Curl_conn_is_ssl(conn, FIRSTSOCKET) && !imapc->ssldone) { - bool ssldone = FALSE; - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - imapc->ssldone = ssldone; - if(result || !ssldone) - return result; - } - result = Curl_pp_statemach(data, &imapc->pp, FALSE, FALSE); *done = (imapc->state == IMAP_STOP); diff --git a/lib/inet_ntop.h b/lib/inet_ntop.h index 3b90ed3..6bc7e27 100644 --- a/lib/inet_ntop.h +++ b/lib/inet_ntop.h @@ -29,6 +29,12 @@ char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size); #ifdef HAVE_INET_NTOP +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif #ifdef HAVE_ARPA_INET_H #include #endif diff --git a/lib/inet_pton.h b/lib/inet_pton.h index 50bce61..915385f 100644 --- a/lib/inet_pton.h +++ b/lib/inet_pton.h @@ -29,6 +29,12 @@ int Curl_inet_pton(int, const char *, void *); #ifdef HAVE_INET_PTON +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif #ifdef HAVE_ARPA_INET_H #include #endif diff --git a/lib/ldap.c b/lib/ldap.c index 0fa304b..77bd9fb 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -389,55 +389,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) #else int ldap_option; char *ldap_ca = conn->ssl_config.CAfile; -#if defined(CURL_HAS_NOVELL_LDAPSDK) - rc = ldapssl_client_init(NULL, NULL); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - if(conn->ssl_config.verifypeer) { - /* Novell SDK supports DER or BASE64 files. */ - int cert_type = LDAPSSL_CERT_FILETYPE_B64; - if((data->set.ssl.cert_type) && - (strcasecompare(data->set.ssl.cert_type, "DER"))) - cert_type = LDAPSSL_CERT_FILETYPE_DER; - if(!ldap_ca) { - failf(data, "LDAP local: ERROR %s CA cert not set", - (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM")); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - infof(data, "LDAP local: using %s CA cert '%s'", - (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), - ldap_ca); - rc = ldapssl_add_trusted_cert(ldap_ca, cert_type); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting %s CA cert: %s", - (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - ldap_option = LDAPSSL_VERIFY_SERVER; - } - else - ldap_option = LDAPSSL_VERIFY_NONE; - rc = ldapssl_set_verify_mode(ldap_option); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting cert verify mode: %s", - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - server = ldapssl_init(host, conn->primary.remote_port, 1); - if(!server) { - failf(data, "LDAP local: Cannot connect to %s:%u", - conn->host.dispname, conn->primary.remote_port); - result = CURLE_COULDNT_CONNECT; - goto quit; - } -#elif defined(LDAP_OPT_X_TLS) +#ifdef LDAP_OPT_X_TLS if(conn->ssl_config.verifypeer) { /* OpenLDAP SDK supports BASE64 files. */ if((data->set.ssl.cert_type) && @@ -758,10 +710,6 @@ quit: ldap_free_urldesc(ludp); if(server) ldap_unbind_s(server); -#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK) - if(ldap_ssl) - ldapssl_client_deinit(); -#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */ FREE_ON_WINLDAP(host); diff --git a/lib/mime.c b/lib/mime.c index d448891..a90d170 100644 --- a/lib/mime.c +++ b/lib/mime.c @@ -1598,8 +1598,8 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream) (void) size; /* Always 1. */ - /* TODO: this loop is broken. If `nitems` is <= 4, some encoders will - * return STOP_FILLING without adding any data and this loops infinitely. */ + /* If `nitems` is <= 4, some encoders will return STOP_FILLING without + * adding any data and this loops infinitely. */ do { hasread = FALSE; ret = readback_part(part, buffer, nitems, &hasread); diff --git a/lib/multi.c b/lib/multi.c index d4dd4a0..2b05e94 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1538,15 +1538,6 @@ CURLMcode curl_multi_wakeup(CURLM *m) Curl_multi struct that are constant */ struct Curl_multi *multi = m; -#if defined(ENABLE_WAKEUP) && !defined(USE_WINSOCK) -#ifdef USE_EVENTFD - const void *buf; - const uint64_t val = 1; -#else - char buf[1]; -#endif -#endif - /* GOOD_MULTI_HANDLE can be safely called */ if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; @@ -1560,15 +1551,14 @@ CURLMcode curl_multi_wakeup(CURLM *m) making it safe to access from another thread after the init part and before cleanup */ if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) { + while(1) { #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 */ + /* eventfd has a stringent rule of requiring the 8-byte buffer when + calling write(2) on it */ + const uint64_t buf[1] = { 1 }; #else - buf[0] = 1; + const char buf[1] = { 1 }; #endif - while(1) { /* swrite() is not thread-safe in general, because concurrent calls can have their messages interleaved, but in this case the content of the messages does not matter, which makes it ok to call. diff --git a/lib/netrc.c b/lib/netrc.c index 7ad81ec..ba67089 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -59,23 +59,26 @@ enum found_state { #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 16384 #define MAX_NETRC_FILE (128*1024) #define MAX_NETRC_TOKEN 4096 -static CURLcode file2memory(const char *filename, struct dynbuf *filebuf) +/* convert a dynbuf call CURLcode error to a NETRCcode error */ +#define curl2netrc(result) \ + (((result) == CURLE_OUT_OF_MEMORY) ? \ + NETRC_OUT_OF_MEMORY : NETRC_SYNTAX_ERROR) + +static NETRCcode file2memory(const char *filename, struct dynbuf *filebuf) { - CURLcode result = CURLE_OK; + NETRCcode ret = NETRC_FILE_MISSING; /* if it cannot open the file */ FILE *file = fopen(filename, FOPEN_READTEXT); struct dynbuf linebuf; Curl_dyn_init(&linebuf, MAX_NETRC_LINE); if(file) { + ret = NETRC_OK; while(Curl_get_line(&linebuf, file)) { + CURLcode result; const char *line = Curl_dyn_ptr(&linebuf); /* skip comments on load */ while(ISBLANK(*line)) @@ -83,27 +86,29 @@ static CURLcode file2memory(const char *filename, struct dynbuf *filebuf) if(*line == '#') continue; result = Curl_dyn_add(filebuf, line); - if(result) + if(result) { + ret = curl2netrc(result); goto done; + } } } done: Curl_dyn_free(&linebuf); if(file) fclose(file); - return result; + return ret; } /* * Returns zero on success. */ -static int parsenetrc(struct store_netrc *store, - const char *host, - char **loginp, /* might point to a username */ - char **passwordp, - const char *netrcfile) +static NETRCcode parsenetrc(struct store_netrc *store, + const char *host, + char **loginp, /* might point to a username */ + char **passwordp, + const char *netrcfile) { - int retcode = NETRC_FILE_MISSING; + NETRCcode retcode = NETRC_NO_MATCH; char *login = *loginp; char *password = NULL; bool specific_login = !!login; /* points to something */ @@ -120,8 +125,9 @@ static int parsenetrc(struct store_netrc *store, Curl_dyn_init(&token, MAX_NETRC_TOKEN); if(!store->loaded) { - if(file2memory(netrcfile, filebuf)) - return NETRC_FAILED; + NETRCcode ret = file2memory(netrcfile, filebuf); + if(ret) + return ret; store->loaded = TRUE; } @@ -151,12 +157,18 @@ static int parsenetrc(struct store_netrc *store, tok_end = tok; if(!quoted) { size_t len = 0; + CURLcode result; while(!ISSPACE(*tok_end)) { tok_end++; len++; } - if(!len || Curl_dyn_addn(&token, tok, len)) { - retcode = NETRC_FAILED; + if(!len) { + retcode = NETRC_SYNTAX_ERROR; + goto out; + } + result = Curl_dyn_addn(&token, tok, len); + if(result) { + retcode = curl2netrc(result); goto out; } } @@ -165,6 +177,7 @@ static int parsenetrc(struct store_netrc *store, bool endquote = FALSE; tok_end++; /* pass the leading quote */ while(*tok_end) { + CURLcode result; char s = *tok_end; if(escape) { escape = FALSE; @@ -190,15 +203,16 @@ static int parsenetrc(struct store_netrc *store, endquote = TRUE; break; } - if(Curl_dyn_addn(&token, &s, 1)) { - retcode = NETRC_FAILED; + result = Curl_dyn_addn(&token, &s, 1); + if(result) { + retcode = curl2netrc(result); goto out; } tok_end++; } if(escape || !endquote) { /* bad syntax, get out */ - retcode = NETRC_FAILED; + retcode = NETRC_SYNTAX_ERROR; goto out; } } @@ -226,7 +240,7 @@ static int parsenetrc(struct store_netrc *store, } else if(strcasecompare("default", tok)) { state = HOSTVALID; - retcode = NETRC_SUCCESS; /* we did find our host */ + retcode = NETRC_OK; /* we did find our host */ } break; case MACDEF: @@ -237,7 +251,7 @@ static int parsenetrc(struct store_netrc *store, if(strcasecompare(host, tok)) { /* and yes, this is our host! */ state = HOSTVALID; - retcode = NETRC_SUCCESS; /* we did find our host */ + retcode = NETRC_OK; /* we did find our host */ } else /* not our host */ @@ -253,7 +267,7 @@ static int parsenetrc(struct store_netrc *store, free(login); login = strdup(tok); if(!login) { - retcode = NETRC_FAILED; /* allocation failed */ + retcode = NETRC_OUT_OF_MEMORY; /* allocation failed */ goto out; } } @@ -264,7 +278,7 @@ static int parsenetrc(struct store_netrc *store, free(password); password = strdup(tok); if(!password) { - retcode = NETRC_FAILED; /* allocation failed */ + retcode = NETRC_OUT_OF_MEMORY; /* allocation failed */ goto out; } if(!specific_login || our_login) @@ -290,7 +304,7 @@ static int parsenetrc(struct store_netrc *store, } else if(strcasecompare("default", tok)) { state = HOSTVALID; - retcode = NETRC_SUCCESS; /* we did find our host */ + retcode = NETRC_OK; /* we did find our host */ Curl_safefree(password); if(!specific_login) Curl_safefree(login); @@ -321,11 +335,11 @@ out: /* success without a password, set a blank one */ password = strdup(""); if(!password) - retcode = 1; /* out of memory */ + retcode = NETRC_OUT_OF_MEMORY; /* out of memory */ } else if(!login && !password) /* a default with no credentials */ - retcode = NETRC_FILE_MISSING; + retcode = NETRC_NO_MATCH; } if(!retcode) { /* success */ @@ -343,17 +357,34 @@ out: return retcode; } +const char *Curl_netrc_strerror(NETRCcode ret) +{ + switch(ret) { + default: + return ""; /* not a legit error */ + case NETRC_FILE_MISSING: + return "no such file"; + case NETRC_NO_MATCH: + return "no matching entry"; + case NETRC_OUT_OF_MEMORY: + return "out of memory"; + case NETRC_SYNTAX_ERROR: + return "syntax error"; + } + /* never reached */ +} + /* * @unittest: 1304 * * *loginp and *passwordp MUST be allocated if they are not NULL when passed * in. */ -int Curl_parsenetrc(struct store_netrc *store, const char *host, - char **loginp, char **passwordp, - char *netrcfile) +NETRCcode Curl_parsenetrc(struct store_netrc *store, const char *host, + char **loginp, char **passwordp, + char *netrcfile) { - int retcode = 1; + NETRCcode retcode = NETRC_OK; char *filealloc = NULL; if(!netrcfile) { @@ -391,23 +422,23 @@ int Curl_parsenetrc(struct store_netrc *store, const char *host, } if(!home) - return retcode; /* no home directory found (or possibly out of - memory) */ + return NETRC_FILE_MISSING; /* no home directory found (or possibly out + of memory) */ filealloc = aprintf("%s%s.netrc", home, DIR_CHAR); if(!filealloc) { free(homea); - return -1; + return NETRC_OUT_OF_MEMORY; } retcode = parsenetrc(store, host, loginp, passwordp, filealloc); free(filealloc); #ifdef _WIN32 - if((retcode == NETRC_FILE_MISSING) || (retcode == NETRC_FAILED)) { + if(retcode == NETRC_FILE_MISSING) { /* fallback to the old-style "_netrc" file */ filealloc = aprintf("%s%s_netrc", home, DIR_CHAR); if(!filealloc) { free(homea); - return -1; + return NETRC_OUT_OF_MEMORY; } retcode = parsenetrc(store, host, loginp, passwordp, filealloc); free(filealloc); diff --git a/lib/netrc.h b/lib/netrc.h index 0ef9ff7..ac0f886 100644 --- a/lib/netrc.h +++ b/lib/netrc.h @@ -34,12 +34,21 @@ struct store_netrc { BIT(loaded); }; +typedef enum { + NETRC_OK, + NETRC_NO_MATCH, /* no matching entry in the file */ + NETRC_SYNTAX_ERROR, /* in the netrc file */ + NETRC_FILE_MISSING, /* the netrc file does not exist */ + NETRC_OUT_OF_MEMORY, /* while parsing netrc */ + NETRC_LAST /* never used */ +} NETRCcode; + +const char *Curl_netrc_strerror(NETRCcode ret); void Curl_netrc_init(struct store_netrc *s); void Curl_netrc_cleanup(struct store_netrc *s); -/* returns -1 on failure, 0 if the host is found, 1 is the host is not found */ -int Curl_parsenetrc(struct store_netrc *s, const char *host, char **loginp, - char **passwordp, char *filename); +NETRCcode Curl_parsenetrc(struct store_netrc *s, const char *host, + char **loginp, char **passwordp, char *filename); /* Assume: (*passwordp)[0]=0, host[0] != 0. * If (*loginp)[0] = 0, search for login and password within a machine * section in the netrc. diff --git a/lib/pop3.c b/lib/pop3.c index 86e9eca..07c7dba 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -83,10 +83,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - /* Local API functions */ static CURLcode pop3_regular_transfer(struct Curl_easy *data, bool *done); static CURLcode pop3_do(struct Curl_easy *data, bool *done); @@ -192,19 +188,6 @@ static const struct SASLproto saslpop3 = { SASL_FLAG_BASE64 /* Configuration flags */ }; -#ifdef USE_SSL -static void pop3_to_pop3s(struct connectdata *conn) -{ - /* Change the connection handler */ - conn->handler = &Curl_handler_pop3s; - - /* Set the connection's upgraded to TLS flag */ - conn->bits.tls_upgraded = TRUE; -} -#else -#define pop3_to_pop3s(x) Curl_nop_stmt -#endif - struct pop3_cmd { const char *name; unsigned short nlen; @@ -239,7 +222,7 @@ static const struct pop3_cmd pop3cmds[] = { static bool pop3_is_multiline(const char *cmdline) { size_t i; - for(i = 0; i < ARRAYSIZE(pop3cmds); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(pop3cmds); ++i) { if(strncasecompare(pop3cmds[i].name, cmdline, pop3cmds[i].nlen)) { if(!cmdline[pop3cmds[i].nlen]) return pop3cmds[i].multiline; @@ -425,6 +408,7 @@ static CURLcode pop3_perform_starttls(struct Curl_easy *data, static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data, struct connectdata *conn) { +#ifdef USE_SSL /* Start the SSL connection */ struct pop3_conn *pop3c = &conn->proto.pop3c; CURLcode result; @@ -434,22 +418,27 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data, result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); if(result) goto out; + /* Change the connection handler */ + conn->handler = &Curl_handler_pop3s; + conn->bits.tls_upgraded = TRUE; } + DEBUGASSERT(!pop3c->ssldone); result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - - if(!result) { + DEBUGF(infof(data, "pop3_perform_upgrade_tls, connect -> %d, %d", + result, ssldone)); + if(!result && ssldone) { pop3c->ssldone = ssldone; - if(pop3c->state != POP3_UPGRADETLS) - pop3_state(data, POP3_UPGRADETLS); - - if(pop3c->ssldone) { - pop3_to_pop3s(conn); - result = pop3_perform_capa(data, conn); - } + /* perform CAPA now, changes pop3c->state out of POP3_UPGRADETLS */ + result = pop3_perform_capa(data, conn); } out: return result; +#else + (void)data; + (void)conn; + return CURLE_NOT_BUILT_IN; +#endif } /*********************************************************************** @@ -861,7 +850,7 @@ static CURLcode pop3_state_starttls_resp(struct Curl_easy *data, result = pop3_perform_authentication(data, conn); } else - result = pop3_perform_upgrade_tls(data, conn); + pop3_state(data, POP3_UPGRADETLS); return result; } @@ -1039,8 +1028,12 @@ static CURLcode pop3_statemachine(struct Curl_easy *data, (void)data; /* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */ - if(pop3c->state == POP3_UPGRADETLS) - return pop3_perform_upgrade_tls(data, conn); +upgrade_tls: + if(pop3c->state == POP3_UPGRADETLS) { + result = pop3_perform_upgrade_tls(data, conn); + if(result || (pop3c->state == POP3_UPGRADETLS)) + return result; + } /* Flush any data that needs to be sent */ if(pp->sendleft) @@ -1067,6 +1060,10 @@ static CURLcode pop3_statemachine(struct Curl_easy *data, case POP3_STARTTLS: result = pop3_state_starttls_resp(data, conn, pop3code, pop3c->state); + /* During UPGRADETLS, leave the read loop as we need to connect + * (e.g. TLS handshake) before we continue sending/receiving. */ + if(!result && (pop3c->state == POP3_UPGRADETLS)) + goto upgrade_tls; break; case POP3_AUTH: @@ -1112,17 +1109,6 @@ static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done) struct connectdata *conn = data->conn; struct pop3_conn *pop3c = &conn->proto.pop3c; - /* Issue #16166, STLS seems to stall and time out. Revert to previous - * check, but it remains to find out why this is wrong. */ - /* if(Curl_conn_is_ssl(conn, FIRSTSOCKET) && !pop3c->ssldone) { */ - if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) { - bool ssldone = FALSE; - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - pop3c->ssldone = ssldone; - if(result || !pop3c->ssldone) - return result; - } - result = Curl_pp_statemach(data, &pop3c->pp, FALSE, FALSE); *done = (pop3c->state == POP3_STOP); diff --git a/lib/setopt.c b/lib/setopt.c index e264c73..8a87d24 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -601,8 +601,8 @@ static CURLcode setopt_long(struct Curl_easy *data, CURLoption option, switch(arg) { case CURL_HTTP_VERSION_NONE: #ifdef USE_HTTP2 - /* TODO: this seems an undesirable quirk to force a behaviour on - * lower implementations that they should recognize independently? */ + /* This seems an undesirable quirk to force a behaviour on lower + * implementations that they should recognize independently? */ arg = CURL_HTTP_VERSION_2TLS; #endif /* accepted */ @@ -1584,10 +1584,6 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, if(data->share->hsts == data->hsts) data->hsts = NULL; #endif -#ifdef USE_SSL - if(data->share->ssl_scache == data->state.ssl_scache) - data->state.ssl_scache = data->multi ? data->multi->ssl_scache : NULL; -#endif #ifdef USE_LIBPSL if(data->psl == &data->share->psl) data->psl = data->multi ? &data->multi->psl : NULL; @@ -1628,10 +1624,6 @@ static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option, data->hsts = data->share->hsts; } #endif -#ifdef USE_SSL - if(data->share->ssl_scache) - data->state.ssl_scache = data->share->ssl_scache; -#endif #ifdef USE_LIBPSL if(data->share->specifier & (1 << CURL_LOCK_DATA_PSL)) data->psl = &data->share->psl; @@ -2425,6 +2417,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, */ return Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], ptr); +#if defined(USE_LIBSSH2) || defined(USE_LIBSSH) case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: /* * Option to allow for the MD5 of the host public key to be checked @@ -2437,7 +2430,7 @@ static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option, * Store the filename to read known hosts from. */ return Curl_setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS], ptr); - +#endif case CURLOPT_SSH_KEYDATA: /* * Custom client data to pass to the SSH keyfunc callback diff --git a/lib/smb.c b/lib/smb.c index 752386d..d22030c 100644 --- a/lib/smb.c +++ b/lib/smb.c @@ -881,7 +881,16 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done) return CURLE_COULDNT_CONNECT; } nrsp = msg; +#if defined(__GNUC__) && __GNUC__ >= 13 +#pragma GCC diagnostic push +/* error: 'memcpy' offset [74, 80] from the object at '' is out of + the bounds of referenced subobject 'bytes' with type 'char[1]' */ +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge)); +#if defined(__GNUC__) && __GNUC__ >= 13 +#pragma GCC diagnostic pop +#endif smbc->session_key = smb_swap32(nrsp->session_key); result = smb_send_setup(data); if(result) { diff --git a/lib/smtp.c b/lib/smtp.c index 7c631a1..b763557 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -189,19 +189,6 @@ static const struct SASLproto saslsmtp = { SASL_FLAG_BASE64 /* Configuration flags */ }; -#ifdef USE_SSL -static void smtp_to_smtps(struct connectdata *conn) -{ - /* Change the connection handler */ - conn->handler = &Curl_handler_smtps; - - /* Set the connection's upgraded to TLS flag */ - conn->bits.tls_upgraded = TRUE; -} -#else -#define smtp_to_smtps(x) Curl_nop_stmt -#endif - /*********************************************************************** * * smtp_endofresp() @@ -396,31 +383,38 @@ static CURLcode smtp_perform_starttls(struct Curl_easy *data, */ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data) { +#ifdef USE_SSL /* Start the SSL connection */ struct connectdata *conn = data->conn; struct smtp_conn *smtpc = &conn->proto.smtpc; CURLcode result; bool ssldone = FALSE; + DEBUGASSERT(smtpc->state == SMTP_UPGRADETLS); if(!Curl_conn_is_ssl(conn, FIRSTSOCKET)) { result = Curl_ssl_cfilter_add(data, conn, FIRSTSOCKET); if(result) goto out; + /* Change the connection handler and SMTP state */ + conn->handler = &Curl_handler_smtps; + conn->bits.tls_upgraded = TRUE; } + DEBUGASSERT(!smtpc->ssldone); result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - if(!result) { + DEBUGF(infof(data, "smtp_perform_upgrade_tls, connect -> %d, %d", + result, ssldone)); + if(!result && ssldone) { smtpc->ssldone = ssldone; - if(smtpc->state != SMTP_UPGRADETLS) - smtp_state(data, SMTP_UPGRADETLS); - - if(smtpc->ssldone) { - smtp_to_smtps(conn); - result = smtp_perform_ehlo(data); - } + /* perform EHLO now, changes smpt->state out of SMTP_UPGRADETLS */ + result = smtp_perform_ehlo(data); } out: return result; +#else + (void)data; + return CURLE_NOT_BUILT_IN; +#endif } /*********************************************************************** @@ -875,7 +869,7 @@ static CURLcode smtp_state_starttls_resp(struct Curl_easy *data, result = smtp_perform_authentication(data); } else - result = smtp_perform_upgrade_tls(data); + smtp_state(data, SMTP_UPGRADETLS); return result; } @@ -1204,8 +1198,11 @@ static CURLcode smtp_statemachine(struct Curl_easy *data, /* Busy upgrading the connection; right now all I/O is SSL/TLS, not SMTP */ upgrade_tls: - if(smtpc->state == SMTP_UPGRADETLS) - return smtp_perform_upgrade_tls(data); + if(smtpc->state == SMTP_UPGRADETLS) { + result = smtp_perform_upgrade_tls(data); + if(result || (smtpc->state == SMTP_UPGRADETLS)) + return result; + } /* Flush any data that needs to be sent */ if(pp->sendleft) @@ -1288,14 +1285,6 @@ static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done) struct connectdata *conn = data->conn; struct smtp_conn *smtpc = &conn->proto.smtpc; - if(Curl_conn_is_ssl(conn, FIRSTSOCKET) && !smtpc->ssldone) { - bool ssldone = FALSE; - result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); - smtpc->ssldone = ssldone; - if(result || !smtpc->ssldone) - return result; - } - result = Curl_pp_statemach(data, &smtpc->pp, FALSE, FALSE); *done = (smtpc->state == SMTP_STOP); diff --git a/lib/telnet.c b/lib/telnet.c index 589f9da..e383917 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -777,22 +777,15 @@ static void printsub(struct Curl_easy *data, } } -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4706) /* assignment within conditional expression */ -#endif static bool str_is_nonascii(const char *str) { char c; - while((c = *str++)) + while((c = *str++) != 0) if(c & 0x80) return TRUE; return FALSE; } -#ifdef _MSC_VER -#pragma warning(pop) -#endif static CURLcode check_telnet_options(struct Curl_easy *data) { @@ -1559,10 +1552,9 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done) /* returned not-zero, this an error */ if(result) { keepon = FALSE; - /* TODO: in test 1452, macOS sees a ECONNRESET sometimes? - * Is this the telnet test server not shutting down the socket - * in a clean way? Seems to be timing related, happens more - * on slow debug build */ + /* In test 1452, macOS sees a ECONNRESET sometimes? Is this the + * telnet test server not shutting down the socket in a clean way? + * Seems to be timing related, happens more on slow debug build */ if(data->state.os_errno == ECONNRESET) { DEBUGF(infof(data, "telnet_do, unexpected ECONNRESET on recv")); } diff --git a/lib/transfer.c b/lib/transfer.c index c4b23a8..742828a 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -567,12 +567,6 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) #endif data->state.httpreq = data->set.method; -#ifdef USE_SSL - if(!data->state.ssl_scache) - /* There was no ssl session cache set via a share, use the multi one */ - data->state.ssl_scache = data->multi->ssl_scache; -#endif - data->state.requests = 0; data->state.followlocation = 0; /* reset the location-follow counter */ data->state.this_is_a_follow = FALSE; /* reset this */ diff --git a/lib/url.c b/lib/url.c index 0f3d100..516ee08 100644 --- a/lib/url.c +++ b/lib/url.c @@ -125,10 +125,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - #ifdef USE_NGHTTP2 static void data_priority_cleanup(struct Curl_easy *data); #else @@ -566,7 +562,7 @@ void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn) DEBUGASSERT(conn); - for(i = 0; i < ARRAYSIZE(conn->cfilter); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(conn->cfilter); ++i) { Curl_conn_cf_discard_all(data, conn, (int)i); } @@ -2690,7 +2686,6 @@ static CURLcode override_login(struct Curl_easy *data, } conn->bits.netrc = FALSE; if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) { - int ret; bool url_provided = FALSE; if(data->state.aptr.user && @@ -2702,17 +2697,19 @@ static CURLcode override_login(struct Curl_easy *data, } if(!*passwdp) { - ret = Curl_parsenetrc(&data->state.netrc, conn->host.name, - userp, passwdp, - data->set.str[STRING_NETRC_FILE]); - if(ret > 0) { + NETRCcode ret = Curl_parsenetrc(&data->state.netrc, conn->host.name, + userp, passwdp, + data->set.str[STRING_NETRC_FILE]); + if(ret && ((ret == NETRC_NO_MATCH) || + (data->set.use_netrc == CURL_NETRC_OPTIONAL))) { 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"); + else if(ret) { + const char *m = Curl_netrc_strerror(ret); + failf(data, ".netrc error: %s", m); return CURLE_READ_ERROR; } else { @@ -3105,7 +3102,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, DEBUGF(infof(data, "check Alt-Svc for host %s", host)); if(srcalpnid == ALPN_none) { /* scan all alt-svc protocol ids in order or relevance */ - for(i = 0; !hit && (i < ARRAYSIZE(alpn_ids)); ++i) { + for(i = 0; !hit && (i < CURL_ARRAYSIZE(alpn_ids)); ++i) { srcalpnid = alpn_ids[i]; hit = Curl_altsvc_lookup(data->asi, srcalpnid, host, conn->remote_port, /* from */ @@ -3215,7 +3212,7 @@ static CURLcode resolve_server(struct Curl_easy *data, #endif if(unix_path) { - /* TODO, this only works if previous transport is TRNSPRT_TCP. Check it? */ + /* This only works if previous transport is TRNSPRT_TCP. Check it? */ conn->transport = TRNSPRT_UNIX; return resolve_unix(data, conn, unix_path); } @@ -3313,7 +3310,7 @@ static void reuse_conn(struct Curl_easy *data, * We want to reuse an existing conn to the remote endpoint. * Since connection reuse does not match on conn->host necessarily, we * switch `existing` conn to `temp` conn's host settings. - * TODO: is this correct in the case of TLS connections that have + * Is this correct in the case of TLS connections that have * used the original hostname in SNI to negotiate? Do we send * requests for another host through the different SNI? */ @@ -3573,7 +3570,6 @@ static CURLcode create_conn(struct Curl_easy *data, if(result) goto out; - /* FIXME: do we really want to run this every time we add a transfer? */ Curl_cpool_prune_dead(data); /************************************************************* diff --git a/lib/urlapi.c b/lib/urlapi.c index d9b04e3..2368bd7 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -395,7 +395,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u, /* We will now try to extract the * possible login information in a string like: - * ftp://user:password@ftp.my.site:8021/README */ + * ftp://user:password@ftp.site.example:8021/README */ ptr++; /* if this is a known scheme, get some details */ diff --git a/lib/urldata.h b/lib/urldata.h index 33fa0d1..d9acb2b 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1108,7 +1108,6 @@ struct Curl_data_prio_node { /** * Priority information for an easy handle in relation to others * on the same connection. - * TODO: we need to adapt it to the new priority scheme as defined in RFC 9218 */ struct Curl_data_priority { #ifdef USE_NGHTTP2 @@ -1199,7 +1198,6 @@ struct UrlState { curl_prot_t first_remote_protocol; int retrycount; /* number of retries on a new connection */ - struct Curl_ssl_scache *ssl_scache; /* TLS session pool */ int os_errno; /* filled in with errno whenever an error occurs */ long followlocation; /* redirect counter */ int requests; /* request counter: redirects + authentication retakes */ diff --git a/lib/vquic/curl_msh3.c b/lib/vquic/curl_msh3.c index 9e7cfbe..e0b5949 100644 --- a/lib/vquic/curl_msh3.c +++ b/lib/vquic/curl_msh3.c @@ -441,10 +441,10 @@ static bool MSH3_CALL msh3_data_received(MSH3_REQUEST *Request, CURLcode result; bool rv = FALSE; - /* TODO: we would like to limit the amount of data we are buffer here. - * There seems to be no mechanism in msh3 to adjust flow control and - * it is undocumented what happens if we return FALSE here or less - * length (buflen is an inout parameter). + /* We would like to limit the amount of data we are buffer here. There seems + * to be no mechanism in msh3 to adjust flow control and it is undocumented + * what happens if we return FALSE here or less length (buflen is an inout + * parameter). */ (void)Request; if(!stream) @@ -703,8 +703,8 @@ static ssize_t cf_msh3_send(struct Curl_cfilter *cf, struct Curl_easy *data, goto out; } - /* TODO - msh3/msquic will hold onto this memory until the send complete - event. How do we make sure curl does not free it until then? */ + /* msh3/msquic will hold onto this memory until the send complete event. + How do we make sure curl does not free it until then? */ *err = CURLE_OK; nwritten = len; } @@ -838,7 +838,7 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf, MSH3_SET_PORT(&addr, (uint16_t)cf->conn->remote_port); if(verify && (conn_config->CAfile || conn_config->CApath)) { - /* TODO: need a way to provide trust anchors to MSH3 */ + /* Need a way to provide trust anchors to MSH3 */ #ifdef DEBUGBUILD /* we need this for our test cases to run */ CURL_TRC_CF(data, cf, "non-standard CA not supported, " @@ -1006,7 +1006,7 @@ static CURLcode cf_msh3_query(struct Curl_cfilter *cf, switch(query) { case CF_QUERY_MAX_CONCURRENT: { - /* TODO: we do not have access to this so far, fake it */ + /* We do not have access to this so far, fake it */ (void)ctx; *pres1 = 100; return CURLE_OK; @@ -1091,7 +1091,7 @@ CURLcode Curl_cf_msh3_create(struct Curl_cfilter **pcf, (void)data; (void)conn; - (void)ai; /* TODO: msh3 resolves itself? */ + (void)ai; /* msh3 resolves itself? */ ctx = calloc(1, sizeof(*ctx)); if(!ctx) { result = CURLE_OUT_OF_MEMORY; diff --git a/lib/vquic/curl_ngtcp2.c b/lib/vquic/curl_ngtcp2.c index f2ceff2..cc9d560 100644 --- a/lib/vquic/curl_ngtcp2.c +++ b/lib/vquic/curl_ngtcp2.c @@ -394,7 +394,7 @@ static void quic_printf(void *user_data, const char *fmt, ...) struct Curl_cfilter *cf = user_data; struct cf_ngtcp2_ctx *ctx = cf->ctx; - (void)ctx; /* TODO: need an easy handle to infof() message */ + (void)ctx; /* need an easy handle to infof() message */ va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); @@ -1591,7 +1591,7 @@ static ssize_t cf_ngtcp2_send(struct Curl_cfilter *cf, struct Curl_easy *data, if(ctx->tls_vrfy_result) return ctx->tls_vrfy_result; - (void)eos; /* TODO: use for stream EOF and block handling */ + (void)eos; /* use for stream EOF and block handling */ result = cf_progress_ingress(cf, data, &pktx); if(result) { *err = result; @@ -1965,8 +1965,8 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf, struct Curl_easy *data, bool pause) { - /* TODO: there seems right now no API in ngtcp2 to shrink/enlarge - * the streams windows. As we do in HTTP/2. */ + /* There seems to exist no API in ngtcp2 to shrink/enlarge the streams + * windows. As we do in HTTP/2. */ if(!pause) { h3_drain_stream(cf, data); Curl_expire(data, 0, EXPIRE_RUN_NOW); diff --git a/lib/vquic/curl_osslq.c b/lib/vquic/curl_osslq.c index 1b78497..4fd4fee 100644 --- a/lib/vquic/curl_osslq.c +++ b/lib/vquic/curl_osslq.c @@ -82,10 +82,6 @@ #define H3_STREAM_SEND_CHUNKS \ (H3_STREAM_WINDOW_SIZE / H3_STREAM_CHUNK_SIZE) -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) typedef uint32_t sslerr_t; #else @@ -458,7 +454,7 @@ static CURLcode cf_osslq_h3conn_add_stream(struct cf_osslq_h3conn *h3, struct cf_osslq_ctx *ctx = cf->ctx; curl_int64_t stream_id = (curl_int64_t)SSL_get_stream_id(stream_ssl); - if(h3->remote_ctrl_n >= ARRAYSIZE(h3->remote_ctrl)) { + if(h3->remote_ctrl_n >= CURL_ARRAYSIZE(h3->remote_ctrl)) { /* rejected, we are full */ CURL_TRC_CF(data, cf, "[%" FMT_PRId64 "] rejecting remote stream", stream_id); @@ -1564,7 +1560,7 @@ static CURLcode h3_send_streams(struct Curl_cfilter *cf, bool blocked = FALSE, eos_written = FALSE; n = nghttp3_conn_writev_stream(ctx->h3.conn, &stream_id, &eos, - vec, ARRAYSIZE(vec)); + vec, CURL_ARRAYSIZE(vec)); if(n < 0) { failf(data, "nghttp3_conn_writev_stream returned error: %s", nghttp3_strerror((int)n)); @@ -1984,7 +1980,7 @@ static ssize_t cf_osslq_send(struct Curl_cfilter *cf, struct Curl_easy *data, ssize_t nwritten; CURLcode result; - (void)eos; /* TODO: use to end stream */ + (void)eos; /* use to end stream */ CF_DATA_SAVE(save, cf, data); DEBUGASSERT(cf->connected); DEBUGASSERT(ctx->tls.ossl.ssl); diff --git a/lib/vquic/curl_quiche.c b/lib/vquic/curl_quiche.c index ec0dcce..679cba3 100644 --- a/lib/vquic/curl_quiche.c +++ b/lib/vquic/curl_quiche.c @@ -926,8 +926,8 @@ static ssize_t cf_quiche_send_body(struct Curl_cfilter *cf, nwritten = quiche_h3_send_body(ctx->h3c, ctx->qconn, stream->id, (uint8_t *)buf, len, eos); if(nwritten == QUICHE_H3_ERR_DONE || (nwritten == 0 && len > 0)) { - /* TODO: we seem to be blocked on flow control and should HOLD - * sending. But when do we open again? */ + /* Blocked on flow control and should HOLD sending. But when do we open + * again? */ if(!quiche_conn_stream_writable(ctx->qconn, stream->id, len)) { CURL_TRC_CF(data, cf, "[%" FMT_PRIu64 "] send_body(len=%zu) " "-> window exhausted", stream->id, len); @@ -1204,8 +1204,8 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf, struct Curl_easy *data, bool pause) { - /* TODO: there seems right now no API in quiche to shrink/enlarge - * the streams windows. As we do in HTTP/2. */ + /* There seems to exist no API in quiche to shrink/enlarge the streams + * windows. As we do in HTTP/2. */ if(!pause) { h3_drain_stream(cf, data); Curl_expire(data, 0, EXPIRE_RUN_NOW); diff --git a/lib/vquic/vquic-tls.c b/lib/vquic/vquic-tls.c index 6e1ace2..ff2445d 100644 --- a/lib/vquic/vquic-tls.c +++ b/lib/vquic/vquic-tls.c @@ -58,10 +58,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - #if defined(USE_WOLFSSL) #define QUIC_CIPHERS \ diff --git a/lib/vquic/vquic.c b/lib/vquic/vquic.c index 9ac3518..69de5c1 100644 --- a/lib/vquic/vquic.c +++ b/lib/vquic/vquic.c @@ -163,7 +163,7 @@ static CURLcode do_sendmsg(struct Curl_cfilter *cf, case EIO: if(pktlen > gsolen) { /* GSO failure */ - failf(data, "sendmsg() returned %zd (errno %d); disable GSO", sent, + infof(data, "sendmsg() returned %zd (errno %d); disable GSO", sent, SOCKERRNO); qctx->no_gso = TRUE; return send_packet_no_gso(cf, data, qctx, pkt, pktlen, gsolen, psent); diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index 8d42ddd..2390967 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -342,17 +342,11 @@ static int myssh_is_known(struct Curl_easy *data) struct curl_khkey *knownkeyp = NULL; curl_sshkeycallback func = data->set.ssh_keyfunc; - -#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0) struct ssh_knownhosts_entry *knownhostsentry = NULL; struct curl_khkey knownkey; -#endif -#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0) rc = ssh_get_server_publickey(sshc->ssh_session, &pubkey); -#else - rc = ssh_get_publickey(sshc->ssh_session, &pubkey); -#endif + if(rc != SSH_OK) return rc; @@ -388,7 +382,6 @@ static int myssh_is_known(struct Curl_easy *data) if(data->set.str[STRING_SSH_KNOWNHOSTS]) { -#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0) /* Get the known_key from the known hosts file */ vstate = ssh_session_get_known_hosts_entry(sshc->ssh_session, &knownhostsentry); @@ -446,22 +439,6 @@ static int myssh_is_known(struct Curl_easy *data) break; } -#else - vstate = ssh_is_server_known(sshc->ssh_session); - switch(vstate) { - case SSH_SERVER_KNOWN_OK: - keymatch = CURLKHMATCH_OK; - break; - case SSH_SERVER_FILE_NOT_FOUND: - case SSH_SERVER_NOT_KNOWN: - keymatch = CURLKHMATCH_MISSING; - break; - default: - keymatch = CURLKHMATCH_MISMATCH; - break; - } -#endif - if(func) { /* use callback to determine action */ rc = ssh_pki_export_pubkey_base64(pubkey, &found_base64); if(rc != SSH_OK) @@ -478,18 +455,14 @@ static int myssh_is_known(struct Curl_easy *data) foundkey.keytype = CURLKHTYPE_RSA1; break; case SSH_KEYTYPE_ECDSA: -#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0) case SSH_KEYTYPE_ECDSA_P256: case SSH_KEYTYPE_ECDSA_P384: case SSH_KEYTYPE_ECDSA_P521: -#endif foundkey.keytype = CURLKHTYPE_ECDSA; break; -#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,7,0) case SSH_KEYTYPE_ED25519: foundkey.keytype = CURLKHTYPE_ED25519; break; -#endif case SSH_KEYTYPE_DSS: foundkey.keytype = CURLKHTYPE_DSS; break; @@ -506,11 +479,7 @@ static int myssh_is_known(struct Curl_easy *data) switch(rc) { case CURLKHSTAT_FINE_ADD_TO_FILE: -#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,8,0) rc = ssh_session_update_known_hosts(sshc->ssh_session); -#else - rc = ssh_write_knownhost(sshc->ssh_session); -#endif if(rc != SSH_OK) { goto cleanup; } @@ -541,11 +510,9 @@ cleanup: if(hash) ssh_clean_pubkey_hash(&hash); ssh_key_free(pubkey); -#if LIBSSH_VERSION_INT >= SSH_VERSION_INT(0,9,0) if(knownhostsentry) { ssh_knownhosts_entry_free(knownhostsentry); } -#endif return rc; } @@ -1848,7 +1815,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } rc = ssh_scp_push_file(sshc->scp_session, protop->path, - data->state.infilesize, + (size_t)data->state.infilesize, (int)data->set.new_file_perms); if(rc != SSH_OK) { err_msg = ssh_get_error(sshc->ssh_session); diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index edfadc8..429abac 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -83,15 +83,6 @@ #include "curl_memory.h" #include "memdebug.h" -#if LIBSSH2_VERSION_NUM >= 0x010206 -/* libssh2_sftp_statvfs and friends were added in 1.2.6 */ -#define HAS_STATVFS_SUPPORT 1 -#endif - -#define sftp_libssh2_realpath(s,p,t,m) \ - libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \ - (t), (m), LIBSSH2_SFTP_REALPATH) - /* Local functions: */ static const char *sftp_libssh2_strerror(unsigned long err); static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc); @@ -389,8 +380,6 @@ static void state(struct Curl_easy *data, sshstate nowstate) sshc->state = nowstate; } - -#ifdef HAVE_LIBSSH2_KNOWNHOST_API static int sshkeycallback(CURL *easy, const struct curl_khkey *knownkey, /* known */ const struct curl_khkey *foundkey, /* found */ @@ -405,37 +394,7 @@ static int sshkeycallback(CURL *easy, /* we only allow perfect matches, and we reject everything else */ return (match != CURLKHMATCH_OK) ? CURLKHSTAT_REJECT : CURLKHSTAT_FINE; } -#endif - -/* - * Earlier libssh2 versions did not have the ability to seek to 64-bit - * positions with 32-bit size_t. - */ -#ifdef HAVE_LIBSSH2_SFTP_SEEK64 -#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y) -#else -#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y) -#endif -/* - * Earlier libssh2 versions did not do SCP properly beyond 32-bit sizes on - * 32-bit architectures so we check of the necessary function is present. - */ -#ifndef HAVE_LIBSSH2_SCP_SEND64 -#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0) -#else -#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \ - (libssh2_int64_t)d, 0, 0) -#endif - -/* - * libssh2 1.2.8 fixed the problem with 32-bit ints used for sockets on win64. - */ -#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE -#define session_startup(x,y) libssh2_session_handshake(x, y) -#else -#define session_startup(x,y) libssh2_session_startup(x, (int)y) -#endif static enum curl_khtype convert_ssh2_keytype(int sshkeytype) { enum curl_khtype keytype = CURLKHTYPE_UNKNOWN; @@ -477,7 +436,6 @@ static CURLcode ssh_knownhost(struct Curl_easy *data) int rc = 0; CURLcode result = CURLE_OK; -#ifdef HAVE_LIBSSH2_KNOWNHOST_API if(data->set.str[STRING_SSH_KNOWNHOSTS]) { /* we are asked to verify the host against a file */ struct connectdata *conn = data->conn; @@ -537,7 +495,6 @@ static CURLcode ssh_knownhost(struct Curl_easy *data) /* no check means failure! */ rc = CURLKHSTAT_REJECT; else { -#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP keycheck = libssh2_knownhost_checkp(sshc->kh, conn->host.name, (conn->remote_port != PORT_SSH) ? @@ -547,15 +504,6 @@ static CURLcode ssh_knownhost(struct Curl_easy *data) LIBSSH2_KNOWNHOST_KEYENC_RAW| keybit, &host); -#else - keycheck = libssh2_knownhost_check(sshc->kh, - conn->host.name, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, - &host); -#endif infof(data, "SSH host check: %d, key: %s", keycheck, (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) ? @@ -639,9 +587,6 @@ static CURLcode ssh_knownhost(struct Curl_easy *data) break; } } -#else /* HAVE_LIBSSH2_KNOWNHOST_API */ - (void)data; -#endif return result; } @@ -819,8 +764,6 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data) { CURLcode result = CURLE_OK; -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519 static const char * const hostkey_method_ssh_ed25519 = "ssh-ed25519"; @@ -916,12 +859,10 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data) break; #endif case LIBSSH2_KNOWNHOST_KEY_SSHRSA: -#ifdef HAVE_LIBSSH2_VERSION if(libssh2_version(0x010900)) /* since 1.9.0 libssh2_session_method_pref() works as expected */ hostkey_method = hostkey_method_ssh_rsa_all; else -#endif /* old libssh2 which cannot correctly remove unsupported methods due * to bug in src/kex.c or does not support the new methods anyways. */ @@ -956,8 +897,6 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data) } } -#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ - return result; } @@ -1094,12 +1033,10 @@ static CURLcode sftp_quote(struct Curl_easy *data, state(data, SSH_SFTP_QUOTE_UNLINK); return result; } -#ifdef HAS_STATVFS_SUPPORT else if(strncasecompare(cmd, "statvfs ", 8)) { state(data, SSH_SFTP_QUOTE_STATVFS); return result; } -#endif failf(data, "Unknown SFTP command"); Curl_safefree(sshc->quote_path1); @@ -1264,7 +1201,8 @@ sftp_upload_init(struct Curl_easy *data, Curl_pgrsSetUploadSize(data, data->state.infilesize); } - SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); + libssh2_sftp_seek64(sshc->sftp_handle, + (libssh2_uint64_t)data->state.resume_from); } if(data->state.infilesize > 0) { data->req.size = data->state.infilesize; @@ -1565,7 +1503,7 @@ sftp_download_stat(struct Curl_easy *data, size = to - from + 1; } - SFTP_SEEK(sshc->sftp_handle, from); + libssh2_sftp_seek64(sshc->sftp_handle, (libssh2_uint64_t)from); } data->req.size = size; data->req.maxdownload = size; @@ -1598,7 +1536,8 @@ sftp_download_stat(struct Curl_easy *data, data->req.maxdownload = attrs.filesize - data->state.resume_from; Curl_pgrsSetDownloadSize(data, attrs.filesize - data->state.resume_from); - SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); + libssh2_sftp_seek64(sshc->sftp_handle, + (libssh2_uint64_t)data->state.resume_from); } /* Setup the actual download */ @@ -1670,10 +1609,10 @@ static CURLcode sftp_readdir(struct Curl_easy *data, return result; } } - else if(rc == 0) { + else if(!rc) { state(data, SSH_SFTP_READDIR_DONE); } - else if(rc < 0) { + else { unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session); result = sftp_libssh2_error_to_CURLE(sftperr); sshc->actualcode = result ? result : CURLE_SSH; @@ -1723,7 +1662,8 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) FALLTHROUGH(); case SSH_S_STARTUP: - rc = session_startup(sshc->ssh_session, conn->sock[FIRSTSOCKET]); + rc = libssh2_session_handshake(sshc->ssh_session, + conn->sock[FIRSTSOCKET]); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } @@ -1878,7 +1818,6 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) break; case SSH_AUTH_AGENT_INIT: -#ifdef HAVE_LIBSSH2_AGENT_API if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT) && (strstr(sshc->authlist, "publickey") != NULL)) { @@ -1908,12 +1847,10 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) } } else -#endif /* HAVE_LIBSSH2_AGENT_API */ state(data, SSH_AUTH_KEY_INIT); break; case SSH_AUTH_AGENT_LIST: -#ifdef HAVE_LIBSSH2_AGENT_API rc = libssh2_agent_list_identities(sshc->ssh_agent); if(rc == LIBSSH2_ERROR_EAGAIN) @@ -1927,11 +1864,9 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) state(data, SSH_AUTH_AGENT); sshc->sshagent_prev_identity = NULL; } -#endif break; case SSH_AUTH_AGENT: -#ifdef HAVE_LIBSSH2_AGENT_API /* as prev_identity evolves only after an identity user auth finished we can safely request it again as long as EAGAIN is returned here or by libssh2_agent_userauth */ @@ -1968,7 +1903,6 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) state(data, SSH_AUTH_KEY_INIT); rc = 0; /* clear rc and continue */ } -#endif break; case SSH_AUTH_KEY_INIT: @@ -2051,8 +1985,10 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) /* * Get the "home" directory */ - rc = sftp_libssh2_realpath(sshc->sftp_session, ".", - sshp->readdir_filename, CURL_PATH_MAX); + rc = libssh2_sftp_symlink_ex(sshc->sftp_session, + ".", curlx_uztoui(strlen(".")), + sshp->readdir_filename, CURL_PATH_MAX, + LIBSSH2_SFTP_REALPATH); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } @@ -2288,7 +2224,6 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) state(data, SSH_SFTP_NEXT_QUOTE); break; -#ifdef HAS_STATVFS_SUPPORT case SSH_SFTP_QUOTE_STATVFS: { LIBSSH2_SFTP_STATVFS statvfs; @@ -2351,7 +2286,7 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) state(data, SSH_SFTP_NEXT_QUOTE); break; } -#endif + case SSH_SFTP_GETINFO: { if(data->set.get_filetime) { @@ -2684,8 +2619,9 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) * directory in the path. */ sshc->ssh_channel = - SCP_SEND(sshc->ssh_session, sshp->path, data->set.new_file_perms, - data->state.infilesize); + libssh2_scp_send64(sshc->ssh_session, sshp->path, + (int)data->set.new_file_perms, + (libssh2_int64_t)data->state.infilesize, 0, 0); if(!sshc->ssh_channel) { int ssh_err; char *err_msg = NULL; @@ -2920,14 +2856,11 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) break; case SSH_SESSION_FREE: -#ifdef HAVE_LIBSSH2_KNOWNHOST_API if(sshc->kh) { libssh2_knownhost_free(sshc->kh); sshc->kh = NULL; } -#endif -#ifdef HAVE_LIBSSH2_AGENT_API if(sshc->ssh_agent) { rc = libssh2_agent_disconnect(sshc->ssh_agent); if(rc == LIBSSH2_ERROR_EAGAIN) { @@ -2948,7 +2881,6 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) sshc->sshagent_identity = NULL; sshc->sshagent_prev_identity = NULL; } -#endif if(sshc->ssh_session) { rc = libssh2_session_free(sshc->ssh_session); @@ -2970,12 +2902,8 @@ static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block) DEBUGASSERT(sshc->ssh_channel == NULL); DEBUGASSERT(sshc->sftp_session == NULL); DEBUGASSERT(sshc->sftp_handle == NULL); -#ifdef HAVE_LIBSSH2_KNOWNHOST_API DEBUGASSERT(sshc->kh == NULL); -#endif -#ifdef HAVE_LIBSSH2_AGENT_API DEBUGASSERT(sshc->ssh_agent == NULL); -#endif Curl_safefree(sshc->rsa_pub); Curl_safefree(sshc->rsa); @@ -3325,14 +3253,11 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) conn->send[FIRSTSOCKET] = sftp_send; } - if(data->set.ssh_compression) { -#if LIBSSH2_VERSION_NUM >= 0x010208 - if(libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) -#endif - infof(data, "Failed to enable compression for ssh session"); + if(data->set.ssh_compression && + libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) { + infof(data, "Failed to enable compression for ssh session"); } -#ifdef HAVE_LIBSSH2_KNOWNHOST_API if(data->set.str[STRING_SSH_KNOWNHOSTS]) { int rc; sshc->kh = libssh2_knownhost_init(sshc->ssh_session); @@ -3350,7 +3275,6 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) infof(data, "Failed to read known hosts from %s", data->set.str[STRING_SSH_KNOWNHOSTS]); } -#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ #ifdef CURL_LIBSSH2_DEBUG libssh2_trace(sshc->ssh_session, ~0); @@ -3761,25 +3685,21 @@ static const char *sftp_libssh2_strerror(unsigned long err) CURLcode Curl_ssh_init(void) { -#ifdef HAVE_LIBSSH2_INIT if(libssh2_init(0)) { DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n")); return CURLE_FAILED_INIT; } -#endif return CURLE_OK; } void Curl_ssh_cleanup(void) { -#ifdef HAVE_LIBSSH2_EXIT (void)libssh2_exit(); -#endif } void Curl_ssh_version(char *buffer, size_t buflen) { - (void)msnprintf(buffer, buflen, "libssh2/%s", CURL_LIBSSH2_VERSION); + (void)msnprintf(buffer, buflen, "libssh2/%s", libssh2_version(0)); } /* The SSH session is associated with the *CONNECTION* but the callback user diff --git a/lib/vssh/ssh.h b/lib/vssh/ssh.h index 8d8a9b3..bbbe95d 100644 --- a/lib/vssh/ssh.h +++ b/lib/vssh/ssh.h @@ -201,17 +201,10 @@ struct ssh_conn { Curl_send *tls_send; #endif -#ifdef HAVE_LIBSSH2_AGENT_API LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */ - struct libssh2_agent_publickey *sshagent_identity, - *sshagent_prev_identity; -#endif - - /* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h - header */ -#ifdef HAVE_LIBSSH2_KNOWNHOST_API + struct libssh2_agent_publickey *sshagent_identity; + struct libssh2_agent_publickey *sshagent_prev_identity; LIBSSH2_KNOWNHOSTS *kh; -#endif #elif defined(USE_WOLFSSH) WOLFSSH *ssh_session; WOLFSSH_CTX *ctx; @@ -221,43 +214,20 @@ struct ssh_conn { #endif /* USE_LIBSSH */ }; -#if defined(USE_LIBSSH2) - -/* Feature detection based on version numbers to better work with - non-configure platforms */ - -#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000) -# error "SCP/SFTP protocols require libssh2 0.16 or later" +#ifdef USE_LIBSSH +#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 9, 0) +# error "SCP/SFTP protocols require libssh 0.9.0 or later" #endif - -#if LIBSSH2_VERSION_NUM >= 0x010000 -#define HAVE_LIBSSH2_SFTP_SEEK64 1 #endif -#if LIBSSH2_VERSION_NUM >= 0x010100 -#define HAVE_LIBSSH2_VERSION 1 -#endif - -#if LIBSSH2_VERSION_NUM >= 0x010205 -#define HAVE_LIBSSH2_INIT 1 -#define HAVE_LIBSSH2_EXIT 1 -#endif - -#if LIBSSH2_VERSION_NUM >= 0x010206 -#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1 -#define HAVE_LIBSSH2_SCP_SEND64 1 -#endif +#if defined(USE_LIBSSH2) -#if LIBSSH2_VERSION_NUM >= 0x010208 -#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1 -#endif +/* Feature detection based on version numbers to better work with + non-configure platforms */ -#ifdef HAVE_LIBSSH2_VERSION -/* get it runtime if possible */ -#define CURL_LIBSSH2_VERSION libssh2_version(0) -#else -/* use build-time if runtime not possible */ -#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION +#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x010208) +# error "SCP/SFTP protocols require libssh2 1.2.8 or later" +/* 1.2.8 was released on April 5 2011 */ #endif #endif /* USE_LIBSSH2 */ diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index d2c0172..a47d803 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -63,10 +63,6 @@ /* The last #include file should be: */ #include "memdebug.h" -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - #define QUIC_PRIORITY \ "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \ "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \ @@ -1223,7 +1219,7 @@ CURLcode Curl_gtls_ctx_init(struct gtls_ctx *gctx, size_t i, alen = alpn_len; unsigned char *salpn = (unsigned char *)alpn; unsigned char slen; - for(i = 0; (i < ARRAYSIZE(gtls_alpns)) && alen; ++i) { + for(i = 0; (i < CURL_ARRAYSIZE(gtls_alpns)) && alen; ++i) { slen = salpn[0]; if(slen >= alen) return CURLE_FAILED_INIT; diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 456b561..13e44c7 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -79,11 +79,8 @@ #include "memdebug.h" /* ALPN for http2 */ -#ifdef USE_HTTP2 -# undef HAS_ALPN -# ifdef MBEDTLS_SSL_ALPN -# define HAS_ALPN -# endif +#if defined(USE_HTTP2) && defined(MBEDTLS_SSL_ALPN) +# define HAS_ALPN_MBEDTLS #endif struct mbed_ssl_backend_data { @@ -97,7 +94,7 @@ struct mbed_ssl_backend_data { #endif mbedtls_pk_context pk; mbedtls_ssl_config config; -#ifdef HAS_ALPN +#ifdef HAS_ALPN_MBEDTLS const char *protocols[3]; #endif int *ciphersuites; @@ -931,7 +928,7 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) return CURLE_SSL_CONNECT_ERROR; } -#ifdef HAS_ALPN +#ifdef HAS_ALPN_MBEDTLS if(connssl->alpn) { struct alpn_proto_buf proto; size_t i; @@ -1109,7 +1106,7 @@ pinnedpubkey_error: } } -#ifdef HAS_ALPN +#ifdef HAS_ALPN_MBEDTLS if(connssl->alpn) { const char *proto = mbedtls_ssl_get_alpn_protocol(&backend->ssl); @@ -1636,7 +1633,6 @@ static CURLcode mbedtls_sha256sum(const unsigned char *input, unsigned char *sha256sum, size_t sha256len UNUSED_PARAM) { - /* TODO: explain this for different mbedtls 2.x vs 3 version */ (void)sha256len; #if MBEDTLS_VERSION_NUMBER < 0x02070000 mbedtls_sha256(input, inputlen, sha256sum, 0); diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index f34ddaf..6ded5f3 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -116,10 +116,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifndef ARRAYSIZE -#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) -#endif - /* Uncomment the ALLOW_RENEG line to a real #define if you want to allow TLS renegotiations when built with BoringSSL. Renegotiating is non-compliant with HTTP/2 and "an extremely dangerous protocol feature". Beware. @@ -1300,7 +1296,9 @@ int cert_stuff(struct Curl_easy *data, if(cert_file || cert_blob || (file_type == SSL_FILETYPE_ENGINE) || (file_type == SSL_FILETYPE_PROVIDER)) { SSL *ssl; - X509 *x509; + X509 *x509 = NULL; + EVP_PKEY *pri = NULL; + STACK_OF(X509) *ca = NULL; int cert_done = 0; int cert_use_result; @@ -1489,8 +1487,6 @@ int cert_stuff(struct Curl_easy *data, { BIO *cert_bio = NULL; PKCS12 *p12 = NULL; - EVP_PKEY *pri; - STACK_OF(X509) *ca = NULL; if(cert_blob) { cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len)); if(!cert_bio) { @@ -1531,8 +1527,7 @@ int cert_stuff(struct Curl_easy *data, PKCS12_PBE_add(); - if(!PKCS12_parse(p12, key_passwd, &pri, &x509, - &ca)) { + if(!PKCS12_parse(p12, key_passwd, &pri, &x509, &ca)) { failf(data, "could not parse PKCS12 file, check password, " OSSL_PACKAGE " error %s", @@ -2054,8 +2049,6 @@ static CURLcode ossl_set_provider(struct Curl_easy *data, const char *provider) sizeof(error_buffer))); /* Do not attempt to load it again */ data->state.provider_failed = TRUE; - /* FIXME not the right error but much less fuss than creating a new - * public one */ return CURLE_SSL_ENGINE_NOTFOUND; } data->state.provider = TRUE; @@ -2871,10 +2864,9 @@ static void ossl_trace(int direction, int ssl_ver, int content_type, /* ====================================================== */ /* Check for OpenSSL 1.0.2 which has ALPN support. */ -#undef HAS_ALPN #if OPENSSL_VERSION_NUMBER >= 0x10002000L \ && !defined(OPENSSL_NO_TLSEXT) -# define HAS_ALPN 1 +# define HAS_ALPN_OPENSSL #endif #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ @@ -3360,7 +3352,7 @@ static CURLcode ossl_populate_x509_store(struct Curl_cfilter *cf, "CA" /* Intermediate Certification Authorities */ }; size_t i; - for(i = 0; i < ARRAYSIZE(storeNames); ++i) { + for(i = 0; i < CURL_ARRAYSIZE(storeNames); ++i) { bool imported = FALSE; result = import_windows_cert_store(data, storeNames[i], store, &imported); @@ -3671,7 +3663,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, ctx_option_t ctx_options = 0; struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); - const long int ssl_version_min = conn_config->version; + unsigned int ssl_version_min = conn_config->version; char * const ssl_cert = ssl_config->primary.clientcert; const struct curl_blob *ssl_cert_blob = ssl_config->primary.cert_blob; const char * const ssl_cert_type = ssl_config->cert_type; @@ -3714,6 +3706,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, } break; case TRNSPRT_QUIC: + ssl_version_min = CURL_SSLVERSION_TLSv1_3; if(conn_config->version_max && (conn_config->version_max != CURL_SSLVERSION_MAX_TLSv1_3)) { failf(data, "QUIC needs at least TLS version 1.3"); @@ -3854,7 +3847,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, #endif if(alpn && alpn_len) { -#ifdef HAS_ALPN +#ifdef HAS_ALPN_OPENSSL if(SSL_CTX_set_alpn_protos(octx->ssl_ctx, alpn, (int)alpn_len)) { failf(data, "Error setting ALPN"); return CURLE_SSL_CONNECT_ERROR; @@ -3877,7 +3870,7 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, ciphers = conn_config->cipher_list; if(!ciphers && (peer->transport != TRNSPRT_QUIC)) ciphers = DEFAULT_CIPHER_SELECTION; - if(ciphers) { + if(ciphers && (ssl_version_min < CURL_SSLVERSION_TLSv1_3)) { if(!SSL_CTX_set_cipher_list(octx->ssl_ctx, ciphers)) { failf(data, "failed setting cipher list: %s", ciphers); return CURLE_SSL_CIPHER; @@ -3888,7 +3881,9 @@ CURLcode Curl_ossl_ctx_init(struct ossl_ctx *octx, #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES { const char *ciphers13 = conn_config->cipher_list13; - if(ciphers13) { + if(ciphers13 && + (!conn_config->version_max || + (conn_config->version_max >= CURL_SSLVERSION_MAX_TLSv1_3))) { if(!SSL_CTX_set_ciphersuites(octx->ssl_ctx, ciphers13)) { failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13); return CURLE_SSL_CIPHER; @@ -4192,7 +4187,7 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, DEBUGASSERT(ssl_connect_1 == connssl->connecting_state); DEBUGASSERT(octx); memset(&proto, 0, sizeof(proto)); -#ifdef HAS_ALPN +#ifdef HAS_ALPN_OPENSSL if(connssl->alpn) { result = Curl_alpn_to_proto_buf(&proto, connssl->alpn); if(result) { @@ -4229,7 +4224,7 @@ static CURLcode ossl_connect_step1(struct Curl_cfilter *cf, SSL_set_bio(octx->ssl, bio, bio); #endif -#ifdef HAS_ALPN +#ifdef HAS_ALPN_OPENSSL if(connssl->alpn) { Curl_alpn_to_proto_str(&proto, connssl->alpn); infof(data, VTLS_INFOF_ALPN_OFFER_1STR, proto.data); @@ -4286,7 +4281,6 @@ static void ossl_trace_ech_retry_configs(struct Curl_easy *data, SSL* 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 BoringSSL */ infof(data, "ECH: retry_configs for %s from %s, %d %d", inner ? inner : "NULL", outer ? outer : "NULL", reason, rv); #endif @@ -4541,7 +4535,7 @@ static CURLcode ossl_connect_step2(struct Curl_cfilter *cf, # endif /* !OPENSSL_IS_BORINGSSL && !OPENSSL_IS_AWSLC */ #endif /* USE_ECH_OPENSSL */ -#ifdef HAS_ALPN +#ifdef HAS_ALPN_OPENSSL /* Sets data and len to negotiated protocol, len is 0 if no protocol was * negotiated */ diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index 8441b46..2af29a4 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -77,7 +77,7 @@ https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx */ #if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(_USING_V110_SDK71_) -# define HAS_ALPN 1 +# define HAS_ALPN_SCHANNEL #endif #ifndef BCRYPT_CHACHA20_POLY1305_ALGORITHM @@ -888,7 +888,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) SecBufferDesc outbuf_desc; SecBuffer inbuf; SecBufferDesc inbuf_desc; -#ifdef HAS_ALPN +#ifdef HAS_ALPN_SCHANNEL unsigned char alpn_buffer[128]; #endif SECURITY_STATUS sspi_status = SEC_E_OK; @@ -908,7 +908,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) "connect to some servers due to lack of SNI, algorithms, etc."); } -#ifdef HAS_ALPN +#ifdef HAS_ALPN_SCHANNEL /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above. Also it does not seem to be supported for WINE, see curl bug #983. */ backend->use_alpn = connssl->alpn && @@ -991,7 +991,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) infof(data, "schannel: using IP address, SNI is not supported by OS."); } -#ifdef HAS_ALPN +#ifdef HAS_ALPN_SCHANNEL if(backend->use_alpn) { int cur = 0; int list_start_index = 0; @@ -1039,7 +1039,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); InitSecBufferDesc(&inbuf_desc, &inbuf, 1); } -#else /* HAS_ALPN */ +#else /* HAS_ALPN_SCHANNEL */ InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); InitSecBufferDesc(&inbuf_desc, &inbuf, 1); #endif @@ -1533,7 +1533,7 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data) CURLcode result = CURLE_OK; SECURITY_STATUS sspi_status = SEC_E_OK; CERT_CONTEXT *ccert_context = NULL; -#ifdef HAS_ALPN +#ifdef HAS_ALPN_SCHANNEL SecPkgContext_ApplicationProtocol alpn_result; #endif @@ -1562,7 +1562,7 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data) return CURLE_SSL_CONNECT_ERROR; } -#ifdef HAS_ALPN +#ifdef HAS_ALPN_SCHANNEL if(backend->use_alpn) { sspi_status = Curl_pSecFn->QueryContextAttributes(&backend->ctxt->ctxt_handle, @@ -2367,7 +2367,6 @@ static CURLcode schannel_shutdown(struct Curl_cfilter *cf, Curl_pSecFn->FreeContextBuffer(outbuf.pvBuffer); if(!result) { if(written < (ssize_t)outbuf.cbBuffer) { - /* TODO: handle partial sends */ failf(data, "schannel: failed to send close msg: %s" " (bytes written: %zd)", curl_easy_strerror(result), written); result = CURLE_SEND_ERROR; diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index c258b11..9c59b4c 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -915,7 +915,9 @@ static int multissl_init(void) { if(multissl_setup(NULL)) return 1; - return Curl_ssl->init(); + if(Curl_ssl->init) + return Curl_ssl->init(); + return 1; } static CURLcode multissl_connect(struct Curl_cfilter *cf, @@ -1939,8 +1941,8 @@ CURLcode Curl_alpn_set_negotiated(struct Curl_cfilter *cf, else { *palpn = CURL_HTTP_VERSION_NONE; failf(data, "unsupported ALPN protocol: '%.*s'", (int)proto_len, proto); - /* TODO: do we want to fail this? Previous code just ignored it and - * some vtls backends even ignore the return code of this function. */ + /* Previous code just ignored it and some vtls backends even ignore the + * return code of this function. */ /* return CURLE_NOT_BUILT_IN; */ goto out; } diff --git a/lib/vtls/vtls_scache.c b/lib/vtls/vtls_scache.c index 9c04b77..365e945 100644 --- a/lib/vtls/vtls_scache.c +++ b/lib/vtls/vtls_scache.c @@ -75,13 +75,35 @@ struct Curl_ssl_scache_peer { BIT(hmac_set); /* if key_salt and key_hmac are present */ }; +#define CURL_SCACHE_MAGIC 0x000e1551 + +#define GOOD_SCACHE(x) ((x) && (x)->magic == CURL_SCACHE_MAGIC) + struct Curl_ssl_scache { + unsigned int magic; struct Curl_ssl_scache_peer *peers; size_t peer_count; int default_lifetime_secs; long age; }; +static struct Curl_ssl_scache *cf_ssl_scache_get(struct Curl_easy *data) +{ + struct Curl_ssl_scache *scache = NULL; + /* If a share is present, its ssl_scache has preference over the multi */ + if(data->share && data->share->ssl_scache) + scache = data->share->ssl_scache; + else if(data->multi && data->multi->ssl_scache) + scache = data->multi->ssl_scache; + if(scache && !GOOD_SCACHE(scache)) { + failf(data, "transfer would use an invalid scache at %p, denied", + (void *)scache); + DEBUGASSERT(0); + return NULL; + } + return scache; +} + static void cf_ssl_scache_clear_session(struct Curl_ssl_session *s) { if(s->sdata) { @@ -306,6 +328,7 @@ CURLcode Curl_ssl_scache_create(size_t max_peers, return CURLE_OUT_OF_MEMORY; } + scache->magic = CURL_SCACHE_MAGIC; scache->default_lifetime_secs = (24*60*60); /* 1 day */ scache->peer_count = max_peers; scache->peers = peers; @@ -322,8 +345,9 @@ CURLcode Curl_ssl_scache_create(size_t max_peers, void Curl_ssl_scache_destroy(struct Curl_ssl_scache *scache) { - if(scache) { + if(scache && GOOD_SCACHE(scache)) { size_t i; + scache->magic = 0; for(i = 0; i < scache->peer_count; ++i) { cf_ssl_scache_clear_peer(&scache->peers[i]); } @@ -359,7 +383,7 @@ static CURLcode cf_ssl_peer_key_add_path(struct dynbuf *buf, char abspath[_MAX_PATH]; if(_fullpath(abspath, path, _MAX_PATH)) return Curl_dyn_addf(buf, ":%s-%s", name, abspath); -#else +#elif defined(HAVE_REALPATH) if(path[0] != '/') { char *abspath = realpath(path, NULL); if(abspath) { @@ -588,6 +612,13 @@ cf_ssl_find_peer_by_key(struct Curl_easy *data, CURLcode result = CURLE_OK; *ppeer = NULL; + if(!GOOD_SCACHE(scache)) { + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + CURL_TRC_SSLS(data, "find peer slot for %s among %zu slots", + ssl_peer_key, scache->peer_count); + /* check for entries with known peer_key */ for(i = 0; scache && i < scache->peer_count; i++) { if(scache->peers[i].ssl_peer_key && @@ -792,7 +823,7 @@ CURLcode Curl_ssl_scache_put(struct Curl_cfilter *cf, const char *ssl_peer_key, struct Curl_ssl_session *s) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); CURLcode result; DEBUGASSERT(ssl_config); @@ -801,6 +832,10 @@ CURLcode Curl_ssl_scache_put(struct Curl_cfilter *cf, Curl_ssl_session_destroy(s); return CURLE_OK; } + if(!GOOD_SCACHE(scache)) { + Curl_ssl_session_destroy(s); + return CURLE_BAD_FUNCTION_ARGUMENT; + } Curl_ssl_scache_lock(data); result = cf_scache_add_session(cf, data, scache, ssl_peer_key, s); @@ -826,7 +861,7 @@ CURLcode Curl_ssl_scache_take(struct Curl_cfilter *cf, const char *ssl_peer_key, struct Curl_ssl_session **ps) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct Curl_ssl_scache_peer *peer = NULL; struct Curl_llist_node *n; @@ -870,7 +905,7 @@ CURLcode Curl_ssl_scache_add_obj(struct Curl_cfilter *cf, void *sobj, Curl_ssl_scache_obj_dtor *sobj_free) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct Curl_ssl_scache_peer *peer = NULL; CURLcode result; @@ -878,6 +913,11 @@ CURLcode Curl_ssl_scache_add_obj(struct Curl_cfilter *cf, DEBUGASSERT(sobj); DEBUGASSERT(sobj_free); + if(!scache) { + result = CURLE_BAD_FUNCTION_ARGUMENT; + goto out; + } + result = cf_ssl_add_peer(data, scache, ssl_peer_key, conn_config, &peer); if(result || !peer) { CURL_TRC_SSLS(data, "unable to add scache peer: %d", result); @@ -898,7 +938,7 @@ bool Curl_ssl_scache_get_obj(struct Curl_cfilter *cf, const char *ssl_peer_key, void **sobj) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct Curl_ssl_scache_peer *peer = NULL; CURLcode result; @@ -924,7 +964,7 @@ void Curl_ssl_scache_remove_all(struct Curl_cfilter *cf, struct Curl_easy *data, const char *ssl_peer_key) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); struct Curl_ssl_scache_peer *peer = NULL; CURLcode result; @@ -977,6 +1017,9 @@ cf_ssl_find_peer_by_hmac(struct Curl_ssl_scache *scache, CURLcode result = CURLE_OK; *ppeer = NULL; + if(!GOOD_SCACHE(scache)) + return CURLE_BAD_FUNCTION_ARGUMENT; + /* look for an entry that matches salt+hmac exactly or has a known * ssl_peer_key which salt+hmac's to the same. */ for(i = 0; scache && i < scache->peer_count; i++) { @@ -1021,7 +1064,7 @@ CURLcode Curl_ssl_session_import(struct Curl_easy *data, const unsigned char *shmac, size_t shmac_len, const unsigned char *sdata, size_t sdata_len) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct Curl_ssl_scache_peer *peer = NULL; struct Curl_ssl_session *s = NULL; bool locked = FALSE; @@ -1092,7 +1135,7 @@ CURLcode Curl_ssl_session_export(struct Curl_easy *data, curl_ssls_export_cb *export_fn, void *userptr) { - struct Curl_ssl_scache *scache = data->state.ssl_scache; + struct Curl_ssl_scache *scache = cf_ssl_scache_get(data); struct Curl_ssl_scache_peer *peer; struct dynbuf sbuf, hbuf; struct Curl_llist_node *n; diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c index 82b21af..546ba03 100644 --- a/lib/vtls/wolfssl.c +++ b/lib/vtls/wolfssl.c @@ -770,7 +770,7 @@ wssl_add_default_ciphers(bool tls13, struct dynbuf *buf) int i; char *str; - for(i = 0; (str = wolfSSL_get_cipher_list(i)); i++) { + for(i = 0; (str = wolfSSL_get_cipher_list(i)) != NULL; i++) { size_t n; if((strncmp(str, "TLS13", 5) == 0) != tls13) continue; -- cgit v0.12