From 43f100ad4b599dbc564f9920e63afdc242f0a27c Mon Sep 17 00:00:00 2001 From: dartraiden Date: Wed, 26 May 2021 22:25:25 +0300 Subject: libcurl: update to 7.77 --- libs/libcurl/docs/CHANGES | 10504 +++++++++++++++--------------- libs/libcurl/docs/THANKS | 44 + libs/libcurl/include/curl/curl.h | 29 +- libs/libcurl/include/curl/curlver.h | 10 +- libs/libcurl/libcurl.vcxproj | 4 + libs/libcurl/libcurl.vcxproj.filters | 6 + libs/libcurl/src/CMakeLists.txt | 6 +- libs/libcurl/src/Makefile.in | 110 +- libs/libcurl/src/Makefile.inc | 2 + libs/libcurl/src/amigaos.c | 29 +- libs/libcurl/src/asyn-ares.c | 53 +- libs/libcurl/src/asyn-thread.c | 23 +- libs/libcurl/src/bufref.c | 127 + libs/libcurl/src/bufref.h | 46 + libs/libcurl/src/c-hyper.c | 19 +- libs/libcurl/src/checksrc.pl | 19 +- libs/libcurl/src/config-amigaos.h | 7 - libs/libcurl/src/config-dos.h | 9 +- libs/libcurl/src/config-mac.h | 7 - libs/libcurl/src/config-os400.h | 22 - libs/libcurl/src/config-plan9.h | 7 - libs/libcurl/src/config-riscos.h | 21 - libs/libcurl/src/config-tpf.h | 36 - libs/libcurl/src/config-vxworks.h | 21 - libs/libcurl/src/config-win32.h | 29 +- libs/libcurl/src/config-win32ce.h | 18 - libs/libcurl/src/connect.c | 29 +- libs/libcurl/src/content_encoding.c | 9 +- libs/libcurl/src/cookie.c | 411 +- libs/libcurl/src/curl_addrinfo.c | 8 +- libs/libcurl/src/curl_config.h.cmake | 39 +- libs/libcurl/src/curl_config.h.in | 9 +- libs/libcurl/src/curl_get_line.c | 4 +- libs/libcurl/src/curl_gssapi.c | 2 +- libs/libcurl/src/curl_krb5.h | 1 - libs/libcurl/src/curl_path.c | 10 +- libs/libcurl/src/curl_rtmp.c | 6 + libs/libcurl/src/curl_sasl.c | 265 +- libs/libcurl/src/curl_sasl.h | 12 +- libs/libcurl/src/curl_setup.h | 36 +- libs/libcurl/src/dict.c | 11 +- libs/libcurl/src/doh.c | 27 +- libs/libcurl/src/easy.c | 8 +- libs/libcurl/src/easyoptions.c | 4 +- libs/libcurl/src/file.c | 13 +- libs/libcurl/src/ftp.c | 17 +- libs/libcurl/src/ftplistparser.c | 2 +- libs/libcurl/src/gopher.c | 2 + libs/libcurl/src/hash.c | 4 +- libs/libcurl/src/hostcheck.c | 8 +- libs/libcurl/src/hostip.c | 29 +- libs/libcurl/src/hostip.h | 9 - libs/libcurl/src/hostip6.c | 19 +- libs/libcurl/src/hsts.c | 19 +- libs/libcurl/src/hsts.h | 8 +- libs/libcurl/src/http.c | 70 +- libs/libcurl/src/http.h | 5 +- libs/libcurl/src/http2.c | 98 +- libs/libcurl/src/http2.h | 2 +- libs/libcurl/src/http_digest.c | 2 +- libs/libcurl/src/http_negotiate.c | 2 +- libs/libcurl/src/http_ntlm.c | 90 +- libs/libcurl/src/http_proxy.c | 109 +- libs/libcurl/src/http_proxy.h | 24 + libs/libcurl/src/imap.c | 4 +- libs/libcurl/src/inet_ntop.c | 4 +- libs/libcurl/src/krb5.c | 22 +- libs/libcurl/src/ldap.c | 30 +- libs/libcurl/src/libcurl.plist | 6 +- libs/libcurl/src/llist.c | 6 +- libs/libcurl/src/md4.c | 2 +- libs/libcurl/src/mime.c | 4 +- libs/libcurl/src/mprintf.c | 4 +- libs/libcurl/src/mqtt.c | 1 + libs/libcurl/src/multi.c | 172 +- libs/libcurl/src/multihandle.h | 4 + libs/libcurl/src/non-ascii.c | 8 +- libs/libcurl/src/openldap.c | 81 +- libs/libcurl/src/pop3.c | 17 +- libs/libcurl/src/progress.c | 86 +- libs/libcurl/src/rtsp.c | 5 +- libs/libcurl/src/select.c | 2 +- libs/libcurl/src/sendf.c | 19 +- libs/libcurl/src/setopt.c | 60 +- libs/libcurl/src/setup-vms.h | 8 +- libs/libcurl/src/share.c | 4 +- libs/libcurl/src/sigpipe.h | 4 +- libs/libcurl/src/smb.c | 7 +- libs/libcurl/src/smtp.c | 6 +- libs/libcurl/src/socks.c | 6 +- libs/libcurl/src/socks_gssapi.c | 2 +- libs/libcurl/src/socks_sspi.c | 2 +- libs/libcurl/src/splay.c | 18 +- libs/libcurl/src/strerror.c | 5 +- libs/libcurl/src/system_win32.c | 4 +- libs/libcurl/src/telnet.c | 3 +- libs/libcurl/src/tftp.c | 7 +- libs/libcurl/src/timeval.c | 8 +- libs/libcurl/src/transfer.c | 15 +- libs/libcurl/src/url.c | 25 +- libs/libcurl/src/urlapi.c | 96 +- libs/libcurl/src/urldata.h | 36 +- libs/libcurl/src/vauth/cleartext.c | 70 +- libs/libcurl/src/vauth/cram.c | 65 +- libs/libcurl/src/vauth/digest.c | 62 +- libs/libcurl/src/vauth/digest_sspi.c | 54 +- libs/libcurl/src/vauth/gsasl.c | 33 +- libs/libcurl/src/vauth/krb5_gssapi.c | 100 +- libs/libcurl/src/vauth/krb5_sspi.c | 115 +- libs/libcurl/src/vauth/ntlm.c | 152 +- libs/libcurl/src/vauth/ntlm_sspi.c | 58 +- libs/libcurl/src/vauth/oauth2.c | 53 +- libs/libcurl/src/vauth/vauth.c | 25 +- libs/libcurl/src/vauth/vauth.h | 66 +- libs/libcurl/src/version.c | 42 +- libs/libcurl/src/vquic/ngtcp2.c | 27 +- libs/libcurl/src/vquic/quiche.c | 29 +- libs/libcurl/src/vssh/libssh.c | 146 +- libs/libcurl/src/vssh/libssh2.c | 79 +- libs/libcurl/src/vssh/ssh.h | 3 + libs/libcurl/src/vssh/wolfssh.c | 6 +- libs/libcurl/src/vtls/bearssl.c | 17 +- libs/libcurl/src/vtls/gskit.c | 37 +- libs/libcurl/src/vtls/gtls.c | 85 +- libs/libcurl/src/vtls/mbedtls.c | 38 +- libs/libcurl/src/vtls/mesalink.c | 7 +- libs/libcurl/src/vtls/nss.c | 53 +- libs/libcurl/src/vtls/openssl.c | 361 +- libs/libcurl/src/vtls/rustls.c | 271 +- libs/libcurl/src/vtls/schannel.c | 122 +- libs/libcurl/src/vtls/schannel.h | 3 + libs/libcurl/src/vtls/schannel_verify.c | 283 +- libs/libcurl/src/vtls/sectransp.c | 1741 ++--- libs/libcurl/src/vtls/vtls.c | 32 +- libs/libcurl/src/vtls/vtls.h | 20 +- libs/libcurl/src/vtls/wolfssl.c | 65 +- libs/libcurl/src/x509asn1.c | 6 +- 137 files changed, 9365 insertions(+), 8385 deletions(-) create mode 100644 libs/libcurl/src/bufref.c create mode 100644 libs/libcurl/src/bufref.h (limited to 'libs') diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES index 62dce2ee97..e7a462b50e 100644 --- a/libs/libcurl/docs/CHANGES +++ b/libs/libcurl/docs/CHANGES @@ -6,7673 +6,7825 @@ Changelog -Version 7.76.1 (14 Apr 2021) +Version 7.77.0 (26 May 2021) -Daniel Stenberg (14 Apr 2021) +Daniel Stenberg (26 May 2021) - RELEASE-NOTES: synced - - curl 7.76.1 release -- THANKS: add names from 7.76.1 +- THANKS: added contributors from 7.77.0 cycle -- misc: update copyright year ranges to match latest updates +- copyright: update copyright year ranges to 2021 -- [Tatsuhiro Tsujikawa brought this change] +- [Radek Zajic brought this change] - ngtcp2: Use ALPN h3-29 for now + hostip: fix broken macOS/CMake/GCC builds - Fixes #6864 - Cloes #6886 + Follow-up to 31f631a142d855f06 + + Fixes #7128 + Closes #7129 -Jay Satiro (11 Apr 2021) -- TODO: remove 18.22 --fail-with-body +- TODO: netrc caching and sharing - --fail-with-body was added in 8a964cb (precedes curl-7_76_0). + URL: https://curl.se/mail/archive-2021-05/0018.html -Daniel Stenberg (10 Apr 2021) -- [Jürgen Gmach brought this change] +- [Orgad Shaneh brought this change] - src/tool_vms.c: remove duplicated word in comment + setopt: streamline ssl option code - Closes #6881 + Make it use the same style as the code next to it + + Closes #7123 -- configure: fix CURL_DARWIN_CFLAGS use +- [Radek Zajic brought this change] + + lib/hostip6.c: make NAT64 address synthesis on macOS work - The macro name change was not completely done. + Closes #7121 + +- [ejanchivdorj brought this change] + + sectransp: fix EXC_BAD_ACCESS caused by uninitialized buffer - Follow-up to 5d2c384452543c - Bug: https://github.com/curl/curl/commit/5d2c384452543c7b6c9fb02eaa0afc84fd5ab941#commitcomment-49315187 - Reported-by: Marcel Raad - Closes #6878 + When the SecCertificateCopyCommonName function fails, it leaves + common_name in a invalid state so CFStringCompare uses the invalid + result, causing EXC_BAD_ACCESS. + + The fix is to check the return value of the function before using the + name. + + Closes #7126 -- [Anthony Shaw brought this change] +- [Paweł Wegner brought this change] - github/workflow: add "security-extended" to codeql-analysis.yml + CMake: add CURL_ENABLE_EXPORT_TARGET option - Extends the CodeQL code scan. + install(EXPORT ...) causes trouble when embedding curl dependencies + which don't provide install(EXPORT ...) targets (e.g libressl and + nghttp2) with cmake's add_subdirectory. - Closes #6815 + Reviewed-by: Jakub Zakrzewski + Closes #7060 -- [Jochem Broekhoff brought this change] +- [Alessandro Ghedini brought this change] - examples/hiperfifo.c: check event_initialized before delete + quiche: update for network path aware API - If event_del is called with the event struct (still) zeroed out, a - segmentation fault may occur. event_initialized checks whether the - event struct is nonzero. + Latest version of quiche requires the application to pass the peer + address of received packets, and it provides the address for outgoing + packets back. - Closes #6876 + Closes #7120 -- [Patrick Monnerat brought this change] +- [Jacob Hoffman-Andrews brought this change] - ntlm: fix negotiated flags usage + rustls: switch read_tls and write_tls to callbacks - According to Microsoft document MS-NLMP, current flags usage is not - accurate: flag NTLMFLAG_NEGOTIATE_NTLM2_KEY controls the use of - extended security in an NTLM authentication message and NTLM version 2 - cannot be negotiated within the protocol. + And update to 0.6.0, including a rename from session to connection for + many fields. - The solution implemented here is: if the extended security flag is set, - prefer using NTLM version 2 (as a server featuring extended security - should also support version 2). If version 2 has been disabled at - compile time, use extended security. + Closes #7071 + +- [Koichi Shiraishi brought this change] + + sectransp: fix 7f4a9a9b2a49 commit about missing comma - Tests involving NTLM are adjusted to this new behavior. + Follow-up to 7f4a9a9b2a495 - Fixes #6813 - Closes #6849 + Closes #7119 -- [Patrick Monnerat brought this change] +- [Harry Sintonen brought this change] - ntlm: support version 2 on 32-bit platforms + openssl: associate/detach the transfer from connection - Closes #6849 + CVE-2021-22901 + + Bug: https://curl.se/docs/CVE-2021-22901.html -- [Patrick Monnerat brought this change] +- [Harry Sintonen brought this change] - curl_ntlm_core.h: simplify conditionals for USE_NTLM2SESSION + telnet: check sscanf() for correct number of matches - ... as !defined(CURL_DISABLE_CRYPTO_AUTH) is a prerequisite for the - whole NTLM. + CVE-2021-22898 - Closes #6849 + Bug: https://curl.se/docs/CVE-2021-22898.html -- lib: remove unused HAVE_INET_NTOA_R* defines +- schannel: don't use static to store selected ciphers - Closes #6867 + CVE-2021-22897 + + Bug: https://curl.se/docs/CVE-2021-22897.html -- [Michael Forney brought this change] +- docs/tests: remove freenode references - configure: include unconditionally +- RELEASE-NOTES: synced + +- [Sergey Markelov brought this change] + + NSS: make colons, commas and spaces valid separators in cipher list - In 2682e5f5, several instances of AC_HEADER_TIME were removed since - it is a deprecated autoconf macro. However, this was the macro that - defined TIME_WITH_SYS_TIME, which was used to indicate that - can be included alongside . TIME_WITH_SYS_TIME is still - used in the configure test body and since it is no longer defined, - is *not* included on systems that have . + Fixes #7110 + Closes #7115 + +- curl: include libmetalink version in --version output - In particular, at least on musl libc and glibc, does - not implicitly include and does not declare clock_gettime, - gmtime_r, or localtime_r. This causes configure to fail to detect - those functions. + Closes #7112 + +Jay Satiro (21 May 2021) +- [Matias N. Goldberg brought this change] + + cmake: Use multithreaded compilation on VS 2008+ - The AC_HEADER_TIME macro deprecation text says + Multithreaded compilation has been supported since at least VS 2005 and + been robustly stable since at least VS 2008 - > All current systems provide time.h; it need not be checked for. - > Not all systems provide sys/time.h, but those that do, all allow - > you to include it and time.h simultaneously. + Closes https://github.com/curl/curl/pull/7109 + +Daniel Stenberg (21 May 2021) +- [Matias N. Goldberg brought this change] + + cmake: fix two invokes result in different curl_config.h - So, to fix this issue, simply include unconditionally when - testing for time-related functions and in libcurl, and don't bother - checking for it. + Fixes #7100 + Closes #7101 - Closes #6859 + Reviewed-by: Jakub Zakrzewski + Signed-off-by: Matias N. Goldberg -- [Michael Forney brought this change] +- [Peng-Yu Chen brought this change] - configure: remove use of RETSIGTYPE + cmake: detect CURL_SA_FAMILY_T - This was previously defined by the obsolete AC_TYPE_SIGNAL macro, - which was removed in 2682e5f5. The deprecation text says + Fixes #7049 + Closes #7065 + +- [Lucas Clemente Vella brought this change] + + CURLOPT_IPRESOLVE: preventing wrong IP version from being used - > Your code may safely assume C89 semantics that RETSIGTYPE is void. + In some situations, it was possible that a transfer was setup to + use an specific IP version, but due do DNS caching or connection + reuse, it ended up using a different IP version from requested. - So, remove it and just use void instead. + This commit changes the effect of CURLOPT_IPRESOLVE from simply + restricting address resolution to preventing the wrong connection + type being used, when choosing a connection from the pool, and + to restricting what addresses could be used when establishing + a new connection. - Closes #6861 + It is important that all addresses versions are resolved, even if + not used in that transfer in particular, because the result is + cached, and could be useful for a different transfer with a + different CURLOPT_IPRESOLVE setting. + + Closes #6853 -- [Muhammed Yavuz Nuzumlalı brought this change] +- [Oliver Urbann brought this change] - install: add instructions for Apple Darwin platforms + AmigaOS: add functions definitions for SHA256 - Closes #6860 + AmiSSL replaces many functions with macros. Curl requires pointer + to some of these functions. Thus, we have to encapsulate these macros: + SHA256_Init, SHA256_Update, SHA256_Final, X509_INFO_free. + + Bug: https://github.com/jens-maus/amissl/issues/15 + Co-authored-by: Daniel Stenberg + + Closes #7099 -- [Muhammed Yavuz Nuzumlalı brought this change] +- test2100: make it run with and require IPv6 + + Closes #7083 - configure: disable min version set for Darwin +- tests/getpart: generate output URL encoded for better diffs - Fixes #6838 - Closes #6860 + Closes #7083 -- [David Hu brought this change] +- [Ryan Beck-Buysse brought this change] - docs/HTTP3.md: update the build instruction using gnutls + docs/TheArtOfHttpScripting: fix markdown links - In ngtcp2 the `with-gnutls` option is disabled by default, which will - cause `curl` unable to be `make` because of lacking the libraries - needed. + extra parens cause the links to be incorrectly formatted + and inconsistent with the rest of the document. - Closes #6857 + Signed-off-by: Ryan Beck-Buysse + Closes #7097 - RELEASE-NOTES: synced -- typecheck-gcc: make the ssl-ctx-cb check use SSL_CTX pointers - - ... and not values. - - Reported-by: locpyl-tidnyd on github - Fixes #6818 - Closes #6819 +- [Emil Engler brought this change] -- ngtcp2+gnutls: clear credentials when freed + docs: replace dots with dashes in markdown enums - ... to avoid double-free. + We use dashes instead of dots nearly everywhere except for those few + cases. This commit addresses this issues and brings more coherency into + it. - Reported-by: Kenneth Davidson - Fixes #6824 - Closes #6856 + Closes #7093 -Jay Satiro (5 Apr 2021) -- [Cherish98 brought this change] +- [Emil Engler brought this change] - tool_progress: Fix progress meter in parallel mode - - Make sure the total amount of DL/UL bytes are counted before the - transfer finalizes. Otherwise if a transfer finishes too quick, its - total numbers are not added, and results in a DL%/UL% that goes above - 100%. + docs: improve INTERNALS.md regarding getsock cb - Detail: + This adds the I/O prefix to indicate that those "actions" are kind-of + related to those found in select(2) or poll(2) (reading/writing). - progress_meter() is called periodically, and it may not catch a - transfer's total bytes if the value was unknown during the last call, - and the transfer is finished and deleted (i.e., lost) during the next - call. + It also adds a note where the prototypes of those functions can be found + in the source code. - Closes https://github.com/curl/curl/pull/6840 + Closes #7092 - [Emil Engler brought this change] - libssh: get rid of PATH_MAX + docs: document attach in INTERNALS.md - This removes the last occurrence of PATH_MAX inside our libssh - implementation by calculating the path length from the string length of - the two components. + The new field in the Curl_handler struct still lacks documentation. This + adds it it from the information extracted from lib/urldata.h:797 - Closes #6829 + Closes #7091 -Daniel Stenberg (5 Apr 2021) -- http_proxy: only loop on 407 + close if we have credentials +- [Marc Aldorasi brought this change] + + config: remove now-unused macros - ... to fix the retry-loop. + Closes #7094 + +- [Marc Aldorasi brought this change] + + hostip.h: remove declaration of unimplemented function - Add test 718 to verify. + Closes #7094 + +- h3: add 'attach' callback to protocol handlers - Reported-by: Daniel Kurečka - Fixes #6828 - Closes #6850 + Follow-up to 0c55fbab45be + + Reviewed-by: Emil Engler + Closes #7090 -- h2: allow 100 streams by default +- wolfssl: remove SSLv3 support leftovers - instead of 13, before the server has told how many streams it - accepts. The server can always reject new streams anyway if we go above - what it accepts. + Closes #7088 + +- curl-wolfssl.m4: without custom include path, assume /usr/include - Ref: #6826 - Closes #6852 + ... so that we can point out the root of the OpenSSL emulation headers. + Previously this used the '$includedir' variable which is wrong since + that defaults to the dir where the current configure invoke will install + the built libcurl headers: /usr/local by default. + + Fixes #7085 + Reported-by: Joel Jakobsson + Closes #7087 -- [Luke Granger-Brown brought this change] +- [Joel Depooter brought this change] - file: support GETing directories again + data_pending: check only SECONDARY socket for FTP(S) transfers - After 957bc1881e686f9714c4e6a01bf33535091f0e21, we no longer compute an - expected_size for directories. This has the upshot that when we compare - even an empty Range with the available size, we fail. + Check the FIRST for all other protocols. - This brings back the previous behaviour, which was to succeed, but with - empty content. This also removes the "Accept-ranges: bytes" header, - which is nonsensical on directories. + This fixes a timeout in an ftps download. The server sends a TLS + close_notify message in the same packet as the file data. The + close_notify seems to not be handled in the schannel_recv function, so + libcurl is not aware that the server has closed the connection. Thus + libcurl ends up waiting for action on the socket until a timeout is + reached. With the secondary socket check added to the data_pending + function, the close_notify is properly handled, and the ftps transfer + terminates as expected. - Adds test 3016 - Fixes #6845 - Closes #6846 + Fixes #7068 + Closes #7069 -- RELEASE-NOTES: synced +- github: inhibit deprecated declarations for clang on macOS - and bumped to 7.76.1 + ... as they otherwise cause ldap build errors in the CI. + + Fixes #7081 + Closes #7082 -- TLS: fix HTTP/2 selection +- conn: add 'attach' to protocol handler, make libssh2 use it - for GnuTLS, BearSSL, mbedTLS, NSS, SChannnel, Secure Transport and - wolfSSL... + The libssh2 backend has SSH session associated with the connection but + the callback context is the easy handle, so when a connection gets + attached to a transfer, the protocol handler now allows for a custom + function to get used to set things up correctly. - Regression since 88dd1a8a115b1f5ece (shipped in 7.76.0) - Reported-by: Kenneth Davidson - Reported-by: romamik om github - Fixes #6825 - Closes #6827 + Reported-by: Michael O'Farrell + Fixes #6898 + Closes #7078 -Jay Satiro (2 Apr 2021) -- hostip: Fix for builds that disable all asynchronous DNS +- http2: make sure pause is done on HTTP - - Define Curl_resolver_error function only when USE_CURL_ASYNC. + Since the function is called for any protocol, we can't assume that the + HTTP struct is there without first making sure it is HTTP. - Prior to this change building curl without an asynchronous resolver - backend (c-ares or threaded) and without DoH (DNS-over-HTTPS, which is - also asynchronous but independent of resolver backend) would cause a - build error since Curl_resolver_error is called by and evaluates - variables only available in asynchronous builds. + Reported-by: Denis Goleshchikhin + Fixes #7079 + Closes #7080 + +- docs: cookies from HTTP headers need domain set - Reported-by: Benbuck Nason + ... or the cookies won't get sent. Push users to using the "Netscape" + format instead, which curl uses when saving a cookie "jar". - Fixes https://github.com/curl/curl/issues/6831 - Closes https://github.com/curl/curl/pull/6832 + Reported-by: Martin Dorey + Reviewed-by: Daniel Gustafsson + Fixes #6723 + Closes #7077 -Daniel Stenberg (31 Mar 2021) -- [Gilles Vollant brought this change] +- RELEASE-NOTES: synced - openssl: Fix CURLOPT_SSLCERT_BLOB without CURLOPT_SSLCERT_KEY +- github: add a workflow with libssh2 on macOS using cmake - Reported-by: Christian Schmitz - Fixes #6816 - Closes #6820 - -Version 7.76.0 (31 Mar 2021) + Closes #7047 -Daniel Stenberg (31 Mar 2021) -- RELEASE-NOTES: synced +- sws: allow HTTP requests up to 2MB in size - curl 7.76.0 release - -- THANKS: added names from 7.76.0 + To allow tests with slightly larger payloads. Like #7071 ... + + Closes #7075 -- CURLOPT_AUTOREFERER.3: clarify that it sets the full URL +Marc Hoersken (16 May 2021) +- CI/azure: increase verbosity and fix outdated task names - ... some users may not want that! + Closes #7063 -- define: remove CURL_DISABLE_NTLM ifdefs +- CI/cirrus: add shared and static Windows release builds - It was never defined anywhere. Fixed disable-scan (test 1165) to also - scan headers, which found this issue. + Azure Pipelines is currently being used for debug builds, + let's also run some non-debug (release) Windows builds and + make use of previously underutilized Cirrus CI for that. - Closes #6809 + Reviewed-by: Marcel Raad + + Closes #6991 -- vtls: fix addsessionid for non-proxy builds +Daniel Stenberg (16 May 2021) +- CURLOPT_CAPATH.3: defaults to a path, not NULL - Follow-up to b09c8ee15771c61 - Fixes #6812 - Closes #6811 + Reported-by: Andrew Barnert + + Closes #7062 -- [Li Xinwei brought this change] +- [Jacob Hoffman-Andrews brought this change] - cmake: support WinIDN + c-hyper: handle body on HYPER_TASK_EMPTY - Closes #6807 - -- transfer: clear 'referer' in declaration + Some of the time, we get a HYPER_TASK_EMPTY response before the status + line, headers, and body have been read. Previously, that would cause us + to poll again, leading to a 1 second timeout. - To silence (false positive) compiler warnings about it. + The HYPER_TASK_EMPTY docs say: - Follow-up to 7214288898f5625 + The value of this task is null (does not imply an error). - Reviewed-by: Marcel Raad - Closes #6810 + So, if we receive a HYPER_TASK_EMPTY, continue on with processing the + response. + + Reported-by: Kevin Burke + Fixes #7064 + Closes #7070 -- [Marc Hoersken brought this change] +- [Ikko Ashimine brought this change] - config: fix SSPI enabling NTLM if crypto auth is disabled + tool_getparam: fix comment typo in tool_getparam.c - Avoid enabling NTLM feature based upon Windows SSPI - being enabled in case that crypto auth is disabled. + enfore -> enforce - Reported-by: Marcel Raad + Closes #7074 + +- mem-include-scan.pl: require a non-word letter before memory funcs - Follow-up to #6277 - Fixes #6803 - Closes #6808 + ... so that ldap_memfree() for example doesn't match the scan for free. + + Closes #7061 -- HISTORY: add two 2021 events +- version: free the openldap info correctly + + ... to avoid memory leaks. + + Follow-up to: bf0feae7768d9 + Closes #7061 -- vtls: add 'isproxy' argument to Curl_ssl_get/addsessionid() +- dupset: remove totally off comment - To make sure we set and extract the correct session. + Closes #7067 + +- configure: if asked for, fail if ldap is not found - Reported-by: Mingtao Yang - Bug: https://curl.se/docs/CVE-2021-22890.html + Reported-by: Jakub Zakrzewski + Fixes #7053 + Closes #7055 + +- version: add OpenLDAP version in the output - CVE-2021-22890 + Assisted-by: Howard Chu + Closes #7054 -- [Viktor Szakats brought this change] +Jay Satiro (13 May 2021) +- [Joel Depooter brought this change] - transfer: strip credentials from the auto-referer header field + schannel: Ensure the security context request flags are always set - Added test 2081 to verify. + As of commit 54e7475, these flags would only be set when using a new + credential handle. When re-using an existing credential handle, the + flags would not be set. - CVE-2021-22876 + Closes https://github.com/curl/curl/pull/7051 + +Dan Fandrich (12 May 2021) +- tests: Fix some tag matching issues in a number of tests + +Daniel Stenberg (12 May 2021) +- sasl: use 'unsigned short' to store mechanism - Bug: https://curl.se/docs/CVE-2021-22876.html + ... saves a few bytes of struct size in memory and it only uses + 10 bits anyway. + + Closes #7045 -- curl_sasl: fix compiler error with --disable-crypto-auth +- hostip: remove the debug code for LocalHost - ... if libgsasl was found. + The Curl_resolv() had special code (when built in debug mode) for when + resolving the host name "LocalHost" (using that exact casing). It would + then get the host name from the --interface option instead. - Closes #6806 + This development-only feature was not used by anything (anymore) and we + have the --resolve feature if we want to play similar tricks properly + going forward. + + Closes #7044 -- [Patrick Monnerat brought this change] +- progress: reset limit_size variables at transfer start + + Otherwise the old value would linger from a previous use and would mess + up the network speed cap logic. + + Reported-by: Ymir1711 on github + + Fixes #7042 + Closes #7043 - ldap: only set the callback ptr for TLS context when TLS is used +- RELEASE-NOTES: synced + +- [Daniel Gustafsson brought this change] + + cookies: use CURLcode for cookie_output reporting - Follow-up to a5eee22e594c2460f - Fixes #6804 - Closes #6805 + Writing the cookie file has multiple error conditions, and was using an + int with magic numbers to report the different error (which in turn were + disregarded anyways). This moves reporting to use a CURLcode value. + + Lightly-touched-by: Daniel Stenberg + + Closes #7037 + Closes #6749 -- copyright: update copyright year ranges to 2021 +- [Daniel Gustafsson brought this change] + + cookies: make use of string duplication function - Reviewed-by: Emil Engler - Closes #6802 + strstore() is defined as a strdup which ensures to free the target + pointer before duping the source char * into it. Make use of it in + two more cases where it can simplify the code. -- send_speed: simplify the checks for if a speed limit is set +- [Daniel Gustafsson brought this change] + + cookies: refactor comments - ... as we know the value cannot be set to negative: enforced by - setopt() + Comments in the cookie code were a bit all over the place in terms of + style and wording. This takes a stab at cleaning them up by keeping to + a single style and overall shape. Some comments are moved a little and + some removed alltogether due to being redundant. No functional changes + have been made, -- http: cap body data amount during send speed limiting +- [Peng-Yu Chen brought this change] + + http2: skip immediate parsing of payload following protocol switch - By making sure never to send off more than the allowed number of bytes - per second the speed limit logic is given more room to actually work. + This is considered not harmful as a following http2_recv shall be + called very soon. - Reported-by: Fabian Keil - Bug: https://curl.se/mail/lib-2021-03/0042.html - Closes #6797 + This is considered helpful in the specific situation where some + servers (e.g. nghttpx v1.43.0) may fulfill stream 1 immediately + following the return of HTTP status 101, other than waiting for + the client-side connection preface to arrive. + + Fixes #7036 + Closes #7040 -- urldata: merge "struct DynamicStatic" into "struct UrlState" +- [Peng-Yu Chen brought this change] + + http2: use nghttp2_session_upgrade2 instead of nghttp2_session_upgrade - Both were used for the same purposes and there was no logical separation - between them. Combined, this also saves 16 bytes in less holes in my - test build. + Following the upstream deprecation of nghttp2_session_upgrade. - Closes #6798 - -- tests/README.md: mentioned that en_US.UTF-8 is required + Also provides further checks for requests with the HEAD method. - Reported-by: Oumph on github - Fixes #6768 + Closes #7041 -- HISTORY: fixed the Mac OS X 10.1 release date +- progress/trspeed: use a local convenient pointer to beautify code - Based on what Wikipedia says + The function becomes easier to read and understand with less repetition. -Jay Satiro (26 Mar 2021) -- examples: Remove threaded-shared-conn.c due to bug +- trspeed: use long double for transfer speed calculation + +- progress: move transfer speed calc into function - Known bug 11.11 is the shared object's connection cache is not thread - safe, so we should not have an example for it. + This silences two scan-build-11 warnings: "The result of the '/' + expression is undefined" - Ref: https://github.com/curl/curl/issues/4915 - Ref: https://curl.se/docs/knownbugs.html#A_shared_connection_cache_is_not + Bug: https://curl.se/mail/lib-2021-05/0022.html + Closes #7035 + +- [Cameron Cawley brought this change] + + openssl: remove unneeded cast for CertOpenSystemStore() - Closes https://github.com/curl/curl/pull/6795 + Closes #7025 -- KNOWN_BUGS: Update 11.9 - DoH option inheritance +- travis: disable the libssh build - - Add description: Explain that some options aren't inherited because - they are not relevant for the DoH SSL connections or may result in - unexpected behavior. + It can't run on focal and causes warnings on bionic. Since the focal + failure started rather suddenly a while ago, we can suspect it might be + temporary. - - Remove the reference to #4578 (SSL verify options not inherited) since - that was fixed by #6597 (separate DoH-specific options for verify). + Added "bring back the build" to the TODO document. - - Explain that DoH-specific options (those created by #6597) are - available: CURLOPT_DOH_SSL_VERIFYHOST, CURLOPT_DOH_SSL_VERIFYPEER and - CURLOPT_DOH_SSL_VERIFYSTATUS. + Fixes #7011 + Closes #7012 + +- [Peng-Yu Chen brought this change] + + http: use calculated offsets inst of integer literals for header parsing - - Add a reference to #6605 and explain that the user's debug function is - not inherited because it would be unexpected to pass internal handles - (ie DoH handles) to the user's callback. + Assumed to be a minor coding style improvement with no behavior change. - Closes https://github.com/curl/curl/issues/6605 + A modern compiler is expected to have the calculation optimized during + compilation. It may be deemed okay even if that's not the case, since + the added overhead is considered very low. + + Closes #7032 -Daniel Stenberg (26 Mar 2021) -- curl_easy_setopt.3: add curl_easy_option* functions to SEE ALSO +- [Peng-Yu Chen brought this change] -- [Jean-Philippe Menil brought this change] + GIT-INFO: suggest using autoreconf instead of buildconf + + Follow-up to 85868537d + + Closes #7033 - openssl: ensure to check SSL_CTX_set_alpn_protos return values +- http: deal with partial CONNECT sends - SSL_CTX_set_alpn_protos() return 0 on success, and non-0 on failure + Also added 'CURL_SMALLSENDS' to make Curl_write() send short packets, + which helped verifying this even more. - Signed-off-by: Jean-Philippe Menil + Add test 363 to verify. - Closes #6794 + Reported-by: ustcqidi on github + Fixes #6950 + Closes #7024 -- multi: close the connection when h2=>h1 downgrading +- HTTP3: make the ngtcp2 build use the quictls fork - Otherwise libcurl is likely to reuse the connection again in the next - attempt since the connection reuse logic doesn't take downgrades into - account. + ... as ngtcp2 itself documents the build this way. - Reported-by: Anthony Ramine - Fixes #6788 - Closes #6793 + Closes #7031 -- openssl: set the transfer pointer for logging early +- http: limit the initial send amount to used upload buffer size - Otherwise, the transfer will be NULL in the trace function when the - early handshake details arrive and then curl won't show them. + Previously this logic would cap the send to CURL_MAX_WRITE_SIZE bytes, + but for the situations where a larger upload buffer has been set, this + function can benefit from sending more bytes. With default size used, + this does the same as before. - Regresssion in 7.75.0 + Also changed the storage of the size to an 'unsigned int' as it is not + allowed to be set larger than 2M. - Reported-by: David Hu - Fixes #6783 - Closes #6792 + Also added cautions to the man pages about changing buffer sizes in + run-time. + + Closes #7022 - RELEASE-NOTES: synced -- TODO: Custom progress meter update interval +- ngtcp2: fix the cb_acked_stream_data_offset proto - Ref: https://stackoverflow.com/q/66789977/93747 + The 'datalen' value should be 64 bit, not size_t! + + Reported-by: Dmitry Karpov + Bug: https://curl.se/mail/lib-2021-05/0019.html + Closes #7027 -- docs/ABI: tighten up the language +- progress: when possible, calculate transfer speeds with microseconds - Make the promises more firm + ... this improves precision, especially for transfers in the few or even + sub millisecond range. - Closes #6786 + Reported-by: J. Bromley + Fixes #7017 + Closes #7020 -- openldap: disconnect better +- http: reset the header buffer when sending the request - Instead of clearing the callback argument in disconnect, set it to the - (new) transfer to make sure the correct data is passed to the callbacks. + A reused transfer handle could otherwise reuse the previous leftover + buffer and havoc would ensue. - Follow-up to e467ea3bd937f38 - Assisted-by: Patrick Monnerat - Closes #6787 + Reported-by: sergio-nsk on github + Fixes #7018 + Closes #7021 -- libssh2: kdb_callback: get the right struct pointer +- curl_mprintf.3: add description - After the recent conn/data refactor in this source file, this function - was mistakenly still getting the old struct pointer which would lead to - crash on servers with keyboard-interactive auth enabled. - - Follow-up to a304051620b92e12b (shipped in 7.75.0) + These functions have existed in the API since the dawn of time. It is + about time we describe how they work, even if we discourage users from + using them. - Reported-by: Christian Schmitz - Fixes #6691 - Closes #6782 + Closes #7010 -- tftp: remove unused struct fields +- [Timothy Gu brought this change] + + URL-SYNTAX: update IDNA section for WHATWG spec changes - Follow-up to d3d90ad9c00530d + WHATWG URL has dictated the use of Nontransitional Processing (IDNA + 2008) for several years now. Chrome (and derivatives) still use + Transitional Processing, but Firefox and Safari have both switched. - Closes #6781 + Also document the fact that winidn functions differently from libidn2 + here. + + Closes #7026 -- openldap: avoid NULL pointer dereferences +- [Calvin Buckley brought this change] + + INSTALL: add IBM i specific quirks - Follow-up to a59c33ceffb8f78 - Reported-by: Patrick Monnerat - Fixes #6676 - Closes #6780 + Fixes #6830 + Closes #7013 -- http: strip default port from URL sent to proxy +- libcurl.3: mention the URL API - To make sure the Host: header and the URL provide the same authority - portion when sent to the proxy, strip the default port number from the - URL if one was provided. + To make it easier to find. Also a minor polish of libcurl-url.3 - Reported-by: Michael Brown - Fixes #6769 - Closes #6778 + Closes #7009 -- azure: disable test 433 on azure-ubuntu +- GnuTLS: don't allow TLS 1.3 for versions that don't support it - Something in that environment sets XDG_CONFIG_HOME for us in a way that - breaks the test. + Follow-up to 781864bedbc5 - Reported-by: Marc Hörsken - Fixes #6739 - Closes #6777 + ... as they don't understand it and will return error at us! + + Closes #7014 -- tftp: remove the 3600 second default timeout +Kamil Dudka (6 May 2021) +- tool_getparam: handle failure of curlx_convert_tchar_to_UTF8() - ... it was never meant to be there. + Reported by GCC analyzer: - Reported-by: Tomas Berger - Fixes #6774 - Closes #6776 + Error: GCC_ANALYZER_WARNING (CWE-476): + src/tool_getparam.c: scope_hint: In function 'parse_args' + src/tool_getparam.c:2318:38: warning[-Wanalyzer-possible-null-dereference]: dereference of possibly-NULL 'orig_opt' + lib/curlx.h:56: included_from: Included from here. + src/tool_getparam.c:28: included_from: Included from here. + lib/curl_multibyte.h:70:51: note: in definition of macro 'curlx_convert_tchar_to_UTF8' + src/tool_getparam.c:2316:16: note: in expansion of macro 'curlx_convert_tchar_to_UTF8' + + Reviewed-by: Marcel Raad + Reviewed-by: Daniel Stenberg + Closes #7023 -- docs: make gen.pl support *italic* and **bold** +Daniel Stenberg (6 May 2021) +- scripts/delta: also show total number of days + +Marc Hoersken (5 May 2021) +- sockfilt: fix invalid increment of handles index variable nfd - Remove some nroffisms from the cmdline doc files to simplify editing, - and instead support this markdown style. + Only increment the array index if we actually stored a handle. - Closes #6771 + Follow up to e917492048f4b85a0fd58a033d10072fc7666c3b + Closes #6992 -- ngtcp2: sync with recent API updates +- sockfilt: avoid getting stuck waiting for writable socket - Closes #6770 - -- RELEASE-NOTES: synced + Reset FD_WRITE event using the same approach as in multi.c + + Follow up to b36442b24305f3cda7c13cc64b46838995a4985b + Closes #6992 -- libssh2:ssh_connect: clear session pointer after free +Jay Satiro (5 May 2021) +- test678: Fix for Windows multibyte builds - If libssh2_knownhost_init() returns NULL, like in an OOM situation, the - ssh session was freed but the pointer wasn't cleared which made libcurl - later call libssh2 to cleanup using the stale pointer. + Follow-up to 77fc385 from yesterday. - Fixes #6764 - Closes #6766 + Bug: https://github.com/curl/curl/pull/6662#issuecomment-832966557 + Reported-by: Marc Hörsken -- [Jacob Hoffman-Andrews brought this change] +- [Dmitry Kostjuchenko brought this change] - docs: document version of crustls dependency + build: fix compilation for Windows UWP platform - This also pins a specific release in the Travis test so future - API-breaking changins in crustls won't break curl builds. + - Include afunix.h which is necessary for sockaddr_un when + USE_UNIX_SOCKETS is defined on Windows. - Add RUSTLS documentation to release tarball. + Closes https://github.com/curl/curl/pull/7006 + +Daniel Stenberg (5 May 2021) +- gnutls: make setting only the MAX TLS allowed version work - Enable running tests for rustls, minus FTP tests (require - connect_blocking, which rustls doesn't implement) and 313 (requires CRL - handling). + Previously, settting only the max allowed TLS version, leaving the + minimum one at default, didn't actually set it and left it to default + (TLS 1.3) too! - Closes #6763 - -- [Jacob Hoffman-Andrews brought this change] + As a bonus, this change also removes the dead code handling of SSLv3 + since that version can't be set anymore (since eff614fb0242cb). + + Reported-by: Daniel Carpenter + Fixes #6998 + Closes #7000 - rustls: Handle close_notify. +- openldap: replace ldap_ prefix on private functions - If we get a close_notify, treat that as EOF. If we get an EOF from the - TCP stream, treat that as an error (because we should have ended the - connection earlier, when we got a close_notify). + Since openldap itself uses that prefix and with OpenĹDAP 2.5.4 (at + least) there's a symbol collision because of that. - Closes #6763 + The private functions now use the 'oldap_' prefix where it previously + used 'ldap_'. + + Reported-by: 3eka on github + Fixes #7004 + Closes #7005 -- docs: clarify timeouts for queued transfers in multi API +Jay Satiro (5 May 2021) +- http2: fix potentially uninitialized variable - Closes #6758 + introduced several days ago in 3193170. caught by visual studio linker. -- ftpserver: only load the preprocessed test file +- [Gilles Vollant brought this change] + + SSL: support in-memory CA certs for some backends - We always preprocess and tests are no longer sensible to load "raw" + - New options CURLOPT_CAINFO_BLOB and CURLOPT_PROXY_CAINFO_BLOB to + specify in-memory PEM certificates for OpenSSL, Schannel (Windows) + and Secure Transport (Apple) SSL backends. - Closes #6738 - -- tests: use %TESTNUMBER instead of fixed number + Prior to this change PEM certificates could only be imported from a file + and not from memory. - This makes the tests easier to copy and relocate to other test numbers - without having to update content. + Co-authored-by: moparisthebest@users.noreply.github.com - Closes #6738 - -- KNOWN_BUGS: CURLOPT_OPENSOCKETPAIRFUNCTION is missing + Ref: https://github.com/curl/curl/pull/4679 + Ref: https://github.com/curl/curl/pull/5677 + Ref: https://github.com/curl/curl/pull/6109 - Closes #5747 + Closes https://github.com/curl/curl/pull/6662 -- TODO: provide timing info for each redirect +Daniel Stenberg (4 May 2021) +- [David Cook brought this change] + + tests: ignore case of chunked hex numbers in tests - Closes #6743 + When hyper is used, it emits uppercase hexadecimal numbers for chunked + encoding lengths. Without hyper, lowercase hexadecimal numbers are used. + This change adds preprocessor statements to tests where this is an + issue, and adapts the fixtures to match. + + Closes #6987 -Jay Satiro (17 Mar 2021) -- docs: Add SSL backend names to CURL_SSL_BACKEND +- cmake: check for getppid and utimes - - Document the names that can be used with CURL_SSL_BACKEND: - bearssl, gnutls, gskit, mbedtls, mesalink, nss, openssl, rustls, - schannel, secure-transport, wolfssl + ... as they're checked for in the configure script and are used by + source code. - Ref: https://github.com/curl/curl/issues/2209#issuecomment-360623286 - Ref: https://github.com/curl/curl/issues/6717#issuecomment-800745201 + Removed checks for perror, setvbuf and strlcat since those defines are + not checked for in source code. - Closes https://github.com/curl/curl/pull/6755 + Bonus: removed HAVE_STRLCPY from a few config-*.h files since that + symbol is not used in source code. + + Closes #6997 -- docs: Explain DOH transfers inherit some SSL settings +- libtest: remove lib530.c - - Document in DOH that some SSL settings are inherited but DOH hostname - and peer verification are not and are controlled separately. + Follow up from e50a877df when test 530 was removed. Since then this + source file has not been used/needed. - - Document that CURLOPT_SSL_CTX_FUNCTION is inherited by DOH handles but - we're considering changing behavior to no longer inherit it. Request - feedback. + Closes #6999 + +- FILEFORMAT: mention sectransp as a feature - Closes https://github.com/curl/curl/pull/6688 + Been supported since at least 40259ca65 + + Closes #7001 -Daniel Stenberg (17 Mar 2021) -- http: make 416 not fail with resume + CURLOPT_FAILONERRROR +- RELEASE-NOTES: synced + +- libssh2: ignore timeout during disconnect - When asked to resume a download, libcurl will convert that to HTTP logic - and if then the entire file is already transferred it will result in a - 416 response from the HTTP server. With CURLOPT_FAILONERRROR set in that - scenario, it should *not* lead to an error return. + ... to avoid memory leaks! - Updated test 1156, added test 1273 + libssh2 is tricky as we have to deal with the non-blockiness even in + close and shutdown cases. In the cases when we shutdown after a timeout + already expired, it is crucial that curl doen't let the timeout abort + the shutdown process as that then leaks memory! - Reported-by: Jonathan Watt - Fixes #6740 - Closes #6753 + Reported-by: Benjamin Riefenstahl + Fixes #6990 -- Curl_timeleft: check both timeouts during connect +- KNOWN_BUGS: add two HTTP/2 bugs + +- KNOWN_BUGS: add three HTTP/3 issues - The duration of a connect and the total transfer are calculated from two - different time-stamps. It can end up with the total timeout triggering - before the connect timeout expires and we should make sure to - acknowledge whichever timeout that is reached first. + ... and moved the HTTP/2 issues to its own section - This is especially notable when a transfer first sits in PENDING, as - that time is counted in the total time but the connect timeout is based - on the time since the handle changed to the CONNECT state. + Closes #6606 + Closes #6510 + Closes #6494 + +- [ejanchivdorj brought this change] + + CURLcode: add CURLE_SSL_CLIENTCERT - The CONNECTTIMEOUT is per connect attempt. The TIMEOUT is for the entire - operation. + When a TLS server requests a client certificate during handshake and + none can be provided, libcurl now returns this new error code + CURLE_SSL_CLIENTCERT - Fixes #6744 - Closes #6745 - Reported-by: Andrei Bica - Assisted-by: Jay Satiro - -- configure: remove use of deprecated macros + Only supported by Secure Transport and OpenSSL for TLS 1.3 so far. - AC_HEADER_TIME, AC_HEADER_STDC and AC_TYPE_SIGNAL + Closes #6721 -- configure: make AC_TRY_* into AC_*_IFELSE - - ... as the former versions are deprecated. +- [Tobias Gabriel brought this change] -- configure: s/AC_HELP_STRING/AS_HELP_STRING - - AC_HELP_STRING is deprecated in 2.70+ and I believe AS_HELP_STRING works - already since 2.59 so bump the minimum required version to that. + .github/FUNDING: add link to GitHub sponsors - Reported-by: Emil Engler - Fixes #6647 - Closes #6748 + Closes #6985 -- RELEASE-NOTES: synced +- [Harry Sintonen brought this change] -- travis: use ubuntu nghttp2 package instead of build our own + krb5/name_to_level: replace checkprefix with curl_strequal - Closes #6751 + Closes #6993 -- travis: bump wolfssl to 4.7.0 +- [Harry Sintonen brought this change] -- travis: only build wolfssl when needed + Curl_input_digest: require space after Digest - Closes #6751 + Closes #6993 -- [Jacob Hoffman-Andrews brought this change] +- [Harry Sintonen brought this change] - rustls: allocate a buffer for TLS data. + Curl_http_header: check for colon when matching Persistent-Auth - Previously, rustls was using an on-stack array for TLS data. However, - crustls has an (unusual) requirement that buffers it deals with are - initialized before writing to them. By using calloc, we can ensure the - buffer is initialized once and then reuse it across calls. + Closes #6993 + +- [Harry Sintonen brought this change] + + Curl_http_input_auth: require valid separator after negotiation type - Closes #6742 + Closes #6993 -- travis: add a rustls build +- http: fix the check for 'Authorization' with Bearer - ... that doesn't run any tests (yet) + The code would wrongly check for it using an additional colon. - Closes #6750 - -- HTTP2: remove the outdated remark about multiplexing for the tool + Reported-by: Blake Burkhart + Closes #6988 -- [Robert Ronto brought this change] +- [Kamil Dudka brought this change] - http2: don't set KEEP_SEND when there's no more data to be sent + http2: fix a resource leak in push_promise() - this should fix an issue where curl sometimes doesn't send out a request - with authorization info after a 401 is received over http2 + ... detected by Coverity: - Closes #6747 + Error: RESOURCE_LEAK (CWE-772): + lib/http2.c:532: alloc_fn: Storage is returned from allocation function "duphandle". + lib/http2.c:532: var_assign: Assigning: "newhandle" = storage returned from "duphandle(data)". + lib/http2.c:552: noescape: Resource "newhandle" is not freed or pointed-to in "set_transfer_url". + lib/http2.c:555: leaked_storage: Variable "newhandle" going out of scope leaks the storage it points to. + + Closes #6986 -Marc Hoersken (15 Mar 2021) -- config: fix building SMB with configure using Win32 Crypto +- [Kamil Dudka brought this change] + + http2: fix resource leaks in set_transfer_url() - Align conditions for NTLM features between CMake and configure - builds by differentiating between USE_NTLM and USE_CURL_NTLM_CORE, - just like curl_setup.h does internally to detect support of: + ... detected by Coverity: - - USE_NTLM: required for NTLM crypto authentication feature - - USE_CURL_NTLM_CORE: required for SMB protocol + Error: RESOURCE_LEAK (CWE-772): + lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.] + lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()". + lib/http2.c:486: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.] + lib/http2.c:488: leaked_storage: Variable "u" going out of scope leaks the storage it points to. - Implement USE_WIN32_CRYPTO detection by checking for Crypt functions - in wincrypt.h which are not available in the Windows App environment. + Error: RESOURCE_LEAK (CWE-772): + lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.] + lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()". + lib/http2.c:493: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.] + lib/http2.c:495: leaked_storage: Variable "u" going out of scope leaks the storage it points to. - Link advapi32 and crypt32 for Crypto API and Schannel SSL backend. - Fix condition of Schannel SSL backend in CMake build accordingly. + Error: RESOURCE_LEAK (CWE-772): + lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.] + lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()". + lib/http2.c:500: noescape: Resource "u" is not freed or pointed-to in "curl_url_set". [Note: The source code implementation of the function has been overridden by a builtin model.] + lib/http2.c:502: leaked_storage: Variable "u" going out of scope leaks the storage it points to. - Reviewed-by: Marcel Raad + Error: RESOURCE_LEAK (CWE-772): + lib/http2.c:480: alloc_fn: Storage is returned from allocation function "curl_url". [Note: The source code implementation of the function has been overridden by a builtin model.] + lib/http2.c:480: var_assign: Assigning: "u" = storage returned from "curl_url()". + lib/http2.c:505: noescape: Resource "u" is not freed or pointed-to in "curl_url_get". [Note: The source code implementation of the function has been overridden by a builtin model.] + lib/http2.c:507: leaked_storage: Variable "u" going out of scope leaks the storage it points to. - Closes #6277 + Closes #6986 -- config: fix detection of restricted Windows App environment +- [Jacob Hoffman-Andrews brought this change] + + rustls: use ALPN - Move the detection of the restricted Windows App environment - in curl_setup.h before the definition of USE_WIN32_CRYPTO - via included config-win32.h in case no build system is used. + Update required rustls to 0.5.0 - Reviewed-by: Marcel Raad + Closes #6960 + +- [MAntoniak brought this change] + + gskit: fix CURL_DISABLE_PROXY build - Part of #6277 + Removed localfd and remotefd from ssl_backend_data (ued only with proxy + connection). Function pipe_ssloverssl return always 0, when proxy is not + used. + + Closes #6981 -Daniel Stenberg (15 Mar 2021) -- HISTORY: curl 7.7.2 was the first version used in Mac OS X 10.1 +- [MAntoniak brought this change] -- gen.pl: quote "bare" minuses in the nroff curl.1 + gskit: fix undefined reference to 'conn' - Reported-by: Alejandro Colomar - Fixes #6698 - Closes #6722 + Closes #6980 -Daniel Gustafsson (14 Mar 2021) -- hsts: remove unused defines +- [Jacob Hoffman-Andrews brought this change] + + tls: add USE_HTTP2 define - MAX_HSTS_SUBLEN and MAX_HSTS_SUBLENSTR were unused from the initial commit, - and mostly likely leftovers from early development. Remove as they're not - used for anything. + This abstracts across the two HTTP/2 backends: nghttp2 and Hyper. - Closes #6741 - Reviewed-by: Daniel Stenberg + Add our own define for the "h2" ALPN protocol, so TLS backends can use + it without depending on a specific HTTP backend. + + Closes #6959 -Daniel Stenberg (12 Mar 2021) -- github: add torture-ftp for FTP-only torture testing +- [Jacob Hoffman-Andrews brought this change] + + lib: fix 0-length Curl_client_write calls - and at 20% to try to keep the run-time reasonable + Closes #6954 + +- [Jacob Hoffman-Andrews brought this change] + + lib: remove strlen call from Curl_client_write - Closes #6728 + At all call sites with an explicit 0 len, pass an appropriate nonzero + len. + + Closes #6954 -- travis: split "torture" into a separate "events" build as well +- [Ayushman Singh Chauhan brought this change] + + docs: camelcase it like GitHub everywhere - Run torture without FTP and reducing coverage to 20% + Closes #6979 + +Jay Satiro (27 Apr 2021) +- [Lucas Servén Marín brought this change] + + docs: fix typo in fail-with-body doc - For some reason the torture tests now run a lot slower on travis and run - into the 50 minute limit all the time. + This commit fixes a small typo in the documentation for the + --fail-with-body flag. - Closes #6728 + Closes https://github.com/curl/curl/pull/6977 -- ftp: fix memory leak in ftp_done +- lib: fix some misuse of curlx_convert_UTF8_to_tchar - If after a transfer is complete Curl_GetFTPResponse() returns an error, - curl would not free the ftp->pathalloc block. + curlx_convert_UTF8_to_tchar must be freed by curlx_unicodefree, but + prior to this change some uses mistakenly called free. - Found by torture-testing test 576 + I've reviewed all other uses of curlx_convert_UTF8_to_tchar and + curlx_convert_tchar_to_UTF8. - Closes #6737 - -- [oxalica brought this change] + Bug: https://github.com/curl/curl/pull/6602#issuecomment-825236763 + Reported-by: sergio-nsk@users.noreply.github.com + + Closes https://github.com/curl/curl/pull/6938 - http2: fail if connection terminated without END_STREAM +Daniel Stenberg (27 Apr 2021) +- ntlm: precaution against super huge type2 offsets - Closes #6736 + ... which otherwise caused an integer overflow and circumvented the if() + conditional size check. + + Detected by OSS-Fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33720 + Assisted-by: Max Dymond + Closes #6975 -- RELEASE-NOTES: synced +- c-hyper: fix unused variable ‘wrote’ -- [Jacob Hoffman-Andrews brought this change] +- libcurl-security.3: be careful of setuid + + Reported-by: Harry Sintonen + Closes #6970 - rustls: support CURLOPT_SSL_VERIFYPEER +- [Kevin Burke brought this change] + + c-hyper: don't write to set.writeheader if null - This requires the latest main branch of crustls, which provides - rustls_client_config_builder_dangerous_set_certificate_verifier and - rustls_client_config_builder_set_enable_sni. + Previously if a caller set CURLOPT_WRITEFUNCTION but did not set a + CURLOPT_HEADERDATA buffer, Hyper would still attempt to write headers to + the data->set.writeheader header buffer, even though it is null. This + led to NPE segfaults attempting to use libcurl+Hyper with Git, for + example. - This refactors the session setup into its own function, and adds a new - function cr_hostname_is_ip. Because crustls doesn't support verification - of IP addresses, special handling is needed: We disable SNI and set a - placeholder hostname (which never actually gets sent on the wire). + Instead, process the client write for the status line using the same + logic we use to process the client write for the later HTTP headers, + which contains the appropriate guard logic. As a side benefit, + data->set.writeheader is now only read in one file instead of two. - Closes #6719 + Fixes #6619 + Fixes abetterinternet/crustls#49 + Fixes hyperium/hyper#2438 + Closes #6971 -Daniel Gustafsson (12 Mar 2021) -- cookies: Fix potential NULL pointer deref with PSL +- wolfssl: handle SSL_write() returns 0 for error - Curl_cookie_init can be called with data being NULL, and this can in turn - be passed to Curl_cookie_add, meaning that both functions must be careful - to only use data where it's checked for being a NULL pointer. The libpsl - support code does however dereference data without checking, so if we are - indeed having an unset data pointer we cannot PSL check the cookiedomain. + Reported-by: Timo Lange - This is currently not a reachable dereference, as the only caller with a - NULL data isn't passing a file to initialize cookies from, but since the - API has this contract let's ensure we hold it. + Closes #6967 + +- easy: ignore sigpipe in curl_easy_send - Closes #6731 - Reviewed-by: Daniel Stenberg + Closes #6965 -Daniel Stenberg (12 Mar 2021) -- [Michael Hordijk brought this change] +- sigpipe: ignore SIGPIPE when using wolfSSL as well + + Closes #6966 - configure: only add OpenSSL paths if they are defined +- libcurl-security.3: don't try to filter IPv4 hosts based on the URL - Add paths for OpenSSL compiling and linking only if they have been - defined. If they haven't been defined, we'll assume that the paths are - already available to the toolchain. + Closes #6942 + +- [Harry Sintonen brought this change] + + nss_set_blocking: avoid static for sock_opt - Closes #6730 + Reviewed-by: Kamil Dudka + Closes #6945 -Jay Satiro (12 Mar 2021) -- retry.d: Clarify transient 5xx HTTP response codes +- RELEASE-NOTES: synced + +- [Yusuke Nakamura brought this change] + + docs/HTTP3.md: fix nghttp2's HTTP/3 server port - - Clarify the only 5xx response codes that are treated as transient are - 500, 502, 503 and 504. + Port 8443 does not work now. + Correct origin is in the quicwg's wiki. + https://github.com/quicwg/base-drafts/wiki/Implementations#ngtcp2 - Prior to this change it said it treated all 5xx as transient, but the - code says otherwise. + Closes #6964 + +- krb5: don't use 'static' to store PBSZ size response - Ref: https://github.com/curl/curl/blob/curl-7_75_0/src/tool_operate.c#L462-L495 + ... because it makes the knowledge and usage cross-transfer in funny and + unexpected ways. - Closes https://github.com/curl/curl/pull/6724 + Reported-by: Harry Sintonen + Closes #6963 -- retry-all-errors.d: Explain curl errors versus HTTP response errors +- [Kevin Burke brought this change] + + m4: add security frameworks on Mac when compiling rustls - - Add a paragraph explaining that curl does not consider HTTP response - errors as curl errors, and how that behavior can be modified by using - --retry and --fail. + Previously compiling rustls on Mac would only complete if you also + compiled the SecureTransport TLS backend, which curl would prefer to + the Rust backend. - The --retry-all-errors doc says "Retry on any error" which some users - may find misleading without the added explanation. + Appending these flags to LDFLAGS makes it possible to compile the + Rustls backend on Mac without the SecureTransport backend, which means + this patch will make it possible for Mac users to use the Rustls + backend for TLS. - Ref: https://curl.se/docs/faq.html#Why_do_I_get_downloaded_data_eve - Ref: https://curl.se/docs/faq.html#curl_doesn_t_return_error_for_HT + Reviewed-by: Jacob Hoffman-Andrews - Reported-by: Lawrence Gripper + Fixes #6955 + Cloes #6956 + +- krb5: remove the unused 'overhead' function - Fixes https://github.com/curl/curl/issues/6712 - Closes https://github.com/curl/curl/pull/6720 + Closes #6947 -Daniel Stenberg (11 Mar 2021) -- travis: switch ngtcp2 build over to quictls +- [Johann150 brought this change] + + curl_url_set.3: add memory management information - The ngtcp2 project switched over to using the quictls OpenSSL fork - instead of their own patched OpenSSL. We follow suit. + wording taken from man page for CURLOPT_URL.3 - Closes #6729 + As far as I can see, the URL part is either malloc'ed before due to + encoding or it is strdup'ed. + + Closes #6953 -- test220/314: adjust to run with Hyper +- [Jacob Hoffman-Andrews brought this change] -- c-hyper: support automatic content-encoding + c-hpyer: fix handling of zero-byte chunk from hyper - Closes #6727 + Closes #6951 -- http: remove superfluous NULL assign +- CURLOPT_POSTFIELDS.3: clarify how it gets the size of the data - Closes #6727 + Ref: https://curl.se/mail/lib-2021-04/0085.html + Closes #6943 -- tool_operate: bail if set CURLOPT_HTTP09_ALLOWED returns error +- [Ralph Langendam brought this change] + + cmake: make libcurl output filename configurable - Closes #6727 + Reviewed-by: Jakub Zakrzewski + Closes #6933 -- setopt: error on CURLOPT_HTTP09_ALLOWED set true with Hyper +- [Patrick Monnerat brought this change] + + vtls: reset ssl use flag upon negotiation failure - Not supported. + Fixes the segfault in ldaps disconnect. - Closes #6727 + Reported-by: Illarion Taev + Fixes #6934 + Closes #6937 -- test306: make it not run with Hyper +- configure: fix typo in TLS error message - ... as it tests HTTP/0.9 which Hyper doesn't support. + Reported-by: Pontus Lundkvist -- test304: header CRLF cleanup to work with Hyper +- README: link to the commercial support option -- FTP: allow SIZE to fail when doing (resumed) upload +Jay Satiro (22 Apr 2021) +- [Martin Halle brought this change] + + version: add gsasl_version to curl_version_info_data - Added test 362 to verify. + - Add gsasl_version string and bump to CURLVERSION_TENTH. - Reported-by: Jordan Brown - Regression since 7ea2e1d0c5a7f (7.73.0) - Fixes #6715 - Closes #6725 + Ref: https://curl.se/mail/lib-2021-04/0003.html + + Closes https://github.com/curl/curl/pull/6843 -- configure: provide Largefile feature for curl-config +- [Morten Minde Neergaard brought this change] + + schannel: Support strong crypto option - ... as cmake now does it correctly, and make test1014 check for it + - Support enabling strong crypto via optional user cipher list when + USE_STRONG_CRYPTO or SCH_USE_STRONG_CRYPTO is in the list. - Closes #6702 - -- config: remove CURL_SIZEOF_CURL_OFF_T use only SIZEOF_CURL_OFF_T + MSDN says SCH_USE_STRONG_CRYPTO "Instructs Schannel to disable known + weak cryptographic algorithms, cipher suites, and SSL/TLS protocol + versions that may be otherwise enabled for better interoperability." - Make the code consistently use a single name for the size of the - "curl_off_t" type. + Ref: https://curl.se/mail/lib-2021-02/0066.html + Ref: https://curl.se/docs/manpage.html#--ciphers + Ref: https://curl.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html + Ref: https://docs.microsoft.com/en-us/windows/win32/api/schannel/ns-schannel-schannel_cred - Closes #6702 + Closes https://github.com/curl/curl/pull/6734 -Jay Satiro (10 Mar 2021) -- [Jun-ya Kato brought this change] +Daniel Stenberg (22 Apr 2021) +- RELEASE-NOTES: synced - ngtcp2: Fix build error due to change in ngtcp2_addr_init - - ngtcp2/ngtcp2@b8d90a9 changed the function prototype. - - Closes https://github.com/curl/curl/pull/6716 +- ci: adapt to configure requiring an explicit TLS choice -Daniel Stenberg (10 Mar 2021) -- [ejanchivdorj brought this change] +- configure: split out each TLS library detector into its own function + + ... and put those functions in separate m4 files per TLS library. - multi: update pending list when removing handle +- configure: make the TLS library choice(s) explicit - when removing a handle, most of the lists are updated but pending list - is not updated. Updating now. + configure no longer tries to find a TLS library by default, but all + libraries are now equal: the user needs to explicitly ask what TLS + library or libraries to use. - Closes #6713 + If no TLS library is selected, configure will error out unless + --without-ssl is explicitly used to request a built without TLS (as that + is very rare these days). + + Removes: --with-winssl, --with-darwinssl and all --without-* options for + TLS libraries. + + Closes #6897 -- [kokke brought this change] +- tests/disable-scan.pl: also scan all m4 files + + Fixes test 1165 when functions are moved from configure.ac to files in + m4/ - lib1536: check ptr against NULL before dereferencing it +Jay Satiro (22 Apr 2021) +- schannel: Disable auto credentials; add an option to enable it - Closes #6710 + - Disable auto credentials by default. This is a breaking change + for clients that are using it, wittingly or not. + + - New libcurl ssl option value CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl + to automatically locate and use a client certificate for + authentication, when requested by the server. + + - New curl tool options --ssl-auto-client-cert and + --proxy-ssl-auto-client-cert map to CURLSSLOPT_AUTO_CLIENT_CERT. + + This option is only supported for Schannel (the native Windows SSL + library). Prior to this change Schannel would, with no notification to + the client, attempt to locate a client certificate and send it to the + server, when requested by the server. Since the server can request any + certificate that supports client authentication in the OS certificate + store it could be a privacy violation and unexpected. + + Fixes https://github.com/curl/curl/issues/2262 + Reported-by: Jeroen Ooms + Assisted-by: Wes Hinsley + Assisted-by: Rich FitzJohn + + Ref: https://curl.se/mail/lib-2021-02/0066.html + Reported-by: Morten Minde Neergaard + + Closes https://github.com/curl/curl/pull/6673 -- [kokke brought this change] +Daniel Stenberg (22 Apr 2021) +- [Michał Antoniak brought this change] - lib1537: check ptr against NULL before dereferencing it + vtls: deduplicate some DISABLE_PROXY ifdefs - Fixes #6707 - Closes #6708 - -- travis: make torture tests skip TLS-SRP tests + continue from #5735 - ... as it seems to often hang. + - using SSL_HOST_NAME, SSL_HOST_DISPNAME, SSL_PINNED_PUB_KEY for other + tls backend - Also: skip the "normal" tests as they're already run by many other - builds. + - create SSL_HOST_PORT - Closes #6705 + Closes #6660 -- openssl: adapt to v3's new const for a few API calls +Jay Satiro (22 Apr 2021) +- OS400: fix typo - Closes #6703 + CURLVERSION_HEIGHTH -> CURLVERSION_EIGHTH -- quiche: fix crash when failing to connect +Daniel Stenberg (22 Apr 2021) +- checksrc: complain on == NULL or != 0 checks in conditions - Reported-by: ウさん - Fixes #6664 - Closes #6701 + ... to make them all consistenly use if(!var) and if(var) + + Also added a few missing warnings to the documentation. + + Closes #6912 -- RELEASE-NOTES: synced +- tidy-up: make conditional checks more consistent - Fixed the release counter and added a missing contributor + ... remove '== NULL' and '!= 0' + + Closes #6912 -- RELEASE-NOTES: synced +- [Patrick Monnerat brought this change] -- dynbuf: bump the max HTTP request to 1MB + vauth: factor base64 conversions out of authentication procedures - Raised from 128KB to allow longer request headers. + Input challenges and returned messages are now in binary. + Conversions from/to base64 are performed by callers (currently curl_sasl.c + and http_ntlm.c). - Reported-by: Carl Zogheib - Fixes #6681 - Closes #6685 + Closes #6654 -Jay Satiro (6 Mar 2021) -- schannel: Evaluate CURLOPT_SSL_OPTIONS via SSL_SET_OPTION macro +- [Patrick Monnerat brought this change] + + bufref: buffer reference support - - Change use of those options from CURLOPT_SSL_OPTIONS that are not - already evaluated via SSL_SET_OPTION in schannel and secure transport - to use that instead of data->set.ssl.optname. + A struct bufref holds a buffer pointer, a data size and a destructor. + When freed or its contents are changed, the previous buffer is implicitly + released by the associated destructor. The data size, although not used + internally, allows binary data support. - Example: + A unit test checks its handling methods: test 1661 - Evaluate SSL_SET_OPTION(no_revoke) instead of data->set.ssl.no_revoke. + Closes #6654 + +- [Patrick Monnerat brought this change] + + os400: additional support for options metadata - This change is because options set via CURLOPT_SSL_OPTIONS - (data->set.ssl.optname) are separate from those set for HTTPS proxy via - CURLOPT_PROXY_SSL_OPTIONS (data->set.proxy_ssl.optname). The - SSL_SET_OPTION macro determines whether the connection is for HTTPS - proxy and based on that which option to evaluate. + New functions curl_easy_option_by_name_ccsid() and + curl_easy_option_get_name_ccsid() allows accessing metadata in alternate + character encoding. - Since neither Schannel nor Secure Transport backends currently support - HTTPS proxy in libcurl, this change is for posterity and has no other - effect. + This commit also updates curl_version_info_ccsid() to handle info version 9 + and adds recent definitions to the ILE/RPG include file. - Closes https://github.com/curl/curl/pull/6690 + Documentation updated accordingly. + + Reviewed-by: Jon Rumsey + Closes #6574 -- [kokke brought this change] +- [Patrick Monnerat brought this change] - c-hyper: Remove superfluous pointer check + test server: take care of siginterrupt() deprecation - `n` pointer is never NULL once set. Found by static analysis. + Closes #6529 + +Marc Hoersken (21 Apr 2021) +- lib1564.c: enable last wakeup test part on Windows - Ref: https://github.com/curl/curl/issues/6696 + Suggested-by: Gergely Nagy + Reviewed-by: Jay Satiro + Reviewed-by: Marcel Raad - Closes https://github.com/curl/curl/pull/6697 + Closes #6245 -- version.d: Add missing features to the features list +- multi: fix slow write/upload performance on Windows - - Add missing entries for gsasl, Kerberos, NTLM_WB, TrackMemory, - Unicode and zstd. + Reset FD_WRITE by sending zero bytes which is permissible + and will be treated by implementations as successful send. - - Remove krb4 since it's no longer a feature. + Without this we won't be notified in case a socket is still + writable if we already received such a notification and did + not send any data afterwards on the socket. This would lead + to waiting forever on a writable socket being writable again. - Reported-by: Ádler Jonas Gross + Assisted-by: Tommy Odom + Reviewed-by: Jay Satiro + Reviewed-by: Marcel Raad + Tested-by: tmkk on github - Fixes https://github.com/curl/curl/issues/6677 - Closes https://github.com/curl/curl/pull/6687 - -- [Vladimir Varlamov brought this change] + Bug: #6146 + Closes #6245 - docs: add missing Arg tag to --stderr +- multi: reduce Win32 API calls to improve performance - Prior to this change the required argument was not shown. + 1. Consolidate pre-checks into a single Curl_poll call: - curl.1 before: --stderr - curl.1 after: --stderr + This is an attempt to restructure the code in Curl_multi_wait + in such a way that less syscalls are made by removing individual + calls to Curl_socket_check via SOCKET_READABLE/SOCKET_WRITABLE. - curl --help before: - --stderr Where to redirect stderr + 2. Avoid resetting the WinSock event multiple times: - curl --help after: - --stderr Where to redirect stderr + We finally call WSAResetEvent anyway, so specifying it as + an optional parameter to WSAEnumNetworkEvents is redundant. - Closes https://github.com/curl/curl/pull/6692 + 3. Wakeup directly in case no sockets are being monitoring: + + Fix the WinSock based implementation to skip extra waiting by + not sleeping in case no sockets are to be waited on and just + the WinSock event is being monitored for wakeup functionality. + + Assisted-by: Tommy Odom + Reviewed-by: Jay Satiro + Reviewed-by: Marcel Raad + + Bug: #6146 + Closes #6245 -- projects: Update VS projects for OpenSSL 1.1.x +- Revert "Revert 'multi: implement wait using winsock events'" - - Update VS project templates to use the OpenSSL lib names and include - directories for OpenSSL 1.1.x. + This reverts commit 2260e0ebe6d45529495231b3e37a0c58fb92a6a2, + also restoring previous follow up changes which were reverted. - This change means the VS project files will now build only with OpenSSL - 1.1.x when an OpenSSL configuration is chosen. Prior to this change the - project files built only with OpenSSL 1.0.x (end-of-life) when an - OpenSSL configuration was chosen. + Authored-by: rcombs on github + Authored-by: Marc Hörsken + Reviewed-by: Jay Satiro + Reviewed-by: Marcel Raad - The template changes in this commit were made by script: + Restores #5634 + Reverts #6281 + Part of #6245 + +Daniel Stenberg (21 Apr 2021) +- Revert "cmake: make libcurl library output name configurable" - libeay32.lib => libcrypto.lib - ssleay32.lib => libssl.lib - ..\..\..\..\..\openssl\inc32 => ..\..\..\..\..\openssl\include + This reverts commit 1cba36d2166c396f987eea587cf92671b27acb92. - And since the output directory now contains the includes it's prepended: - ..\..\..\..\..\openssl\build\Win{32,64}\VC{6..15}\{DLL,LIB} - {Debug,Release}\include + CMake provides properties that can be set on a target to rename the + output artifact without changing the name of a target. - - Change build-openssl.bat to copy the build's include directory to the - output directory (as seen above). + Ref: #6899 + +- [Michael Kolechkin brought this change] + + sectransp: allow cipher name to be specified - Each build has its own opensslconf.h which is different so we can't just - include the source include directory any longer. + Add parser for CURLOPT_SSL_CIPHER_LIST option for Secure Transport (ST) + back-end. Similar to NSS and GSKit back-ends, new code parses string + value and configures ST library to use those ciphers for communication. + Create cipher spec data structure and initialize the array of specs with + cipher number, name, alias, and 'weak' flag. - Note the include directory in the output directory is a full copy from - the build so technically we don't need to include the OpenSSL source - include directory in the template. However, I left it last in case the - user made a custom OpenSSL build using the old method which would put - opensslconf in the OpenSSL source include directory. + Mark triple-DES ciphers as 'weak', and exclude them from the default + ciphers list. - - Change build-openssl.bat to use a temporary install directory that is - different from the temporary build directory. + Closes #6464 + +- [Michael Kolechkin brought this change] + + NSS: add ciphers to map - For OpenSSL 1.1.x the temporary paths must be separate not a descendant - of the other, otherwise pdb files will be lost between builds. + Add cipher names to the `cipherlist` map, based on the list of ciphers + implemented by the NSS in the source code file + https://github.com/nss-dev/nss/blob/master/lib/ssl/sslenum.c - Ref: https://curl.se/mail/lib-2018-10/0049.html - Ref: https://gist.github.com/jay/125191c35bbeb894444eff827651f755 - Ref; https://github.com/openssl/openssl/issues/10005 + Closes #6670 + +- http2: remove DEBUG_HTTP2 - Fixes https://github.com/curl/curl/issues/984 - Closes https://github.com/curl/curl/pull/6675 + Accidentally committed in 605e84235 -- doh: Inherit CURLOPT_STDERR from user's easy handle +- [Ralph Langendam brought this change] + + cmake: make libcurl library output name configurable - Prior to this change if the user set their easy handle's error stream - to something other than stderr it was not inherited by the doh handles, - which meant that they would still write to the default standard error - stream (stderr) for verbose output. + Closes #6899 + +- sws: #ifdef S_IFSOCK use - Bug: https://github.com/curl/curl/issues/6605 - Reported-by: arvids-kokins-bidstack@users.noreply.github.com + SCO OpenServer 5.0.7 does not define S_IFSOCK. - Closes https://github.com/curl/curl/pull/6661 + Reported-by: Kevin R. Bulgrien + Bug: https://curl.se/mail/lib-2021-04/0074.html + Closes #6926 -Marc Hoersken (1 Mar 2021) -- CI/azure: replace python-impacket with python3-impacket +- curl_setup: provide the shutdown flags wider - As of this month Azure DevOps uses Ubuntu 20.04 LTS which - no longer supports Python 2 and instead ships Python 3. + By using #ifdef on the symbol names to work on anything that don't + provide them. SCO OpenServer 5.0.7, sys/socket.h does not define either + SHUT_RDWR, SHUT_RD, and SHUT_WR. - Closes #6678 + Reported-by: Kevin R. Bulgrien + Bug: https://curl.se/mail/lib-2021-04/0073.html + Closes #6925 -- runtests.pl: kill processes locking test log files +- connect: use CURL_SA_FAMILY_T for portability - Introduce a new runtests.pl command option: -rm + Reported-by: Kevin R. Bulgrien + Bug: https://curl.se/mail/lib-2021-04/0071.html - For now only required and implemented for Windows. - Ignore stunnel logs due to long running processes. + Closes #6918 + +- urlapi: make sure no +/- signs are accepted in IPv4 numericals - Requires Sysinternals handle[64].exe to be on PATH. + Follow-up to 56a037cc0ad1b2. Extends test 1560 to verify. - Reviewed-by: Jay Satiro + Reported-by: Tuomas Siipola + Fixes #6916 + Closes #6917 + +- ConnectionExists: respect requests for h1 connections better - Ref: #6058 - Closes #6179 + ... for situations when multiplexing isn't enabled on the h2 connection + and h1 is explicitly requested for the transfer. + + Assisted-by: Gergely Nagy -- pathhelp.pm: fix use of pwd -L in Msys environment +- multi: don't close connection HTTP_1_1_REQUIRED - While Msys2 has a pwd binary which supports -L, - Msys1 only has a shell built-in with that feature. + The ConnectionExists() function will note that the new transfer wants + less then h2 and that it can't multiplex it and therefor opt to open a + new connection instead. + +- http2: move the stream error field to the per-transfer storage - Reviewed-by: Jay Satiro + Storing a stream error in the per-connection struct was an error that lead to + race conditions as subsequent stream handling could overwrite the error code + before it was used for the stream with the actual problem. - Part of #6179 + Closes #6910 -Daniel Gustafsson (1 Mar 2021) -- ldap: use correct memory free function +- http2: call the handle-closed function correctly on closed stream - unescaped is coming from Curl_urldecode and not a unicode conversion - function, so reclaiming its memory should be performed with a normal - call to free rather than curlx_unicodefree. In reality, this is the - same thing as curlx_unicodefree is implemented as a call to free but - that's not guaranteed to always hold. Using the curlx macro present - issues with memory debugging as well. + This was this one condition where the stream could be closed due to an + error and the function would still wrongly just return 0 for it. - Closes #6671 - Reviewed-by: Jay Satiro - Reviewed-by: Daniel Stenberg + Reported-by: Gergely Nagy + Fixes #6862 + Closes #6910 -- url: fix typo in comment +- test1660: check the created HSTS file as text mode - Correct a small typo which snuck in with a304051620. + Closes #6922 -Jay Satiro (28 Feb 2021) -- tool_help: Increase space between option and description +- RELEASE-NOTES: synced + +- test 493: require https in curl to run - - Increase the minimum number of spaces between the option and the - description from 1 to 2. + Closes #6927 + +Jay Satiro (20 Apr 2021) +- tool_operate: don't discard failed parallel transfer result + + - Save a parallel transfer's result code only when it fails and the + transfer is not being retried. + + Prior to this change the result code was always set which meant that a + failed result could be erroneously discarded if a different transfer + later had a successful result (CURLE_OK). Before: - ~~~ - -u, --user Server user and password - -A, --user-agent Send User-Agent to server - -v, --verbose Make the operation more talkative - -V, --version Show version number and quit - -w, --write-out Use output FORMAT after completion - --xattr Store metadata in extended file attributes - ~~~ - After: - ~~~ - -u, --user Server user and password - -A, --user-agent Send User-Agent to server - -v, --verbose Make the operation more talkative - -V, --version Show version number and quit - -w, --write-out Use output FORMAT after completion - --xattr Store metadata in extended file attributes - ~~~ + > curl --fail -Z https://httpbin.org/status/404 https://httpbin.org/delay/10 + > echo %ERRORLEVEL% + 0 - Closes https://github.com/curl/curl/pull/6674 - -Daniel Stenberg (27 Feb 2021) -- curl: set CURLOPT_NEW_FILE_PERMS if requested + After: - The --create-file-mode code logic accepted the value but never actually - passed it on to libcurl! + > curl --fail -Z https://httpbin.org/status/404 https://httpbin.org/delay/10 + > echo %ERRORLEVEL% + 22 - Follow-up to a7696c73436f (shipped in 7.75.0) - Reported-by: Johannes Lesr - Fixes #6657 - Closes #6666 + Closes #xxxx -- tool_operate: check argc before accessing argv[1] +- [Georeth Zhou brought this change] + + openssl: fix build error with OpenSSL < 1.0.2 - Follow-up to 09363500b - Reported-by: Emil Engler - Reviewed-by: Daniel Gustafsson - Closes #6668 + Closes https://github.com/curl/curl/pull/6920 -Daniel Gustafsson (26 Feb 2021) -- [Jean-Philippe Menil brought this change] +Viktor Szakats (19 Apr 2021) +- README.md: delete Codacy UTM parameters & follow permanent redirect [ci skip] + + UTM parameters leak referrer and various marketing/tracking information + even if these would normally be stripped by website or client policy. + This link also works fine without them. Also took the opportunity to + update the URL to the one pointed to by the previous one via permanent + redirect. + + Reviewed-by: Daniel Stenberg + Closes #6919 - openssl: remove get_ssl_version_txt in favor of SSL_get_version +Daniel Stenberg (19 Apr 2021) +- urlapi: "normalize" numerical IPv4 host names - openssl: use SSL_get_version to get connection protocol + When the host name in a URL is given as an IPv4 numerical address, the + address can be specified with dotted numericals in four different ways: + a32, a.b24, a.b.c16 or a.b.c.d and each part can be specified in + decimal, octal (0-prefixed) or hexadecimal (0x-prefixed). - Replace our bespoke get_ssl_version_txt in favor of SSL_get_version. - We can get rid of few lines of code, since SSL_get_version achieve - the exact same thing + Instead of passing on the name as-is and leaving the handling to the + underlying name functions, which made them not work with c-ares but work + with getaddrinfo, this change now makes the curl URL API itself detect + and "normalize" host names specified as IPv4 numericals. - Closes #6665 - Reviewed-by: Daniel Gustafsson - Signed-off-by: Jean-Philippe Menil - -- gnutls: Fix nettle discovery + The WHATWG URL Spec says this is an okay way to specify a host name in a + URL. RFC 3896 does not allow them, but curl didn't prevent them before + and it seems other RFC 3896-using tools have not either. Host names used + like this are widely supported by other tools as well due to the + handling being done by getaddrinfo and friends. - Commit e06fa7462ac258c removed support for libgcrypt leaving only - support for nettle which has been the default crypto library in - GnuTLS for a long time. There were however a few conditionals on - USE_GNUTLS_NETTLE which cause compilation errors in the metalink - code (as it used the gcrypt fallback instead as a result). See the - below autobuild for an example of the error: + I decided to add the functionality into the URL API itself so that all + users of these functions get the benefits, when for example wanting to + compare two URLs. Also, it makes curl built to use c-ares now support + them as well and make curl builds more consistent. - https://curl.se/dev/log.cgi?id=20210225123226-30704#prob1 + The normalization makes HTTPS and virtual hosted HTTP work fine even + when curl gets the address specified using one of the "obscure" formats. - This removes all uses of USE_GNUTLS_NETTLE and also removes the - gcrypt support from the metalink code while at it. + Test 1560 is extended to verify. - Closes #6656 - Reviewed-by: Daniel Stenberg + Fixes #6863 + Closes #6871 -- cookies: Support multiple -b parameters +- libssh: fix "empty expression statement has no effect" warnings - Previously only a single -b cookie parameter was supported with the last - one winning. This adds support for supplying multiple -b params to have - them serialized semicolon separated. Both cookiefiles and cookies can be - entered multiple times. + ... by fixing macros to do-while constructs and moving out the calls to + "break" outside of the actual macro. It also fixes the problem where the + macro was used witin a loop and the break didn't do right. - Closes #6649 - Reviewed-by: Daniel Stenberg + Reported-by: Emil Engler + Fixes #6847 + Closes #6909 -Daniel Stenberg (25 Feb 2021) -- build: remove all traces of USE_BLOCKING_SOCKETS - - libcurl doesn't behave properly with the define set +- hsts: enable by default - Closes #6655 - -- RELEASE-NOTES: synced - -Daniel Gustafsson (25 Feb 2021) -- docs: Fix typos + No longer considered experimental. - Random typos spotted when skimming docs. + Closes #6700 -- cookies: Use named parameters in header prototypes +- vtls: refuse setting any SSL version - Align header with project style of using named parameters in the - function prototypes to aid readability and self-documentation. + ... previously they were supported if a TLS library would (unexpectedly) + still support them, but from this change they will be refused already in + curl_easy_setopt(). SSLv2 and SSLv3 have been known to be insecure for + many years now. - Closes #6653 - Reviewed-by: Daniel Stenberg + Closes #6773 -Daniel Stenberg (24 Feb 2021) -- urldata: make 'actions[]' use unsigned char instead of int +- curl: ignore options asking for SSLv2 or SSLv3 - ... as it only needs a few bits per index anyway. + Instead output a warning about it and continue with the defaults. - Reviewed-by: Daniel Gustafsson - Closes #6648 - -- configure: fail if --with-quiche is used and quiche isn't found + These SSL versions are typically not supported by the TLS libraries since a + long time back already since they are inherently insecure and broken. Asking + for them to be used will just cause an error to be returned slightly later. - Closes #6652 - -- [Gregor Jasny brought this change] - - cmake: use CMAKE_INSTALL_INCLUDEDIR indirection + In the unlikely event that a user's TLS library actually still supports these + protocol versions, this change might make the request a little less insecure. - Reviewed-by: Sergei Nikulov - Closes #6440 + Closes #6772 -Viktor Szakats (23 Feb 2021) -- mingw: enable using strcasecmp() +- test972: verify the json output with jsonlint - This makes the 'Features:' list sorted case-insensitively, - bringing output in-line with *nix builds. + Make sure one of the azure jobs has jsonlint installed so that the test + runs there. - Reviewed-by: Jay Satiro - Closes #6644 + Ref: #6905 -- build: delete unused feature guards +- [Jay Satiro brought this change] + + tool_writeout: fix the HTTP_CODE json output - - `HAVE_STRNCASECMP` - - `HAVE_TCGETATTR` - - `HAVE_TCSETATTR` + Update test 970 accordingly. - Reviewed-by: Jay Satiro - Reviewed-by: Daniel Stenberg - Closes #6645 + Reported-by: Michal Rus + Fixes #6905 + Closes #6906 -Jay Satiro (23 Feb 2021) -- docs: add CURLOPT_CURLU to 'See also' in curl_url_ functions +- openldap: protect SSL-specific code with proper #ifdef - Closes https://github.com/curl/curl/pull/6639 + Closes #6901 -Daniel Stenberg (23 Feb 2021) -- [Jacob Hoffman-Andrews brought this change] - - configure: make hyper opt-in, and fail if missing +- libssh2: fix Value stored to 'sshp' is never read - Previously, configure would look for hyper by default, and use it if - found; otherwise it would not use hyper, and not error. + Pointed out by scan-build - Now, configure will not look for hyper unless --with-hyper is passed. If - configure looks for hyper and fails, it will error. + Closes #6900 + +- [Victor Vieux brought this change] + + tool_getparam: replace (in-place) '%20' by '+' according to RFC1866 - Also, add -ld -lpthread -lm to Hyper's libs. I think they are required. + Signed-off-by: Victor Vieux - Closes #6598 + Closes #6895 -- multi: do once-per-transfer inits in before_perform in DID state - - ... since the state machine might go to RATELIMITING and then back to - PERFORMING doing once-per-transfer inits in that function is wrong and - it caused problems with receiving chunked HTTP and it set the - PRETRANSFER time much too often... +- configure: provide --with-openssl, deprecate --with-ssl - Regression from b68dc34af341805aeb7b3715 (shipped in 7.75.0) + Makes the option more explicit. - Reported-by: Amaury Denoyelle - Fixes #6640 - Closes #6641 + Closes #6887 - RELEASE-NOTES: synced - -- CODE_STYLE.md: fix broken link to INTERNALS - ... the link would only work if browsed on GitHub, while this link now - takes the user to the website instead and thus should work on either. - - Reported-by: David Demelier + and bumped curlver to 7.77.0 -- curl_url_set.3: mention CURLU_PATH_AS_IS +- [Javier Blazquez brought this change] + + rustls: only return CURLE_AGAIN when TLS session is fully drained - ... it has been supported since the URL API was added. + The code in cr_recv was returning prematurely as soon as the socket + reported no more data to read. However, this could be leaving some + unread plaintext data in the rustls session from a previous call, + causing causing the transfer to hang if the socket never receives + further data. - Bug: https://curl.se/mail/lib-2021-02/0046.html + We need to ensure that the session is fully drained of plaintext data + before returning CURLE_AGAIN to the caller. - Closes #6638 + Reviewed-by: Jacob Hoffman-Andrews + Closes #6894 -Viktor Szakats (21 Feb 2021) -- time: enable 64-bit time_t in supported mingw environments +- cookie: CURLOPT_COOKIEFILE set to NULL switches off cookies - (Unless 32-bit `time_t` is selected manually via the `_USE_32BIT_TIME_T` - mingw macro.) - - Previously, 64-bit `time_t` was enabled on VS2005 and newer only, and - 32-bit `time_t` was used on all other Windows builds. + Add test 676 to verify that setting CURLOPT_COOKIEFILE to NULL again clears + the cookiejar from memory. - Assisted-by: Jay Satiro - Closes #6636 + Reported-by: Stefan Karpinski + Fixes #6889 + Closes #6891 -Jay Satiro (20 Feb 2021) -- test1188: Check for --fail HTTP status +Version 7.76.1 (14 Apr 2021) + +Daniel Stenberg (14 Apr 2021) +- RELEASE-NOTES: synced - - Change the test to check for curl error on HTTP 404 Not Found. + curl 7.76.1 release + +- THANKS: add names from 7.76.1 + +- misc: update copyright year ranges to match latest updates + +- [Tatsuhiro Tsujikawa brought this change] + + ngtcp2: Use ALPN h3-29 for now - test1188 tests "--write-out with %{onerror} and %{urlnum} to stderr". - Prior to this change it did that by specifying a non-existent host which - would cause an error. ISPs may hijack DNS and resolve non-existent hosts - so the test would not work if that was the case. + Fixes #6864 + Cloes #6886 + +Jay Satiro (11 Apr 2021) +- TODO: remove 18.22 --fail-with-body - Ref: https://en.wikipedia.org/wiki/DNS_hijacking#Manipulation_by_ISPs - Ref: https://github.com/curl/curl/issues/6621 - Ref: https://github.com/curl/curl/pull/6623 + --fail-with-body was added in 8a964cb (precedes curl-7_76_0). + +Daniel Stenberg (10 Apr 2021) +- [Jürgen Gmach brought this change] + + src/tool_vms.c: remove duplicated word in comment - Closes https://github.com/curl/curl/pull/6637 + Closes #6881 -- memdebug: close debug logfile explicitly on exit +- configure: fix CURL_DARWIN_CFLAGS use - - Use atexit to register a dbg cleanup function that closes the logfile. + The macro name change was not completely done. - LeakSantizier (LSAN) calls _exit() instead of exit() when a leak is - detected on exit so the logfile must be closed explicitly or data could - be lost. Though _exit() does not call atexit handlers such as this, - LSAN's call to _exit() comes after the atexit handlers are called. + Follow-up to 5d2c384452543c + Bug: https://github.com/curl/curl/commit/5d2c384452543c7b6c9fb02eaa0afc84fd5ab941#commitcomment-49315187 + Reported-by: Marcel Raad + Closes #6878 + +- [Anthony Shaw brought this change] + + github/workflow: add "security-extended" to codeql-analysis.yml - Prior to this change the logfile was not explicitly closed so it was - possible that if LSAN detected a leak and called _exit (which does - not flush or close files like exit) then the logfile could be missing - data. That could then cause curl's memanalyze to report false leaks - (eg a malloc was recorded to the logfile but the corresponding free was - discarded from the buffer instead of written to the logfile, then - memanalyze reports that as a leak). + Extends the CodeQL code scan. - Ref: https://github.com/google/sanitizers/issues/1374 + Closes #6815 + +- [Jochem Broekhoff brought this change] + + examples/hiperfifo.c: check event_initialized before delete - Bug: https://github.com/curl/curl/pull/6591#issuecomment-780396541 + If event_del is called with the event struct (still) zeroed out, a + segmentation fault may occur. event_initialized checks whether the + event struct is nonzero. - Closes https://github.com/curl/curl/pull/6620 + Closes #6876 -- curl_multibyte: always return a heap-allocated copy of string +- [Patrick Monnerat brought this change] + + ntlm: fix negotiated flags usage - - Change the Windows char <-> UTF-8 conversion functions to return an - allocated copy of the passed in string instead of the original. + According to Microsoft document MS-NLMP, current flags usage is not + accurate: flag NTLMFLAG_NEGOTIATE_NTLM2_KEY controls the use of + extended security in an NTLM authentication message and NTLM version 2 + cannot be negotiated within the protocol. - Prior to this change the curlx_convert_ functions would, as what I - assume was an optimization, not make a copy of the passed in string if - no conversion was required. No conversion is required in non-UNICODE - Windows builds since our tchar strings are type char and remain in - whatever the passed in encoding is, which is assumed to be UTF-8 but may - be other encoding. + The solution implemented here is: if the extended security flag is set, + prefer using NTLM version 2 (as a server featuring extended security + should also support version 2). If version 2 has been disabled at + compile time, use extended security. - In contrast the UNICODE Windows builds require conversion - (wchar <-> char) and do return a copy. That inconsistency could lead to - programming errors where the developer expects a copy, and does not - realize that won't happen in all cases. + Tests involving NTLM are adjusted to this new behavior. - Closes https://github.com/curl/curl/pull/6602 + Fixes #6813 + Closes #6849 -Viktor Szakats (19 Feb 2021) -- http: add new files missed from referrer commit - - Ref: 44872aefc2d54f297caf2b0cc887df321bc9d791 - Ref: #6591 +- [Patrick Monnerat brought this change] -- http: add support to read and store the referrer header - - - add CURLINFO_REFERER libcurl option - - add --write-out '%{referer}' command-line option - - extend --xattr command-line option to fill user.xdg.referrer.url extended - attribute with the referrer (if there was any) + ntlm: support version 2 on 32-bit platforms - Closes #6591 + Closes #6849 -Daniel Stenberg (19 Feb 2021) -- urldata: remove the _ORIG suffix from string names - - It doesn't provide any useful info but only makes the names longer. - - Closes #6624 +- [Patrick Monnerat brought this change] -- url: fix memory leak if OOM in the HSTS handling + curl_ntlm_core.h: simplify conditionals for USE_NTLM2SESSION - Reported-by: Viktor Szakats - Bug: https://github.com/curl/curl/pull/6627#issuecomment-781626205 + ... as !defined(CURL_DISABLE_CRYPTO_AUTH) is a prerequisite for the + whole NTLM. - Closes #6628 + Closes #6849 -- gnutls: assume nettle crypto support - - nettle has been the default crypto library with GnuTLS since 2010. By - dropping support for the previous libcrypto, we simplify code. +- lib: remove unused HAVE_INET_NTOA_R* defines - Closes #6625 + Closes #6867 -- asyn-ares: use consistent resolve error message - - ... with the help of Curl_resolver_error() which now is moved from - asyn-thead.c and is provided globally for this purpose. +- [Michael Forney brought this change] + + configure: include unconditionally - Follow-up to 35ca04ce1b77636 + In 2682e5f5, several instances of AC_HEADER_TIME were removed since + it is a deprecated autoconf macro. However, this was the macro that + defined TIME_WITH_SYS_TIME, which was used to indicate that + can be included alongside . TIME_WITH_SYS_TIME is still + used in the configure test body and since it is no longer defined, + is *not* included on systems that have . - Makes test 1188 work for c-ares builds + In particular, at least on musl libc and glibc, does + not implicitly include and does not declare clock_gettime, + gmtime_r, or localtime_r. This causes configure to fail to detect + those functions. - Closes #6626 + The AC_HEADER_TIME macro deprecation text says + + > All current systems provide time.h; it need not be checked for. + > Not all systems provide sys/time.h, but those that do, all allow + > you to include it and time.h simultaneously. + + So, to fix this issue, simply include unconditionally when + testing for time-related functions and in libcurl, and don't bother + checking for it. + + Closes #6859 -Viktor Szakats (18 Feb 2021) -- ci: stop building on freebsd-12-1 +- [Michael Forney brought this change] + + configure: remove use of RETSIGTYPE - An updated freebsd-12-2 image was added a few months ago, and this - older one is consistently failing to go past `pkginstall`: - ``` - Newer FreeBSD version for package py37-mlt: - To ignore this error set IGNORE_OSVERSION=yes - - package: 1202000 - - running kernel: 1201000 - Ignore the mismatch and continue? [Y/n]: pkg: repository FreeBSD contains packages for wrong OS version: FreeBSD:12:amd64 - ``` + This was previously defined by the obsolete AC_TYPE_SIGNAL macro, + which was removed in 2682e5f5. The deprecation text says - FreeBSD thread suggests that 12.1 is EOL, and best to avoid. + > Your code may safely assume C89 semantics that RETSIGTYPE is void. - Ref: https://forums.freebsd.org/threads/78856/ + So, remove it and just use void instead. - Reviewed-by: Daniel Stenberg - Closes #6622 + Closes #6861 -Daniel Stenberg (18 Feb 2021) -- test1188: change error from connect to resolve error +- [Muhammed Yavuz Nuzumlalı brought this change] + + install: add instructions for Apple Darwin platforms - Using the %NOLISTENPORT to trigger a connection failure is somewhat - "risky" (since it isn't guaranteed to not be listened to) and caused - occasional CI problems. This fix changes the infused error to be a more - reliable one but still verifies the --write-out functionality properly - - which is the purpose of this test. + Closes #6860 + +- [Muhammed Yavuz Nuzumlalı brought this change] + + configure: disable min version set for Darwin - Reported-by: Jay Satiro - Fixes #6621 - Closes #6623 + Fixes #6838 + Closes #6860 -- url.c: use consistent error message for failed resolve +- [David Hu brought this change] -- BUGS: language polish + docs/HTTP3.md: update the build instruction using gnutls + + In ngtcp2 the `with-gnutls` option is disabled by default, which will + cause `curl` unable to be `make` because of lacking the libraries + needed. + + Closes #6857 -- wolfssl: don't store a NULL sessionid +- RELEASE-NOTES: synced + +- typecheck-gcc: make the ssl-ctx-cb check use SSL_CTX pointers - This caused a memory leak as the session id cache entry was still - erroneously stored with a NULL sessionid and that would later be treated - as not needed to get freed. + ... and not values. - Reported-by: Gisle Vanem - Fixes #6616 - Closes #6617 + Reported-by: locpyl-tidnyd on github + Fixes #6818 + Closes #6819 -- parse_proxy: fix a memory leak in the OOM path +- ngtcp2+gnutls: clear credentials when freed - Reported-by: Jay Satiro - Reviewed-by: Jay Satiro - Reviewed-by: Emil Engler + ... to avoid double-free. - Closes #6614 - Bug: https://github.com/curl/curl/pull/6591#issuecomment-780396541 + Reported-by: Kenneth Davidson + Fixes #6824 + Closes #6856 -Jay Satiro (17 Feb 2021) -- url: fix possible use-after-free in default protocol +Jay Satiro (5 Apr 2021) +- [Cherish98 brought this change] + + tool_progress: Fix progress meter in parallel mode - Prior to this change if the user specified a default protocol and a - separately allocated non-absolute URL was used then it was freed - prematurely, before it was then used to make the replacement URL. + Make sure the total amount of DL/UL bytes are counted before the + transfer finalizes. Otherwise if a transfer finishes too quick, its + total numbers are not added, and results in a DL%/UL% that goes above + 100%. - Bug: https://github.com/curl/curl/issues/6604#issuecomment-780138219 - Reported-by: arvids-kokins-bidstack@users.noreply.github.com + Detail: - Closes https://github.com/curl/curl/pull/6613 + progress_meter() is called periodically, and it may not catch a + transfer's total bytes if the value was unknown during the last call, + and the transfer is finished and deleted (i.e., lost) during the next + call. + + Closes https://github.com/curl/curl/pull/6840 -Daniel Stenberg (16 Feb 2021) -- multi: rename the multi transfer states +- [Emil Engler brought this change] + + libssh: get rid of PATH_MAX - While working on documenting the states it dawned on me that step one is - to use more descriptive names on the states. This also changes prefix on - the states to make them shorter in the source. + This removes the last occurrence of PATH_MAX inside our libssh + implementation by calculating the path length from the string length of + the two components. - State names NOT ending with *ing are transitional ones. + Closes #6829 + +Daniel Stenberg (5 Apr 2021) +- http_proxy: only loop on 407 + close if we have credentials - Closes #6612 + ... to fix the retry-loop. + + Add test 718 to verify. + + Reported-by: Daniel Kurečka + Fixes #6828 + Closes #6850 -Viktor Szakats (16 Feb 2021) -- http: do not add a referrer header with empty value +- h2: allow 100 streams by default - Previously an empty 'Referer:' header was added to the HTTP request when - passing `--referer ';auto'` or `--referer ''` on the command-line. This - patch makes `--referer` work like `--header 'Referer:'` and will only add - the header if it has a non-zero length value. + instead of 13, before the server has told how many streams it + accepts. The server can always reject new streams anyway if we go above + what it accepts. - Reviewed-by: Jay Satiro - Closes #6610 + Ref: #6826 + Closes #6852 -Daniel Stenberg (16 Feb 2021) -- lib: remove 'conn->data' completely +- [Luke Granger-Brown brought this change] + + file: support GETing directories again - The Curl_easy pointer struct entry in connectdata is now gone. Just - before commit 215db086e0 landed on January 8, 2021 there were 919 - references to conn->data. + After 957bc1881e686f9714c4e6a01bf33535091f0e21, we no longer compute an + expected_size for directories. This has the upshot that when we compare + even an empty Range with the available size, we fail. - Closes #6608 + This brings back the previous behaviour, which was to succeed, but with + empty content. This also removes the "Accept-ranges: bytes" header, + which is nonsensical on directories. + + Adds test 3016 + Fixes #6845 + Closes #6846 -- openldap: pass 'data' to the callbacks instead of 'conn' +- RELEASE-NOTES: synced + + and bumped to 7.76.1 -Jay Satiro (15 Feb 2021) -- doh: Fix sharing user's resolve list with DOH handles +- TLS: fix HTTP/2 selection - - Share the shared object from the user's easy handle with the DOH - handles. + for GnuTLS, BearSSL, mbedTLS, NSS, SChannnel, Secure Transport and + wolfSSL... - Prior to this change if the user had set a shared object with shared - cached DNS (CURL_LOCK_DATA_DNS) for their easy handle then that wasn't - used by any associated DOH handles, since they used the multi's default - hostcache. + Regression since 88dd1a8a115b1f5ece (shipped in 7.76.0) + Reported-by: Kenneth Davidson + Reported-by: romamik om github + Fixes #6825 + Closes #6827 + +Jay Satiro (2 Apr 2021) +- hostip: Fix for builds that disable all asynchronous DNS - This change means all the handles now use the same hostcache, which is - either the shared hostcache from the user created shared object if it - exists or if not then the multi's default hostcache. + - Define Curl_resolver_error function only when USE_CURL_ASYNC. - Reported-by: Manuj Bhatia + Prior to this change building curl without an asynchronous resolver + backend (c-ares or threaded) and without DoH (DNS-over-HTTPS, which is + also asynchronous but independent of resolver backend) would cause a + build error since Curl_resolver_error is called by and evaluates + variables only available in asynchronous builds. - Fixes https://github.com/curl/curl/issues/6589 - Closes https://github.com/curl/curl/pull/6607 + Reported-by: Benbuck Nason + + Fixes https://github.com/curl/curl/issues/6831 + Closes https://github.com/curl/curl/pull/6832 -Daniel Stenberg (15 Feb 2021) -- http2: remove conn->data use +Daniel Stenberg (31 Mar 2021) +- [Gilles Vollant brought this change] + + openssl: Fix CURLOPT_SSLCERT_BLOB without CURLOPT_SSLCERT_KEY - ... but instead use a private alternative that points to the "driving - transfer" from the connection. We set the "user data" associated with - the connection to be the connectdata struct, but when we drive transfers - the code still needs to know the pointer to the transfer. We can change - the user data to become the Curl_easy handle, but with older nghttp2 - version we cannot dynamically update that pointer properly when - different transfers are used over the same connection. + Reported-by: Christian Schmitz + Fixes #6816 + Closes #6820 + +Version 7.76.0 (31 Mar 2021) + +Daniel Stenberg (31 Mar 2021) +- RELEASE-NOTES: synced - Closes #6520 + curl 7.76.0 release -- openssl: remove conn->data use +- THANKS: added names from 7.76.0 + +- CURLOPT_AUTOREFERER.3: clarify that it sets the full URL - We still make the trace callback function get the connectdata struct - passed to it, since the callback is anchored on the connection. + ... some users may not want that! + +- define: remove CURL_DISABLE_NTLM ifdefs - Repeatedly updating the callback pointer to set 'data' with - SSL_CTX_set_msg_callback_arg() doesn't seem to work, probably because - there might already be messages in the queue with the old pointer. + It was never defined anywhere. Fixed disable-scan (test 1165) to also + scan headers, which found this issue. - This code therefore makes sure to set the "logger" handle before using - OpenSSL calls so that the right easy handle gets used for tracing. + Closes #6809 + +- vtls: fix addsessionid for non-proxy builds - Closes #6522 + Follow-up to b09c8ee15771c61 + Fixes #6812 + Closes #6811 + +- [Li Xinwei brought this change] + + cmake: support WinIDN + + Closes #6807 + +- transfer: clear 'referer' in declaration + + To silence (false positive) compiler warnings about it. + + Follow-up to 7214288898f5625 + + Reviewed-by: Marcel Raad + Closes #6810 + +- [Marc Hoersken brought this change] + + config: fix SSPI enabling NTLM if crypto auth is disabled + + Avoid enabling NTLM feature based upon Windows SSPI + being enabled in case that crypto auth is disabled. + + Reported-by: Marcel Raad + + Follow-up to #6277 + Fixes #6803 + Closes #6808 + +- HISTORY: add two 2021 events + +- vtls: add 'isproxy' argument to Curl_ssl_get/addsessionid() + + To make sure we set and extract the correct session. + + Reported-by: Mingtao Yang + Bug: https://curl.se/docs/CVE-2021-22890.html + + CVE-2021-22890 + +- [Viktor Szakats brought this change] + + transfer: strip credentials from the auto-referer header field + + Added test 2081 to verify. + + CVE-2021-22876 + + Bug: https://curl.se/docs/CVE-2021-22876.html + +- curl_sasl: fix compiler error with --disable-crypto-auth + + ... if libgsasl was found. + + Closes #6806 + +- [Patrick Monnerat brought this change] + + ldap: only set the callback ptr for TLS context when TLS is used + + Follow-up to a5eee22e594c2460f + Fixes #6804 + Closes #6805 + +- copyright: update copyright year ranges to 2021 + + Reviewed-by: Emil Engler + Closes #6802 + +- send_speed: simplify the checks for if a speed limit is set + + ... as we know the value cannot be set to negative: enforced by + setopt() + +- http: cap body data amount during send speed limiting + + By making sure never to send off more than the allowed number of bytes + per second the speed limit logic is given more room to actually work. + + Reported-by: Fabian Keil + Bug: https://curl.se/mail/lib-2021-03/0042.html + Closes #6797 + +- urldata: merge "struct DynamicStatic" into "struct UrlState" + + Both were used for the same purposes and there was no logical separation + between them. Combined, this also saves 16 bytes in less holes in my + test build. + + Closes #6798 + +- tests/README.md: mentioned that en_US.UTF-8 is required + + Reported-by: Oumph on github + Fixes #6768 + +- HISTORY: fixed the Mac OS X 10.1 release date + + Based on what Wikipedia says + +Jay Satiro (26 Mar 2021) +- examples: Remove threaded-shared-conn.c due to bug + + Known bug 11.11 is the shared object's connection cache is not thread + safe, so we should not have an example for it. + + Ref: https://github.com/curl/curl/issues/4915 + Ref: https://curl.se/docs/knownbugs.html#A_shared_connection_cache_is_not + + Closes https://github.com/curl/curl/pull/6795 + +- KNOWN_BUGS: Update 11.9 - DoH option inheritance + + - Add description: Explain that some options aren't inherited because + they are not relevant for the DoH SSL connections or may result in + unexpected behavior. + + - Remove the reference to #4578 (SSL verify options not inherited) since + that was fixed by #6597 (separate DoH-specific options for verify). + + - Explain that DoH-specific options (those created by #6597) are + available: CURLOPT_DOH_SSL_VERIFYHOST, CURLOPT_DOH_SSL_VERIFYPEER and + CURLOPT_DOH_SSL_VERIFYSTATUS. + + - Add a reference to #6605 and explain that the user's debug function is + not inherited because it would be unexpected to pass internal handles + (ie DoH handles) to the user's callback. + + Closes https://github.com/curl/curl/issues/6605 + +Daniel Stenberg (26 Mar 2021) +- curl_easy_setopt.3: add curl_easy_option* functions to SEE ALSO + +- [Jean-Philippe Menil brought this change] + + openssl: ensure to check SSL_CTX_set_alpn_protos return values + + SSL_CTX_set_alpn_protos() return 0 on success, and non-0 on failure + + Signed-off-by: Jean-Philippe Menil + + Closes #6794 + +- multi: close the connection when h2=>h1 downgrading + + Otherwise libcurl is likely to reuse the connection again in the next + attempt since the connection reuse logic doesn't take downgrades into + account. + + Reported-by: Anthony Ramine + Fixes #6788 + Closes #6793 + +- openssl: set the transfer pointer for logging early + + Otherwise, the transfer will be NULL in the trace function when the + early handshake details arrive and then curl won't show them. + + Regresssion in 7.75.0 + + Reported-by: David Hu + Fixes #6783 + Closes #6792 - RELEASE-NOTES: synced -Jay Satiro (14 Feb 2021) -- doh: add options to disable ssl verification +- TODO: Custom progress meter update interval - - New libcurl options CURLOPT_DOH_SSL_VERIFYHOST, - CURLOPT_DOH_SSL_VERIFYPEER and CURLOPT_DOH_SSL_VERIFYSTATUS do the - same as their respective counterparts. + Ref: https://stackoverflow.com/q/66789977/93747 + +- docs/ABI: tighten up the language - - New curl tool options --doh-insecure and --doh-cert-status do the same - as their respective counterparts. + Make the promises more firm - Prior to this change DOH SSL certificate verification settings for - verifyhost and verifypeer were supposed to be inherited respectively - from CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER, but due to a bug - were not. As a result DOH verification remained at the default, ie - enabled, and it was not possible to disable. This commit changes - behavior so that the DOH verification settings are independent and not - inherited. + Closes #6786 + +- openldap: disconnect better - Ref: https://github.com/curl/curl/pull/4579#issuecomment-554723676 + Instead of clearing the callback argument in disconnect, set it to the + (new) transfer to make sure the correct data is passed to the callbacks. - Fixes https://github.com/curl/curl/issues/4578 - Closes https://github.com/curl/curl/pull/6597 + Follow-up to e467ea3bd937f38 + Assisted-by: Patrick Monnerat + Closes #6787 -- hostip: fix crash in sync resolver builds that use DOH +- libssh2: kdb_callback: get the right struct pointer - - Guard some Curl_async accesses with USE_CURL_ASYNC instead of - !CURLRES_SYNCH. + After the recent conn/data refactor in this source file, this function + was mistakenly still getting the old struct pointer which would lead to + crash on servers with keyboard-interactive auth enabled. - This is another follow-up to 8335c64 which moved the async struct from - the connectdata struct into the Curl_easy struct. A previous follow-up - 6cd167a fixed building for sync resolver by guarding some async struct - accesses with !CURLRES_SYNCH. The problem is since DOH (DNS-over-HTTPS) - is available as an asynchronous secondary resolver the async struct may - be used even when libcurl is built for the sync resolver. That means - that CURLRES_SYNCH and USE_CURL_ASYNC may be defined at the same time. + Follow-up to a304051620b92e12b (shipped in 7.75.0) - Closes https://github.com/curl/curl/pull/6603 + Reported-by: Christian Schmitz + Fixes #6691 + Closes #6782 -Daniel Stenberg (13 Feb 2021) -- KNOWN_BUGS: cannot enable LDAPS on Windows with cmake +- tftp: remove unused struct fields - Reported-by: Jack Boos Yu - Closes #6284 + Follow-up to d3d90ad9c00530d + + Closes #6781 -- KNOWN_BUGS: Excessive HTTP/2 packets with TCP_NODELAY +- openldap: avoid NULL pointer dereferences + + Follow-up to a59c33ceffb8f78 + Reported-by: Patrick Monnerat + Fixes #6676 + Closes #6780 + +- http: strip default port from URL sent to proxy + + To make sure the Host: header and the URL provide the same authority + portion when sent to the proxy, strip the default port number from the + URL if one was provided. - Reported-by: Alex Xu - Closes #6363 + Reported-by: Michael Brown + Fixes #6769 + Closes #6778 -- http: use credentials from transfer, not connection +- azure: disable test 433 on azure-ubuntu - HTTP auth "accidentally" worked before this cleanup since the code would - always overwrite the connection credentials with the credentials from - the most recent transfer and since HTTP auth is typically done first - thing, this has not been an issue. It was still wrong and subject to - possible race conditions or future breakage if the sequence of functions - would change. + Something in that environment sets XDG_CONFIG_HOME for us in a way that + breaks the test. - The data.set.str[] strings MUST remain unmodified exactly as set by the - user, and the credentials to use internally are instead set/updated in - state.aptr.* + Reported-by: Marc Hörsken + Fixes #6739 + Closes #6777 + +- tftp: remove the 3600 second default timeout - Added test 675 to verify different credentials used in two requests done - over a reused HTTP connection, which previously behaved wrongly. + ... it was never meant to be there. - Fixes #6542 - Closes #6545 + Reported-by: Tomas Berger + Fixes #6774 + Closes #6776 -- test433: clear some home dir env variables +- docs: make gen.pl support *italic* and **bold** - Follow-up to bd6b54ba1f55b5 + Remove some nroffisms from the cmdline doc files to simplify editing, + and instead support this markdown style. - ... so that XDG_CONFIG_HOME is the only home dir variable set and thus - used correctly in the test! + Closes #6771 + +- ngtcp2: sync with recent API updates - Fixes #6599 - Closes #6600 + Closes #6770 - RELEASE-NOTES: synced - - bumped the version to 7.76.0 -- travis: install libgsasl-dev to add that to the builds +- libssh2:ssh_connect: clear session pointer after free - Closes #6588 + If libssh2_knownhost_init() returns NULL, like in an OOM situation, the + ssh session was freed but the pointer wasn't cleared which made libcurl + later call libssh2 to cleanup using the stale pointer. + + Fixes #6764 + Closes #6766 -- urldata: don't touch data->set.httpversion at run-time +- [Jacob Hoffman-Andrews brought this change] + + docs: document version of crustls dependency - Rename it to 'httpwant' and make a cloned field in the state struct as - well for run-time updates. + This also pins a specific release in the Travis test so future + API-breaking changins in crustls won't break curl builds. - Also: refuse non-supported HTTP versions. Verified with test 129. + Add RUSTLS documentation to release tarball. - Closes #6585 + Enable running tests for rustls, minus FTP tests (require + connect_blocking, which rustls doesn't implement) and 313 (requires CRL + handling). + + Closes #6763 -Viktor Szakats (11 Feb 2021) -- tests: disable .curlrc in more environments +- [Jacob Hoffman-Andrews brought this change] + + rustls: Handle close_notify. - by also setting CURL_HOME and XDG_CONFIG_HOME envvars to the local - directory. + If we get a close_notify, treat that as EOF. If we get an EOF from the + TCP stream, treat that as an error (because we should have ended the + connection earlier, when we got a close_notify). - Reviewed-by: Daniel Stenberg - Fixes #6595 - Closes #6596 + Closes #6763 -- docs/Makefile.inc: format to be update-friendly +- docs: clarify timeouts for queued transfers in multi API - - one source file per line - - convert tabs to spaces - - do not align line-continuation backslashes - - sort source files alphabetically + Closes #6758 + +- ftpserver: only load the preprocessed test file - Reviewed-by: Daniel Stenberg - Closes #6593 + We always preprocess and tests are no longer sensible to load "raw" + + Closes #6738 -Daniel Stenberg (11 Feb 2021) -- curl: provide libgsasl version and feature info in -V output +- tests: use %TESTNUMBER instead of fixed number - Closes #6592 + This makes the tests easier to copy and relocate to other test numbers + without having to update content. + + Closes #6738 -- gsasl: provide CURL_VERSION_GSASL if built-in +- KNOWN_BUGS: CURLOPT_OPENSOCKETPAIRFUNCTION is missing - To let applications know the feature is available. + Closes #5747 + +- TODO: provide timing info for each redirect - Closes #6592 + Closes #6743 -- curl: add --fail-with-body +Jay Satiro (17 Mar 2021) +- docs: Add SSL backend names to CURL_SSL_BACKEND - Prevent both --fail and --fail-with-body on the same command line. + - Document the names that can be used with CURL_SSL_BACKEND: + bearssl, gnutls, gskit, mbedtls, mesalink, nss, openssl, rustls, + schannel, secure-transport, wolfssl - Verify with test 349, 360 and 361. + Ref: https://github.com/curl/curl/issues/2209#issuecomment-360623286 + Ref: https://github.com/curl/curl/issues/6717#issuecomment-800745201 - Closes #6449 + Closes https://github.com/curl/curl/pull/6755 -- TODO: remove HSTS +- docs: Explain DOH transfers inherit some SSL settings - Provided now since commit 7385610d0c74 + - Document in DOH that some SSL settings are inherited but DOH hostname + and peer verification are not and are controlled separately. + + - Document that CURLOPT_SSL_CTX_FUNCTION is inherited by DOH handles but + we're considering changing behavior to no longer inherit it. Request + feedback. + + Closes https://github.com/curl/curl/pull/6688 -Jay Satiro (10 Feb 2021) -- tests: Fix tests failing due to change in curl --help +Daniel Stenberg (17 Mar 2021) +- http: make 416 not fail with resume + CURLOPT_FAILONERRROR - Follow-up to parent 3183217 which added add missing argument to - --create-file-mode . + When asked to resume a download, libcurl will convert that to HTTP logic + and if then the entire file is already transferred it will result in a + 416 response from the HTTP server. With CURLOPT_FAILONERRROR set in that + scenario, it should *not* lead to an error return. - Ref: https://github.com/curl/curl/issues/6590 + Updated test 1156, added test 1273 + + Reported-by: Jonathan Watt + Fixes #6740 + Closes #6753 -- tool_help: add missing argument for --create-file-mode +- Curl_timeleft: check both timeouts during connect - Prior to this change the required argument was not shown in curl --help. + The duration of a connect and the total transfer are calculated from two + different time-stamps. It can end up with the total timeout triggering + before the connect timeout expires and we should make sure to + acknowledge whichever timeout that is reached first. - before: - --create-file-mode File mode for created files + This is especially notable when a transfer first sits in PENDING, as + that time is counted in the total time but the connect timeout is based + on the time since the handle changed to the CONNECT state. - after: - --create-file-mode File mode (octal) for created files + The CONNECTTIMEOUT is per connect attempt. The TIMEOUT is for the entire + operation. - Reported-by: ZimCodes@users.noreply.github.com + Fixes #6744 + Closes #6745 + Reported-by: Andrei Bica + Assisted-by: Jay Satiro + +- configure: remove use of deprecated macros - Fixes https://github.com/curl/curl/issues/6590 + AC_HEADER_TIME, AC_HEADER_STDC and AC_TYPE_SIGNAL -- create-file-mode.d: add missing Arg tag +- configure: make AC_TRY_* into AC_*_IFELSE - Prior to this change the required argument was not shown. + ... as the former versions are deprecated. + +- configure: s/AC_HELP_STRING/AS_HELP_STRING - curl.1 before: --create-file-mode - curl.1 after: --create-file-mode + AC_HELP_STRING is deprecated in 2.70+ and I believe AS_HELP_STRING works + already since 2.59 so bump the minimum required version to that. - Reported-by: ZimCodes@users.noreply.github.com + Reported-by: Emil Engler + Fixes #6647 + Closes #6748 + +- RELEASE-NOTES: synced + +- travis: use ubuntu nghttp2 package instead of build our own - Fixes https://github.com/curl/curl/issues/6590 + Closes #6751 -Viktor Szakats (10 Feb 2021) -- gsasl: fix errors/warnings building against libgsasl +- travis: bump wolfssl to 4.7.0 + +- travis: only build wolfssl when needed - - also fix an indentation - - make Curl_auth_gsasl_token() use CURLcode (by Daniel Stenberg) + Closes #6751 + +- [Jacob Hoffman-Andrews brought this change] + + rustls: allocate a buffer for TLS data. - Ref: https://github.com/curl/curl/pull/6372#issuecomment-776118711 - Ref: https://github.com/curl/curl/pull/6588 + Previously, rustls was using an on-stack array for TLS data. However, + crustls has an (unusual) requirement that buffers it deals with are + initialized before writing to them. By using calloc, we can ensure the + buffer is initialized once and then reuse it across calls. - Reviewed-by: Jay Satiro - Assisted-by: Daniel Stenberg - Reviewed-by: Simon Josefsson - Closes #6587 + Closes #6742 -- Makefile.m32: add support for libgsasl dependency +- travis: add a rustls build - Reviewed-by: Marcel Raad - Closes #6586 + ... that doesn't run any tests (yet) + + Closes #6750 -Marcel Raad (10 Feb 2021) -- ngtcp2: clarify calculation precedence +- HTTP2: remove the outdated remark about multiplexing for the tool + +- [Robert Ronto brought this change] + + http2: don't set KEEP_SEND when there's no more data to be sent - As suggested by Codacy/cppcheck. + this should fix an issue where curl sometimes doesn't send out a request + with authorization info after a 401 is received over http2 - Closes https://github.com/curl/curl/pull/6576 + Closes #6747 -- server: remove redundant condition +Marc Hoersken (15 Mar 2021) +- config: fix building SMB with configure using Win32 Crypto + + Align conditions for NTLM features between CMake and configure + builds by differentiating between USE_NTLM and USE_CURL_NTLM_CORE, + just like curl_setup.h does internally to detect support of: + + - USE_NTLM: required for NTLM crypto authentication feature + - USE_CURL_NTLM_CORE: required for SMB protocol + + Implement USE_WIN32_CRYPTO detection by checking for Crypt functions + in wincrypt.h which are not available in the Windows App environment. + + Link advapi32 and crypt32 for Crypto API and Schannel SSL backend. + Fix condition of Schannel SSL backend in CMake build accordingly. - `end` is always non-null here. + Reviewed-by: Marcel Raad - Closes https://github.com/curl/curl/pull/6576 + Closes #6277 -- lib: remove redundant code +- config: fix detection of restricted Windows App environment - Closes https://github.com/curl/curl/pull/6576 - -- mqttd: remove unused variable + Move the detection of the restricted Windows App environment + in curl_setup.h before the definition of USE_WIN32_CRYPTO + via included config-win32.h in case no build system is used. - Closes https://github.com/curl/curl/pull/6576 - -- tool_paramhlp: reduce variable scope + Reviewed-by: Marcel Raad - Closes https://github.com/curl/curl/pull/6576 + Part of #6277 -- tests: reduce variable scopes - - Closes https://github.com/curl/curl/pull/6576 +Daniel Stenberg (15 Mar 2021) +- HISTORY: curl 7.7.2 was the first version used in Mac OS X 10.1 -- lib: reduce variable scopes +- gen.pl: quote "bare" minuses in the nroff curl.1 - Closes https://github.com/curl/curl/pull/6576 + Reported-by: Alejandro Colomar + Fixes #6698 + Closes #6722 -- ftp: fix Codacy/cppcheck warning about null pointer arithmetic +Daniel Gustafsson (14 Mar 2021) +- hsts: remove unused defines - Increment `bytes` only if it is non-null. + MAX_HSTS_SUBLEN and MAX_HSTS_SUBLENSTR were unused from the initial commit, + and mostly likely leftovers from early development. Remove as they're not + used for anything. - Closes https://github.com/curl/curl/pull/6576 - -Daniel Stenberg (9 Feb 2021) -- ngtcp2: adapt to the new recv_datagram callback + Closes #6741 + Reviewed-by: Daniel Stenberg -- quiche: fix build error: use 'int' for port number +Daniel Stenberg (12 Mar 2021) +- github: add torture-ftp for FTP-only torture testing - Follow-up to cb2dc1ba8 + and at 20% to try to keep the run-time reasonable + + Closes #6728 -- ftp: add 'list_only' to the transfer state struct +- travis: split "torture" into a separate "events" build as well - and rename it from 'ftp_list_only' since it is also used for SSH and - POP3. The state is updated internally for 'type=D' FTP URLs. + Run torture without FTP and reducing coverage to 20% - Added test case 1570 to verify. + For some reason the torture tests now run a lot slower on travis and run + into the 50 minute limit all the time. - Closes #6578 + Closes #6728 -- ftp: add 'prefer_ascii' to the transfer state struct +- ftp: fix memory leak in ftp_done - ... and make sure the code never updates 'set.prefer_ascii' as it breaks - handle reuse which should use the setting as the user specified it. + If after a transfer is complete Curl_GetFTPResponse() returns an error, + curl would not free the ftp->pathalloc block. - Added test 1569 to verify: it first makes an FTP transfer with ';type=A' - and then another without type on the same handle and the second should - then use binary. Previously, curl failed this. + Found by torture-testing test 576 - Closes #6578 + Closes #6737 + +- [oxalica brought this change] + + http2: fail if connection terminated without END_STREAM + + Closes #6736 - RELEASE-NOTES: synced - [Jacob Hoffman-Andrews brought this change] - vtls: initial implementation of rustls backend + rustls: support CURLOPT_SSL_VERIFYPEER - This adds a new TLS backend, rustls. It uses the C-to-rustls bindings - from https://github.com/abetterinternet/crustls. + This requires the latest main branch of crustls, which provides + rustls_client_config_builder_dangerous_set_certificate_verifier and + rustls_client_config_builder_set_enable_sni. - Rustls is at https://github.com/ctz/rustls/. + This refactors the session setup into its own function, and adds a new + function cr_hostname_is_ip. Because crustls doesn't support verification + of IP addresses, special handling is needed: We disable SNI and set a + placeholder hostname (which never actually gets sent on the wire). - There is still a fair bit to be done, like sending CloseNotify on - connection shutdown, respecting CAPATH, and properly indicating features - like "supports TLS 1.3 ciphersuites." But it works well enough to make - requests and receive responses. + Closes #6719 + +Daniel Gustafsson (12 Mar 2021) +- cookies: Fix potential NULL pointer deref with PSL - Blog post for context: - https://www.abetterinternet.org/post/memory-safe-curl/ + Curl_cookie_init can be called with data being NULL, and this can in turn + be passed to Curl_cookie_add, meaning that both functions must be careful + to only use data where it's checked for being a NULL pointer. The libpsl + support code does however dereference data without checking, so if we are + indeed having an unset data pointer we cannot PSL check the cookiedomain. - Closes #6350 + This is currently not a reachable dereference, as the only caller with a + NULL data isn't passing a file to initialize cookies from, but since the + API has this contract let's ensure we hold it. + + Closes #6731 + Reviewed-by: Daniel Stenberg -- [Simon Josefsson brought this change] +Daniel Stenberg (12 Mar 2021) +- [Michael Hordijk brought this change] - sasl: support SCRAM-SHA-1 and SCRAM-SHA-256 via libgsasl + configure: only add OpenSSL paths if they are defined - Closes #6372 + Add paths for OpenSSL compiling and linking only if they have been + defined. If they haven't been defined, we'll assume that the paths are + already available to the toolchain. + + Closes #6730 -Jay Satiro (9 Feb 2021) -- lib: use int type for more port variables +Jay Satiro (12 Mar 2021) +- retry.d: Clarify transient 5xx HTTP response codes - This is a follow-up to 764c6bd. Prior to that change port variables - were usually type long. + - Clarify the only 5xx response codes that are treated as transient are + 500, 502, 503 and 504. - Closes https://github.com/curl/curl/pull/6553 - -- tool_writeout: refactor write-out and write-out json + Prior to this change it said it treated all 5xx as transient, but the + code says otherwise. - - Deduplicate the logic used by write-out and write-out json. + Ref: https://github.com/curl/curl/blob/curl-7_75_0/src/tool_operate.c#L462-L495 - Rather than have separate writeLong, writeString, etc, logic for - each of write-out and write-out json instead have respective shared - functions that can output either format and a 'use_json' parameter to - indicate whether it is json that is output. + Closes https://github.com/curl/curl/pull/6724 + +- retry-all-errors.d: Explain curl errors versus HTTP response errors - This will make it easier to maintain. Rather than have to go through - two sets of logic now we only have to go through one. + - Add a paragraph explaining that curl does not consider HTTP response + errors as curl errors, and how that behavior can be modified by using + --retry and --fail. - - Support write-out %{errormsg} and %{exitcode} in json. + The --retry-all-errors doc says "Retry on any error" which some users + may find misleading without the added explanation. - - Clarify in the doc that %{exitcode} is the exit code of the transfer. + Ref: https://curl.se/docs/faq.html#Why_do_I_get_downloaded_data_eve + Ref: https://curl.se/docs/faq.html#curl_doesn_t_return_error_for_HT - Prior to this change it just said "The numerical exitcode" which - implies it's the exit code of the tool, and it's not necessarily that. + Reported-by: Lawrence Gripper - Closes https://github.com/curl/curl/pull/6544 + Fixes https://github.com/curl/curl/issues/6712 + Closes https://github.com/curl/curl/pull/6720 -- lib: drop USE_SOCKETPAIR in favor of CURL_DISABLE_SOCKETPAIR +Daniel Stenberg (11 Mar 2021) +- travis: switch ngtcp2 build over to quictls - .. since the former is undocumented and they both do the same thing. + The ngtcp2 project switched over to using the quictls OpenSSL fork + instead of their own patched OpenSSL. We follow suit. - Closes https://github.com/curl/curl/pull/6517 + Closes #6729 -- curl_multibyte: fall back to local code page stat/access on Windows +- test220/314: adjust to run with Hyper + +- c-hyper: support automatic content-encoding - If libcurl is built with Unicode support for Windows then it is assumed - the filename string is Unicode in UTF-8 encoding and it is converted to - UTF-16 to be passed to the wide character version of the respective - function (eg wstat). However the filename string may actually be in the - local encoding so, even if it successfully converted to UTF-16, if it - could not be stat/accessed then try again using the local code page - version of the function (eg wstat fails try stat). + Closes #6727 + +- http: remove superfluous NULL assign - We already do this with fopen (ie wfopen fails try fopen), so I think it - makes sense to extend it to stat and access functions. + Closes #6727 + +- tool_operate: bail if set CURLOPT_HTTP09_ALLOWED returns error - Closes https://github.com/curl/curl/pull/6514 + Closes #6727 -- [Stephan Szabo brought this change] +- setopt: error on CURLOPT_HTTP09_ALLOWED set true with Hyper + + Not supported. + + Closes #6727 - file: Support unicode urls on windows +- test306: make it not run with Hyper - Closes https://github.com/curl/curl/pull/6501 + ... as it tests HTTP/0.9 which Hyper doesn't support. -- [Vincent Torri brought this change] +- test304: header CRLF cleanup to work with Hyper - cmake: fix import library name for non-MS compiler on Windows +- FTP: allow SIZE to fail when doing (resumed) upload - - Use _imp.lib suffix only for Microsoft's compiler (MSVC). + Added test 362 to verify. - Prior to this change library suffix _imp.lib was used for the import - library on Windows regardless of compiler. + Reported-by: Jordan Brown + Regression since 7ea2e1d0c5a7f (7.73.0) + Fixes #6715 + Closes #6725 + +- configure: provide Largefile feature for curl-config - With this change the other compilers should now use their default - suffix which should be .dll.a. + ... as cmake now does it correctly, and make test1014 check for it - This change is motivated by the usage of pkg-config on MSYS2. - Indeed, when 'pkg-config --libs libcurl' is used, -lcurl is - passed to ld. The documentation of ld on Windows : + Closes #6702 + +- config: remove CURL_SIZEOF_CURL_OFF_T use only SIZEOF_CURL_OFF_T - https://sourceware.org/binutils/docs/ld/WIN32.html + Make the code consistently use a single name for the size of the + "curl_off_t" type. - lists, in the 'direct linking to a dll' section, the pattern - of the searched import library, and libcurl_imp.lib is not there. + Closes #6702 + +Jay Satiro (10 Mar 2021) +- [Jun-ya Kato brought this change] + + ngtcp2: Fix build error due to change in ngtcp2_addr_init - Closes https://github.com/curl/curl/pull/6225 + ngtcp2/ngtcp2@b8d90a9 changed the function prototype. + + Closes https://github.com/curl/curl/pull/6716 -Daniel Stenberg (9 Feb 2021) -- urldata: move 'followlocation' to UrlState +Daniel Stenberg (10 Mar 2021) +- [ejanchivdorj brought this change] + + multi: update pending list when removing handle - As this is a state variable it does not belong in UserDefined which is - used to store values set by the user. + when removing a handle, most of the lists are updated but pending list + is not updated. Updating now. - Closes #6582 + Closes #6713 + +- [kokke brought this change] + + lib1536: check ptr against NULL before dereferencing it + + Closes #6710 -- [Ikko Ashimine brought this change] +- [kokke brought this change] - http_proxy: fix typo in http_proxy.c - - settting -> setting + lib1537: check ptr against NULL before dereferencing it - Closes #6583 - -- [Fabian Keil brought this change] + Fixes #6707 + Closes #6708 - tests/server: Bump MAX_TAG_LEN to 200 +- travis: make torture tests skip TLS-SRP tests - This is useful for tests containing HTML inside of sections. - For tags it's not uncommon to be longer than the previous - limit of 79 bytes. + ... as it seems to often hang. - An example of a previously problem-causing tag is: - - which is needed for a Privoxy test for the banners-by-size filter. + Also: skip the "normal" tests as they're already run by many other + builds. - Previously it caused server failures like: - 12:29:05.786961 ====> Client connect - 12:29:05.787116 accept_connection 3 returned 4 - 12:29:05.787194 accept_connection 3 returned 0 - 12:29:05.787285 Read 119 bytes - 12:29:05.787345 Process 119 bytes request - 12:29:05.787407 Got request: GET /banners-by-size/9 HTTP/1.1 - 12:29:05.787464 Requested test number 9 part 0 - 12:29:05.787686 getpart() failed with error: -2 - 12:29:05.787744 - request found to be complete (9) - 12:29:05.787912 getpart() failed with error: -2 - 12:29:05.788048 Wrote request (119 bytes) input to log/server.input - 12:29:05.788157 Send response test9 section - 12:29:05.788443 getpart() failed with error: -2 - 12:29:05.788498 instructed to close connection after server-reply - 12:29:05.788550 ====> Client disconnect 0 - 12:29:05.871448 exit_signal_handler: 15 - 12:29:05.871714 signalled to die - 12:29:05.872040 ========> IPv4 sws (port 21108 pid: 51758) exits with signal (15) - -- [Fabian Keil brought this change] - - tests/badsymbols.pl: when opening '$incdir' fails include it in the error message - -- [Fabian Keil brought this change] + Closes #6705 - runtests.1: document -o, -P, -L, and -E +- openssl: adapt to v3's new const for a few API calls + + Closes #6703 -- [Fabian Keil brought this change] +- quiche: fix crash when failing to connect + + Reported-by: ウさん + Fixes #6664 + Closes #6701 - runtests.pl: add %TESTNUMBER variable to make copying tests more convenient +- RELEASE-NOTES: synced + + Fixed the release counter and added a missing contributor -- [Fabian Keil brought this change] +- RELEASE-NOTES: synced - runtests.pl: add an -o option to change internal variables +- dynbuf: bump the max HTTP request to 1MB - runtests.pl has lots of internal variables one might want to - change in certain situations, but adding a dedicated option - for every single one of them isn't practical. + Raised from 128KB to allow longer request headers. - Usage: - ./runtests.pl -o TESTDIR=$privoxy_curl_test_dir -o HOSTIP=10.0.0.1 ... - -- [Fabian Keil brought this change] + Reported-by: Carl Zogheib + Fixes #6681 + Closes #6685 - runtests.pl: cleanups +Jay Satiro (6 Mar 2021) +- schannel: Evaluate CURLOPT_SSL_OPTIONS via SSL_SET_OPTION macro - - show the summarized test result in the last line of the report - - do not use $_ after mapping it to a named variable - Doing that makes the code harder to follow. - - log the restraints sorted by the number of their occurrences - - fix language when logging restraints that only occured once - - let runhttpserver() use $TESTDIR instead of $srcdir - ... so it works if a non-default $TESTDIR is being used. - -- [Fabian Keil brought this change] - - runtests.pl: add an -E option to specify an exclude file + - Change use of those options from CURLOPT_SSL_OPTIONS that are not + already evaluated via SSL_SET_OPTION in schannel and secure transport + to use that instead of data->set.ssl.optname. - It can contain additional restraints for test numbers, - keywords and tools. + Example: - The idea is to let third parties like the Privoxy project - distribute an exclude file with their tarballs that specifies - which curl tests are not expected to work when using Privoxy - as a proxy, without having to fork the whole curl test suite. + Evaluate SSL_SET_OPTION(no_revoke) instead of data->set.ssl.no_revoke. - The syntax could be changed to be extendable and maybe - more closely reflect the "curl test" syntax. Currently - it's a bunch of lines like these: + This change is because options set via CURLOPT_SSL_OPTIONS + (data->set.ssl.optname) are separate from those set for HTTPS proxy via + CURLOPT_PROXY_SSL_OPTIONS (data->set.proxy_ssl.optname). The + SSL_SET_OPTION macro determines whether the connection is for HTTPS + proxy and based on that which option to evaluate. - test:$TESTNUMBER:Reason why this test with number $TESTNUMBER should be skipped - keyword:$KEYWORD:Reason why tests whose keywords contain the $KEYWORD should be skipped - tool:$TOOL:Reason why tests with tools that contain $TOOL should be skipped + Since neither Schannel nor Secure Transport backends currently support + HTTPS proxy in libcurl, this change is for posterity and has no other + effect. - To specify multiple $TESTNUMBERs, $KEYWORDs and $TOOLs - on a single line, split them with commas. + Closes https://github.com/curl/curl/pull/6690 -- [Fabian Keil brought this change] +- [kokke brought this change] - runtests.pl: add -L parameter to require additional perl libraries + c-hyper: Remove superfluous pointer check - This is useful to change the behaviour of the script without - having to modify the file itself, for example to use a custom - compareparts() function that ignores header differences that - are expected to occur when an external proxy is being used. + `n` pointer is never NULL once set. Found by static analysis. - Such differences are proxy-specific and thus the modifications - should be maintained together with the proxy. - -- [Fabian Keil brought this change] + Ref: https://github.com/curl/curl/issues/6696 + + Closes https://github.com/curl/curl/pull/6697 - runtests.pl: add a -P option to specify an external proxy +- version.d: Add missing features to the features list - ... that should be used when executing the tests. + - Add missing entries for gsasl, Kerberos, NTLM_WB, TrackMemory, + Unicode and zstd. - The assumption is that the proxy is an HTTP proxy. + - Remove krb4 since it's no longer a feature. - This option should be used together with -L to provide - a customized compareparts() version that knows which - proxy-specific header differences should be ignored. + Reported-by: Ádler Jonas Gross - This option doesn't work for all test types yet. + Fixes https://github.com/curl/curl/issues/6677 + Closes https://github.com/curl/curl/pull/6687 -- [Fabian Keil brought this change] +- [Vladimir Varlamov brought this change] - tests: fixup several tests - - missing CRs and modified %hostip + docs: add missing Arg tag to --stderr - lib556/test556: use a real HTTP version to make test reuse more convenient + Prior to this change the required argument was not shown. - make sure the weekday in Date headers matches the date + curl.1 before: --stderr + curl.1 after: --stderr - test61: replace stray "^M" (5e 4d) at the end of a cookie with a '^M' (0d) + curl --help before: + --stderr Where to redirect stderr - Gets the test working with external proxies like Privoxy again. + curl --help after: + --stderr Where to redirect stderr - Closes #6463 + Closes https://github.com/curl/curl/pull/6692 -- ftp: never set data->set.ftp_append outside setopt +- projects: Update VS projects for OpenSSL 1.1.x - Since the set value then risks getting used like that when the easy - handle is reused by the application. + - Update VS project templates to use the OpenSSL lib names and include + directories for OpenSSL 1.1.x. - Also: renamed the struct field from 'ftp_append' to 'remote_append' - since it is also used for SSH protocols. + This change means the VS project files will now build only with OpenSSL + 1.1.x when an OpenSSL configuration is chosen. Prior to this change the + project files built only with OpenSSL 1.0.x (end-of-life) when an + OpenSSL configuration was chosen. - Closes #6579 - -- urldata: remove the 'rtspversion' field + The template changes in this commit were made by script: - from struct connectdata and the corresponding code in http.c that set - it. It was never used for anything! + libeay32.lib => libcrypto.lib + ssleay32.lib => libssl.lib + ..\..\..\..\..\openssl\inc32 => ..\..\..\..\..\openssl\include - Closes #6581 - -- CURLOPT_QUOTE.3: clarify that libcurl doesn't parse what's sent + And since the output directory now contains the includes it's prepended: + ..\..\..\..\..\openssl\build\Win{32,64}\VC{6..15}\{DLL,LIB} + {Debug,Release}\include - ... so passed in commands may confuse libcurl's knowledge of state. + - Change build-openssl.bat to copy the build's include directory to the + output directory (as seen above). - Reported-by: Bodo Bergmann - Fixes #6577 - Closes #6580 - -- [Jacob Hoffman-Andrews brought this change] - - vtls: factor out Curl_ssl_getsock to field of Curl_ssl + Each build has its own opensslconf.h which is different so we can't just + include the source include directory any longer. - Closes #6558 - -- RELEASE-PROCEDURE: remove old release dates, add new - -- docs/SSL-PROBLEMS: enhanced + Note the include directory in the output directory is a full copy from + the build so technically we don't need to include the OpenSSL source + include directory in the template. However, I left it last in case the + user made a custom OpenSSL build using the old method which would put + opensslconf in the OpenSSL source include directory. - Elaborate on the intermediate cert issue, and mention that anything - below TLS 1.2 is generally considered insecure these days. + - Change build-openssl.bat to use a temporary install directory that is + different from the temporary build directory. - Closes #6572 - -- THANKS: remove a Jon Rumsey dupe - -Daniel Gustafsson (5 Feb 2021) -- [nimaje brought this change] - - docs: fix FILE example url in --metalink documentation + For OpenSSL 1.1.x the temporary paths must be separate not a descendant + of the other, otherwise pdb files will be lost between builds. - In a url after :// follows the possibly empty authority part - till the next /, so that url missed a /. + Ref: https://curl.se/mail/lib-2018-10/0049.html + Ref: https://gist.github.com/jay/125191c35bbeb894444eff827651f755 + Ref; https://github.com/openssl/openssl/issues/10005 - Closes #6573 - Reviewed-by: Daniel Stenberg - Reviewed-by: Daniel Gustafsson + Fixes https://github.com/curl/curl/issues/984 + Closes https://github.com/curl/curl/pull/6675 -Daniel Stenberg (5 Feb 2021) -- hostip: fix build with sync resolver +- doh: Inherit CURLOPT_STDERR from user's easy handle - Reported-by: David Goerger - Follow-up from 8335c6417 - Fixes #6566 - Closes #6568 - -- mailmap: Jon Rumsey - -- [Jon Rumsey brought this change] - - gskit: correct the gskit_send() prototype + Prior to this change if the user set their easy handle's error stream + to something other than stderr it was not inherited by the doh handles, + which meant that they would still write to the default standard error + stream (stderr) for verbose output. - gskit_send() first paramater is a pointer to Curl_easy not connectdata - struct. + Bug: https://github.com/curl/curl/issues/6605 + Reported-by: arvids-kokins-bidstack@users.noreply.github.com - Closes #6570 - Fixes #6569 + Closes https://github.com/curl/curl/pull/6661 -- urldata: fix build without HTTP and MQTT +Marc Hoersken (1 Mar 2021) +- CI/azure: replace python-impacket with python3-impacket - Reported-by: Joseph Chen - Fixes #6562 - Closes #6563 + As of this month Azure DevOps uses Ubuntu 20.04 LTS which + no longer supports Python 2 and instead ships Python 3. + + Closes #6678 -- ftp: avoid SIZE when asking for a TYPE A file +- runtests.pl: kill processes locking test log files - ... as we ignore it anyway because servers don't report the correct size - and proftpd even blatantly returns a 550. + Introduce a new runtests.pl command option: -rm - Updates a set of tests accordingly. + For now only required and implemented for Windows. + Ignore stunnel logs due to long running processes. - Reported-by: awesomenode on github - Fixes #6564 - Closes #6565 - -- pingpong: rename the curl_pp_transfer enum to use PP prefix + Requires Sysinternals handle[64].exe to be on PATH. - Using an FTP prefix for PP provided functionality was misleading. - -- RELEASE-NOTES: synced + Reviewed-by: Jay Satiro - ... and bump pending version to 7.75.1 (for now) + Ref: #6058 + Closes #6179 -Jay Satiro (4 Feb 2021) -- build: fix --disable-http-auth +- pathhelp.pm: fix use of pwd -L in Msys environment - Broken since 215db08 (precedes 7.75.0). + While Msys2 has a pwd binary which supports -L, + Msys1 only has a shell built-in with that feature. - Reported-by: Benbuck Nason + Reviewed-by: Jay Satiro - Fixes https://github.com/curl/curl/issues/6567 + Part of #6179 -- build: fix --disable-dateparse +Daniel Gustafsson (1 Mar 2021) +- ldap: use correct memory free function - Broken since 215db08 (precedes 7.75.0). + unescaped is coming from Curl_urldecode and not a unicode conversion + function, so reclaiming its memory should be performed with a normal + call to free rather than curlx_unicodefree. In reality, this is the + same thing as curlx_unicodefree is implemented as a call to free but + that's not guaranteed to always hold. Using the curlx macro present + issues with memory debugging as well. - Bug: https://curl.se/mail/lib-2021-02/0008.html - Reported-by: Firefox OS + Closes #6671 + Reviewed-by: Jay Satiro + Reviewed-by: Daniel Stenberg -Daniel Stenberg (4 Feb 2021) -- [Jon Rumsey brought this change] +- url: fix typo in comment + + Correct a small typo which snuck in with a304051620. - OS400: update for CURLOPT_AWS_SIGV4 +Jay Satiro (28 Feb 2021) +- tool_help: Increase space between option and description - chkstrings fails because a new string option that could require codepage - conversion has been added. + - Increase the minimum number of spaces between the option and the + description from 1 to 2. - Closes #6561 - Fixes #6560 - -- BUG-BOUNTY: removed the cooperation mention - -Version 7.75.0 (3 Feb 2021) + Before: + ~~~ + -u, --user Server user and password + -A, --user-agent Send User-Agent to server + -v, --verbose Make the operation more talkative + -V, --version Show version number and quit + -w, --write-out Use output FORMAT after completion + --xattr Store metadata in extended file attributes + ~~~ + + After: + ~~~ + -u, --user Server user and password + -A, --user-agent Send User-Agent to server + -v, --verbose Make the operation more talkative + -V, --version Show version number and quit + -w, --write-out Use output FORMAT after completion + --xattr Store metadata in extended file attributes + ~~~ + + Closes https://github.com/curl/curl/pull/6674 -Daniel Stenberg (3 Feb 2021) -- RELEASE-NOTES: synced +Daniel Stenberg (27 Feb 2021) +- curl: set CURLOPT_NEW_FILE_PERMS if requested + + The --create-file-mode code logic accepted the value but never actually + passed it on to libcurl! + + Follow-up to a7696c73436f (shipped in 7.75.0) + Reported-by: Johannes Lesr + Fixes #6657 + Closes #6666 -- THANKS: added contributors from 7.75.0 +- tool_operate: check argc before accessing argv[1] + + Follow-up to 09363500b + Reported-by: Emil Engler + Reviewed-by: Daniel Gustafsson + Closes #6668 -- copyright: fix year ranges in need of updates +Daniel Gustafsson (26 Feb 2021) +- [Jean-Philippe Menil brought this change] -- TODO: remove items for next SONAME bump etc + openssl: remove get_ssl_version_txt in favor of SSL_get_version - We want to avoid that completely, so we don't plan for things after such - an event. - -- [Jay Satiro brought this change] + openssl: use SSL_get_version to get connection protocol + + Replace our bespoke get_ssl_version_txt in favor of SSL_get_version. + We can get rid of few lines of code, since SSL_get_version achieve + the exact same thing + + Closes #6665 + Reviewed-by: Daniel Gustafsson + Signed-off-by: Jean-Philippe Menil - ngtcp2: Fix build error due to change in ngtcp2_settings +- gnutls: Fix nettle discovery - - Separate ngtcp2_transport_params. + Commit e06fa7462ac258c removed support for libgcrypt leaving only + support for nettle which has been the default crypto library in + GnuTLS for a long time. There were however a few conditionals on + USE_GNUTLS_NETTLE which cause compilation errors in the metalink + code (as it used the gcrypt fallback instead as a result). See the + below autobuild for an example of the error: - ngtcp2/ngtcp2@05d7adc made ngtcp2_transport_params separate from - ngtcp2_settings. + https://curl.se/dev/log.cgi?id=20210225123226-30704#prob1 - ngtcp2 master is required to build curl with http3 support. + This removes all uses of USE_GNUTLS_NETTLE and also removes the + gcrypt support from the metalink code while at it. - Closes #6554 + Closes #6656 + Reviewed-by: Daniel Stenberg -- vtls: remove md5sum +- cookies: Support multiple -b parameters - As it is not used anymore. + Previously only a single -b cookie parameter was supported with the last + one winning. This adds support for supplying multiple -b params to have + them serialized semicolon separated. Both cookiefiles and cookies can be + entered multiple times. - Reported-by: Jacob Hoffman-Andrews - Bug: https://curl.se/mail/lib-2021-02/0000.html + Closes #6649 + Reviewed-by: Daniel Stenberg + +Daniel Stenberg (25 Feb 2021) +- build: remove all traces of USE_BLOCKING_SOCKETS - Closes #6557 + libcurl doesn't behave properly with the define set + + Closes #6655 -- [Alessandro Ghedini brought this change] +- RELEASE-NOTES: synced - quiche: don't use primary_ip / primary_port +Daniel Gustafsson (25 Feb 2021) +- docs: Fix typos - Closes #6555 - -Alessandro Ghedini (1 Feb 2021) -- travis: enable quiche's FFI feature + Random typos spotted when skimming docs. -Daniel Stenberg (30 Jan 2021) -- [Dmitry Wagin brought this change] +- cookies: Use named parameters in header prototypes + + Align header with project style of using named parameters in the + function prototypes to aid readability and self-documentation. + + Closes #6653 + Reviewed-by: Daniel Stenberg - http: improve AWS HTTP v4 Signature auth +Daniel Stenberg (24 Feb 2021) +- urldata: make 'actions[]' use unsigned char instead of int - - Add support services without region and service prefixes in - the URL endpoint (ex. Min.IO, GCP, Yandex Cloud, Mail.Ru Cloud Solutions, etc) - by providing region and service parameters via aws-sigv4 option. - - Add [:region[:service]] suffix to aws-sigv4 option; - - Fix memory allocation errors. - - Refactor memory management. - - Use Curl_http_method instead() STRING_CUSTOMREQUEST. - - Refactor canonical headers generating. - - Remove repeated sha256_to_hex() usage. - - Add some docs fixes. - - Add some codestyle fixes. - - Add overloaded strndup() for debug - curl_dbg_strndup(). - - Update tests. + ... as it only needs a few bits per index anyway. - Closes #6524 + Reviewed-by: Daniel Gustafsson + Closes #6648 -- hyper: fix CONNECT to set 'data' as userdata +- configure: fail if --with-quiche is used and quiche isn't found - Follow-up to 14e075d1a7fd + Closes #6652 -- [Layla brought this change] +- [Gregor Jasny brought this change] - connect: fix compile errors in `Curl_conninfo_local` + cmake: use CMAKE_INSTALL_INCLUDEDIR indirection - .. for the `#else` (`!HAVE_GETSOCKNAME`) case + Reviewed-by: Sergei Nikulov + Closes #6440 + +Viktor Szakats (23 Feb 2021) +- mingw: enable using strcasecmp() - Fixes https://github.com/curl/curl/issues/6548 - Closes #6549 + This makes the 'Features:' list sorted case-insensitively, + bringing output in-line with *nix builds. - Signed-off-by: Layla - -- [Michał Antoniak brought this change] + Reviewed-by: Jay Satiro + Closes #6644 - transfer: fix GCC 10 warning with flag '-Wint-in-bool-context' +- build: delete unused feature guards - ... and return the error code from the Curl_mime_rewind call. + - `HAVE_STRNCASECMP` + - `HAVE_TCGETATTR` + - `HAVE_TCSETATTR` - Closes #6537 - -- [Michał Antoniak brought this change] - - avoid warning: enum constant in boolean context + Reviewed-by: Jay Satiro + Reviewed-by: Daniel Stenberg + Closes #6645 -- copyright: fix missing year (range) updates +Jay Satiro (23 Feb 2021) +- docs: add CURLOPT_CURLU to 'See also' in curl_url_ functions + + Closes https://github.com/curl/curl/pull/6639 -- RELEASE-NOTES: synced +Daniel Stenberg (23 Feb 2021) +- [Jacob Hoffman-Andrews brought this change] -- openssl: lowercase the hostname before using it for SNI + configure: make hyper opt-in, and fail if missing - ... because it turns out several servers out there don't actually behave - correctly otherwise in spite of the fact that the SNI field is - specifically said to be case insensitive in RFC 6066 section 3. + Previously, configure would look for hyper by default, and use it if + found; otherwise it would not use hyper, and not error. - Reported-by: David Earl - Fixes #6540 - Closes #6543 - -- KNOWN_BUGS: cmake: ExternalProject_Add does not set CURL_CA_PATH + Now, configure will not look for hyper unless --with-hyper is passed. If + configure looks for hyper and fails, it will error. - Closes #6313 - -- KNOWN_BUGS: Multi perform hangs waiting for threaded resolver + Also, add -ld -lpthread -lm to Hyper's libs. I think they are required. - Closes #4852 + Closes #6598 -- KNOWN_BUGS: "pulseUI VPN client" is known to be buggy +- multi: do once-per-transfer inits in before_perform in DID state - First entry in the new section "applications" for known problems in - libcurl using applications. + ... since the state machine might go to RATELIMITING and then back to + PERFORMING doing once-per-transfer inits in that function is wrong and + it caused problems with receiving chunked HTTP and it set the + PRETRANSFER time much too often... - Closes #6306 - -- tool_writeout: make %{errormsg} blank for no errors + Regression from b68dc34af341805aeb7b3715 (shipped in 7.75.0) - Closes #6539 + Reported-by: Amaury Denoyelle + Fixes #6640 + Closes #6641 -Jay Satiro (27 Jan 2021) -- [Gisle Vanem brought this change] +- RELEASE-NOTES: synced - build: fix djgpp builds +- CODE_STYLE.md: fix broken link to INTERNALS - - Update build instructions in packages/DOS/README + ... the link would only work if browsed on GitHub, while this link now + takes the user to the website instead and thus should work on either. - - Extend 'VPATH' with 'vquic' and 'vssh'. + Reported-by: David Demelier + +- curl_url_set.3: mention CURLU_PATH_AS_IS - - Allow 'Makefile.dist' to build both 'lib' and 'src'. + ... it has been supported since the URL API was added. - - Allow using the Windows hosted djgpp cross compiler to build for MSDOS - under Windows. + Bug: https://curl.se/mail/lib-2021-02/0046.html - - 'USE_SSL' -> 'USE_OPENSSL' + Closes #6638 + +Viktor Szakats (21 Feb 2021) +- time: enable 64-bit time_t in supported mingw environments - - Added a 'link_EXE' macro. Etc, etc. + (Unless 32-bit `time_t` is selected manually via the `_USE_32BIT_TIME_T` + mingw macro.) - - Linking 'curl.exe' needs '$(CURLX_CFILES)' too. + Previously, 64-bit `time_t` was enabled on VS2005 and newer only, and + 32-bit `time_t` was used on all other Windows builds. - - Do not pick-up '../lib/djgpp/*.o' files. Recompile locally. + Assisted-by: Jay Satiro + Closes #6636 + +Jay Satiro (20 Feb 2021) +- test1188: Check for --fail HTTP status - - Generate a gzipped 'tool_hugehelp.c' if 'USE_ZLIB=1'. + - Change the test to check for curl error on HTTP 404 Not Found. - - Remove 'djgpp-clean' + test1188 tests "--write-out with %{onerror} and %{urlnum} to stderr". + Prior to this change it did that by specifying a non-existent host which + would cause an error. ISPs may hijack DNS and resolve non-existent hosts + so the test would not work if that was the case. - - Adapt to new C-ares directory structure + Ref: https://en.wikipedia.org/wiki/DNS_hijacking#Manipulation_by_ISPs + Ref: https://github.com/curl/curl/issues/6621 + Ref: https://github.com/curl/curl/pull/6623 - - Use conditional variable assignments + Closes https://github.com/curl/curl/pull/6637 + +- memdebug: close debug logfile explicitly on exit - Clarify the 'conditional variable assignment' in 'common.dj'. + - Use atexit to register a dbg cleanup function that closes the logfile. - Closes https://github.com/curl/curl/pull/6382 - -Daniel Stenberg (27 Jan 2021) -- [Ikko Ashimine brought this change] - - hyper: fix typo in c-hyper.c + LeakSantizier (LSAN) calls _exit() instead of exit() when a leak is + detected on exit so the logfile must be closed explicitly or data could + be lost. Though _exit() does not call atexit handlers such as this, + LSAN's call to _exit() comes after the atexit handlers are called. - settting -> setting + Prior to this change the logfile was not explicitly closed so it was + possible that if LSAN detected a leak and called _exit (which does + not flush or close files like exit) then the logfile could be missing + data. That could then cause curl's memanalyze to report false leaks + (eg a malloc was recorded to the logfile but the corresponding free was + discarded from the buffer instead of written to the logfile, then + memanalyze reports that as a leak). - Closes #6538 - -- libssh2: fix CURL_LIBSSH2_DEBUG-enabled build + Ref: https://github.com/google/sanitizers/issues/1374 - Follow-up to 2dcc940959772a + Bug: https://github.com/curl/curl/pull/6591#issuecomment-780396541 - Reported-by: Gisle Vanem - Bug: https://github.com/curl/curl/commit/2dcc940959772a652f6813fb6bd3092095a4877b#commitcomment-46420088 + Closes https://github.com/curl/curl/pull/6620 -Jay Satiro (27 Jan 2021) -- asyn-thread: fix build for when getaddrinfo missing +- curl_multibyte: always return a heap-allocated copy of string - This is a follow-up to 8315343 which several days ago moved the resolver - pointer into the async struct but did not update the code that uses it - when getaddrinfo is not present. + - Change the Windows char <-> UTF-8 conversion functions to return an + allocated copy of the passed in string instead of the original. - Closes https://github.com/curl/curl/pull/6536 - -Daniel Stenberg (27 Jan 2021) -- urldata: move 'ints' to the end of 'connectdata' + Prior to this change the curlx_convert_ functions would, as what I + assume was an optimization, not make a copy of the passed in string if + no conversion was required. No conversion is required in non-UNICODE + Windows builds since our tchar strings are type char and remain in + whatever the passed in encoding is, which is assumed to be UTF-8 but may + be other encoding. - To optimize storage slightly. + In contrast the UNICODE Windows builds require conversion + (wchar <-> char) and do return a copy. That inconsistency could lead to + programming errors where the developer expects a copy, and does not + realize that won't happen in all cases. - Closes #6534 + Closes https://github.com/curl/curl/pull/6602 -- urldata: store ip version in a single byte +Viktor Szakats (19 Feb 2021) +- http: add new files missed from referrer commit - Closes #6534 + Ref: 44872aefc2d54f297caf2b0cc887df321bc9d791 + Ref: #6591 -- urldata: remove duplicate 'upkeep_interval_ms' from connectdata +- http: add support to read and store the referrer header - ... and rely only on the value already set in Curl_easy. + - add CURLINFO_REFERER libcurl option + - add --write-out '%{referer}' command-line option + - extend --xattr command-line option to fill user.xdg.referrer.url extended + attribute with the referrer (if there was any) - Closes #6534 + Closes #6591 -- urldata: remove 'local_ip' from the connectdata struct +Daniel Stenberg (19 Feb 2021) +- urldata: remove the _ORIG suffix from string names - As the info is already stored in the transfer handle anyway, there's no - need to carry around a duplicate buffer for the life-time of the handle. + It doesn't provide any useful info but only makes the names longer. - Closes #6534 + Closes #6624 -- urldata: remove duplicate port number storage +- url: fix memory leak if OOM in the HSTS handling - ... and use 'int' for ports. We don't use 'unsigned short' since -1 is - still often used internally to signify "unknown value" and 0 - 65535 are - all valid port numbers. + Reported-by: Viktor Szakats + Bug: https://github.com/curl/curl/pull/6627#issuecomment-781626205 - Closes #6534 + Closes #6628 -- urldata: remove the duplicate 'ip_addr_str' field +- gnutls: assume nettle crypto support - ... as the numerical IP address is already stored and kept in 'primary_ip'. + nettle has been the default crypto library with GnuTLS since 2010. By + dropping support for the previous libcrypto, we simplify code. - Closes #6534 + Closes #6625 -- select: convert Curl_select() to private static function +- asyn-ares: use consistent resolve error message - The old function should not be used anywhere anymore (the only remaining - gskit use has to be fixed to instead use Curl_poll or none at all). + ... with the help of Curl_resolver_error() which now is moved from + asyn-thead.c and is provided globally for this purpose. - The static function version is now called our_select() and is only built - if necessary. + Follow-up to 35ca04ce1b77636 - Closes #6531 + Makes test 1188 work for c-ares builds + + Closes #6626 -- Curl_chunker: shrink the struct +Viktor Szakats (18 Feb 2021) +- ci: stop building on freebsd-12-1 - ... by removing a field, converting the hex index into a byte and - rearranging the order. Cuts it down from 48 bytes to 32 on x86_64. + An updated freebsd-12-2 image was added a few months ago, and this + older one is consistently failing to go past `pkginstall`: + ``` + Newer FreeBSD version for package py37-mlt: + To ignore this error set IGNORE_OSVERSION=yes + - package: 1202000 + - running kernel: 1201000 + Ignore the mismatch and continue? [Y/n]: pkg: repository FreeBSD contains packages for wrong OS version: FreeBSD:12:amd64 + ``` - Closes #6527 - -- curl: include the file name in --xattr/--remote-time error msgs - -- curl: s/config->global/global/ in single_transfer() - -- curl: move fprintf outputs to warnf + FreeBSD thread suggests that 12.1 is EOL, and best to avoid. - For setting and getting time of the download. To make the outputs - respect --silent etc. + Ref: https://forums.freebsd.org/threads/78856/ - Reported-by: Viktor Szakats - Fixes #6533 - Closes #6535 - -- [Tatsuhiro Tsujikawa brought this change] + Reviewed-by: Daniel Stenberg + Closes #6622 - ngtcp2: Fix http3 upload stall +Daniel Stenberg (18 Feb 2021) +- test1188: change error from connect to resolve error - Closes #6521 + Using the %NOLISTENPORT to trigger a connection failure is somewhat + "risky" (since it isn't guaranteed to not be listened to) and caused + occasional CI problems. This fix changes the infused error to be a more + reliable one but still verifies the --write-out functionality properly - + which is the purpose of this test. + + Reported-by: Jay Satiro + Fixes #6621 + Closes #6623 -- [Tatsuhiro Tsujikawa brought this change] +- url.c: use consistent error message for failed resolve - ngtcp2: Fix stack buffer overflow +- BUGS: language polish + +- wolfssl: don't store a NULL sessionid - Closes #6521 + This caused a memory leak as the session id cache entry was still + erroneously stored with a NULL sessionid and that would later be treated + as not needed to get freed. + + Reported-by: Gisle Vanem + Fixes #6616 + Closes #6617 -- warnless.h: remove the prototype for curlx_ultosi +- parse_proxy: fix a memory leak in the OOM path - Follow-up to 217552503ff3 + Reported-by: Jay Satiro + Reviewed-by: Jay Satiro + Reviewed-by: Emil Engler + + Closes #6614 + Bug: https://github.com/curl/curl/pull/6591#issuecomment-780396541 -- warnless: remove curlx_ultosi +Jay Satiro (17 Feb 2021) +- url: fix possible use-after-free in default protocol - ... not used anywhere + Prior to this change if the user specified a default protocol and a + separately allocated non-absolute URL was used then it was freed + prematurely, before it was then used to make the replacement URL. - Closes #6530 - -- [Patrick Monnerat brought this change] - - lib: remove conn->data uses + Bug: https://github.com/curl/curl/issues/6604#issuecomment-780138219 + Reported-by: arvids-kokins-bidstack@users.noreply.github.com - Closes #6515 + Closes https://github.com/curl/curl/pull/6613 -- pingpong: remove the 'conn' struct member +Daniel Stenberg (16 Feb 2021) +- multi: rename the multi transfer states - ... as it's superfluous now when Curl_easy is passed in and we can - derive the connection from that instead and avoid the duplicate copy. + While working on documenting the states it dawned on me that step one is + to use more descriptive names on the states. This also changes prefix on + the states to make them shorter in the source. - Closes #6525 + State names NOT ending with *ing are transitional ones. + + Closes #6612 -- hostip/proxy: remove conn->data use +Viktor Szakats (16 Feb 2021) +- http: do not add a referrer header with empty value - Closes #6513 + Previously an empty 'Referer:' header was added to the HTTP request when + passing `--referer ';auto'` or `--referer ''` on the command-line. This + patch makes `--referer` work like `--header 'Referer:'` and will only add + the header if it has a non-zero length value. + + Reviewed-by: Jay Satiro + Closes #6610 -- url: reduce conn->data references +Daniel Stenberg (16 Feb 2021) +- lib: remove 'conn->data' completely - ... there are a few left but let's keep them to last + The Curl_easy pointer struct entry in connectdata is now gone. Just + before commit 215db086e0 landed on January 8, 2021 there were 919 + references to conn->data. - Closes #6512 + Closes #6608 -- scripts/singleuse: add curl_easy_option* +- openldap: pass 'data' to the callbacks instead of 'conn' -Jay Satiro (25 Jan 2021) -- test410: fix for windows +Jay Satiro (15 Feb 2021) +- doh: Fix sharing user's resolve list with DOH handles - - Pass the very long request header via file instead of command line. + - Share the shared object from the user's easy handle with the DOH + handles. - Prior to this change the 49k very long request header string was passed - via command line and on Windows that is too long so it was truncated and - the test would fail (specifically msys CI). + Prior to this change if the user had set a shared object with shared + cached DNS (CURL_LOCK_DATA_DNS) for their easy handle then that wasn't + used by any associated DOH handles, since they used the multi's default + hostcache. - Closes https://github.com/curl/curl/pull/6516 - -Daniel Stenberg (25 Jan 2021) -- libssh2: move data from connection object to transfer object + This change means all the handles now use the same hostcache, which is + either the shared hostcache from the user created shared object if it + exists or if not then the multi's default hostcache. - Readdir data, filenames and attributes are strictly related to the - transfer and not the connection. This also reduces the total size of the - fixed connectdata struct. + Reported-by: Manuj Bhatia - Closes #6519 - -- RELEASE-NOTES: synced - -- [Patrick Monnerat brought this change] + Fixes https://github.com/curl/curl/issues/6589 + Closes https://github.com/curl/curl/pull/6607 - lib: remove conn->data uses +Daniel Stenberg (15 Feb 2021) +- http2: remove conn->data use - Closes #6499 - -- hyper: remove the conn->data references + ... but instead use a private alternative that points to the "driving + transfer" from the connection. We set the "user data" associated with + the connection to be the connectdata struct, but when we drive transfers + the code still needs to know the pointer to the transfer. We can change + the user data to become the Curl_easy handle, but with older nghttp2 + version we cannot dynamically update that pointer properly when + different transfers are used over the same connection. - Closes #6508 + Closes #6520 -- travis: build ngtcp2 --with-gnutls +- openssl: remove conn->data use - ... since they disable it by default since a few days back. + We still make the trace callback function get the connectdata struct + passed to it, since the callback is anchored on the connection. - Closes #6506 - Fixes #6493 - -- hostip: remove conn->data from resolver functions + Repeatedly updating the callback pointer to set 'data' with + SSL_CTX_set_msg_callback_arg() doesn't seem to work, probably because + there might already be messages in the queue with the old pointer. - This also moves the 'async' struct from the connectdata struct into the - Curl_easy struct, which seems like a better home for it. + This code therefore makes sure to set the "logger" handle before using + OpenSSL calls so that the right easy handle gets used for tracing. - Closes #6497 + Closes #6522 -Jay Satiro (22 Jan 2021) -- strerror: skip errnum >= 0 assertion on windows +- RELEASE-NOTES: synced + +Jay Satiro (14 Feb 2021) +- doh: add options to disable ssl verification - On Windows an error number may be greater than INT_MAX and negative once - cast to int. + - New libcurl options CURLOPT_DOH_SSL_VERIFYHOST, + CURLOPT_DOH_SSL_VERIFYPEER and CURLOPT_DOH_SSL_VERIFYSTATUS do the + same as their respective counterparts. - The assertion is checked only in debug builds. + - New curl tool options --doh-insecure and --doh-cert-status do the same + as their respective counterparts. - Closes https://github.com/curl/curl/pull/6504 - -Daniel Stenberg (21 Jan 2021) -- doh: make Curl_doh_is_resolved survive a NULL pointer + Prior to this change DOH SSL certificate verification settings for + verifyhost and verifypeer were supposed to be inherited respectively + from CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER, but due to a bug + were not. As a result DOH verification remained at the default, ie + enabled, and it was not possible to disable. This commit changes + behavior so that the DOH verification settings are independent and not + inherited. - ... if Curl_doh() returned a NULL, this function gets called anyway as - in a asynch procedure. Then the doh struct pointer is NULL and signifies - an OOM situation. + Ref: https://github.com/curl/curl/pull/4579#issuecomment-554723676 - Follow-up to 6246a1d8c6776 + Fixes https://github.com/curl/curl/issues/4578 + Closes https://github.com/curl/curl/pull/6597 -- wolfssh: remove conn->data references - - ... and repair recent build breakage +- hostip: fix crash in sync resolver builds that use DOH - Closes #6507 - -- http: empty reply connection are not left intact + - Guard some Curl_async accesses with USE_CURL_ASYNC instead of + !CURLRES_SYNCH. - ... so mark the connection as closed in this condition to prevent that - verbose message to wrongly appear. + This is another follow-up to 8335c64 which moved the async struct from + the connectdata struct into the Curl_easy struct. A previous follow-up + 6cd167a fixed building for sync resolver by guarding some async struct + accesses with !CURLRES_SYNCH. The problem is since DOH (DNS-over-HTTPS) + is available as an asynchronous secondary resolver the async struct may + be used even when libcurl is built for the sync resolver. That means + that CURLRES_SYNCH and USE_CURL_ASYNC may be defined at the same time. - Reported-by: Matt Holt - Bug: https://twitter.com/mholt6/status/1352130240265375744 - Closes #6503 + Closes https://github.com/curl/curl/pull/6603 -- chunk/encoding: remove conn->data references - - ... by anchoring more functions on Curl_easy instead of connectdata +Daniel Stenberg (13 Feb 2021) +- KNOWN_BUGS: cannot enable LDAPS on Windows with cmake - Closes #6498 + Reported-by: Jack Boos Yu + Closes #6284 -Jay Satiro (20 Jan 2021) -- [Erik Olsson brought this change] +- KNOWN_BUGS: Excessive HTTP/2 packets with TCP_NODELAY + + Reported-by: Alex Xu + Closes #6363 - lib: save a bit of space with some structure packing +- http: use credentials from transfer, not connection - - Reorder some internal struct members so that less padding is used. + HTTP auth "accidentally" worked before this cleanup since the code would + always overwrite the connection credentials with the credentials from + the most recent transfer and since HTTP auth is typically done first + thing, this has not been an issue. It was still wrong and subject to + possible race conditions or future breakage if the sequence of functions + would change. - This is an attempt at saving a bit of space by packing some structs - (using pahole to find the holes) where it might make sense to do - so without losing readability. + The data.set.str[] strings MUST remain unmodified exactly as set by the + user, and the credentials to use internally are instead set/updated in + state.aptr.* - I.e., I tried to avoid separating fields that seem grouped - together (like the cwd... fields in struct ftp_conn for instance). - Also abstained from touching fields behind conditional macros as - that quickly can get complicated. + Added test 675 to verify different credentials used in two requests done + over a reused HTTP connection, which previously behaved wrongly. - Closes https://github.com/curl/curl/pull/6483 + Fixes #6542 + Closes #6545 -Daniel Stenberg (20 Jan 2021) -- INSTALL.md: fix typo +- test433: clear some home dir env variables - Found-by: Marcel Raad - -- [Fabian Keil brought this change] - - http: get CURLOPT_REQUEST_TARGET working with a HTTP proxy + Follow-up to bd6b54ba1f55b5 - Added test 1613 to verify. + ... so that XDG_CONFIG_HOME is the only home dir variable set and thus + used correctly in the test! - Closes #6490 - -- Merge branch 'bagder/curl_range-data-conn' - -- ftp: remove conn->data leftover + Fixes #6599 + Closes #6600 -- curl_range: remove conn->data +- RELEASE-NOTES: synced - Closes #6496 - -- INSTALL: now at 85 operating systems + bumped the version to 7.76.0 -- quiche: fix unused parameter ‘conn’ +- travis: install libgsasl-dev to add that to the builds - Follow-up to 2bdec0b3 + Closes #6588 -- transfer: fix ‘conn’ undeclared mistake for iconv build +- urldata: don't touch data->set.httpversion at run-time - Follow-up to 219d9f8620d - -- doh: allocate state struct on demand + Rename it to 'httpwant' and make a cloned field in the state struct as + well for run-time updates. - ... instead of having it static within the Curl_easy struct. This takes - away 1176 bytes (18%) from the Curl_easy struct that aren't used very - often and instead makes the code allocate it when needed. + Also: refuse non-supported HTTP versions. Verified with test 129. - Closes #6492 + Closes #6585 -- socks: use the download buffer instead +Viktor Szakats (11 Feb 2021) +- tests: disable .curlrc in more environments - The SOCKS code now uses the generic download buffer for temporary - storage during the connection procedure, instead of having its own - private 600 byte buffer that adds to the connectdata struct size. This - works fine because this point the buffer is allocated but is not use for - download yet since the connection hasn't completed. + by also setting CURL_HOME and XDG_CONFIG_HOME envvars to the local + directory. - This reduces the connection struct size by 22% on a 64bit arch! + Reviewed-by: Daniel Stenberg + Fixes #6595 + Closes #6596 + +- docs/Makefile.inc: format to be update-friendly - The SOCKS buffer needs to be at least 600 bytes, and the download buffer - is guaranteed to never be smaller than 1000 bytes. + - one source file per line + - convert tabs to spaces + - do not align line-continuation backslashes + - sort source files alphabetically - Closes #6491 + Reviewed-by: Daniel Stenberg + Closes #6593 -- urldata: make magic be the first struct field +Daniel Stenberg (11 Feb 2021) +- curl: provide libgsasl version and feature info in -V output - By making the `magic` identifier the same size and at the same place - within the structs (easy, multi, share), libcurl will be able to more - reliably detect and safely error out if an application passes in the - wrong handle to APIs. Easier to detect and less likely to cause crashes - if done. + Closes #6592 + +- gsasl: provide CURL_VERSION_GSASL if built-in - Such mixups can't be detected at compile-time due to them being - typedefed void pointers - unless `CURL_STRICTER` is defined. + To let applications know the feature is available. - Closes #6484 + Closes #6592 -- http_chunks: correct and clarify a comment on hexnumber length +- curl: add --fail-with-body - ... and also rename the define for max length. + Prevent both --fail and --fail-with-body on the same command line. - Closes #6489 - -- curl_path: remove conn->data use + Verify with test 349, 360 and 361. - Closes #6487 + Closes #6449 -- transfer: remove conn->data use +- TODO: remove HSTS - Closes #6486 + Provided now since commit 7385610d0c74 -- quic: remove conn->data use +Jay Satiro (10 Feb 2021) +- tests: Fix tests failing due to change in curl --help - Closes #6485 - -- [Fabian Keil brought this change] - - Add test1181: Proxy request with --proxy-header "Connection: Keep-Alive" - -- [Fabian Keil brought this change] - - Add test1180: Proxy request with -H "Proxy-Connection: Keep-Alive" + Follow-up to parent 3183217 which added add missing argument to + --create-file-mode . - At the moment the test fails as curl sends two Proxy-Connection - headers. - -- c-hyper: avoid duplicated Proxy-Connection headers + Ref: https://github.com/curl/curl/issues/6590 -- http: make providing Proxy-Connection header not cause duplicated headers +- tool_help: add missing argument for --create-file-mode - Fixes test 1180 + Prior to this change the required argument was not shown in curl --help. - Bug: https://curl.se/mail/lib-2021-01/0095.html - Reported-by: Fabian Keil - Closes #6472 - -- runtests: preprocess DISABLED to allow conditionals + before: + --create-file-mode File mode for created files - ... with this function provided, we can disable tests for specific - environments and setups directly within this file. + after: + --create-file-mode File mode (octal) for created files - Closes #6477 - -- runtests: turn preprocessing into a separate function + Reported-by: ZimCodes@users.noreply.github.com - ... and remove all other variable substitutions as they're now done once - and for all in the preprocessor. + Fixes https://github.com/curl/curl/issues/6590 -- lib/Makefile.inc: convert to listing each file on its own line +- create-file-mode.d: add missing Arg tag - ... to make it diff friendlier and easier to read. + Prior to this change the required argument was not shown. - Closes #6448 - -- ftplistparser: remove use of conn->data + curl.1 before: --create-file-mode + curl.1 after: --create-file-mode - Closes #6482 - -- lib: more conn->data cleanups + Reported-by: ZimCodes@users.noreply.github.com - Closes #6479 + Fixes https://github.com/curl/curl/issues/6590 -- [Patrick Monnerat brought this change] +Viktor Szakats (10 Feb 2021) +- gsasl: fix errors/warnings building against libgsasl + + - also fix an indentation + - make Curl_auth_gsasl_token() use CURLcode (by Daniel Stenberg) + + Ref: https://github.com/curl/curl/pull/6372#issuecomment-776118711 + Ref: https://github.com/curl/curl/pull/6588 + + Reviewed-by: Jay Satiro + Assisted-by: Daniel Stenberg + Reviewed-by: Simon Josefsson + Closes #6587 - vtls: reduce conn->data use +- Makefile.m32: add support for libgsasl dependency - Closes #6474 + Reviewed-by: Marcel Raad + Closes #6586 -- hyper: deliver data to application with Curl_client_write +Marcel Raad (10 Feb 2021) +- ngtcp2: clarify calculation precedence - ... just as the native code path does. Avoids sending too large data - chunks in the callback and more. + As suggested by Codacy/cppcheck. - Reported-by: Gisle Vanem - Fixes #6462 - Closes #6473 - -- gopher: remove accidental conn->data leftover + Closes https://github.com/curl/curl/pull/6576 -- libssh: avoid plain free() of libssh-memory +- server: remove redundant condition - Since curl's own memory debugging system redefines free() calls to track - and fiddle with memory, it cannot be used on memory allocated by 3rd - party libraries. + `end` is always non-null here. - Third party libraries SHOULD NOT require free() to release allocated - resources for this reason - and libs can use separate healp allocators - on some systems (like Windows) so free() doesn't necessarily work - anyway. + Closes https://github.com/curl/curl/pull/6576 + +- lib: remove redundant code - Filed as an issue with libssh: https://bugs.libssh.org/T268 + Closes https://github.com/curl/curl/pull/6576 + +- mqttd: remove unused variable - Closes #6481 + Closes https://github.com/curl/curl/pull/6576 -- send: assert that Curl_write_plain() has a ->conn when called +- tool_paramhlp: reduce variable scope - To help catch bad invokes. + Closes https://github.com/curl/curl/pull/6576 + +- tests: reduce variable scopes - Closes #6476 + Closes https://github.com/curl/curl/pull/6576 -- test410: verify HTTPS GET with a 49K request header +- lib: reduce variable scopes - skip test 410 for mesalink in the CI as it otherwise hangs "forever" + Closes https://github.com/curl/curl/pull/6576 -- lib: pass in 'struct Curl_easy *' to most functions +- ftp: fix Codacy/cppcheck warning about null pointer arithmetic - ... in most cases instead of 'struct connectdata *' but in some cases in - addition to. + Increment `bytes` only if it is non-null. - - We mostly operate on transfers and not connections. + Closes https://github.com/curl/curl/pull/6576 + +Daniel Stenberg (9 Feb 2021) +- ngtcp2: adapt to the new recv_datagram callback + +- quiche: fix build error: use 'int' for port number - - We need the transfer handle to log, store data and more. Everything in - libcurl is driven by a transfer (the CURL * in the public API). + Follow-up to cb2dc1ba8 + +- ftp: add 'list_only' to the transfer state struct - - This work clarifies and separates the transfers from the connections - better. + and rename it from 'ftp_list_only' since it is also used for SSH and + POP3. The state is updated internally for 'type=D' FTP URLs. - - We should avoid "conn->data". Since individual connections can be used - by many transfers when multiplexing, making sure that conn->data - points to the current and correct transfer at all times is difficult - and has been notoriously error-prone over the years. The goal is to - ultimately remove the conn->data pointer for this reason. + Added test case 1570 to verify. - Closes #6425 + Closes #6578 -Emil Engler (17 Jan 2021) -- docs: fix typos in NEW-PROTOCOL.md +- ftp: add 'prefer_ascii' to the transfer state struct - This fixes a misspelled "it" and a grammatically wrong "-ing" suffix. + ... and make sure the code never updates 'set.prefer_ascii' as it breaks + handle reuse which should use the setting as the user specified it. - Closes #6471 + Added test 1569 to verify: it first makes an FTP transfer with ';type=A' + and then another without type on the same handle and the second should + then use binary. Previously, curl failed this. + + Closes #6578 -Daniel Stenberg (16 Jan 2021) - RELEASE-NOTES: synced -Jay Satiro (16 Jan 2021) -- [Razvan Cojocaru brought this change] +- [Jacob Hoffman-Andrews brought this change] - cmake: expose CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG - - This does for cmake builds what --disable-openssl-auto-load-config - does for autoconf builds. + vtls: initial implementation of rustls backend - Closes https://github.com/curl/curl/pull/6435 - -Daniel Stenberg (15 Jan 2021) -- test1918: verify curl_easy_option_by_name() and curl_easy_option_by_id() + This adds a new TLS backend, rustls. It uses the C-to-rustls bindings + from https://github.com/abetterinternet/crustls. - ... and as a practical side-effect, make sure that the - Curl_easyopts_check() function is asserted in debug builds, which we - want to detect mismatches between the options list in easyoptions.c and - the options in curl.h + Rustls is at https://github.com/ctz/rustls/. - Found-by: Gisle Vanem - Bug: https://github.com/curl/curl/commit/08e8455dddc5e48e58a12ade3815c01ae3da3b64#commitcomment-45991815 + There is still a fair bit to be done, like sending CloseNotify on + connection shutdown, respecting CAPATH, and properly indicating features + like "supports TLS 1.3 ciphersuites." But it works well enough to make + requests and receive responses. - Closes #6461 - -- [Gisle Vanem brought this change] - - easyoptions: add the missing AWS_SIGV4 + Blog post for context: + https://www.abetterinternet.org/post/memory-safe-curl/ - Follow-up from AWS_SIGV4 + Closes #6350 -- schannel_verify: fix safefree call typo - - Follow-up from e87ad71d1ba00519 - - Closes #6459 +- [Simon Josefsson brought this change] -- mime: make sure setting MIMEPOST to NULL resets properly - - ... so that a function can first use MIMEPOST and then set it to NULL to - reset it back to a blank POST. + sasl: support SCRAM-SHA-1 and SCRAM-SHA-256 via libgsasl - Added test 584 to verify the fix. + Closes #6372 + +Jay Satiro (9 Feb 2021) +- lib: use int type for more port variables - Reported-by: Christoph M. Becker + This is a follow-up to 764c6bd. Prior to that change port variables + were usually type long. - Fixes #6455 - Closes #6456 + Closes https://github.com/curl/curl/pull/6553 -- multi: set the PRETRANSFER time-stamp when we switch to PERFORM +- tool_writeout: refactor write-out and write-out json - ... instead of at end of the DO state. This makes the timer more - accurate for the protocols that use the DOING state (such as FTP), and - simplifies how the function (now called init_perform) is called. + - Deduplicate the logic used by write-out and write-out json. - The timer will then include the entire procedure up to PERFORM - - including all instructions for getting the transfer started. + Rather than have separate writeLong, writeString, etc, logic for + each of write-out and write-out json instead have respective shared + functions that can output either format and a 'use_json' parameter to + indicate whether it is json that is output. - Closes #6454 - -- CURLINFO_PRETRANSFER_TIME.3: clarify + This will make it easier to maintain. Rather than have to go through + two sets of logic now we only have to go through one. - ... the timer *does* include the instructions for getting the remote - file. + - Support write-out %{errormsg} and %{exitcode} in json. - Ref: #6452 - Closes #6453 - -- [Gisle Vanem brought this change] - - schannel: plug a memory-leak + - Clarify in the doc that %{exitcode} is the exit code of the transfer. - ... when built without -DUNICODE. + Prior to this change it just said "The numerical exitcode" which + implies it's the exit code of the tool, and it's not necessarily that. - Closes #6457 + Closes https://github.com/curl/curl/pull/6544 -Jay Satiro (14 Jan 2021) -- gitattributes: Set batch files to CRLF line endings on checkout - - If a batch file is run without CRLF line endings (ie LF-only) then - arbitrary behavior may occur. I consider that a bug in Windows, however - the effects can be serious enough (eg unintended code executed) that - we're fixing it in the repo by requiring CRLF line endings for batch - files on checkout. +- lib: drop USE_SOCKETPAIR in favor of CURL_DISABLE_SOCKETPAIR - Prior to this change the checked-out line endings of batch files were - dependent on a user's git preferences. On Windows it is common for git - users to have automatic CRLF conversion enabled (core.autocrlf true), - but those users that don't would run into this behavior. + .. since the former is undocumented and they both do the same thing. - For example a user has reported running the Visual Studio project - generator batch file (projects/generate.bat) and it looped forever. - Output showed that the Windows OS interpreter was occasionally jumping - to arbitrary points in the batch file and executing commands. This - resulted in unintended files being removed (a removal sequence called) - and looping forever. + Closes https://github.com/curl/curl/pull/6517 + +- curl_multibyte: fall back to local code page stat/access on Windows - Ref: https://serverfault.com/q/429594 - Ref: https://stackoverflow.com/q/232651 - Ref: https://www.dostips.com/forum/viewtopic.php?t=8988 - Ref: https://git-scm.com/docs/gitattributes#_checking_out_and_checking_in - Ref: https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#_core_autocrlf + If libcurl is built with Unicode support for Windows then it is assumed + the filename string is Unicode in UTF-8 encoding and it is converted to + UTF-16 to be passed to the wide character version of the respective + function (eg wstat). However the filename string may actually be in the + local encoding so, even if it successfully converted to UTF-16, if it + could not be stat/accessed then try again using the local code page + version of the function (eg wstat fails try stat). - Bug: https://github.com/curl/curl/discussions/6427 - Reported-by: Ganesh Kamath + We already do this with fopen (ie wfopen fails try fopen), so I think it + makes sense to extend it to stat and access functions. - Closes https://github.com/curl/curl/pull/6442 + Closes https://github.com/curl/curl/pull/6514 -Daniel Stenberg (14 Jan 2021) -- tool_operate: spellfix a comment +- [Stephan Szabo brought this change] -- ROADMAP: refreshed + file: Support unicode urls on windows - o removed HSTS - already implemented - o added HTTPS RR records - o mention HTTP/3 completion - -- http_chunks: remove Curl_ prefix from static functions - -- transfer: remove Curl_ prefix from static functions - -- tftp: remove Curl_ prefix from static functions - -- multi: remove Curl_ prefix from static functions - -- ldap: remove Curl_ prefix from static functions - -- doh: remove Curl_ prefix from static functions - -- asyn-ares: remove Curl_ prefix from static functions - -- vtls: remove Curl_ prefix from static functions - -- bearssl: remove Curl_ prefix from static functions - -- mbedtls: remove Curl_ prefix from static functions - -- wolfssl: remove Curl_ prefix from static functions - -- nss: remove Curl_ prefix from static functions - -- gnutls: remove Curl_ prefix from static functions + Closes https://github.com/curl/curl/pull/6501 -- openssl: remove Curl_ prefix from static functions - - ... as we reserve this prefix to library-wide functions. - - Closes #6443 +- [Vincent Torri brought this change] -- nss: get the run-time version instead of build-time + cmake: fix import library name for non-MS compiler on Windows - Closes #6445 - -Jay Satiro (12 Jan 2021) -- tool_doswin: Restore original console settings on CTRL signal + - Use _imp.lib suffix only for Microsoft's compiler (MSVC). - - Move Windows terminal init code from tool_main to tool_doswin. + Prior to this change library suffix _imp.lib was used for the import + library on Windows regardless of compiler. - - Restore the original console settings on CTRL+C and CTRL+BREAK. + With this change the other compilers should now use their default + suffix which should be .dll.a. - Background: On Windows the curl tool changes the console settings to - enable virtual terminal processing (eg color output) if supported - (ie Win 10). The original settings are restored on exit but prior to - this change were not restored in the case of the CTRL signals. + This change is motivated by the usage of pkg-config on MSYS2. + Indeed, when 'pkg-config --libs libcurl' is used, -lcurl is + passed to ld. The documentation of ld on Windows : - Windows VT behavior varies depending on console/powershell/terminal; - refer to the discussion in #6226. + https://sourceware.org/binutils/docs/ld/WIN32.html - Assisted-by: Rich Turner + lists, in the 'direct linking to a dll' section, the pattern + of the searched import library, and libcurl_imp.lib is not there. - Closes https://github.com/curl/curl/pull/6226 + Closes https://github.com/curl/curl/pull/6225 -Daniel Stenberg (12 Jan 2021) -- gen.pl: fix perl syntax +Daniel Stenberg (9 Feb 2021) +- urldata: move 'followlocation' to UrlState - Follow-up to 324cf1d2e + As this is a state variable it does not belong in UserDefined which is + used to store values set by the user. + + Closes #6582 -- [Emil Engler brought this change] +- [Ikko Ashimine brought this change] - help: update to current codebase + http_proxy: fix typo in http_proxy.c - This commit bumps the help to the current state of the project. + settting -> setting - Closes #6437 + Closes #6583 -- [Emil Engler brought this change] +- [Fabian Keil brought this change] - docs: fix line length bug in gen.pl + tests/server: Bump MAX_TAG_LEN to 200 - The script warns if the length of $opt and $desc is > 78. However, these - two variables are on totally separate lines so the check makes no sense. - Also the $bitmask field is totally forgotten. Currently this leads to - two warnings within `--resolve` and `--aws-sigv4`. + This is useful for tests containing HTML inside of sections. + For tags it's not uncommon to be longer than the previous + limit of 79 bytes. - Closes #6438 + An example of a previously problem-causing tag is: + + which is needed for a Privoxy test for the banners-by-size filter. + + Previously it caused server failures like: + 12:29:05.786961 ====> Client connect + 12:29:05.787116 accept_connection 3 returned 4 + 12:29:05.787194 accept_connection 3 returned 0 + 12:29:05.787285 Read 119 bytes + 12:29:05.787345 Process 119 bytes request + 12:29:05.787407 Got request: GET /banners-by-size/9 HTTP/1.1 + 12:29:05.787464 Requested test number 9 part 0 + 12:29:05.787686 getpart() failed with error: -2 + 12:29:05.787744 - request found to be complete (9) + 12:29:05.787912 getpart() failed with error: -2 + 12:29:05.788048 Wrote request (119 bytes) input to log/server.input + 12:29:05.788157 Send response test9 section + 12:29:05.788443 getpart() failed with error: -2 + 12:29:05.788498 instructed to close connection after server-reply + 12:29:05.788550 ====> Client disconnect 0 + 12:29:05.871448 exit_signal_handler: 15 + 12:29:05.871714 signalled to die + 12:29:05.872040 ========> IPv4 sws (port 21108 pid: 51758) exits with signal (15) -- [Emil Engler brought this change] +- [Fabian Keil brought this change] - docs: fix wrong documentation in help.d - - curl does not list all categories when you invoke "--help" without any - parameters. - - Closes #6436 + tests/badsymbols.pl: when opening '$incdir' fails include it in the error message -- aws-sigv4.d: polish the wording - - Make it shorter and imperative form - - Closes #6439 +- [Fabian Keil brought this change] + + runtests.1: document -o, -P, -L, and -E - [Fabian Keil brought this change] - misc: fix typos - - Bug: https://curl.se/mail/lib-2021-01/0063.html - Closes #6434 + runtests.pl: add %TESTNUMBER variable to make copying tests more convenient -- multi_runsingle: bail out early on data->conn == NULL +- [Fabian Keil brought this change] + + runtests.pl: add an -o option to change internal variables - As that's a significant error condition and scan-build warns for NULL - pointer dereferences if we don't. + runtests.pl has lots of internal variables one might want to + change in certain situations, but adding a dedicated option + for every single one of them isn't practical. - Closes #6433 + Usage: + ./runtests.pl -o TESTDIR=$privoxy_curl_test_dir -o HOSTIP=10.0.0.1 ... -- multi: skip DONE state if there's no connection left for ftp wildcard +- [Fabian Keil brought this change] + + runtests.pl: cleanups - ... to avoid running in that state with data->conn being NULL. + - show the summarized test result in the last line of the report + - do not use $_ after mapping it to a named variable + Doing that makes the code harder to follow. + - log the restraints sorted by the number of their occurrences + - fix language when logging restraints that only occured once + - let runhttpserver() use $TESTDIR instead of $srcdir + ... so it works if a non-default $TESTDIR is being used. -- libssh2: fix "Value stored to 'readdir_len' is never read" - - Detected by scan-build +- [Fabian Keil brought this change] -- connect: mark intentional ignores of setsockopt return values - - Pointed out by Coverity + runtests.pl: add an -E option to specify an exclude file - Closes #6431 - -Jay Satiro (11 Jan 2021) -- http_proxy: Fix CONNECT chunked encoding race condition + It can contain additional restraints for test numbers, + keywords and tools. - - During the end-of-headers response phase do not mark the tunnel - complete unless the response body was completely parsed/ignored. + The idea is to let third parties like the Privoxy project + distribute an exclude file with their tarballs that specifies + which curl tests are not expected to work when using Privoxy + as a proxy, without having to fork the whole curl test suite. - Prior to this change if the entirety of a CONNECT response with chunked - encoding was not received by the time the final header was parsed then - the connection would be marked done prematurely, before all the chunked - data could be read in and ignored (since this is what we do with any - CONNECT response body) and the connection could not be used. + The syntax could be changed to be extendable and maybe + more closely reflect the "curl test" syntax. Currently + it's a bunch of lines like these: - Bug: https://curl.se/mail/lib-2021-01/0033.html - Reported-by: Fabian Keil + test:$TESTNUMBER:Reason why this test with number $TESTNUMBER should be skipped + keyword:$KEYWORD:Reason why tests whose keywords contain the $KEYWORD should be skipped + tool:$TOOL:Reason why tests with tools that contain $TOOL should be skipped - Closes https://github.com/curl/curl/pull/6432 + To specify multiple $TESTNUMBERs, $KEYWORDs and $TOOLs + on a single line, split them with commas. -Daniel Stenberg (11 Jan 2021) -- RELEASE-NOTES: synced +- [Fabian Keil brought this change] -- url: if IDNA conversion fails, fallback to Transitional + runtests.pl: add -L parameter to require additional perl libraries - This improves IDNA2003 compatiblity. + This is useful to change the behaviour of the script without + having to modify the file itself, for example to use a custom + compareparts() function that ignores header differences that + are expected to occur when an external proxy is being used. - Reported-by: Bubu on github - Fixes #6423 - Closes #6428 + Such differences are proxy-specific and thus the modifications + should be maintained together with the proxy. -- travis: make the Hyper build from its master branch - - Closes #6430 +- [Fabian Keil brought this change] -- http: make 'authneg' also work for Hyper - - When doing a request with a request body expecting a 401/407 back, that - initial request is sent with a zero content-length. Test 177 and more. + runtests.pl: add a -P option to specify an external proxy - Closes #6424 - -Jay Satiro (8 Jan 2021) -- cmake: Add an option to disable libidn2 + ... that should be used when executing the tests. - New option USE_LIBIDN2 defaults to ON for libidn2 detection. Prior to - this change libidn2 detection could not be turned off in cmake builds. + The assumption is that the proxy is an HTTP proxy. - Reported-by: William A Rowe Jr + This option should be used together with -L to provide + a customized compareparts() version that knows which + proxy-specific header differences should be ignored. - Fixes https://github.com/curl/curl/issues/6361 - Closes https://github.com/curl/curl/pull/6362 + This option doesn't work for all test types yet. -Daniel Stenberg (8 Jan 2021) -- HYPER: no longer needs the special branch +- [Fabian Keil brought this change] -- test179: use consistent header line endings + tests: fixup several tests - ... to make "Hyper mode" work better. - -- file: don't provide content-length for directories + missing CRs and modified %hostip - ... as it is misleading. + lib556/test556: use a real HTTP version to make test reuse more convenient - Ref #6379 - Closes #6421 - -- TODO: Directory listing for FILE: + make sure the weekday in Date headers matches the date - Ref #6379 - -- curl.h: add CURLPROTO_GOPHERS as own protocol identifier + test61: replace stray "^M" (5e 4d) at the end of a cookie with a '^M' (0d) - Follow-up to a1f06f32b860, to make sure it can be handled separately - from plain gopher. + Gets the test working with external proxies like Privoxy again. - Closes #6418 + Closes #6463 -- http: have CURLOPT_FAILONERROR fail after all headers +- ftp: never set data->set.ftp_append outside setopt - ... so that Retry-After and other meta-content can still be used. + Since the set value then risks getting used like that when the easy + handle is reused by the application. - Added 1634 to verify. Adjusted test 194 and 281 since --fail now also - includes the header-terminating CRLF in the output before it exits. + Also: renamed the struct field from 'ftp_append' to 'remote_append' + since it is also used for SSH protocols. - Fixes #6408 - Closes #6409 + Closes #6579 -- global_init: debug builds allocates a byte in init - - ... to make build tools/valgrind warn if no curl_global_cleanup is - called. - - This is conditionally only done for debug builds with the env variable - CURL_GLOBAL_INIT set. +- urldata: remove the 'rtspversion' field - Closes #6410 - -- lib/unit tests: add missing curl_global_cleanup() calls - -- travis: adapt to Hyper build change + from struct connectdata and the corresponding code in http.c that set + it. It was never used for anything! - Closes #6419 + Closes #6581 -- pretransfer: setup the User-Agent header here +- CURLOPT_QUOTE.3: clarify that libcurl doesn't parse what's sent - ... and not in the connection setup, as for multiplexed transfers the - connection setup might be skipped and then the transfer would end up - without the set user-agent! + ... so passed in commands may confuse libcurl's knowledge of state. - Reported-by: Flameborn on github - Assisted-by: Andrey Gursky - Assisted-by: Jay Satiro - Assisted-by: Mike Gelfand - Fixes #6312 - Closes #6417 + Reported-by: Bodo Bergmann + Fixes #6577 + Closes #6580 -- test66: disable with Hyper - - ...as Hyper doesn't support HTTP/0.9 +- [Jacob Hoffman-Andrews brought this change] -- c-hyper: poll the tasks until end correctly - - ... makes test 36 work. + vtls: factor out Curl_ssl_getsock to field of Curl_ssl - Closes #6412 + Closes #6558 -- [Gergely Nagy brought this change] +- RELEASE-PROCEDURE: remove old release dates, add new - mk-ca-bundle.pl: deterministic output when using -t +- docs/SSL-PROBLEMS: enhanced - Printing trust purposes are now sorted, making the output deterministic - when running on the same input certdata.txt. + Elaborate on the intermediate cert issue, and mention that anything + below TLS 1.2 is generally considered insecure these days. - Closes #6413 + Closes #6572 -- KNOWN_BUGS: fixed "wolfSSL lacks support for renegotiation" - - Fixed by #6411 +- THANKS: remove a Jon Rumsey dupe -- [Himanshu Gupta brought this change] +Daniel Gustafsson (5 Feb 2021) +- [nimaje brought this change] - wolfssl: add SECURE_RENEGOTIATION support + docs: fix FILE example url in --metalink documentation - Closes #6411 - -- RELEASE-NOTES: synced - -- wolfssl: update copyright year range + In a url after :// follows the possibly empty authority part + till the next /, so that url missed a /. - Follow-up to 7de2e96535e9 + Closes #6573 + Reviewed-by: Daniel Stenberg + Reviewed-by: Daniel Gustafsson -- c-hyper: make CURLE_GOT_NOTHING work - - Test 30 +Daniel Stenberg (5 Feb 2021) +- hostip: fix build with sync resolver - Closes #6407 + Reported-by: David Goerger + Follow-up from 8335c6417 + Fixes #6566 + Closes #6568 -- http_proxy: make CONNECT work with the Hyper backend - - Makes test 80 run - - Closes #6406 +- mailmap: Jon Rumsey -- TODO: --fail-with-body perchance? +- [Jon Rumsey brought this change] -Jay Satiro (4 Jan 2021) -- tool_operate: fix the suppression logic of some error messages - - - Fix the failed truncation and failed writing body error messages to - not be shown unless error messages are shown. (ie the user has - specified -sS, or has not specified -s). - - - Also prefix same error messages with "curl: ", for example: - curl: (23) Failed to truncate, exiting - - Prior to this change the failed truncation error messages would be shown - if not -s, but did not account for -sS which should show. - - Prior to this change the failed writing body error messages would be - shown always. - - Ref: https://curl.se/docs/manpage.html#-S + gskit: correct the gskit_send() prototype - Bug: https://curl.se/mail/archive-2020-12/0017.html - Reported-by: Hongyi Zhao + gskit_send() first paramater is a pointer to Curl_easy not connectdata + struct. - Closes https://github.com/curl/curl/pull/6402 + Closes #6570 + Fixes #6569 -- wolfssl: Support wolfSSL builds missing TLS 1.1 - - The wolfSSL TLS library defines NO_OLD_TLS in some of their build - configurations and that causes the library to be built without TLS 1.1. - For example if MD5 is explicitly disabled when building wolfSSL then - that defines NO_OLD_TLS and the library is built without TLS 1.1 [1]. - - Prior to this change attempting to build curl with a wolfSSL that was - built with NO_OLD_TLS would cause a build link error undefined reference - to wolfTLSv1_client_method. +- urldata: fix build without HTTP and MQTT - [1]: https://github.com/wolfSSL/wolfssl/blob/v4.5.0-stable/configure.ac#L2366 + Reported-by: Joseph Chen + Fixes #6562 + Closes #6563 + +- ftp: avoid SIZE when asking for a TYPE A file - Bug: https://curl.se/mail/lib-2020-12/0121.html - Reported-by: Julian Montes + ... as we ignore it anyway because servers don't report the correct size + and proftpd even blatantly returns a 550. - Closes https://github.com/curl/curl/pull/6388 - -Daniel Stenberg (4 Jan 2021) -- test1633: set appropriate name + Updates a set of tests accordingly. - "--retry with a 429 response and Retry-After:" + Reported-by: awesomenode on github + Fixes #6564 + Closes #6565 -- travis: limit the tests with quiche builds to HTTPS and FTPS only +- pingpong: rename the curl_pp_transfer enum to use PP prefix - ... since it runs into the 50 minute time limit too often otherwise. + Using an FTP prefix for PP provided functionality was misleading. + +- RELEASE-NOTES: synced - Closes #6403 + ... and bump pending version to 7.75.1 (for now) -- HISTORY: added dates to early history +Jay Satiro (4 Feb 2021) +- build: fix --disable-http-auth - Mostly thanks to this archived web page for urlget: + Broken since 215db08 (precedes 7.75.0). - https://web.archive.org/web/19980216125115/http://www.inf.ufrgs.br/~sagula/urlget.html - -- httpauth: make multi-request auth work with custom port + Reported-by: Benbuck Nason - When doing HTTP authentication and a port number set with CURLOPT_PORT, - the code would previously have the URL's port number override as if it - had been a redirect to an absolute URL. + Fixes https://github.com/curl/curl/issues/6567 + +- build: fix --disable-dateparse - Added test 1568 to verify. + Broken since 215db08 (precedes 7.75.0). - Reported-by: UrsusArctos on github - Fixes #6397 - Closes #6400 + Bug: https://curl.se/mail/lib-2021-02/0008.html + Reported-by: Firefox OS -- [Emil Engler brought this change] +Daniel Stenberg (4 Feb 2021) +- [Jon Rumsey brought this change] - language: s/behaviour/behavior/g + OS400: update for CURLOPT_AWS_SIGV4 - We currently use both spellings the british "behaviour" and the american - "behavior". However "behavior" is more used in the project so I think - it's worth dropping the british name. + chkstrings fails because a new string option that could require codepage + conversion has been added. - Closes #6395 + Closes #6561 + Fixes #6560 -- cmdline-opts/retry.d: mention response code 429 as well - - Reported-by: Cherish98 - Bug: https://curl.se/mail/archive-2020-12/0018.html +- BUG-BOUNTY: removed the cooperation mention -- docs/HYPER.md: mention outstanding issues - - To make it more obvious to users what doesn't work (yet) +Version 7.75.0 (3 Feb 2021) + +Daniel Stenberg (3 Feb 2021) +- RELEASE-NOTES: synced + +- THANKS: added contributors from 7.75.0 + +- copyright: fix year ranges in need of updates + +- TODO: remove items for next SONAME bump etc - Closes #6389 + We want to avoid that completely, so we don't plan for things after such + an event. -- COPYING/configure: bump copyright year range +- [Jay Satiro brought this change] -- c-hyper: add timecondition to the request + ngtcp2: Fix build error due to change in ngtcp2_settings - Test 77-78 + - Separate ngtcp2_transport_params. - Closes #6391 - -- c-hyper: make Digest and NTLM work + ngtcp2/ngtcp2@05d7adc made ngtcp2_transport_params separate from + ngtcp2_settings. - Test 64, 65, 67, 68, 69, 70, 72 + ngtcp2 master is required to build curl with http3 support. - Closes #6390 + Closes #6554 -- examples/curlgtk.c: fix the copyright year range +- vtls: remove md5sum - ... and make private functions static. - -- [Olaf Hering brought this change] - - docs/examples: adjust prototypes for CURLOPT_READFUNCTION + As it is not used anymore. - The type of the buffer in curl_read_callback is 'char *', not 'void *'. + Reported-by: Jacob Hoffman-Andrews + Bug: https://curl.se/mail/lib-2021-02/0000.html - Signed-off-by: Olaf Hering - Closes #6392 + Closes #6557 -- examples: fix more empty expression statement has no effect - - Follow-up to 26e46617b9 +- [Alessandro Ghedini brought this change] -- cleanup: fix two empty expression statement has no effect + quiche: don't use primary_ip / primary_port - Follow-up to 26e46617b9 + Closes #6555 -- configure: set -Wextra-semi-stmt for clang with --enable-debug +Alessandro Ghedini (1 Feb 2021) +- travis: enable quiche's FFI feature + +Daniel Stenberg (30 Jan 2021) +- [Dmitry Wagin brought this change] + + http: improve AWS HTTP v4 Signature auth - To have it properly complain on empty statements with no effect. + - Add support services without region and service prefixes in + the URL endpoint (ex. Min.IO, GCP, Yandex Cloud, Mail.Ru Cloud Solutions, etc) + by providing region and service parameters via aws-sigv4 option. + - Add [:region[:service]] suffix to aws-sigv4 option; + - Fix memory allocation errors. + - Refactor memory management. + - Use Curl_http_method instead() STRING_CUSTOMREQUEST. + - Refactor canonical headers generating. + - Remove repeated sha256_to_hex() usage. + - Add some docs fixes. + - Add some codestyle fixes. + - Add overloaded strndup() for debug - curl_dbg_strndup(). + - Update tests. - Ref: #6376 - Closes #6378 + Closes #6524 -- tests/unit: fix empty statements with no effect +- hyper: fix CONNECT to set 'data' as userdata - ... by making macros use "do {} while(0)" + Follow-up to 14e075d1a7fd -- [Paul Groke brought this change] +- [Layla brought this change] - dns: extend CURLOPT_RESOLVE syntax for adding non-permanent entries - - Extend the syntax of CURLOPT_RESOLVE strings: allow using a '+' prefix - (similar to the existing '-' prefix for removing entries) to add - DNS cache entries that will time out just like entries that are added - by libcurl itself. + connect: fix compile errors in `Curl_conninfo_local` - Append " (non-permanent)" to info log message in case a non-permanent - entry is added. + .. for the `#else` (`!HAVE_GETSOCKNAME`) case - Adjust relevant comments to reflect the new behavior. + Fixes https://github.com/curl/curl/issues/6548 + Closes #6549 - Adjust documentation. + Signed-off-by: Layla + +- [Michał Antoniak brought this change] + + transfer: fix GCC 10 warning with flag '-Wint-in-bool-context' - Extend unit1607 to test the new functionality. + ... and return the error code from the Curl_mime_rewind call. - Closes #6294 + Closes #6537 -- schannel: fix "empty expression statement has no effect" - - Bug: https://github.com/curl/curl/commit/8ab78f720ae478d533e30b202baec4b451741579#commitcomment-45445950 - Reported-by: Gisle Vanem - Closes #6381 +- [Michał Antoniak brought this change] -- [Denis Laxalde brought this change] + avoid warning: enum constant in boolean context - docs: remove redundant "better" in --fail help - - Closes #6385 +- copyright: fix missing year (range) updates -- [Kevin Ushey brought this change] +- RELEASE-NOTES: synced - curl.1: fix typo microsft -> microsoft +- openssl: lowercase the hostname before using it for SNI - Closes #6380 - -- [XhmikosR brought this change] - - misc: assorted typo fixes + ... because it turns out several servers out there don't actually behave + correctly otherwise in spite of the fact that the SNI field is + specifically said to be case insensitive in RFC 6066 section 3. - Closes #6375 + Reported-by: David Earl + Fixes #6540 + Closes #6543 -- RELEASE-NOTES: synced +- KNOWN_BUGS: cmake: ExternalProject_Add does not set CURL_CA_PATH + + Closes #6313 -- tool_operate: avoid NULL dereference of first_arg +- KNOWN_BUGS: Multi perform hangs waiting for threaded resolver - Follow-up to 6a5e020d4d2b04a - Identified by OSS-Fuzz - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28999 - Closes #6377 + Closes #4852 -- misc: fix "warning: empty expression statement has no effect" +- KNOWN_BUGS: "pulseUI VPN client" is known to be buggy - Turned several macros into do-while(0) style to allow their use to work - find with semicolon. + First entry in the new section "applications" for known problems in + libcurl using applications. - Bug: https://github.com/curl/curl/commit/08e8455dddc5e48e58a12ade3815c01ae3da3b64#commitcomment-45433279 - Follow-up to 08e8455dddc5e4 - Reported-by: Gisle Vanem - Closes #6376 + Closes #6306 -- KNOWN_BUGS: 6.10 curl never completes Negotiate over HTTP +- tool_writeout: make %{errormsg} blank for no errors - Closes #5235 - Closes #6370 + Closes #6539 -- writeout: fix NULL dereference for "this url" - - Detected by torture test 1029 +Jay Satiro (27 Jan 2021) +- [Gisle Vanem brought this change] + + build: fix djgpp builds - Follow-up to 7a90ddf88f5a + - Update build instructions in packages/DOS/README - Closes #6374 - -- failf: remove newline from formatting strings + - Extend 'VPATH' with 'vquic' and 'vssh'. - ... as failf adds one itself. + - Allow 'Makefile.dist' to build both 'lib' and 'src'. - Also: add an assert() to failf() that triggers on a newline in the - format string! + - Allow using the Windows hosted djgpp cross compiler to build for MSDOS + under Windows. - Closes #6365 - -- [XhmikosR brought this change] - - CI: fix warning with the latest versions + - 'USE_SSL' -> 'USE_OPENSSL' - `git checkout HEAD^2` is no longer needed + - Added a 'link_EXE' macro. Etc, etc. - Closes #6369 - -- INSTALL: update the list known OSes and CPU archs curl has run on + - Linking 'curl.exe' needs '$(CURLX_CFILES)' too. - Closes #6366 - -- [Cherish98 brought this change] - - curl: fix handling of -q option + - Do not pick-up '../lib/djgpp/*.o' files. Recompile locally. - The match of the "-q" option (short for "--disable") should: - a) allow concatenation with other single-letters; and - b) be case-sensitive, lest confusing with "-Q" ("--quote") + - Generate a gzipped 'tool_hugehelp.c' if 'USE_ZLIB=1'. - Closes #6364 - -- tests/badsymbols.pl: ignore stand-alone single hash lines + - Remove 'djgpp-clean' - Bug: https://curl.se/mail/lib-2020-12/0084.html - Reported-by: Dennis Clarke - Assisted-by: Jay Satiro + - Adapt to new C-ares directory structure - Closes #6355 - -- curl_easy_pause.3: add multiplexed pause effects + - Use conditional variable assignments - and generally refresh and update. Remove details for ancient versions. + Clarify the 'conditional variable assignment' in 'common.dj'. - Reviewed-by: Jay Satiro - Closes #6360 + Closes https://github.com/curl/curl/pull/6382 -Jay Satiro (22 Dec 2020) -- curl_easy_pause.3: fix man page reference +Daniel Stenberg (27 Jan 2021) +- [Ikko Ashimine brought this change] + + hyper: fix typo in c-hyper.c - Follow-up to ac9a724 from earlier today. + settting -> setting - Ref: https://github.com/curl/curl/pull/6359 + Closes #6538 -Daniel Stenberg (22 Dec 2020) -- EXPERIMENTAL: add the Hyper backend to the list +- libssh2: fix CURL_LIBSSH2_DEBUG-enabled build - ... of current experimental features in curl. + Follow-up to 2dcc940959772a + + Reported-by: Gisle Vanem + Bug: https://github.com/curl/curl/commit/2dcc940959772a652f6813fb6bd3092095a4877b#commitcomment-46420088 -- speedcheck: exclude paused transfers +Jay Satiro (27 Jan 2021) +- asyn-thread: fix build for when getaddrinfo missing - Paused transfers should not be stopped due to slow speed even when - CURLOPT_LOW_SPEED_LIMIT is set. Additionally, the slow speed timer is - now reset when the transfer is unpaused - as otherwise it would easily - just trigger immediately after unpausing. + This is a follow-up to 8315343 which several days ago moved the resolver + pointer into the async struct but did not update the code that uses it + when getaddrinfo is not present. - Reported-by: Harry Sintonen - Fixes #6358 - Closes #6359 + Closes https://github.com/curl/curl/pull/6536 -- h2: do not wait for RECV on paused transfers +Daniel Stenberg (27 Jan 2021) +- urldata: move 'ints' to the end of 'connectdata' - ... as the socket might be readable all the time when paused and thus - causing a busy-loop. + To optimize storage slightly. - Reported-by: Harry Sintonen - Reviewed-by: Jay Satiro - Fixes #6356 - Closes #6357 + Closes #6534 -- RELEASE-NOTES: synced +- urldata: store ip version in a single byte + + Closes #6534 -- cmdline-opts/gen.pl: return hard on errors +- urldata: remove duplicate 'upkeep_interval_ms' from connectdata - ... as the warnings tend to go unnoticed otherwise! + ... and rely only on the value already set in Curl_easy. - Closes #6354 + Closes #6534 -- examples/libtest: add .checksrc to dist +- urldata: remove 'local_ip' from the connectdata struct - ... so that (auto)builds from tarballs also get the correct instructions. + As the info is already stored in the transfer handle anyway, there's no + need to carry around a duplicate buffer for the life-time of the handle. - Fixes #6176 - Closes #6353 + Closes #6534 -- test: verify new --write-out variables +- urldata: remove duplicate port number storage - Extended test 1029 and added 1188 - -- test970: adapted to the new internal order of variables - -- curl: add variables to --write-out + ... and use 'int' for ports. We don't use 'unsigned short' since -1 is + still often used internally to signify "unknown value" and 0 - 65535 are + all valid port numbers. - In particular, these ones can help a user to create its own error - message when one or transfers fail. + Closes #6534 + +- urldata: remove the duplicate 'ip_addr_str' field - writeout: add 'onerror', 'url', 'urlnum', 'exitcode', 'errormsg' + ... as the numerical IP address is already stored and kept in 'primary_ip'. - onerror - lets a user only show the rest on non-zero exit codes + Closes #6534 + +- select: convert Curl_select() to private static function - url - the input URL used for this transfer + The old function should not be used anywhere anymore (the only remaining + gskit use has to be fixed to instead use Curl_poll or none at all). - urlnum - the numerical URL counter (0 indexed) for this transfer + The static function version is now called our_select() and is only built + if necessary. - exitcode - the numerical exit code for the transfer + Closes #6531 + +- Curl_chunker: shrink the struct - errormsg - obvious + ... by removing a field, converting the hex index into a byte and + rearranging the order. Cuts it down from 48 bytes to 32 on x86_64. - Reported-by: Earnestly on github - Fixes #6199 - Closes #6207 + Closes #6527 -- [Matthias Gatto brought this change] +- curl: include the file name in --xattr/--remote-time error msgs - tests: add very simple AWS HTTP v4 Signature test +- curl: s/config->global/global/ in single_transfer() + +- curl: move fprintf outputs to warnf - Signed-off-by: Matthias Gatto + For setting and getting time of the download. To make the outputs + respect --silent etc. + + Reported-by: Viktor Szakats + Fixes #6533 + Closes #6535 -- [Matthias Gatto brought this change] +- [Tatsuhiro Tsujikawa brought this change] - docs: add AWS HTTP v4 Signature + ngtcp2: Fix http3 upload stall + + Closes #6521 -- [Matthias Gatto brought this change] +- [Tatsuhiro Tsujikawa brought this change] - tool: add AWS HTTP v4 Signature support + ngtcp2: Fix stack buffer overflow - Signed-off-by: Matthias Gatto + Closes #6521 -- [Matthias Gatto brought this change] +- warnless.h: remove the prototype for curlx_ultosi + + Follow-up to 217552503ff3 - http: Make the call to v4 signature +- warnless: remove curlx_ultosi - This patch allow to call the v4 signature introduce in previous commit + ... not used anywhere - Signed-off-by: Matthias Gatto + Closes #6530 -- [Matthias Gatto brought this change] +- [Patrick Monnerat brought this change] - http: introduce AWS HTTP v4 Signature - - It is a security process for HTTP. - - It doesn't seems to be standard, but it is used by some cloud providers. - - Aws: - https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html - Outscale: - https://wiki.outscale.net/display/EN/Creating+a+Canonical+Request - GCP (I didn't test that this code work with GCP though): - https://cloud.google.com/storage/docs/access-control/signing-urls-manually - - most of the code is in lib/http_v4_signature.c - - Information require by the algorithm: - - The URL - - Current time - - some prefix that are append to some of the signature parameters. - - The data extracted from the URL are: the URI, the region, - the host and the API type - - example: - https://api.eu-west-2.outscale.com/api/latest/ReadNets - ~~~ ~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ - ^ ^ ^ - / \ URI - API type region + lib: remove conn->data uses - Small description of the algorithm: - - make canonical header using content type, the host, and the date - - hash the post data - - make canonical_request using custom request, the URI, - the get data, the canonical header, the signed header - and post data hash - - hash canonical_request - - make str_to_sign using one of the prefix pass in parameter, - the date, the credential scope and the canonical_request hash - - compute hmac from date, using secret key as key. - - compute hmac from region, using above hmac as key - - compute hmac from api_type, using above hmac as key - - compute hmac from request_type, using above hmac as key - - compute hmac from str_to_sign using above hmac as key - - create Authorization header using above hmac, prefix pass in parameter, - the date, and above hash + Closes #6515 + +- pingpong: remove the 'conn' struct member - Signed-off-by: Matthias Gatto + ... as it's superfluous now when Curl_easy is passed in and we can + derive the connection from that instead and avoid the duplicate copy. - Closes #5703 - -- [Matthias Gatto brought this change] + Closes #6525 - http: add hmac support for sha256 +- hostip/proxy: remove conn->data use - It seems current hmac implementation use md5 for the hash, - V4 signature require sha256, so I've added the needed struct in - this commit. + Closes #6513 + +- url: reduce conn->data references - I've added the functions that do the hmac in v4 signature file - as a static function ,in the next patch of the serie, - because it's used only by this file. + ... there are a few left but let's keep them to last - Signed-off-by: Matthias Gatto + Closes #6512 -- [Cristian Rodríguez brought this change] +- scripts/singleuse: add curl_easy_option* - connect: on linux, enable reporting of all ICMP errors on UDP sockets - - The linux kernel does not report all ICMP errors back to userspace due - to historical reasons. +Jay Satiro (25 Jan 2021) +- test410: fix for windows - IP*_RECVERR sockopt must be turned on to have the correct behaviour - which is to pass all ICMP errors to userspace. + - Pass the very long request header via file instead of command line. - See https://bugzilla.kernel.org/show_bug.cgi?id=202355 + Prior to this change the 49k very long request header string was passed + via command line and on Windows that is too long so it was truncated and + the test would fail (specifically msys CI). - Closes #6341 + Closes https://github.com/curl/curl/pull/6516 -- curl: add --create-file-mode [mode] +Daniel Stenberg (25 Jan 2021) +- libssh2: move data from connection object to transfer object - This option sets the (octal) mode to use for the remote file when one is - created, using the SFTP, SCP or FILE protocols. When not set, the - default is 0644. + Readdir data, filenames and attributes are strictly related to the + transfer and not the connection. This also reduces the total size of the + fixed connectdata struct. - Closes #6244 + Closes #6519 -- c-hyper: fix compiler warnings - - Identified by clang on windows. - - Reported-by: Gisle Vanem - Bug: 58974d25d8173aec154e593ed9d866da566c9811 +- RELEASE-NOTES: synced + +- [Patrick Monnerat brought this change] + + lib: remove conn->data uses - Closes #6351 + Closes #6499 -- KNOWN_BUGS: Remote recursive folder creation with SFTP +- hyper: remove the conn->data references - Closes #5204 + Closes #6508 -Jay Satiro (20 Dec 2020) -- badsymbols.pl: Add verbose mode -v +- travis: build ngtcp2 --with-gnutls - Use -v as the first option to enable verbose mode which will show source - input, extracted symbol and line info. For example: + ... since they disable it by default since a few days back. - Source: ./../include/curl/typecheck-gcc.h - Symbol: curlcheck_socket_info(info) - Line #423: #define curlcheck_socket_info(info) \ + Closes #6506 + Fixes #6493 + +- hostip: remove conn->data from resolver functions - Ref: https://curl.se/mail/lib-2020-12/0084.html + This also moves the 'async' struct from the connectdata struct into the + Curl_easy struct, which seems like a better home for it. - Closes https://github.com/curl/curl/pull/6349 + Closes #6497 -- KNOWN_BUGS: Secure Transport disabling hostname validation also disables SNI - - That behavior is a limitation of Apple's Secure Transport. +Jay Satiro (22 Jan 2021) +- strerror: skip errnum >= 0 assertion on windows - Reported-by: Cory Benfield - Reported-by: Ian Spence - Confirmed-by: Nick Zitzmann + On Windows an error number may be greater than INT_MAX and negative once + cast to int. - Ref: https://github.com/curl/curl/issues/998 + The assertion is checked only in debug builds. - Closes https://github.com/curl/curl/issues/6347 - Closes https://github.com/curl/curl/pull/6348 + Closes https://github.com/curl/curl/pull/6504 -Daniel Stenberg (18 Dec 2020) -- TODO: alt-svc should fallback if alt-svc doesn't work +Daniel Stenberg (21 Jan 2021) +- doh: make Curl_doh_is_resolved survive a NULL pointer - Closes #4908 + ... if Curl_doh() returned a NULL, this function gets called anyway as + in a asynch procedure. Then the doh struct pointer is NULL and signifies + an OOM situation. + + Follow-up to 6246a1d8c6776 -- travis: restrict the openssl3 job to only run https and ftps tests +- wolfssh: remove conn->data references - ... as it runs too long otherwise and the other tests are verified in - other builds anyway. + ... and repair recent build breakage - Closes #6345 + Closes #6507 -- build: repair http disabled but mqtt enabled build +- http: empty reply connection are not left intact - ... as the mqtt code reuses the "method" originally used for HTTP. + ... so mark the connection as closed in this condition to prevent that + verbose message to wrongly appear. - Closes #6344 - -- [Jon Wilkes brought this change] + Reported-by: Matt Holt + Bug: https://twitter.com/mholt6/status/1352130240265375744 + Closes #6503 - cookie: avoid the C1001 internal compiler error with MSVC 14 +- chunk/encoding: remove conn->data references - Fixes #6112 - Closes #6135 + ... by anchoring more functions on Curl_easy instead of connectdata + + Closes #6498 -- RELEASE-NOTES: synced +Jay Satiro (20 Jan 2021) +- [Erik Olsson brought this change] -- mqtt: handle POST/PUBLISH without a set POSTFIELDSIZE + lib: save a bit of space with some structure packing - Detected by OSS-Fuzz - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28735 + - Reorder some internal struct members so that less padding is used. - Added test 1916 and 1917 to verify. + This is an attempt at saving a bit of space by packing some structs + (using pahole to find the holes) where it might make sense to do + so without losing readability. - Closes #6338 + I.e., I tried to avoid separating fields that seem grouped + together (like the cwd... fields in struct ftp_conn for instance). + Also abstained from touching fields behind conditional macros as + that quickly can get complicated. + + Closes https://github.com/curl/curl/pull/6483 -- travis: add CI job for Hyper build +Daniel Stenberg (20 Jan 2021) +- INSTALL.md: fix typo + + Found-by: Marcel Raad -- tests: updated tests for Hyper +- [Fabian Keil brought this change] -- lib: introduce c-hyper for using Hyper + http: get CURLOPT_REQUEST_TARGET working with a HTTP proxy - ... as an alternative HTTP backend within libcurl. - -- tool_setopt: provide helper output in debug builds + Added test 1613 to verify. - ... for when setopt() returns error. - -- setopt: adjust to Hyper and disabled HTTP builds + Closes #6490 -- rtsp: disable if Hyper is used +- Merge branch 'bagder/curl_range-data-conn' -- getinfo: build with disabled HTTP support +- ftp: remove conn->data leftover -- version: include hyper version +- curl_range: remove conn->data + + Closes #6496 -- docs: add HYPER.md +- INSTALL: now at 85 operating systems -- configure: add --with-hyper +- quiche: fix unused parameter ‘conn’ - As the first (optional) HTTP backend alternative instead of native + Follow-up to 2bdec0b3 + +- transfer: fix ‘conn’ undeclared mistake for iconv build - Close #6110 + Follow-up to 219d9f8620d -- test1522: add debug tracing +- doh: allocate state struct on demand - I used this to track down some issues and I figured I could just as well - keep this extra logging in here for future needs. + ... instead of having it static within the Curl_easy struct. This takes + away 1176 bytes (18%) from the Curl_easy struct that aren't used very + often and instead makes the code allocate it when needed. - Closes #6331 + Closes #6492 -- http: show the request as headers even when split-sending +- socks: use the download buffer instead - When the initial request isn't possible to send in its entirety, the - remainder of request would be delivered to the debug callback as data - and would wrongly be counted internally as body-bytes sent. + The SOCKS code now uses the generic download buffer for temporary + storage during the connection procedure, instead of having its own + private 600 byte buffer that adds to the connectdata struct size. This + works fine because this point the buffer is allocated but is not use for + download yet since the connection hasn't completed. - Extended test 1295 to verify. + This reduces the connection struct size by 22% on a 64bit arch! - Closes #6328 + The SOCKS buffer needs to be at least 600 bytes, and the download buffer + is guaranteed to never be smaller than 1000 bytes. + + Closes #6491 -- multi: when erroring in TOOFAST state, act as for PERFORM +- urldata: make magic be the first struct field - When failing in TOOFAST, the multi_done() wasn't called so the same - cleanup and handling wasn't done like when it fails in PERFORM, which in - the case of FTP could mean that the control connection wouldn't be - marked as "dead" for the CURLE_ABORTED_BY_CALLBACK case. Which caused - ftp_disconnect() to use it to send "QUIT", which could end up waiting - for a response a long time before giving up! + By making the `magic` identifier the same size and at the same place + within the structs (easy, multi, share), libcurl will be able to more + reliably detect and safely error out if an application passes in the + wrong handle to APIs. Easier to detect and less likely to cause crashes + if done. - Reported-by: Tomas Berger - Fixes #6333 - Closes #6337 - -- cmake: enable gophers correctly in curl-config + Such mixups can't be detected at compile-time due to them being + typedefed void pointers - unless `CURL_STRICTER` is defined. - Closes #6336 + Closes #6484 -- test1198/9: add two mqtt publish tests without payload lengths +- http_chunks: correct and clarify a comment on hexnumber length - Closes #6335 - -- tests/mqttd: extract the client id from the correct offset + ... and also rename the define for max length. - Closes #6334 + Closes #6489 -- TODO: Prevent terminal injection when writing to terminal +- curl_path: remove conn->data use - Closes #6150 + Closes #6487 -- Revert "CI/github: work-around for brew breakage on macOS" - - This reverts commit 4cbb17a2cbbbe6337142d39479e21c3990b9c22f. - - ... as the work-around now causes failures. +- transfer: remove conn->data use - Closes #6332 + Closes #6486 -- examples: remove superfluous asterisk uses +- quic: remove conn->data use - ... for function pointers. Breaks in ancient compilers. - -- RELEASE-NOTES: synced + Closes #6485 -- test1272: fix line ending - - Follow-up to f24784f9143 +- [Fabian Keil brought this change] -- URL-SYNTAX: add gophers details + Add test1181: Proxy request with --proxy-header "Connection: Keep-Alive" -- test1272: test gophers +- [Fabian Keil brought this change] -- runtests: add support for gophers, gopher over TLS + Add test1180: Proxy request with -H "Proxy-Connection: Keep-Alive" + + At the moment the test fails as curl sends two Proxy-Connection + headers. -- [parazyd brought this change] +- c-hyper: avoid duplicated Proxy-Connection headers - gopher: Implement secure gopher protocol. - - This commit introduces a "gophers" handler inside the gopher protocol if - USE_SSL is defined. This protocol is no different than the usual gopher - prococol, with the added TLS encapsulation upon connecting. The protocol - has been adopted in the gopher community, and many people have enabled - TLS in their gopher daemons like geomyidae(8), and clients, like clic(1) - and hurl(1). - - I have not implemented test units for this protocol because my knowledge - of Perl is sub-par. However, for someone more knowledgeable it might be - fairly trivial, because the same test that tests the plain gopher - protocol can be used for "gophers" just by adding a TLS listener. +- http: make providing Proxy-Connection header not cause duplicated headers - Signed-off-by: parazyd + Fixes test 1180 - Closes #6208 + Bug: https://curl.se/mail/lib-2021-01/0095.html + Reported-by: Fabian Keil + Closes #6472 -- TODO: Package curl for Windows in a signed installer +- runtests: preprocess DISABLED to allow conditionals - Closes #5424 - -- mqtt: deal with 0 byte reads correctly + ... with this function provided, we can disable tests for specific + environments and setups directly within this file. - OSS-Fuzz found it - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28676 + Closes #6477 + +- runtests: turn preprocessing into a separate function - Closes #6327 + ... and remove all other variable substitutions as they're now done once + and for all in the preprocessor. -- BUG-BOUNTY: minor language update +- lib/Makefile.inc: convert to listing each file on its own line - ... and remove the wording about entries from before 2019 as the "within - 12 months" is still there and covers that. + ... to make it diff friendlier and easier to read. - Closes #6318 + Closes #6448 -- tooĺ_writeout: fix the -w time output units +- ftplistparser: remove use of conn->data - Fix regression from commit fc813f80e1bcac (#6248) that changed the unit - to microseconds instead of seconds with fractions + Closes #6482 + +- lib: more conn->data cleanups - Reported-by: 不确定 - Fixes #6321 - Closes #6322 + Closes #6479 -- quiche: remove fprintf() leftover +- [Patrick Monnerat brought this change] -Jay Satiro (14 Dec 2020) -- KNOWN_BUGS: SHA-256 digest not supported in Windows SSPI builds + vtls: reduce conn->data use - Closes https://github.com/curl/curl/issues/6302 + Closes #6474 -- digest_sspi: Show InitializeSecurityContext errors in verbose mode +- hyper: deliver data to application with Curl_client_write - The error is shown with infof rather than failf so that the user will - see the extended error message information only in verbose mode, and - will still see the standard CURLE_AUTH_ERROR message. For example: + ... just as the native code path does. Avoids sending too large data + chunks in the callback and more. - --- + Reported-by: Gisle Vanem + Fixes #6462 + Closes #6473 + +- gopher: remove accidental conn->data leftover + +- libssh: avoid plain free() of libssh-memory - * schannel: InitializeSecurityContext failed: SEC_E_QOP_NOT_SUPPORTED - (0x8009030A) - The per-message Quality of Protection is not supported by - the security package - * multi_done - * Connection #1 to host 127.0.0.1 left intact - curl: (94) An authentication function returned an error + Since curl's own memory debugging system redefines free() calls to track + and fiddle with memory, it cannot be used on memory allocated by 3rd + party libraries. - --- + Third party libraries SHOULD NOT require free() to release allocated + resources for this reason - and libs can use separate healp allocators + on some systems (like Windows) so free() doesn't necessarily work + anyway. - Ref: https://github.com/curl/curl/issues/6302 + Filed as an issue with libssh: https://bugs.libssh.org/T268 - Closes https://github.com/curl/curl/pull/6315 + Closes #6481 -Daniel Stenberg (13 Dec 2020) -- URL-SYNTAX: add default port numbers and IDNA details +- send: assert that Curl_write_plain() has a ->conn when called - Closes #6316 + To help catch bad invokes. + + Closes #6476 -- URL-SYNTAX: mention how FILE:// access can access network on windows +- test410: verify HTTPS GET with a 49K request header - Closes #6314 + skip test 410 for mesalink in the CI as it otherwise hangs "forever" -Jay Satiro (12 Dec 2020) -- URL-SYNTAX: Document default SMTP port 25 +- lib: pass in 'struct Curl_easy *' to most functions - Note that ports 25 and 587 are common ports for smtp, the former being - the default. + ... in most cases instead of 'struct connectdata *' but in some cases in + addition to. - Closes https://github.com/curl/curl/pull/6310 - -Daniel Stenberg (12 Dec 2020) -- CURLOPT_URL.3: remove scheme specific details + - We mostly operate on transfers and not connections. - ... that are now found in URL-SYNTAX.md + - We need the transfer handle to log, store data and more. Everything in + libcurl is driven by a transfer (the CURL * in the public API). - Closes #6307 - -Dan Fandrich (12 Dec 2020) -- docs: Fix some typos + - This work clarifies and separates the transfers from the connections + better. - [skip ci] - -Daniel Stenberg (12 Dec 2020) -- URL-SYNTAX: mention all supported schemes + - We should avoid "conn->data". Since individual connections can be used + by many transfers when multiplexing, making sure that conn->data + points to the current and correct transfer at all times is difficult + and has been notoriously error-prone over the years. The goal is to + ultimately remove the conn->data pointer for this reason. - Closes #6311 - -- [Douglas R. Reno brought this change] + Closes #6425 - URL-SYNTAX.md: minor language improvements +Emil Engler (17 Jan 2021) +- docs: fix typos in NEW-PROTOCOL.md - Closes #6308 - -- docs/URL-SYNTAX: the URL syntax curl accepts and works with + This fixes a misspelled "it" and a grammatically wrong "-ing" suffix. - Closes #6285 + Closes #6471 -- [0xflotus brought this change] +Daniel Stenberg (16 Jan 2021) +- RELEASE-NOTES: synced - docs: enable syntax highlighting in several docs files +Jay Satiro (16 Jan 2021) +- [Razvan Cojocaru brought this change] + + cmake: expose CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG - ... for better readability + This does for cmake builds what --disable-openssl-auto-load-config + does for autoconf builds. - Closes #6286 + Closes https://github.com/curl/curl/pull/6435 -- test1564/1565: require the 'wakeup' feature to run +Daniel Stenberg (15 Jan 2021) +- test1918: verify curl_easy_option_by_name() and curl_easy_option_by_id() - Fixes #6299 - Fixes #6300 - Closes #6301 + ... and as a practical side-effect, make sure that the + Curl_easyopts_check() function is asserted in debug builds, which we + want to detect mismatches between the options list in easyoptions.c and + the options in curl.h + + Found-by: Gisle Vanem + Bug: https://github.com/curl/curl/commit/08e8455dddc5e48e58a12ade3815c01ae3da3b64#commitcomment-45991815 + + Closes #6461 -- runtests: add 'wakeup' as a feature +- [Gisle Vanem brought this change] -- tests/server/disabled: add "wakeup" + easyoptions: add the missing AWS_SIGV4 - To allow the test suite to know if wakeup support is disabled in the - build. - -- lib1564/5: verify that curl_multi_wakeup returns OK + Follow-up from AWS_SIGV4 -- tests: make --libcurl tests only test FTP options if ftp enabled +- schannel_verify: fix safefree call typo - Adjust six --libcurl tests to only check the FTP option if FTP is - actually present in the build. + Follow-up from e87ad71d1ba00519 - Fixes #6303 - Closes #6305 + Closes #6459 -- runtests.pl: fix "uninitialized value" warning +- mime: make sure setting MIMEPOST to NULL resets properly - follow-up to e12825c642a88774 - -- runtests: add support for %if [feature] conditions + ... so that a function can first use MIMEPOST and then set it to NULL to + reset it back to a blank POST. - ... to make tests run differently or expect different results depending - on what features that are present or not in curl. + Added test 584 to verify the fix. - Bonus: initial minor 'Hyper' awareness but nothing is using that yet + Reported-by: Christoph M. Becker - Closes #6304 - -- [Jon Rumsey brought this change] + Fixes #6455 + Closes #6456 - OS400: update ccsidcurl.c +- multi: set the PRETRANSFER time-stamp when we switch to PERFORM - Add 'struct' to cast and declaration of cfcdata to fix compilation - error. + ... instead of at end of the DO state. This makes the timer more + accurate for the protocols that use the DOING state (such as FTP), and + simplifies how the function (now called init_perform) is called. - Fixes #6292 - Closes #6297 + The timer will then include the entire procedure up to PERFORM - + including all instructions for getting the transfer started. + + Closes #6454 -- ngtcp2: make it build it current master again +- CURLINFO_PRETRANSFER_TIME.3: clarify - Closes #6296 + ... the timer *does* include the instructions for getting the remote + file. + + Ref: #6452 + Closes #6453 -- [Cristian Rodríguez brought this change] +- [Gisle Vanem brought this change] - connect: defer port selection until connect() time + schannel: plug a memory-leak - If supported, defer port selection until connect() time - if --interface is given and source port is 0. + ... when built without -DUNICODE. - Reproducer: + Closes #6457 + +Jay Satiro (14 Jan 2021) +- gitattributes: Set batch files to CRLF line endings on checkout - * start fast webserver on port 80 - * starve system of ephemeral ports - $ sysctl net.ipv4.ip_local_port_range="60990 60999" + If a batch file is run without CRLF line endings (ie LF-only) then + arbitrary behavior may occur. I consider that a bug in Windows, however + the effects can be serious enough (eg unintended code executed) that + we're fixing it in the repo by requiring CRLF line endings for batch + files on checkout. - * start a curl/libcurl "crawler" - $curl --keepalive --parallel --parallel-immediate --head --interface - 127.0.0.2 "http://127.0.0.[1-254]/file[001-002].txt" + Prior to this change the checked-out line endings of batch files were + dependent on a user's git preferences. On Windows it is common for git + users to have automatic CRLF conversion enabled (core.autocrlf true), + but those users that don't would run into this behavior. - current result: - (possible some successful data) - curl: (45) bind failed with errno 98: Address already in use + For example a user has reported running the Visual Studio project + generator batch file (projects/generate.bat) and it looped forever. + Output showed that the Windows OS interpreter was occasionally jumping + to arbitrary points in the batch file and executing commands. This + resulted in unintended files being removed (a removal sequence called) + and looping forever. - result after patch: - (complete success or few connections failing, higlhy depending on load) + Ref: https://serverfault.com/q/429594 + Ref: https://stackoverflow.com/q/232651 + Ref: https://www.dostips.com/forum/viewtopic.php?t=8988 + Ref: https://git-scm.com/docs/gitattributes#_checking_out_and_checking_in + Ref: https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#_core_autocrlf - Fail only when all the possible 4-tuple combinations are exhausted, - which is impossible to do when port is selected at bind() time becuse - the kernel does not know if socket will be listen()'ed on or connect'ed - yet. + Bug: https://github.com/curl/curl/discussions/6427 + Reported-by: Ganesh Kamath - Closes #6295 + Closes https://github.com/curl/curl/pull/6442 + +Daniel Stenberg (14 Jan 2021) +- tool_operate: spellfix a comment + +- ROADMAP: refreshed + + o removed HSTS - already implemented + o added HTTPS RR records + o mention HTTP/3 completion + +- http_chunks: remove Curl_ prefix from static functions -- [Hans-Christian Noren Egtvedt brought this change] +- transfer: remove Curl_ prefix from static functions - connect: zero variable on stack to silence valgrind complaint - - Valgrind will complain that ssrem buffer usage if not explicit - initialized, hence initialize it to zero. - - This completes the change intially started in commit 2c0d7212151 ('ftp: - retry getpeername for FTP with TCP_FASTOPEN') where the ssloc buffer has - a similar memset to zero. - - Signed-off-by: Hans-Christian Noren Egtvedt - Closes #6289 +- tftp: remove Curl_ prefix from static functions -- RELEASE-NOTES: synced - - start over on the next release cycle +- multi: remove Curl_ prefix from static functions -Version 7.74.0 (9 Dec 2020) +- ldap: remove Curl_ prefix from static functions -Daniel Stenberg (9 Dec 2020) -- RELEASE-NOTES: synced - - for 7.74.0 +- doh: remove Curl_ prefix from static functions -Jay Satiro (7 Dec 2020) -- [Jacob Hoffman-Andrews brought this change] +- asyn-ares: remove Curl_ prefix from static functions - urldata: restore comment on ssl_connect_data.use - - This comment was originally on the `use` field, but was separated from - its field in 62a2534. - - Closes https://github.com/curl/curl/pull/6287 +- vtls: remove Curl_ prefix from static functions -Daniel Stenberg (7 Dec 2020) -- VERSIONS: refreshed - - We always use the patch number these days: all releases are - "major.minor.patch" +- bearssl: remove Curl_ prefix from static functions -- [Jakub Zakrzewski brought this change] +- mbedtls: remove Curl_ prefix from static functions - cmake: don't use reserved target name 'test' - - CMake up to 3.10 always reserves this name - - Fixes #6257 - Closes #6258 +- wolfssl: remove Curl_ prefix from static functions -- openssl: make the OCSP verification verify the certificate id +- nss: remove Curl_ prefix from static functions + +- gnutls: remove Curl_ prefix from static functions + +- openssl: remove Curl_ prefix from static functions - CVE-2020-8286 + ... as we reserve this prefix to library-wide functions. - Reported by anonymous + Closes #6443 + +- nss: get the run-time version instead of build-time - Bug: https://curl.se/docs/CVE-2020-8286.html + Closes #6445 -- ftp: make wc_statemach loop instead of recurse +Jay Satiro (12 Jan 2021) +- tool_doswin: Restore original console settings on CTRL signal - CVE-2020-8285 + - Move Windows terminal init code from tool_main to tool_doswin. - Fixes #6255 - Bug: https://curl.se/docs/CVE-2020-8285.html - Reported-by: xnynx on github - -- ftp: CURLOPT_FTP_SKIP_PASV_IP by default + - Restore the original console settings on CTRL+C and CTRL+BREAK. - The command line tool also independently sets --ftp-skip-pasv-ip by - default. + Background: On Windows the curl tool changes the console settings to + enable virtual terminal processing (eg color output) if supported + (ie Win 10). The original settings are restored on exit but prior to + this change were not restored in the case of the CTRL signals. - Ten test cases updated to adapt the modified --libcurl output. + Windows VT behavior varies depending on console/powershell/terminal; + refer to the discussion in #6226. - Bug: https://curl.se/docs/CVE-2020-8284.html - CVE-2020-8284 + Assisted-by: Rich Turner - Reported-by: Varnavas Papaioannou + Closes https://github.com/curl/curl/pull/6226 -- urlapi: don't accept blank port number field without scheme +Daniel Stenberg (12 Jan 2021) +- gen.pl: fix perl syntax - ... as it makes the URL parser accept "very-long-hostname://" as a valid - host name and we don't want that. The parser now only accepts a blank - (no digits) after the colon if the URL starts with a scheme. + Follow-up to 324cf1d2e + +- [Emil Engler brought this change] + + help: update to current codebase - Reported-by: d4d on hackerone + This commit bumps the help to the current state of the project. - Closes #6283 + Closes #6437 -- Revert "multi: implement wait using winsock events" - - This reverts commit d2a7d7c185f98df8f3e585e5620cbc0482e45fac. +- [Emil Engler brought this change] + + docs: fix line length bug in gen.pl - This commit also reverts the subsequent follow-ups to that commit, which - were all done within windows #ifdefs that are removed in this - change. Marc helped me verify this. + The script warns if the length of $opt and $desc is > 78. However, these + two variables are on totally separate lines so the check makes no sense. + Also the $bitmask field is totally forgotten. Currently this leads to + two warnings within `--resolve` and `--aws-sigv4`. - Fixes #6146 - Closes #6281 + Closes #6438 -- [Klaus Crusius brought this change] +- [Emil Engler brought this change] - ftp: retry getpeername for FTP with TCP_FASTOPEN - - In the case of TFO, the remote host name is not resolved at the - connetion time. + docs: fix wrong documentation in help.d - For FTP that has lead to missing hostname for the secondary connection. - Therefore the name resolution is done at the time, when FTP requires it. + curl does not list all categories when you invoke "--help" without any + parameters. - Fixes #6252 - Closes #6265 - Closes #6282 - -- [Thomas Danielsson brought this change] + Closes #6436 - scripts/completion.pl: parse all opts +- aws-sigv4.d: polish the wording - For tab-completion it may be preferable to include all the - available options. + Make it shorter and imperative form - Closes #6280 + Closes #6439 -- RELEASE-NOTES: synced +- [Fabian Keil brought this change] -- openssl: use OPENSSL_init_ssl() with >= 1.1.0 + misc: fix typos - Reported-by: Kovalkov Dmitrii and Per Nilsson - Fixes #6254 - Fixes #6256 - Closes #6260 + Bug: https://curl.se/mail/lib-2021-01/0063.html + Closes #6434 -- SECURITY-PROCESS: disclose on hackerone +- multi_runsingle: bail out early on data->conn == NULL - Once a vulnerability has been published, the hackerone issue should be - disclosed. For tranparency. + As that's a significant error condition and scan-build warns for NULL + pointer dereferences if we don't. - Closes #6275 + Closes #6433 -Marc Hoersken (3 Dec 2020) -- tests/util.py: fix compatibility with Python 2 - - Backporting the Python 3 implementation of setStream - to ClosingFileHandler as a fallback within Python 2. - - Reported-by: Jay Satiro +- multi: skip DONE state if there's no connection left for ftp wildcard - Fixes #6259 - Closes #6270 + ... to avoid running in that state with data->conn being NULL. -Daniel Gustafsson (3 Dec 2020) -- docs: fix typos and markup in ETag manpage sections +- libssh2: fix "Value stored to 'readdir_len' is never read" - Reported-by: emanruse on github - Fixes #6273 + Detected by scan-build -Daniel Stenberg (2 Dec 2020) -- quiche: close the connection +- connect: mark intentional ignores of setsockopt return values - Reported-by: Junho Choi - Fixes #6213 - Closes #6217 + Pointed out by Coverity + + Closes #6431 -Jay Satiro (2 Dec 2020) -- ngtcp2: Fix build error due to symbol name change +Jay Satiro (11 Jan 2021) +- http_proxy: Fix CONNECT chunked encoding race condition - - NGTCP2_CRYPTO_LEVEL_APP -> NGTCP2_CRYPTO_LEVEL_APPLICATION + - During the end-of-headers response phase do not mark the tunnel + complete unless the response body was completely parsed/ignored. - ngtcp2/ngtcp2@76232e9 changed the name. + Prior to this change if the entirety of a CONNECT response with chunked + encoding was not received by the time the final header was parsed then + the connection would be marked done prematurely, before all the chunked + data could be read in and ignored (since this is what we do with any + CONNECT response body) and the connection could not be used. - ngtcp2 master is required to build curl with http3 support. + Bug: https://curl.se/mail/lib-2021-01/0033.html + Reported-by: Fabian Keil - Closes https://github.com/curl/curl/pull/6271 + Closes https://github.com/curl/curl/pull/6432 -Daniel Stenberg (1 Dec 2020) -- [Klaus Crusius brought this change] +Daniel Stenberg (11 Jan 2021) +- RELEASE-NOTES: synced - cmake: check for linux/tcp.h +- url: if IDNA conversion fails, fallback to Transitional - The HAVE_LINUX_TCP_H define was not set by cmake. + This improves IDNA2003 compatiblity. - Closes #6252 + Reported-by: Bubu on github + Fixes #6423 + Closes #6428 -- NEW-PROTOCOL: document what needs to be done to add one +- travis: make the Hyper build from its master branch - Closes #6263 + Closes #6430 -- splay: rename Curl_splayremovebyaddr to Curl_splayremove +- http: make 'authneg' also work for Hyper - ... and remove the old unused proto for the old Curl_splayremove - version. + When doing a request with a request body expecting a 401/407 back, that + initial request is sent with a zero content-length. Test 177 and more. - Closes #6269 + Closes #6424 -- openssl: free mem_buf in error path +Jay Satiro (8 Jan 2021) +- cmake: Add an option to disable libidn2 - To fix a memory-leak. + New option USE_LIBIDN2 defaults to ON for libidn2 detection. Prior to + this change libidn2 detection could not be turned off in cmake builds. + + Reported-by: William A Rowe Jr + + Fixes https://github.com/curl/curl/issues/6361 + Closes https://github.com/curl/curl/pull/6362 + +Daniel Stenberg (8 Jan 2021) +- HYPER: no longer needs the special branch + +- test179: use consistent header line endings + + ... to make "Hyper mode" work better. + +- file: don't provide content-length for directories + + ... as it is misleading. + + Ref #6379 + Closes #6421 + +- TODO: Directory listing for FILE: - Closes #6267 + Ref #6379 -- openssl: remove #if 0 leftover +- curl.h: add CURLPROTO_GOPHERS as own protocol identifier - Follow-up to 4c9768565ec3a9 (from Sep 2008) + Follow-up to a1f06f32b860, to make sure it can be handled separately + from plain gopher. - Closes #6268 + Closes #6418 -- ntlm: avoid malloc(0) on zero length user and domain +- http: have CURLOPT_FAILONERROR fail after all headers - ... and simplify the too-long checks somewhat. + ... so that Retry-After and other meta-content can still be used. - Detected by OSS-Fuzz + Added 1634 to verify. Adjusted test 194 and 281 since --fail now also + includes the header-terminating CRLF in the output before it exits. - Closes #6264 - -- RELEASE-NOTES: synced + Fixes #6408 + Closes #6409 -Marc Hoersken (28 Nov 2020) -- tests/server/tftpd.c: close upload file in case of abort - - Commit c353207 removed the closing right after do_tftp - which covered the case of abort. This handles that case. +- global_init: debug builds allocates a byte in init - Reviewed-by: Jay Satiro - Reviewed-by: Daniel Stenberg + ... to make build tools/valgrind warn if no curl_global_cleanup is + called. - Follow up to #6209 - Closes #6234 - -Daniel Stenberg (26 Nov 2020) -- [Daiki Ueno brought this change] - - ngtcp2: use the minimal version of QUIC supported by ngtcp2 + This is conditionally only done for debug builds with the env variable + CURL_GLOBAL_INIT set. - Closes #6250 + Closes #6410 -- [Daiki Ueno brought this change] +- lib/unit tests: add missing curl_global_cleanup() calls - ngtcp2: advertise h3 ALPN unconditionally +- travis: adapt to Hyper build change - Closes #6250 - -- [Daiki Ueno brought this change] + Closes #6419 - vquic/ngtcp2.h: define local_addr as sockaddr_storage +- pretransfer: setup the User-Agent header here - This field needs to be wide enough to hold sockaddr_in6 when - connecting via IPv6. Otherwise, ngtcp2_conn_read_pkt will drop the - packets because of the address mismatch: - I00000022 [...] con ignore packet from unknown path + ... and not in the connection setup, as for multiplexed transfers the + connection setup might be skipped and then the transfer would end up + without the set user-agent! - We can safely assume that struct sockaddr_storage is available, as it - is used in the public interface of ngtcp2. + Reported-by: Flameborn on github + Assisted-by: Andrey Gursky + Assisted-by: Jay Satiro + Assisted-by: Mike Gelfand + Fixes #6312 + Closes #6417 + +- test66: disable with Hyper - Closes #6250 + ...as Hyper doesn't support HTTP/0.9 -- socks: check for DNS entries with the right port number +- c-hyper: poll the tasks until end correctly - The resolve call is done with the right port number, but the subsequent - check used the wrong one, which then could find a previous resolve which - would return and leave the fresh resolve "incomplete" and leaking - memory. + ... makes test 36 work. - Fixes #6247 - Closes #6253 + Closes #6412 -- curl_setup: USE_RESOLVE_ON_IPS is for Apple native resolver use - - ... so don't define it when instructed to use c-ares! +- [Gergely Nagy brought this change] -- test506: make it not run in c-ares builds + mk-ca-bundle.pl: deterministic output when using -t - As the asynch nature of it may trigger events in another order. A c-ares - upgrade made it break. + Printing trust purposes are now sorted, making the output deterministic + when running on the same input certdata.txt. - Reported-by: Marc Hörsken - Fixes #6247 + Closes #6413 -- runtests: make 'c-ares' a "feature" to depend on +- KNOWN_BUGS: fixed "wolfSSL lacks support for renegotiation" - ... also added to the docs. + Fixed by #6411 -- tool_writeout: use off_t getinfo-types instead of doubles - - Commit 3b80d3ca46b12e52342 (June 2017) introduced getinfo replacement - variables that use curl_off_t instead of doubles. Switch the --write-out - function over to use them. +- [Himanshu Gupta brought this change] + + wolfssl: add SECURE_RENEGOTIATION support - Closes #6248 + Closes #6411 -- [Emil Engler brought this change] +- RELEASE-NOTES: synced - file: avoid duplicated code sequence - - file_disconnect() is identical with file_do() except the function header - but as the arguments are unused anyway so why not just return file_do() - directly! +- wolfssl: update copyright year range - Reviewed-by: Daniel Stenberg - Closes #6249 - -- [Rikard Falkeborn brought this change] + Follow-up to 7de2e96535e9 - infof/failf calls: fix format specifiers +- c-hyper: make CURLE_GOT_NOTHING work - Update a few format specifiers to match what is being printed. + Test 30 - Closes #6241 + Closes #6407 -- docs/INTERNALS: remove reference to Curl_sendf() +- http_proxy: make CONNECT work with the Hyper backend - The function has been removed from common usage. Also removed comment in - gopher.c that still referenced it. + Makes test 80 run - Reported-by: Rikard Falkeborn - Fixes #6242 - Closes #6243 + Closes #6406 -- [Rikard Falkeborn brought this change] +- TODO: --fail-with-body perchance? - examples: update .gitignore +Jay Satiro (4 Jan 2021) +- tool_operate: fix the suppression logic of some error messages - Add files that are generated by 'make examples' and remove some that - have been renamed. + - Fix the failed truncation and failed writing body error messages to + not be shown unless error messages are shown. (ie the user has + specified -sS, or has not specified -s). - The commits that renamed the programs are e9625c5bc6c046a (imap.c and - simplesmtp.c were renamed to imap-fetch.c and smtp-send.c) and - ad39e7ec01e7 (pop3slist.c and pop3s.c were renamed to pop3-list.c and - pop3-ssl.c). + - Also prefix same error messages with "curl: ", for example: + curl: (23) Failed to truncate, exiting - Closes #6240 - -- asyn: use 'struct thread_data *' instead of 'void *' + Prior to this change the failed truncation error messages would be shown + if not -s, but did not account for -sS which should show. - To reduce use of types that can't be checked at compile time. Also - removes several typecasts. + Prior to this change the failed writing body error messages would be + shown always. - ... and rename the struct field from 'os_specific' to 'tdata'. + Ref: https://curl.se/docs/manpage.html#-S - Closes #6239 - Reviewed-by: Jay Satiro + Bug: https://curl.se/mail/archive-2020-12/0017.html + Reported-by: Hongyi Zhao + + Closes https://github.com/curl/curl/pull/6402 -Viktor Szakats (23 Nov 2020) -- Makefile.m32: add support for UNICODE builds +- wolfssl: Support wolfSSL builds missing TLS 1.1 - It requires the linker to support the `-municode` option. - This is available in more recent mingw-w64 releases. + The wolfSSL TLS library defines NO_OLD_TLS in some of their build + configurations and that causes the library to be built without TLS 1.1. + For example if MD5 is explicitly disabled when building wolfSSL then + that defines NO_OLD_TLS and the library is built without TLS 1.1 [1]. - Ref: https://gcc.gnu.org/onlinedocs/gcc/x86-Windows-Options.html - Ref: https://stackoverflow.com/questions/3571250/wwinmain-unicode-and-mingw/11706847#11706847 + Prior to this change attempting to build curl with a wolfSSL that was + built with NO_OLD_TLS would cause a build link error undefined reference + to wolfTLSv1_client_method. - Reviewed-by: Jay Satiro - Reviewed-by: Marcel Raad + [1]: https://github.com/wolfSSL/wolfssl/blob/v4.5.0-stable/configure.ac#L2366 - Closes #6228 + Bug: https://curl.se/mail/lib-2020-12/0121.html + Reported-by: Julian Montes + + Closes https://github.com/curl/curl/pull/6388 -Daniel Stenberg (23 Nov 2020) -- urldata: remove 'void *protop' and create the union 'p' +Daniel Stenberg (4 Jan 2021) +- test1633: set appropriate name - ... to avoid the use of 'void *' for the protocol specific structs done - per transfer. + "--retry with a 429 response and Retry-After:" + +- travis: limit the tests with quiche builds to HTTPS and FTPS only - Closes #6238 + ... since it runs into the 50 minute time limit too often otherwise. + + Closes #6403 -- winbuild: remove docs from Makefiles and refer to README.md +- HISTORY: added dates to early history - Reduce risk for conflicting docs and makes it to a single place to fix - and polish. + Mostly thanks to this archived web page for urlget: - add these missing options to the readme: + https://web.archive.org/web/19980216125115/http://www.inf.ufrgs.br/~sagula/urlget.html + +- httpauth: make multi-request auth work with custom port - ENABLE_OPENSSL_AUTO_LOAD_CONFIG and ENABLE_UNICODE + When doing HTTP authentication and a port number set with CURLOPT_PORT, + the code would previously have the URL's port number override as if it + had been a redirect to an absolute URL. - clarify ENABLE_SCHANNEL default varies + Added test 1568 to verify. - Fixes #6216 - Closes #6227 - Co-Authored-by: Jay Satiro + Reported-by: UrsusArctos on github + Fixes #6397 + Closes #6400 -- [Daiki Ueno brought this change] +- [Emil Engler brought this change] - http3: use the master branch of GnuTLS for testing + language: s/behaviour/behavior/g - Closes #6235 - -- KNOWN_BUGS: curl with wolfSSL lacks support for renegotiation + We currently use both spellings the british "behaviour" and the american + "behavior". However "behavior" is more used in the project so I think + it's worth dropping the british name. - Closes #5839 + Closes #6395 -- KNOWN_BUGS: wakeup socket disconnect causes havoc +- cmdline-opts/retry.d: mention response code 429 as well - Closes #6132 - Closes #6133 + Reported-by: Cherish98 + Bug: https://curl.se/mail/archive-2020-12/0018.html -- RELEASE-NOTES: synced +- docs/HYPER.md: mention outstanding issues + + To make it more obvious to users what doesn't work (yet) + + Closes #6389 -- [Oliver Urbann brought this change] +- COPYING/configure: bump copyright year range - curl: add compatibility for Amiga and GCC 6.5 +- c-hyper: add timecondition to the request - Changes are mainly reordering and adding of includes required - to compile with a more recent version of GCC. + Test 77-78 - Closes #6220 + Closes #6391 -Marc Hoersken (20 Nov 2020) -- tests/server/tftpd.c: close upload file right after transfer - - Make sure uploaded file is no longer locked after the - transfer while waiting for the final ACK to be handled. +- c-hyper: make Digest and NTLM work - Assisted-by: Daniel Stenberg + Test 64, 65, 67, 68, 69, 70, 72 - Bug: #6058 - Closes #6209 + Closes #6390 -- CI/cirrus: simplify logic for disabled tests - - The OpenSSH server instance for the testsuite cannot - be started on FreeBSD, therefore the SFTP and SCP - tests are disabled right away from the beginning. +- examples/curlgtk.c: fix the copyright year range - The previous OS version specific logic for SKIP_TESTS - is no longer needed/used and can therefore be removed. + ... and make private functions static. + +- [Olaf Hering brought this change] + + docs/examples: adjust prototypes for CURLOPT_READFUNCTION - Reviewed-by: Daniel Stenberg + The type of the buffer in curl_read_callback is 'char *', not 'void *'. - Follow up to #6211 - Closes #6229 + Signed-off-by: Olaf Hering + Closes #6392 -Daniel Gustafsson (20 Nov 2020) -- mailmap: Daniel Hwang - - Add Daniel Hwang to the mailmap to cover the alternative spelling - Daniel Lee Hwang which was used in one commit. +- examples: fix more empty expression statement has no effect - Closes #6230 - Reviewed-by: Daniel Stenberg + Follow-up to 26e46617b9 -- openssl: guard against OOM on context creation +- cleanup: fix two empty expression statement has no effect - EVP_MD_CTX_create will allocate memory for the context and returns - NULL in case the allocation fails. Make sure to catch any allocation - failures and exit early if so. + Follow-up to 26e46617b9 + +- configure: set -Wextra-semi-stmt for clang with --enable-debug - In passing, also move to EVP_DigestInit rather than EVP_DigestInit_ex - as the latter is intended for ENGINE selection which we don't do. + To have it properly complain on empty statements with no effect. - Closes #6224 - Reviewed-by: Daniel Stenberg - Reviewed-by: Emil Engler - -Daniel Stenberg (19 Nov 2020) -- [Vincent Torri brought this change] + Ref: #6376 + Closes #6378 - cmake: use libcurl.rc in all Windows builds +- tests/unit: fix empty statements with no effect - Reviewed-by: Marcel Raad - Closes #6215 + ... by making macros use "do {} while(0)" -- [Cristian Morales Vega brought this change] +- [Paul Groke brought this change] - cmake: make CURL_ZLIB a tri-state variable + dns: extend CURLOPT_RESOLVE syntax for adding non-permanent entries - By differentiating between ON and AUTO it can make a missing zlib - library a hard error when CURL_ZLIB=ON is used. + Extend the syntax of CURLOPT_RESOLVE strings: allow using a '+' prefix + (similar to the existing '-' prefix for removing entries) to add + DNS cache entries that will time out just like entries that are added + by libcurl itself. - Reviewed-by: Jakub Zakrzewski - Closes #6221 - Fixes #6173 - -- quiche: remove 'static' from local buffer + Append " (non-permanent)" to info log message in case a non-permanent + entry is added. - For thread-safety + Adjust relevant comments to reflect the new behavior. - Closes #6223 - -- KNOWN_BUGS: cmake: libspsl is not supported + Adjust documentation. - Closes #6214 - -- KNOWN_BUGS: cmake autodetects cert paths when cross-compiling + Extend unit1607 to test the new functionality. - Closes #6178 + Closes #6294 -- KNOWN_BUGS: cmake build doesn't fail if zlib not found +- schannel: fix "empty expression statement has no effect" - Closes #6173 + Bug: https://github.com/curl/curl/commit/8ab78f720ae478d533e30b202baec4b451741579#commitcomment-45445950 + Reported-by: Gisle Vanem + Closes #6381 -- KNOWN_BUGS: cmake libcurl.pc uses absolute library paths - - Closes #6169 +- [Denis Laxalde brought this change] -- KNOWN_BUGS: cmake: generated .pc file contains strange entries + docs: remove redundant "better" in --fail help - Closes #6167 + Closes #6385 -- KNOWN_BUGS: cmake uses -lpthread instead of Threads::Threads - - Closes #6166 +- [Kevin Ushey brought this change] -- KNOWN_BUGS: cmake build in Linux links libcurl to libdl + curl.1: fix typo microsft -> microsoft - Closes #6165 + Closes #6380 -- KNOWN_BUGS: make a new section for cmake topics +- [XhmikosR brought this change] + + misc: assorted typo fixes - Closes #6219 + Closes #6375 -- [Emil Engler brought this change] +- RELEASE-NOTES: synced - cirrus: build with FreeBSD 12.2 in CirrusCI +- tool_operate: avoid NULL dereference of first_arg - Closes #6211 + Follow-up to 6a5e020d4d2b04a + Identified by OSS-Fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28999 + Closes #6377 -Marc Hoersken (14 Nov 2020) -- tests/*server.py: close log file after each log line - - Make sure the log file is not locked once a test has - finished and align with the behavior of our logmsg. +- misc: fix "warning: empty expression statement has no effect" - Rename curl_test_data.py to be a general util.py. - Format and sort Python imports with isort/VSCode. + Turned several macros into do-while(0) style to allow their use to work + find with semicolon. - Bug: #6058 - Closes #6206 + Bug: https://github.com/curl/curl/commit/08e8455dddc5e48e58a12ade3815c01ae3da3b64#commitcomment-45433279 + Follow-up to 08e8455dddc5e4 + Reported-by: Gisle Vanem + Closes #6376 -Daniel Stenberg (13 Nov 2020) -- CURLOPT_HSTS.3: document the file format +- KNOWN_BUGS: 6.10 curl never completes Negotiate over HTTP - Closes #6205 - -- RELEASE-NOTES: synced - -- release-notes.pl: detect #[number] better for Ref: etc + Closes #5235 + Closes #6370 -- curl: only warn not fail, if not finding the home dir +- writeout: fix NULL dereference for "this url" - ... as there's no good reason to error out completely. + Detected by torture test 1029 - Reported-by: Andreas Fischer - Fixes #6200 - Closes #6201 + Follow-up to 7a90ddf88f5a + + Closes #6374 -- httpput-postfields.c: new example doing PUT with POSTFIELDS +- failf: remove newline from formatting strings - Proposed-by: Jeroen Ooms - Ref: #6186 - Closes #6188 + ... as failf adds one itself. + + Also: add an assert() to failf() that triggers on a newline in the + format string! + + Closes #6365 -- [Tobias Hieta brought this change] +- [XhmikosR brought this change] - cmake: correctly handle linker flags for static libs + CI: fix warning with the latest versions - curl CMake was setting the the EXE flags for static libraries which made - the /manifest:no flag ended up when linking the static library, which is - not a valid flag for lib.exe or llvm-lib.exe and caused llvm-lib to exit - with an error. + `git checkout HEAD^2` is no longer needed - The better way to handle this is to make sure that we pass the correct - linker flags to CMAKE_STATIC_LINKER_FLAGS instead. + Closes #6369 + +- INSTALL: update the list known OSes and CPU archs curl has run on - Reviewed-by: Jakub Zakrzewski - Closes #6195 + Closes #6366 -- [Tobias Hieta brought this change] +- [Cherish98 brought this change] - cmake: don't pass -fvisibility=hidden to clang-cl on Windows + curl: fix handling of -q option - When using clang-cl on windows -fvisibility=hidden is not an known - argument. Instead it behaves exactly like MSVC in this case. So let's - make sure we take that path. + The match of the "-q" option (short for "--disable") should: + a) allow concatenation with other single-letters; and + b) be case-sensitive, lest confusing with "-Q" ("--quote") - In CMake clang-cl sets both CMAKE_C_COMPILER_ID=clang and MSVC get's - defined since clang-cl is basically a MSVC emulator. So guarding like we - do in this patch seems logical. + Closes #6364 + +- tests/badsymbols.pl: ignore stand-alone single hash lines - Reviewed-by: Jakub Zakrzewski - Closes #6194 + Bug: https://curl.se/mail/lib-2020-12/0084.html + Reported-by: Dennis Clarke + Assisted-by: Jay Satiro + + Closes #6355 -- http_proxy: use enum with state names for 'keepon' +- curl_easy_pause.3: add multiplexed pause effects - To make the code clearer, change the 'keepon' from an int to an enum - with better state names. + and generally refresh and update. Remove details for ancient versions. - Reported-by: Niranjan Hasabnis - Bug: https://curl.se/mail/lib-2020-11/0026.html - Closes #6193 + Reviewed-by: Jay Satiro + Closes #6360 -- curl_easy_escape: limit output string length to 3 * max input +Jay Satiro (22 Dec 2020) +- curl_easy_pause.3: fix man page reference - ... instead of the limiting it to just the max input size. As every - input byte can be expanded to 3 output bytes, this could limit the input - string to 2.66 MB instead of the intended 8 MB. + Follow-up to ac9a724 from earlier today. - Reported-by: Marc Schlatter - Closes #6192 + Ref: https://github.com/curl/curl/pull/6359 -- docs: document the 8MB input string limit +Daniel Stenberg (22 Dec 2020) +- EXPERIMENTAL: add the Hyper backend to the list - for curl_easy_escape and curl_easy_setopt() + ... of current experimental features in curl. + +- speedcheck: exclude paused transfers - The limit is there to catch mistakes and abuse. It is meant to be large - enough to allow virtually all "fine" use cases. + Paused transfers should not be stopped due to slow speed even when + CURLOPT_LOW_SPEED_LIMIT is set. Additionally, the slow speed timer is + now reset when the transfer is unpaused - as otherwise it would easily + just trigger immediately after unpausing. - Reported-by: Marc Schlatter - Fixes #6190 - Closes #6191 + Reported-by: Harry Sintonen + Fixes #6358 + Closes #6359 -- mqttd: fclose test file when done +- h2: do not wait for RECV on paused transfers - Reported-by: Marc Hörsken + ... as the socket might be readable all the time when paused and thus + causing a busy-loop. + + Reported-by: Harry Sintonen Reviewed-by: Jay Satiro - Bug: #6058 - Closes #6189 + Fixes #6356 + Closes #6357 - RELEASE-NOTES: synced -- THANKS-filter: ignore autobuild links +- cmdline-opts/gen.pl: return hard on errors + + ... as the warnings tend to go unnoticed otherwise! + + Closes #6354 -- Revert "libcurl.pc: make it relocatable" +- examples/libtest: add .checksrc to dist - This reverts commit 3862c37b6373a55ca704171d45ba5ee91dec2c9f. + ... so that (auto)builds from tarballs also get the correct instructions. - That fix should either be done differently or with an option. + Fixes #6176 + Closes #6353 + +- test: verify new --write-out variables - Reported-by: asavah on github - Fixes #6157 - Closes #6183 + Extended test 1029 and added 1188 -- examples/httpput: remove use of CURLOPT_PUT +- test970: adapted to the new internal order of variables + +- curl: add variables to --write-out - It is deprecated and unnecessary since it already sets CURLOPT_UPLOAD. + In particular, these ones can help a user to create its own error + message when one or transfers fail. - Reported-by: Jeroen Ooms - Fixes #6186 - Closes #6187 - -- Curl_pgrsStartNow: init speed limit time stamps at start + writeout: add 'onerror', 'url', 'urlnum', 'exitcode', 'errormsg' - By setting the speed limit time stamps unconditionally at transfer - start, we can start off a transfer without speed limits and yet allow - them to get set during transfer and have an effect. + onerror - lets a user only show the rest on non-zero exit codes - Reported-by: Kael1117 on github - Fixes #6162 - Closes #6184 - -- ngtcp2: adapt to recent nghttp3 updates + url - the input URL used for this transfer - 'reset_stream' was added to the nghttp3_conn_callbacks struct + urlnum - the numerical URL counter (0 indexed) for this transfer - Closes #6185 - -- configure: pass -pthread to Libs.private for pkg-config + exitcode - the numerical exit code for the transfer - Reported-by: Cristian Morales Vega - Fixes #6168 - Closes #6181 - -- altsvc: minimize variable scope and avoid "DEAD_STORE" + errormsg - obvious - Closes #6182 + Reported-by: Earnestly on github + Fixes #6199 + Closes #6207 -- FAQ: remove "Why is there a HTTP/1.1 in my HTTP/2 request?" - - This hasn't been the case for a while now, remove. +- [Matthias Gatto brought this change] -- FAQ: refresh "Why do I get "certificate verify failed" + tests: add very simple AWS HTTP v4 Signature test - Add more details, remove references to ancient curl version. + Signed-off-by: Matthias Gatto -- test493: verify --hsts upgrade and that %{url_effective} reflects that - - Closes #6175 +- [Matthias Gatto brought this change] -- url: make sure an HSTS upgrade updates URL and scheme correctly - - Closes #6175 + docs: add AWS HTTP v4 Signature -- tool_operate: set HSTS with CURLOPT_HSTS to pass on filename - - Closes #6175 +- [Matthias Gatto brought this change] -- hsts: remove debug code leftovers + tool: add AWS HTTP v4 Signature support - Closes #6175 + Signed-off-by: Matthias Gatto -- FAQ: refreshed - - - remove a few ancient questions - - add configure with static libs question - - updated wording in several places - - lowercased curl - - Closes #6177 +- [Matthias Gatto brought this change] -Daniel Gustafsson (5 Nov 2020) -- examples: fix comment syntax + http: Make the call to v4 signature - Commit ac0a88fd2 accidentally added a stray character outside of the - comment which broke compilation. Fix by removing. + This patch allow to call the v4 signature introduce in previous commit - Reported-by: autobuild https://curl.se/dev/log.cgi?id=20201105084306-12742 + Signed-off-by: Matthias Gatto -- hsts: Remove pointless call to free in errorpath +- [Matthias Gatto brought this change] + + http: introduce AWS HTTP v4 Signature - The line variable will always be NULL in the error path, so remove - the free call since it's pointless. + It is a security process for HTTP. - Closes #6170 - Reviewed-by: Daniel Stenberg - -- docs: Fix various typos in documentation + It doesn't seems to be standard, but it is used by some cloud providers. - Closes #6171 - Reviewed-by: Daniel Stenberg - -Daniel Stenberg (5 Nov 2020) -- copyright: fix year ranges + Aws: + https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html + Outscale: + https://wiki.outscale.net/display/EN/Creating+a+Canonical+Request + GCP (I didn't test that this code work with GCP though): + https://cloud.google.com/storage/docs/access-control/signing-urls-manually - Follow-up from 4d2f8006777 - -- HISTORY: the new domain - -- curl.se: new home + most of the code is in lib/http_v4_signature.c - Closes #6172 - -- KNOWN_BUGS: FTPS with Schannel times out file list operation + Information require by the algorithm: + - The URL + - Current time + - some prefix that are append to some of the signature parameters. - Reported-by: bobmitchell1956 on github - Closes #5284 - -- KNOWN_BUGS: SMB tests fail with Python 2 + The data extracted from the URL are: the URI, the region, + the host and the API type - Reported-by: Jay Satiro - Closes #5983 - -- KNOWN_BUGS: LDAPS with NSS is slow + example: + https://api.eu-west-2.outscale.com/api/latest/ReadNets + ~~~ ~~~~~~~~ ~~~~~~~~~~~~~~~~~~~ + ^ ^ ^ + / \ URI + API type region - Reported-by: nosajsnikta on github - Closes #5874 - -Sergei Nikulov (4 Nov 2020) -- travis: use ninja-build for CMake builds + Small description of the algorithm: + - make canonical header using content type, the host, and the date + - hash the post data + - make canonical_request using custom request, the URI, + the get data, the canonical header, the signed header + and post data hash + - hash canonical_request + - make str_to_sign using one of the prefix pass in parameter, + the date, the credential scope and the canonical_request hash + - compute hmac from date, using secret key as key. + - compute hmac from region, using above hmac as key + - compute hmac from api_type, using above hmac as key + - compute hmac from request_type, using above hmac as key + - compute hmac from str_to_sign using above hmac as key + - create Authorization header using above hmac, prefix pass in parameter, + the date, and above hash - Added package ninja-build to environment - Use ninja to speed up CMake builds + Signed-off-by: Matthias Gatto - Closes #6077 - -Daniel Stenberg (4 Nov 2020) -- [Harry Sintonen brought this change] - - rtsp: error out on empty Session ID, unified the code + Closes #5703 -- [Harry Sintonen brought this change] +- [Matthias Gatto brought this change] - rtsp: fixed the RTST Session ID mismatch in test 570 + http: add hmac support for sha256 - Closes #6161 - -- [Harry Sintonen brought this change] - - rtsp: fixed Session ID comparison to refuse prefix + It seems current hmac implementation use md5 for the hash, + V4 signature require sha256, so I've added the needed struct in + this commit. - Closes #6161 - -- RELEASE-NOTES: synced + I've added the functions that do the hmac in v4 signature file + as a static function ,in the next patch of the serie, + because it's used only by this file. - (forgot to update the list of contributors) - -- RELEASE-NOTES: synced + Signed-off-by: Matthias Gatto -- curlver: bumped to 7.74.0 +- [Cristian Rodríguez brought this change] -- hsts: add read/write callbacks + connect: on linux, enable reporting of all ICMP errors on UDP sockets - - read/write callback options - - man pages for the 4 new setopts - - test 1915 verifies the callbacks + The linux kernel does not report all ICMP errors back to userspace due + to historical reasons. - Closes #5896 + IP*_RECVERR sockopt must be turned on to have the correct behaviour + which is to pass all ICMP errors to userspace. + + See https://bugzilla.kernel.org/show_bug.cgi?id=202355 + + Closes #6341 -- hsts: add support for Strict-Transport-Security +- curl: add --create-file-mode [mode] - - enable in the build (configure) - - header parsing - - host name lookup - - unit tests for the above - - CI build - - CURL_VERSION_HSTS bit - - curl_version_info support - - curl -V output - - curl-config --features - - CURLOPT_HSTS_CTRL - - man page for CURLOPT_HSTS_CTRL - - curl --hsts (sets CURLOPT_HSTS_CTRL and works with --libcurl) - - man page for --hsts - - save cache to disk - - load cache from disk - - CURLOPT_HSTS - - man page for CURLOPT_HSTS - - added docs/HSTS.md - - fixed --version docs - - adjusted curl_easy_duphandle + This option sets the (octal) mode to use for the remote file when one is + created, using the SFTP, SCP or FILE protocols. When not set, the + default is 0644. - Closes #5896 - -- [Sergei Nikulov brought this change] + Closes #6244 - CI/tests: enable test target on TravisCI for CMake builds +- c-hyper: fix compiler warnings - Added test-nonflaky target to CMake builds + Identified by clang on windows. - Disabled test 1139 because the cmake build doesn't create docs/curl.1 + Reported-by: Gisle Vanem + Bug: 58974d25d8173aec154e593ed9d866da566c9811 - Closes #6074 + Closes #6351 -- tool_debug_cb: do not assume zero-terminated data +- KNOWN_BUGS: Remote recursive folder creation with SFTP - Follow-up to d70a5b5a0f5e3 + Closes #5204 -- sendf: move the verbose-check into Curl_debug +Jay Satiro (20 Dec 2020) +- badsymbols.pl: Add verbose mode -v - Saves us from having the same check done everywhere. + Use -v as the first option to enable verbose mode which will show source + input, extracted symbol and line info. For example: - Closes #6159 - -- travis: use valgrind when running tests for debug builds + Source: ./../include/curl/typecheck-gcc.h + Symbol: curlcheck_socket_info(info) + Line #423: #define curlcheck_socket_info(info) \ - Except the non-x86 and sanitizer builds + Ref: https://curl.se/mail/lib-2020-12/0084.html - Closes #6154 + Closes https://github.com/curl/curl/pull/6349 -- header.d: fix syntax mistake +- KNOWN_BUGS: Secure Transport disabling hostname validation also disables SNI - follow-up from 1144886f38fd0 - -- [Harry Sintonen brought this change] - - gnutls: fix memory leaks (certfields memory wasn't released) + That behavior is a limitation of Apple's Secure Transport. - Closes #6153 - -- tests: add missing global_init/cleanup calls + Reported-by: Cory Benfield + Reported-by: Ian Spence + Confirmed-by: Nick Zitzmann - Without the cleanup call in these test files, the mbedTLS backend leaks - memory. + Ref: https://github.com/curl/curl/issues/998 - Closes #6156 + Closes https://github.com/curl/curl/issues/6347 + Closes https://github.com/curl/curl/pull/6348 -- tool_operate: --retry for HTTP 408 responses too +Daniel Stenberg (18 Dec 2020) +- TODO: alt-svc should fallback if alt-svc doesn't work - This was inadvertently dropped from the code when the parallel support - was added. + Closes #4908 + +- travis: restrict the openssl3 job to only run https and ftps tests - Regression since b88940850 (7.66.0) + ... as it runs too long otherwise and the other tests are verified in + other builds anyway. - Reviewed-by: Jay Satiro - Closes #6155 + Closes #6345 -- http: pass correct header size to debug callback for chunked post +- build: repair http disabled but mqtt enabled build - ... when the chunked framing was added, the size of the "body part" of - the data was calculated wrongly so the debug callback would get told a - header chunk a few bytes too big that would also contain the first few - bytes of the request body. + ... as the mqtt code reuses the "method" originally used for HTTP. - Reported-by: Dirk Wetter - Ref: #6144 - Closes #6147 + Closes #6344 -- header.d: mention the "Transfer-Encoding: chunked" handling - - Ref: #6144 - Closes #6148 +- [Jon Wilkes brought this change] -- acinclude: detect manually set minimum macos/ipod version - - ... even if set in the CC or IPHONEOS/MACOSX_DEPLOYMENT_TARGET - variables. + cookie: avoid the C1001 internal compiler error with MSVC 14 - Reported-by: hamstergene on github - Fixes #6138 - Closes #6140 + Fixes #6112 + Closes #6135 -Jay Satiro (29 Oct 2020) -- tests: fix some http/2 tests for older versions of nghttpx - - - Add regex that strips http/2 server header name to those http/2 tests - that don't already have it. +- RELEASE-NOTES: synced + +- mqtt: handle POST/PUBLISH without a set POSTFIELDSIZE - - Improve that regex in all http/2 tests. + Detected by OSS-Fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28735 - Tests 358 and 359 were failing for me before this change on a system - that uses an older version of nghttpx which includes its version number - in the server header. + Added test 1916 and 1917 to verify. - Closes https://github.com/curl/curl/pull/6139 + Closes #6338 -Daniel Stenberg (30 Oct 2020) -- RELEASE-NOTES: synced +- travis: add CI job for Hyper build -- [Cristian Morales Vega brought this change] +- tests: updated tests for Hyper - configure: use pkgconfig to find openSSL when cross-compiling - - This reverts 736a40fec (November 2004), which doesn't explain why it was - done. +- lib: introduce c-hyper for using Hyper - Closes #6145 + ... as an alternative HTTP backend within libcurl. -- tool_operate: bail out proper on errors for parallel setup - - ... otherwise for example trying to upload a missing file just causes a - loop. +- tool_setopt: provide helper output in debug builds - Reported-by: BrumBrum on hackerone - Closes #6141 + ... for when setopt() returns error. -- [Sergei Nikulov brought this change] +- setopt: adjust to Hyper and disabled HTTP builds - CMake: make BUILD_TESTING dependent option +- rtsp: disable if Hyper is used + +- getinfo: build with disabled HTTP support + +- version: include hyper version + +- docs: add HYPER.md + +- configure: add --with-hyper - CMake will now handle BUILD_TESTING depending on PERL_FOUND and - CURL_DISABLE_TESTING + As the first (optional) HTTP backend alternative instead of native - Ref: #6036 - Closes #6072 + Close #6110 -- libssh2: fix transport over HTTPS proxy +- test1522: add debug tracing - The fix in #6021 was not enough. This fix makes sure SCP/SFTP content - can also be transfered over a HTTPS proxy. + I used this to track down some issues and I figured I could just as well + keep this extra logging in here for future needs. - Fixes #6113 - Closes #6128 + Closes #6331 -- curl.1: add an "OUTPUT" section at the top of the manpage +- http: show the request as headers even when split-sending - Explain the basic concepts behind curl output. + When the initial request isn't possible to send in its entirety, the + remainder of request would be delivered to the debug callback as data + and would wrongly be counted internally as body-bytes sent. - Inspired by #6124 + Extended test 1295 to verify. - Closes #6134 - -- mailmap: set Viktor Szakats's email + Closes #6328 -- runtests: show keywords when no tests ran +- multi: when erroring in TOOFAST state, act as for PERFORM - To help out future debugging, runtests now outputs the list of keywords - when it fails because no tests ran. + When failing in TOOFAST, the multi_done() wasn't called so the same + cleanup and handling wasn't done like when it fails in PERFORM, which in + the case of FTP could mean that the control connection wouldn't be + marked as "dead" for the CURLE_ABORTED_BY_CALLBACK case. Which caused + ftp_disconnect() to use it to send "QUIT", which could end up waiting + for a response a long time before giving up! - Ref: #6120 - Closes #6126 + Reported-by: Tomas Berger + Fixes #6333 + Closes #6337 -Jay Satiro (26 Oct 2020) -- CURLOPT_DNS_USE_GLOBAL_CACHE.3: fix typo - - Reported-by: Rui LIU +- cmake: enable gophers correctly in curl-config - Closes https://github.com/curl/curl/issues/6131 + Closes #6336 -- range.d: fix typo +- test1198/9: add two mqtt publish tests without payload lengths - Follow-up to 15ae039 from earlier today. + Closes #6335 -Daniel Stenberg (26 Oct 2020) -- CI/github: work-around for brew breakage on macOS +- tests/mqttd: extract the client id from the correct offset - ... and make it use OpenSSL 1.1 properly + Closes #6334 + +- TODO: Prevent terminal injection when writing to terminal - Fixes #6130 - Closes #6129 + Closes #6150 -- [José Joaquín Atria brought this change] +- Revert "CI/github: work-around for brew breakage on macOS" + + This reverts commit 4cbb17a2cbbbe6337142d39479e21c3990b9c22f. + + ... as the work-around now causes failures. + + Closes #6332 - range.d: clarify that curl will not parse multipart responses +- examples: remove superfluous asterisk uses - Closes #6127 - Fixes #6124 + ... for function pointers. Breaks in ancient compilers. - RELEASE-NOTES: synced -- [Baruch Siach brought this change] - - libssh2: fix build with disabled proxy support - - Build breaks because the http_proxy field is missing: - - vssh/libssh2.c:3119:10: error: 'struct connectdata' has no member named 'http_proxy' - - Regression from #6021, shipped in curl 7.73.0 +- test1272: fix line ending - Closes #6125 + Follow-up to f24784f9143 -- alt-svc: enable by default +- URL-SYNTAX: add gophers details + +- test1272: test gophers + +- runtests: add support for gophers, gopher over TLS + +- [parazyd brought this change] + + gopher: Implement secure gopher protocol. - Remove CURLALTSVC_IMMEDIATELY, which was never implemented/supported. + This commit introduces a "gophers" handler inside the gopher protocol if + USE_SSL is defined. This protocol is no different than the usual gopher + prococol, with the added TLS encapsulation upon connecting. The protocol + has been adopted in the gopher community, and many people have enabled + TLS in their gopher daemons like geomyidae(8), and clients, like clic(1) + and hurl(1). - alt-svc support in curl is no longer considered experimental + I have not implemented test units for this protocol because my knowledge + of Perl is sub-par. However, for someone more knowledgeable it might be + fairly trivial, because the same test that tests the plain gopher + protocol can be used for "gophers" just by adding a TLS listener. + + Signed-off-by: parazyd - Closes #5868 - -- CI/appveyor: remove (unused) runtests.pl -b option - -- [Emil Engler brought this change] + Closes #6208 - tool_help: make "output" description less confusing - - Currently the description of "output" is misleading when comparing it - "verbose". +- TODO: Package curl for Windows in a signed installer - Closes #6118 + Closes #5424 -- CI/appveyor: disable test 571 in two cmake builds +- mqtt: deal with 0 byte reads correctly - ... they're simply too flaky there. + OSS-Fuzz found it + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28676 - Closes #6119 + Closes #6327 -- cmake: set the unicode feature in curl-config on Windows +- BUG-BOUNTY: minor language update - ... if built that way. To make it match curl -V output. + ... and remove the wording about entries from before 2019 as the "within + 12 months" is still there and covers that. - Reviewed-by: Marcel Raad - Closes #6117 + Closes #6318 -- libssh2: require version 1.0 or later +- tooĺ_writeout: fix the -w time output units - ... and simplify the code accordingly. libssh2 version 1.0 was released - in April 2009. + Fix regression from commit fc813f80e1bcac (#6248) that changed the unit + to microseconds instead of seconds with fractions - Closes #6116 + Reported-by: 不确定 + Fixes #6321 + Closes #6322 -- KNOWN_BUGS: mention the individual cmake issues +- quiche: remove fprintf() leftover + +Jay Satiro (14 Dec 2020) +- KNOWN_BUGS: SHA-256 digest not supported in Windows SSPI builds - ... to make them easier to refer to and address separately and - one-by-one. + Closes https://github.com/curl/curl/issues/6302 -- CMake: store IDN2 information in curl_config.h +- digest_sspi: Show InitializeSecurityContext errors in verbose mode - This allows the build to enable IDN properly and it makes test 1014 - happier. + The error is shown with infof rather than failf so that the user will + see the extended error message information only in verbose mode, and + will still see the standard CURLE_AUTH_ERROR message. For example: - Ref: #6074 - Closes #6108 - -- CMake: call the feature unixsockets without dash + --- - ... so that curl-config gets correct and makes test 1014 happy! + * schannel: InitializeSecurityContext failed: SEC_E_QOP_NOT_SUPPORTED + (0x8009030A) - The per-message Quality of Protection is not supported by + the security package + * multi_done + * Connection #1 to host 127.0.0.1 left intact + curl: (94) An authentication function returned an error - Ref: #6074 - Closes #6108 - -- CI/travis: add brotli and zstd to the libssh2 build + --- - ... to make sure such tests are run with valgrind. Suppress the zstd - valgrind warnings we get with version 1.3.3 on Ubuntu 18.04 (for debug - and non-debug builds). + Ref: https://github.com/curl/curl/issues/6302 - Closes #6105 + Closes https://github.com/curl/curl/pull/6315 -- runtests: revert the mistaken edit of $CURL +Daniel Stenberg (13 Dec 2020) +- URL-SYNTAX: add default port numbers and IDNA details - Regression from c4693adc62 - -- RELEASE-NOTES: synced + Closes #6316 -- curl_url_set.3: fix typo in the RETURN VALUE section +- URL-SYNTAX: mention how FILE:// access can access network on windows - Reported-by: Basuke Suzuki - Fixes #6102 - -Jay Satiro (17 Oct 2020) -- [Daniel Stenberg brought this change] + Closes #6314 - packages/OS400: make the source code-style compliant +Jay Satiro (12 Dec 2020) +- URL-SYNTAX: Document default SMTP port 25 - ... and make sure 'make checksrc' in the root dir also verifies the - packages/OS400 sources. + Note that ports 25 and 587 are common ports for smtp, the former being + the default. - Closes https://github.com/curl/curl/pull/6085 + Closes https://github.com/curl/curl/pull/6310 -- os400: Sync libcurl API options - - This fixes the OS400 build and also an incorrect entry for - CURLINFO_APPCONNECT_TIME_T where it was treated as - CURLINFO_STARTTRANSFER_TIME_T. +Daniel Stenberg (12 Dec 2020) +- CURLOPT_URL.3: remove scheme specific details - Reported-by: Jon Rumsey + ... that are now found in URL-SYNTAX.md - Fixes https://github.com/curl/curl/issues/6083 - Closes https://github.com/curl/curl/pull/6084 + Closes #6307 -Daniel Stenberg (16 Oct 2020) -- CURLOPT_NOBODY.3: fix typo +Dan Fandrich (12 Dec 2020) +- docs: Fix some typos - Reported-by: Basuke Suzuki - Fixes #6097 + [skip ci] -Marc Hoersken (16 Oct 2020) -- CI/azure: improve on flakiness by avoiding libtool wrappers - - Install curl binaries into MinGW bin folder and use that - for the tests in order to avoid libtool wrapper binaries. - - The libtool wrapper binaries (not scripts) on Windows seem - to be one of the possible causes for the following issues: - - 1. Process output can be lost in the wrapper process chain. - 2. Killing the wrapper process does not kill the actual one. +Daniel Stenberg (12 Dec 2020) +- URL-SYNTAX: mention all supported schemes - Derived from #5904 - Closes #6049 + Closes #6311 -Daniel Stenberg (16 Oct 2020) -- CURLOPT_URL.3: clarify SCP/SFTP URLs are for uploads as well +- [Douglas R. Reno brought this change] -- [Zenju brought this change] + URL-SYNTAX.md: minor language improvements + + Closes #6308 - CURLOPT_TCP_NODELAY.3: fix comment in example code +- docs/URL-SYNTAX: the URL syntax curl accepts and works with - Closes #6096 + Closes #6285 -- openssl: acknowledge SRP disabling in configure properly +- [0xflotus brought this change] + + docs: enable syntax highlighting in several docs files - Follow-up to 68a513247409 + ... for better readability - Use a new separate define that is the combination of both - HAVE_OPENSSL_SRP and USE_TLS_SRP: USE_OPENSSL_SRP + Closes #6286 + +- test1564/1565: require the 'wakeup' feature to run - Bug: https://curl.haxx.se/mail/lib-2020-10/0037.html + Fixes #6299 + Fixes #6300 + Closes #6301 + +- runtests: add 'wakeup' as a feature + +- tests/server/disabled: add "wakeup" - Closes #6094 + To allow the test suite to know if wakeup support is disabled in the + build. -Viktor Szakats (16 Oct 2020) -- http3: fix two build errors, silence warnings +- lib1564/5: verify that curl_multi_wakeup returns OK + +- tests: make --libcurl tests only test FTP options if ftp enabled - * fix two build errors due to mismatch between function - declarations and their definitions - * silence two mismatched signs warnings via casts + Adjust six --libcurl tests to only check the FTP option if FTP is + actually present in the build. - Approved-by: Daniel Stenberg - Closes #6093 + Fixes #6303 + Closes #6305 -- Makefile.m32: add support for HTTP/3 via ngtcp2+nghttp3 +- runtests.pl: fix "uninitialized value" warning - Approved-by: Daniel Stenberg - Closes #6092 + follow-up to e12825c642a88774 -Daniel Stenberg (16 Oct 2020) -- tool_operate: fix compiler warning when --libcurl is disabled +- runtests: add support for %if [feature] conditions - Closes #6095 - -- checksrc: warn on empty line before open brace + ... to make tests run differently or expect different results depending + on what features that are present or not in curl. - ... and fix a few occurances + Bonus: initial minor 'Hyper' awareness but nothing is using that yet - Closes #6088 + Closes #6304 -- urlapi: URL encode a '+' in the query part +- [Jon Rumsey brought this change] + + OS400: update ccsidcurl.c - ... when asked to with CURLU_URLENCODE. + Add 'struct' to cast and declaration of cfcdata to fix compilation + error. - Extended test 1560 to verify. - Reported-by: Dietmar Hauser - Fixes #6086 - Closes #6087 - -- [Cristian Morales Vega brought this change] + Fixes #6292 + Closes #6297 - libcurl.pc: make it relocatable - - It supposes when people specify the libdir/includedir they do it to - change where under prefix/exec_prefix it should be, not to make it - independent of prefix/exec_prefix. +- ngtcp2: make it build it current master again - Closes #6061 + Closes #6296 -- runtests: return error if no tests ran +- [Cristian Rodríguez brought this change] + + connect: defer port selection until connect() time - ... and make TESTFAIL stand out a little better by adding newlines - before and after. + If supported, defer port selection until connect() time + if --interface is given and source port is 0. - Reported-by: Marc Hörsken - Issue: #6052 - Closes #6053 - -- docs/FEATURE: convert to markdown + Reproducer: - ... and clean it up a bit. + * start fast webserver on port 80 + * starve system of ephemeral ports + $ sysctl net.ipv4.ip_local_port_range="60990 60999" - Closes #6067 - -- [Philipp Klaus Krause brought this change] - - strerror: use 'const' as the string should never be modified + * start a curl/libcurl "crawler" + $curl --keepalive --parallel --parallel-immediate --head --interface + 127.0.0.2 "http://127.0.0.[1-254]/file[001-002].txt" - Closes #6068 - -- [Jay Satiro brought this change] - - connect: repair build without ipv6 availability + current result: + (possible some successful data) + curl: (45) bind failed with errno 98: Address already in use - Assisted-by: Daniel Stenberg - Reported-by: Tom G. Christensen + result after patch: + (complete success or few connections failing, higlhy depending on load) - Fixes https://github.com/curl/curl/issues/6069 - Closes https://github.com/curl/curl/pull/6071 - -- RELEASE-NOTES: synced + Fail only when all the possible 4-tuple combinations are exhausted, + which is impossible to do when port is selected at bind() time becuse + the kernel does not know if socket will be listen()'ed on or connect'ed + yet. - Started over for the journey to next release. + Closes #6295 -- src/tool_filetime: disable -Wformat on mingw for this file +- [Hans-Christian Noren Egtvedt brought this change] + + connect: zero variable on stack to silence valgrind complaint - With gcc 10 on mingw we otherwise get this warning: + Valgrind will complain that ssrem buffer usage if not explicit + initialized, hence initialize it to zero. - error: ISO C does not support the 'I' printf flag [-Werror=format=] + This completes the change intially started in commit 2c0d7212151 ('ftp: + retry getpeername for FTP with TCP_FASTOPEN') where the ssloc buffer has + a similar memset to zero. - Fixes #6079 - Closes #6082 + Signed-off-by: Hans-Christian Noren Egtvedt + Closes #6289 -- test122[12]: remove these two tests - - ... and remove the objnames scripts they tested. They're not used for - anything anymore so testing them serves no purpose! +- RELEASE-NOTES: synced - Reported-by: Marc Hörsken - Fixes #6080 - Closes #6081 + start over on the next release cycle -Version 7.73.0 (14 Oct 2020) +Version 7.74.0 (9 Dec 2020) -Daniel Stenberg (14 Oct 2020) +Daniel Stenberg (9 Dec 2020) - RELEASE-NOTES: synced - for 7.73.0 + for 7.74.0 -- THANKS: from 7.73.0 and .mailmap fixes +Jay Satiro (7 Dec 2020) +- [Jacob Hoffman-Andrews brought this change] -- mailmap: fixups of some contributors + urldata: restore comment on ssl_connect_data.use + + This comment was originally on the `use` field, but was separated from + its field in 62a2534. + + Closes https://github.com/curl/curl/pull/6287 -- projects/build-wolfssl.bat: fix the copyright year range +Daniel Stenberg (7 Dec 2020) +- VERSIONS: refreshed + + We always use the patch number these days: all releases are + "major.minor.patch" -Marc Hoersken (14 Oct 2020) -- [Sergei Nikulov brought this change] +- [Jakub Zakrzewski brought this change] - CI/tests: fix invocation of tests for CMake builds - - Update appveyor.yml to set env variable TFLAGS and run tests - Remove curly braces due to CMake error (${TFLAGS} -> $TFLAGS) - Move testdeps build to build step (per review comments) + cmake: don't use reserved target name 'test' - Reviewed-by: Marc Hörsken + CMake up to 3.10 always reserves this name - Closes #6066 - Fixes #6052 + Fixes #6257 + Closes #6258 -- tests/server/util.c: fix support for Windows Unicode builds +- openssl: make the OCSP verification verify the certificate id - Detected via #6066 - Closes #6070 - -Daniel Stenberg (13 Oct 2020) -- [Jay Satiro brought this change] + CVE-2020-8286 + + Reported by anonymous + + Bug: https://curl.se/docs/CVE-2020-8286.html - strerror: Revert to local codepage for Windows error string +- ftp: make wc_statemach loop instead of recurse - - Change get_winapi_error() to return the error string in the local - codepage instead of UTF-8 encoding. + CVE-2020-8285 - Two weeks ago bed5f84 fixed get_winapi_error() to work on xbox, but it - also changed the error string's encoding from local codepage to UTF-8. + Fixes #6255 + Bug: https://curl.se/docs/CVE-2020-8285.html + Reported-by: xnynx on github + +- ftp: CURLOPT_FTP_SKIP_PASV_IP by default - We return the local codepage version of the error string because if it - is output to the user's terminal it will likely be with functions which - expect the local codepage (eg fprintf, failf, infof). + The command line tool also independently sets --ftp-skip-pasv-ip by + default. - This is essentially a partial revert of bed5f84. The support for xbox - remains but the error string is reverted back to local codepage. + Ten test cases updated to adapt the modified --libcurl output. - Ref: https://github.com/curl/curl/pull/6005 + Bug: https://curl.se/docs/CVE-2020-8284.html + CVE-2020-8284 - Reviewed-by: Marcel Raad - Closes #6065 + Reported-by: Varnavas Papaioannou -Marc Hoersken (13 Oct 2020) -- CI/tests: use verification curl for test reporting APIs +- urlapi: don't accept blank port number field without scheme - Avoid using our own, potentially installed, curl for - the test reporting APIs in case it is broken. + ... as it makes the URL parser accept "very-long-hostname://" as a valid + host name and we don't want that. The parser now only accepts a blank + (no digits) after the colon if the URL starts with a scheme. - Reviewed-by: Daniel Stenberg + Reported-by: d4d on hackerone - Preparation for #6049 - Closes #6063 + Closes #6283 -Viktor Szakats (12 Oct 2020) -- windows: fix comparison of mismatched types warning +- Revert "multi: implement wait using winsock events" - clang 10, mingw-w64: - ``` - vtls/openssl.c:2917:33: warning: comparison of integers of different signs: 'DWORD' (aka 'unsigned long') and 'HRESULT' (aka 'long') - [-Wsign-compare] - if(GetLastError() != CRYPT_E_NOT_FOUND) - ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~ - ``` + This reverts commit d2a7d7c185f98df8f3e585e5620cbc0482e45fac. - Approved-by: Daniel Stenberg - Closes #6062 + This commit also reverts the subsequent follow-ups to that commit, which + were all done within windows #ifdefs that are removed in this + change. Marc helped me verify this. + + Fixes #6146 + Closes #6281 -Daniel Stenberg (11 Oct 2020) -- [Viktor Szakats brought this change] +- [Klaus Crusius brought this change] - src/Makefile.m32: fix undefined curlx_dyn_* errors + ftp: retry getpeername for FTP with TCP_FASTOPEN - by linking `lib/dynbuf.c` when building a static curl binary. - Previously this source file was only included when building - a dynamic curl binary. This was likely possibly because no - functions from the `src/Makefile.inc` / `CURLX_CFILES` sources - were actually required for a curl tool build. This has - recently changed with the introduction of `curlx_dyn_*()` - memory functions and their use by the tool sources. + In the case of TFO, the remote host name is not resolved at the + connetion time. - Closes #6060 - -- HISTORY: curl verifies SSL certs by default since version 7.10 - -Marc Hoersken (8 Oct 2020) -- runtests.pl: use $LIBDIR variable instead of hardcoded path + For FTP that has lead to missing hostname for the secondary connection. + Therefore the name resolution is done at the time, when FTP requires it. - Reviewed-by: Daniel Stenberg - Closes #6051 + Fixes #6252 + Closes #6265 + Closes #6282 -Daniel Stenberg (7 Oct 2020) -- checksrc: detect // comments on column 0 +- [Thomas Danielsson brought this change] + + scripts/completion.pl: parse all opts - Spotted while working on #6045 + For tab-completion it may be preferable to include all the + available options. - Closes #6048 + Closes #6280 -- [Frederik Wedel-Heinen brought this change] +- RELEASE-NOTES: synced - mbedtls: add missing header when defining MBEDTLS_DEBUG +- openssl: use OPENSSL_init_ssl() with >= 1.1.0 - Closes #6045 + Reported-by: Kovalkov Dmitrii and Per Nilsson + Fixes #6254 + Fixes #6256 + Closes #6260 -- curl: make sure setopt CURLOPT_IPRESOLVE passes on a long +- SECURITY-PROCESS: disclose on hackerone - Previously, it would pass on a define (int) which could make libcurl - read junk as a value - which prevented the CURLOPT_IPRESOLVE option to - "take". This could then make test 2100 do two DoH requests instead of - one! + Once a vulnerability has been published, the hackerone issue should be + disclosed. For tranparency. - Fixes #6042 - Closes #6043 - -- RELEASE-NOTES: synced + Closes #6275 -- scripts/release-notes.pl: don't "embed" $ in format string for printf() +Marc Hoersken (3 Dec 2020) +- tests/util.py: fix compatibility with Python 2 - ... since they might contain %-codes that mess up the output! + Backporting the Python 3 implementation of setStream + to ClosingFileHandler as a fallback within Python 2. + + Reported-by: Jay Satiro + + Fixes #6259 + Closes #6270 -Jay Satiro (5 Oct 2020) -- [M.R.T brought this change] +Daniel Gustafsson (3 Dec 2020) +- docs: fix typos and markup in ETag manpage sections + + Reported-by: emanruse on github + Fixes #6273 - build-wolfssl: fix build with Visual Studio 2019 +Daniel Stenberg (2 Dec 2020) +- quiche: close the connection - Closes https://github.com/curl/curl/pull/6033 + Reported-by: Junho Choi + Fixes #6213 + Closes #6217 -Daniel Stenberg (4 Oct 2020) -- runtests: add %repeat[]% for test files +Jay Satiro (2 Dec 2020) +- ngtcp2: Fix build error due to symbol name change - ... and use this new keywords in all the test files larger than 50K to reduce - their sizes and make them a lot easier to read and understand. + - NGTCP2_CRYPTO_LEVEL_APP -> NGTCP2_CRYPTO_LEVEL_APPLICATION - Closes #6040 - -- [Emil Engler brought this change] - - --help: move two options from the misc category + ngtcp2/ngtcp2@76232e9 changed the name. - The cmdline opts delegation and suppress-connect-headers - fit better into auth and proxy rather than misc. + ngtcp2 master is required to build curl with http3 support. - Follow-up to aa8777f63febc - Closes #6038 + Closes https://github.com/curl/curl/pull/6271 -- [Samanta Navarro brought this change] +Daniel Stenberg (1 Dec 2020) +- [Klaus Crusius brought this change] - docs/opts: fix typos in two manual pages + cmake: check for linux/tcp.h - Closes #6039 - -- ldap: reduce the amount of #ifdefs needed + The HAVE_LINUX_TCP_H define was not set by cmake. - Closes #6035 + Closes #6252 -- runtests: provide curl's version string as %VERSION for tests +- NEW-PROTOCOL: document what needs to be done to add one - ... so that we can check HTTP requests for User-Agent: curl/%VERSION + Closes #6263 + +- splay: rename Curl_splayremovebyaddr to Curl_splayremove - Update 600+ test cases accordingly. + ... and remove the old unused proto for the old Curl_splayremove + version. - Closes #6037 + Closes #6269 -- checksrc: warn on space after exclamation mark +- openssl: free mem_buf in error path - Closes #6034 - -- test1465: verify --libcurl with binary POST data - -- runtests: allow generating a binary sequence from hex - -- tool_setopt: escape binary data to hex, not octal - -- curl: make --libcurl show binary posts correctly + To fix a memory-leak. - Reported-by: Stephan Mühlstrasser - Fixes #6031 - Closes #6032 + Closes #6267 -Jay Satiro (1 Oct 2020) -- strerror: fix null deref on winapi out-of-memory +- openssl: remove #if 0 leftover - Follow-up to bed5f84 from several days ago. + Follow-up to 4c9768565ec3a9 (from Sep 2008) - Ref: https://github.com/curl/curl/pull/6005 - -Daniel Stenberg (1 Oct 2020) -- [Kamil Dudka brought this change] + Closes #6268 - vtls: deduplicate some DISABLE_PROXY ifdefs +- ntlm: avoid malloc(0) on zero length user and domain - ... in the code of gtls, nss, and openssl + ... and simplify the too-long checks somewhat. - Closes #5735 + Detected by OSS-Fuzz + + Closes #6264 - RELEASE-NOTES: synced -- [Emil Engler brought this change] - - TODO: Add OpenBSD libtool notice +Marc Hoersken (28 Nov 2020) +- tests/server/tftpd.c: close upload file in case of abort - See #5862 - Closes #6030 - -- tests/unit/README: convert to markdown + Commit c353207 removed the closing right after do_tftp + which covered the case of abort. This handles that case. - ... and add to dist! + Reviewed-by: Jay Satiro + Reviewed-by: Daniel Stenberg - Closes #6028 + Follow up to #6209 + Closes #6234 -- tests/README: convert to markdown - - Closes #6028 +Daniel Stenberg (26 Nov 2020) +- [Daiki Ueno brought this change] -- include/README: convert to markdown + ngtcp2: use the minimal version of QUIC supported by ngtcp2 - Closes #6028 + Closes #6250 -- examples/README: convert to markdown - - Closes #6028 +- [Daiki Ueno brought this change] -- configure: don't say HTTPS-proxy is enabled when disabled! + ngtcp2: advertise h3 ALPN unconditionally - Reported-by: Kamil Dudka - Reviewed-by: Kamil Dudka - Bug: https://github.com/curl/curl/pull/5735#issuecomment-701376388 - Closes #6029 + Closes #6250 -Daniel Gustafsson (30 Sep 2020) -- src: Consistently spell whitespace without whitespace +- [Daiki Ueno brought this change] + + vquic/ngtcp2.h: define local_addr as sockaddr_storage - Whitespace is spelled without a space between white and space, so - make sure to consistently spell it that way across the codebase. + This field needs to be wide enough to hold sockaddr_in6 when + connecting via IPv6. Otherwise, ngtcp2_conn_read_pkt will drop the + packets because of the address mismatch: + I00000022 [...] con ignore packet from unknown path - Closes #6023 - Reviewed-by: Daniel Stenberg - Reviewed-by: Emil Engler + We can safely assume that struct sockaddr_storage is available, as it + is used in the public interface of ngtcp2. + + Closes #6250 -- MANUAL: update examples to resolve without redirects +- socks: check for DNS entries with the right port number - www.netscape.com is redirecting to a cookie consent form on Aol, and - cool.haxx.se isn't responding to FTP anymore. Replace with examples - that resolves in case users try out the commands when reading the - manual. + The resolve call is done with the right port number, but the subsequent + check used the wrong one, which then could find a previous resolve which + would return and leave the fresh resolve "incomplete" and leaking + memory. - Closes #6024 - Reviewed-by: Daniel Stenberg - Reviewed-by: Emil Engler - -Daniel Stenberg (30 Sep 2020) -- HISTORY: add some 2020 events + Fixes #6247 + Closes #6253 -- sectransp: make it build with --disable-proxy +- curl_setup: USE_RESOLVE_ON_IPS is for Apple native resolver use - Follow-up from #5466 and f3d501dc678d80 - Reported-by: Javier Navarro - Fixes #6025 - Closes #6026 + ... so don't define it when instructed to use c-ares! -- ECH: renamed from ESNI in docs and configure +- test506: make it not run in c-ares builds - Encrypted Client Hello (ECH) is the current name. + As the asynch nature of it may trigger events in another order. A c-ares + upgrade made it break. - Closes #6022 + Reported-by: Marc Hörsken + Fixes #6247 -- configure: use "no" instead of "disabled" for the end summary +- runtests: make 'c-ares' a "feature" to depend on - ... for consistency but also to make them more distinctly stand out next - to the "enabled" lines. + ... also added to the docs. -- TODO: SSH over HTTPS proxy with more backends +- tool_writeout: use off_t getinfo-types instead of doubles - ... as right now only the libssh2 backend supports it. - -- libssh2: handle the SSH protocols done over HTTPS proxy + Commit 3b80d3ca46b12e52342 (June 2017) introduced getinfo replacement + variables that use curl_off_t instead of doubles. Switch the --write-out + function over to use them. - Reported-by: Robin Douine - Fixes #4295 - Closes #6021 + Closes #6248 - [Emil Engler brought this change] - memdebug: remove 9 year old unused debug function + file: avoid duplicated code sequence - There used to be a way to have memdebug fill allocated memory. 9 years - later this has no value there (valgrind and ASAN etc are way better). If - people need to know about it they can have a look at VCS logs. + file_disconnect() is identical with file_do() except the function header + but as the arguments are unused anyway so why not just return file_do() + directly! - Closes #5973 + Reviewed-by: Daniel Stenberg + Closes #6249 -- sendf: move Curl_sendf to dict.c and make it static - - ... as the only remaining user of that function. Also fix gopher.c to - instead use Curl_write() - - Closes #6020 +- [Rikard Falkeborn brought this change] -- ROADMAP: updates and cleanups + infof/failf calls: fix format specifiers - Fix the HSTS PR + Update a few format specifiers to match what is being printed. - Remove DoT, thread-safe init and hard-coded localhost. I feel very - little interest for these with users so I downgrade them to plain "TODO" - entries again. + Closes #6241 -- schannel: return CURLE_PEER_FAILED_VERIFICATION for untrusted root +- docs/INTERNALS: remove reference to Curl_sendf() - This matches what is returned in other TLS backends in the same - situation. + The function has been removed from common usage. Also removed comment in + gopher.c that still referenced it. - Reviewed-by: Jay Satiro - Reviewed-by: Emil Engler - Follow-up to 5a3efb1 - Reported-by: iammrtau on github - Fixes #6003 - Closes #6018 + Reported-by: Rikard Falkeborn + Fixes #6242 + Closes #6243 -- RELEASE-NOTES: synced +- [Rikard Falkeborn brought this change] -- ftp: make a 552 response return CURLE_REMOTE_DISK_FULL + examples: update .gitignore - Added test 348 to verify. Added a 'STOR' command to the test FTP - server to enable test 348. Documented the command in FILEFORMAT.md + Add files that are generated by 'make examples' and remove some that + have been renamed. - Reported-by: Duncan Wilcox - Fixes #6016 - Closes #6017 + The commits that renamed the programs are e9625c5bc6c046a (imap.c and + simplesmtp.c were renamed to imap-fetch.c and smtp-send.c) and + ad39e7ec01e7 (pop3slist.c and pop3s.c were renamed to pop3-list.c and + pop3-ssl.c). + + Closes #6240 -- pause: only trigger a reread if the unpause sticks +- asyn: use 'struct thread_data *' instead of 'void *' - As an unpause might itself get paused again and then triggering another - reread doesn't help. + To reduce use of types that can't be checked at compile time. Also + removes several typecasts. - Follow-up from e040146f22608fd9 (shipped since 7.69.1) + ... and rename the struct field from 'os_specific' to 'tdata'. - Bug: https://curl.haxx.se/mail/lib-2020-09/0081.html - Patch-by: Kunal Chandarana - Fixes #5988 - Closes #6013 + Closes #6239 + Reviewed-by: Jay Satiro -- test163[12]: require http to be built-in to run +Viktor Szakats (23 Nov 2020) +- Makefile.m32: add support for UNICODE builds - ... as speaking over an HTTPS proxy implies http! + It requires the linker to support the `-municode` option. + This is available in more recent mingw-w64 releases. - Closes #6014 - -- ngtcp2: adapt to new NGTCP2_PROTO_VER_MAX define + Ref: https://gcc.gnu.org/onlinedocs/gcc/x86-Windows-Options.html + Ref: https://stackoverflow.com/questions/3571250/wwinmain-unicode-and-mingw/11706847#11706847 - Closes #6012 - -- [Javier Blazquez brought this change] + Reviewed-by: Jay Satiro + Reviewed-by: Marcel Raad + + Closes #6228 - strerror: honor Unicode API choice on Windows +Daniel Stenberg (23 Nov 2020) +- urldata: remove 'void *protop' and create the union 'p' - Closes #6005 + ... to avoid the use of 'void *' for the protocol specific structs done + per transfer. + + Closes #6238 -- imap: make imap_send use dynbuf for the send buffer management +- winbuild: remove docs from Makefiles and refer to README.md + + Reduce risk for conflicting docs and makes it to a single place to fix + and polish. - Reuses the buffer and thereby reduces number of mallocs over a transfer. + add these missing options to the readme: - Closes #6010 - -- Curl_send: return error when pre_receive_plain can't malloc + ENABLE_OPENSSL_AUTO_LOAD_CONFIG and ENABLE_UNICODE - ... will probably trigger some false DEAD CODE positives on non-windows - code analyzers for the conditional code. + clarify ENABLE_SCHANNEL default varies - Closes #6011 + Fixes #6216 + Closes #6227 + Co-Authored-by: Jay Satiro -- ftp: separate FTPS from FTP over "HTTPS proxy" +- [Daiki Ueno brought this change] + + http3: use the master branch of GnuTLS for testing - When using HTTPS proxy, SSL is used but not in the view of the FTP - protocol handler itself so separate the connection's use of SSL from the - FTP control connection's sue. + Closes #6235 + +- KNOWN_BUGS: curl with wolfSSL lacks support for renegotiation - Reported-by: Mingtao Yang - Fixes #5523 - Closes #6006 + Closes #5839 -Dan Fandrich (23 Sep 2020) -- tests/data: Fix some mismatched XML tags in test cases +- KNOWN_BUGS: wakeup socket disconnect causes havoc - This allows these test files to pass xmllint. + Closes #6132 + Closes #6133 -Daniel Stenberg (23 Sep 2020) -- pingpong: use a dynbuf for the *_pp_sendf() function +- RELEASE-NOTES: synced + +- [Oliver Urbann brought this change] + + curl: add compatibility for Amiga and GCC 6.5 - ... reuses the same dynamic buffer instead of doing repeated malloc/free - cycles. + Changes are mainly reordering and adding of includes required + to compile with a more recent version of GCC. - Test case 100 (FTP dir list PASV) does 7 fewer memory allocation calls - after this change in my test setup (132 => 125), curl 7.72.0 needed 140 - calls for this. + Closes #6220 + +Marc Hoersken (20 Nov 2020) +- tests/server/tftpd.c: close upload file right after transfer - Test case 103 makes 9 less allocations now (130). Down from 149 in - 7.72.0. + Make sure uploaded file is no longer locked after the + transfer while waiting for the final ACK to be handled. - Closes #6004 - -- dynbuf: add Curl_dyn_vaddf + Assisted-by: Daniel Stenberg - Closes #6004 + Bug: #6058 + Closes #6209 -- dynbuf: make *addf() not require extra mallocs +- CI/cirrus: simplify logic for disabled tests - ... by introducing a printf() function that appends directly into a - dynbuf: Curl_dyn_vprintf(). This avoids the mandatory extra malloc so if - the buffer is already big enough it can just printf directly into it. + The OpenSSH server instance for the testsuite cannot + be started on FreeBSD, therefore the SFTP and SCP + tests are disabled right away from the beginning. - Since this less-malloc version requires tthe use of a library internal - printf function, we only provide this version when building libcurl and - not for the dynbuf code that is used when building the curl tool. + The previous OS version specific logic for SKIP_TESTS + is no longer needed/used and can therefore be removed. - Closes #5998 - -- KNOWN_BUGS: Unable to use PKCS12 certificate with Secure Transport + Reviewed-by: Daniel Stenberg - Closes #5403 + Follow up to #6211 + Closes #6229 -- pingpong: remove a malloc per Curl_pp_vsendf call +Daniel Gustafsson (20 Nov 2020) +- mailmap: Daniel Hwang - This typically makes 7-9 fewer mallocs per FTP transfer. + Add Daniel Hwang to the mailmap to cover the alternative spelling + Daniel Lee Hwang which was used in one commit. - Closes #5997 + Closes #6230 + Reviewed-by: Daniel Stenberg -- symbian: drop support +- openssl: guard against OOM on context creation - The OS is deprecated. I see no traces of anyone having actually built - curl for Symbian after 2012. + EVP_MD_CTX_create will allocate memory for the context and returns + NULL in case the allocation fails. Make sure to catch any allocation + failures and exit early if so. - The public headers are unmodified. + In passing, also move to EVP_DigestInit rather than EVP_DigestInit_ex + as the latter is intended for ENGINE selection which we don't do. - Closes #5989 + Closes #6224 + Reviewed-by: Daniel Stenberg + Reviewed-by: Emil Engler -- RELEASE-NOTES: synced +Daniel Stenberg (19 Nov 2020) +- [Vincent Torri brought this change] -- curl_krb5.h: rename from krb5.h - - Follow-up from f4873ebd0be32cf + cmake: use libcurl.rc in all Windows builds - Turns out some older openssl installations go bananas otherwise. - Reported-by: Tom van der Woerdt - Fixes #5995 - Closes #5996 + Reviewed-by: Marcel Raad + Closes #6215 -- test1297: verify GOT_NOTHING with http proxy tunnel +- [Cristian Morales Vega brought this change] -- http_proxy: do not count proxy headers in the header bytecount + cmake: make CURL_ZLIB a tri-state variable - ... as that counter is subsequently used to detect if nothing was - returned from the peer. This made curl return CURLE_OK when it should - have returned CURLE_GOT_NOTHING. + By differentiating between ON and AUTO it can make a missing zlib + library a hard error when CURL_ZLIB=ON is used. - Fixes #5992 - Reported-by: Tom van der Woerdt - Closes #5994 + Reviewed-by: Jakub Zakrzewski + Closes #6221 + Fixes #6173 -- setopt: return CURLE_BAD_FUNCTION_ARGUMENT on bad argument +- quiche: remove 'static' from local buffer - Fixed two return code mixups. CURLE_UNKNOWN_OPTION is saved for when the - option is, yeah, not known. Clarified this in the setopt man page too. + For thread-safety - Closes #5993 + Closes #6223 -- krb5: merged security.c and krb specific FTP functions in here - - These two files were always tightly connected and it was hard to - understand what went into which. This also allows us to make the - ftpsend() function static (moved from ftp.c). - - Removed security.c - Renamed curl_sec.h to krb5.h +- KNOWN_BUGS: cmake: libspsl is not supported - Closes #5987 + Closes #6214 -- Curl_handler: add 'family' to each protocol - - Makes get_protocol_family() faster and it moves the knowledge about the - "families" to each protocol handler, where it belongs. +- KNOWN_BUGS: cmake autodetects cert paths when cross-compiling - Closes #5986 + Closes #6178 -- parsedate: tune the date to epoch conversion - - By avoiding an unnecessary error check and the temp use of the tm - struct, the time2epoch conversion function gets a little bit faster. - When repeating test 517, the updated version is perhaps 1% faster (on - one particular build on one particular architecture). +- KNOWN_BUGS: cmake build doesn't fail if zlib not found - Closes #5985 + Closes #6173 -- cmake: remove scary warning - - Remove the text saying - - "the curl cmake build system is poorly maintained. Be aware" +- KNOWN_BUGS: cmake libcurl.pc uses absolute library paths - ... not because anything changed just now, but to encourage users to use - it and subsequently improve it. + Closes #6169 + +- KNOWN_BUGS: cmake: generated .pc file contains strange entries - Closes #5984 + Closes #6167 -- docs/MQTT: remove outdated paaragraphs +- KNOWN_BUGS: cmake uses -lpthread instead of Threads::Threads + + Closes #6166 -- docs/MQTT: not experimental anymore +- KNOWN_BUGS: cmake build in Linux links libcurl to libdl - Follow-up to e37e4468688d8f + Closes #6165 -- docs/RESOURCES: remove +- KNOWN_BUGS: make a new section for cmake topics - This document is not maintained and rather than trying to refresh it, - let's kill it. A more up-to-date document with relevant RFCs is this - page on the curl website: https://curl.haxx.se/rfc/ + Closes #6219 + +- [Emil Engler brought this change] + + cirrus: build with FreeBSD 12.2 in CirrusCI - Closes #5980 + Closes #6211 -- docs/TheArtOfHttpScripting: convert to markdown +Marc Hoersken (14 Nov 2020) +- tests/*server.py: close log file after each log line - Makes it easier to browse on github etc. Offers (better) links. + Make sure the log file is not locked once a test has + finished and align with the behavior of our logmsg. - It should be noted that this document is already mostly outdated and - "Everything curl" at https://ec.haxx.se/ is a better resource and - tutorial. + Rename curl_test_data.py to be a general util.py. + Format and sort Python imports with isort/VSCode. - Closes #5981 + Bug: #6058 + Closes #6206 -- BUGS: convert document to markdown +Daniel Stenberg (13 Nov 2020) +- CURLOPT_HSTS.3: document the file format - Closes #5979 + Closes #6205 -- --help: strdup the category +- RELEASE-NOTES: synced + +- release-notes.pl: detect #[number] better for Ref: etc + +- curl: only warn not fail, if not finding the home dir - ... since it is converted and the original pointer is freed on Windows - unicode handling. + ... as there's no good reason to error out completely. - Follow-up to aa8777f63febc - Fixes #5977 - Closes #5978 - Reported-by: xwxbug on github + Reported-by: Andreas Fischer + Fixes #6200 + Closes #6201 -- CHECKSRC: document two missing warnings +- httpput-postfields.c: new example doing PUT with POSTFIELDS + + Proposed-by: Jeroen Ooms + Ref: #6186 + Closes #6188 -- RELEASE-NOTES: synced +- [Tobias Hieta brought this change] -- ftp: avoid risk of reading uninitialized integers + cmake: correctly handle linker flags for static libs - If the received PASV response doesn't match the expected pattern, we - could end up reading uninitialized integers for IP address and port - number. + curl CMake was setting the the EXE flags for static libraries which made + the /manifest:no flag ended up when linking the static library, which is + not a valid flag for lib.exe or llvm-lib.exe and caused llvm-lib to exit + with an error. - Issue pointed out by muse.dev - Closes #5972 + The better way to handle this is to make sure that we pass the correct + linker flags to CMAKE_STATIC_LINKER_FLAGS instead. + + Reviewed-by: Jakub Zakrzewski + Closes #6195 -- [Quentin Balland brought this change] +- [Tobias Hieta brought this change] - easy_reset: clear retry counter + cmake: don't pass -fvisibility=hidden to clang-cl on Windows - Closes #5975 - Fixes #5974 - -- ftp: get rid of the PPSENDF macro + When using clang-cl on windows -fvisibility=hidden is not an known + argument. Instead it behaves exactly like MSVC in this case. So let's + make sure we take that path. - The use of such a macro hides some of what's actually going on to the - reader and is generally disapproved of in the project. + In CMake clang-cl sets both CMAKE_C_COMPILER_ID=clang and MSVC get's + defined since clang-cl is basically a MSVC emulator. So guarding like we + do in this patch seems logical. - Closes #5971 + Reviewed-by: Jakub Zakrzewski + Closes #6194 -- man pages: switch to https://example.com URLs +- http_proxy: use enum with state names for 'keepon' - Since HTTPS is "the new normal", this update changes a lot of man page - examples to use https://example.com instead of the previous "http://..." + To make the code clearer, change the 'keepon' from an int to an enum + with better state names. - Closes #5969 + Reported-by: Niranjan Hasabnis + Bug: https://curl.se/mail/lib-2020-11/0026.html + Closes #6193 -- github: remove the duplicate "Security vulnerability" entry +- curl_easy_escape: limit output string length to 3 * max input - ... since github adds an entry automatically by itself. + ... instead of the limiting it to just the max input size. As every + input byte can be expanded to 3 output bytes, this could limit the input + string to 2.66 MB instead of the intended 8 MB. - Closes #5970 - -- [Emil Engler brought this change] + Reported-by: Marc Schlatter + Closes #6192 - github: use new issue template feature +- docs: document the 8MB input string limit - This helps us to avoid getting feature requests as well as security - bugs reported into the issue tracker. + for curl_easy_escape and curl_easy_setopt() - Closes #5936 - -- [Emil Engler brought this change] + The limit is there to catch mistakes and abuse. It is meant to be large + enough to allow virtually all "fine" use cases. + + Reported-by: Marc Schlatter + Fixes #6190 + Closes #6191 - urlapi: use more Curl_safefree +- mqttd: fclose test file when done - Closes #5968 + Reported-by: Marc Hörsken + Reviewed-by: Jay Satiro + Bug: #6058 + Closes #6189 -Marc Hoersken (17 Sep 2020) -- multi: align WinSock mask variables in Curl_multi_wait +- RELEASE-NOTES: synced + +- THANKS-filter: ignore autobuild links + +- Revert "libcurl.pc: make it relocatable" - Also skip pre-checking sockets to set timeout_ms to 0 - after the first socket has been detected to be ready. + This reverts commit 3862c37b6373a55ca704171d45ba5ee91dec2c9f. - Reviewed-by: rcombs on github - Reviewed-by: Daniel Stenberg + That fix should either be done differently or with an option. - Follow up to #5886 + Reported-by: asavah on github + Fixes #6157 + Closes #6183 -- multi: reuse WinSock events variable in Curl_multi_wait - - Since the struct is quite large (1 long and 10 ints) we - declare it once at the beginning of the function instead - of multiple times inside loops to avoid stack movements. +- examples/httpput: remove use of CURLOPT_PUT - Reviewed-by: Viktor Szakats - Reviewed-by: Daniel Stenberg + It is deprecated and unnecessary since it already sets CURLOPT_UPLOAD. - Closes #5886 + Reported-by: Jeroen Ooms + Fixes #6186 + Closes #6187 -Daniel Stenberg (16 Sep 2020) -- TODO: dynamically decide to use socketpair +- Curl_pgrsStartNow: init speed limit time stamps at start - Suggested-by: Anders Bakken + By setting the speed limit time stamps unconditionally at transfer + start, we can start off a transfer without speed limits and yet allow + them to get set during transfer and have an effect. - Closes #4829 + Reported-by: Kael1117 on github + Fixes #6162 + Closes #6184 -- TODO: add PR reference for native IDN support on macOS +- ngtcp2: adapt to recent nghttp3 updates - As there was work started on this that never got completed. + 'reset_stream' was added to the nghttp3_conn_callbacks struct - Closes #5371 + Closes #6185 -- tool_help.h: update copyright year range +- configure: pass -pthread to Libs.private for pkg-config - Follow-up from aa8777f63febca + Reported-by: Cristian Morales Vega + Fixes #6168 + Closes #6181 -- CI/azure: disable test 571 in the msys2 builds +- altsvc: minimize variable scope and avoid "DEAD_STORE" - It's just too flaky there + Closes #6182 + +- FAQ: remove "Why is there a HTTP/1.1 in my HTTP/2 request?" - Reviewed-by: Marc Hoersken - Closes #5954 + This hasn't been the case for a while now, remove. -- tool_writeout: protect fputs() from NULL +- FAQ: refresh "Why do I get "certificate verify failed" - When the code was changed to do fputs() instead of fprintf() it got - sensitive for NULL pointers; add checks for that. + Add more details, remove references to ancient curl version. + +- test493: verify --hsts upgrade and that %{url_effective} reflects that - Follow-up from 0c1e767e83ec66 + Closes #6175 + +- url: make sure an HSTS upgrade updates URL and scheme correctly - Closes #5963 + Closes #6175 -- test3015: verify stdout "as text" +- tool_operate: set HSTS with CURLOPT_HSTS to pass on filename - Follow-up from 0c1e767e83e to please win32 tests + Closes #6175 + +- hsts: remove debug code leftovers - Closes #5962 + Closes #6175 -- travis: use libressl v3.1.4 instead of master +- FAQ: refreshed - ... as their git master seems too fragile to use (and 3.2.1 which is the - latest has a build failure). + - remove a few ancient questions + - add configure with static libs question + - updated wording in several places + - lowercased curl - Closes #5964 - -- tests/FILEFORMAT: document type=shell for + Closes #6177 -- tests/FILEFORMAT: document nonewline support for +Daniel Gustafsson (5 Nov 2020) +- examples: fix comment syntax - The one in , that creates files. + Commit ac0a88fd2 accidentally added a stray character outside of the + comment which broke compilation. Fix by removing. - Follow-up from b83947c8df7 - -- [anio brought this change] + Reported-by: autobuild https://curl.se/dev/log.cgi?id=20201105084306-12742 - tool_writeout: add new writeout variable, %{num_headers} +- hsts: Remove pointless call to free in errorpath - This variable gives the number of headers. + The line variable will always be NULL in the error path, so remove + the free call since it's pointless. - Closes #5947 + Closes #6170 + Reviewed-by: Daniel Stenberg -- tool_urlglob: fix compiler warning "unreachable code" +- docs: Fix various typos in documentation - (On Windows builds.) + Closes #6171 + Reviewed-by: Daniel Stenberg + +Daniel Stenberg (5 Nov 2020) +- copyright: fix year ranges - Follow-up to 70a3b003d9 + Follow-up from 4d2f8006777 -- [Gergely Nagy brought this change] +- HISTORY: the new domain - vtls: deduplicate client certificates in ssl_config_data +- curl.se: new home - Closes #5629 + Closes #6172 -- ftp: a 550 response to SIZE returns CURLE_REMOTE_FILE_NOT_FOUND +- KNOWN_BUGS: FTPS with Schannel times out file list operation - This is primarily interesting for cases where CURLOPT_NOBODY is set as - previously curl would not return an error for this case. + Reported-by: bobmitchell1956 on github + Closes #5284 + +- KNOWN_BUGS: SMB tests fail with Python 2 - MDTM getting 550 now also returns this error (it returned - CURLE_FTP_COULDNT_RETR_FILE before) in order to unify return codes for - missing files across protocols and specific FTP commands. + Reported-by: Jay Satiro + Closes #5983 + +- KNOWN_BUGS: LDAPS with NSS is slow - libcurl already returns error on a 550 as a MDTM response (when - CURLOPT_FILETIME is set). If CURLOPT_NOBODY is not set, an error would - happen subsequently anyway since the RETR command would fail. + Reported-by: nosajsnikta on github + Closes #5874 + +Sergei Nikulov (4 Nov 2020) +- travis: use ninja-build for CMake builds - Add test 1913 and 1914 to verify. Updated several tests accordingly due - to the updated SIZE behavior. + Added package ninja-build to environment + Use ninja to speed up CMake builds - Reported-by: Tomas Berger - Fixes #5953 - Closes #5957 + Closes #6077 -- curl: make checkpasswd use dynbuf - - Closes #5952 +Daniel Stenberg (4 Nov 2020) +- [Harry Sintonen brought this change] -- curl: make glob_match_url use dynbuf - - Closes #5952 + rtsp: error out on empty Session ID, unified the code -- curl: make file2memory use dynbuf - - Closes #5952 +- [Harry Sintonen brought this change] -- curl: make file2string use dynbuf + rtsp: fixed the RTST Session ID mismatch in test 570 - Closes #5952 + Closes #6161 -- [Antarpreet Singh brought this change] +- [Harry Sintonen brought this change] - imap: set cselect_bits to CURL_CSELECT_IN initially - - ... when continuing a transfer from a FETCH response. + rtsp: fixed Session ID comparison to refuse prefix - When the size of the file was small enough that the entirety of the - transfer happens in a single go and schannel buffers holds the entire - data. However, it wasn't completely read in Curl_pp_readresp since a - line break was found before that could happen. So, by the time we are in - imap_state_fetch_resp - there's data in buffers that needs to be read - via Curl_read but nothing to read from the socket. After we setup a - transfer (Curl_setup_transfer), curl just waits on the socket state to - change - which doesn't happen since no new data ever comes. + Closes #6161 + +- RELEASE-NOTES: synced - Closes #5961 + (forgot to update the list of contributors) - RELEASE-NOTES: synced -- test434: test -K use in a single line without newline +- curlver: bumped to 7.74.0 + +- hsts: add read/write callbacks - Closes #5946 + - read/write callback options + - man pages for the 4 new setopts + - test 1915 verifies the callbacks + + Closes #5896 -- runtests: allow creating files without newlines +- hsts: add support for Strict-Transport-Security - Closes #5946 + - enable in the build (configure) + - header parsing + - host name lookup + - unit tests for the above + - CI build + - CURL_VERSION_HSTS bit + - curl_version_info support + - curl -V output + - curl-config --features + - CURLOPT_HSTS_CTRL + - man page for CURLOPT_HSTS_CTRL + - curl --hsts (sets CURLOPT_HSTS_CTRL and works with --libcurl) + - man page for --hsts + - save cache to disk + - load cache from disk + - CURLOPT_HSTS + - man page for CURLOPT_HSTS + - added docs/HSTS.md + - fixed --version docs + - adjusted curl_easy_duphandle + + Closes #5896 -- curl: use curlx_dynbuf for realloc when loading config files +- [Sergei Nikulov brought this change] + + CI/tests: enable test target on TravisCI for CMake builds - ... fixes an integer overflow at the same time. + Added test-nonflaky target to CMake builds - Reported-by: ihsinme on github - Assisted-by: Jay Satiro + Disabled test 1139 because the cmake build doesn't create docs/curl.1 - Closes #5946 + Closes #6074 -- dynbuf: provide curlx_ names for reuse by the curl tool +- tool_debug_cb: do not assume zero-terminated data - Closes #5946 + Follow-up to d70a5b5a0f5e3 -- dynbuf: make sure Curl_dyn_tail() zero terminates +- sendf: move the verbose-check into Curl_debug - Closes #5959 - -- tests: add test1912 to the dist + Saves us from having the same check done everywhere. - Follow-up to 70984ce1be4cab6c + Closes #6159 -- docs/LICENSE-MIXING: remove +- travis: use valgrind when running tests for debug builds - This document is not maintained and I feel that it doesn't provide much - value to users anymore (if it ever did). + Except the non-x86 and sanitizer builds - Closes #5955 - -- [Laramie Leavitt brought this change] + Closes #6154 - http: consolidate nghttp2_session_mem_recv() call paths - - Previously there were several locations that called - nghttp2_session_mem_recv and handled responses slightly differently. - Those have been converted to call the existing - h2_process_pending_input() function. +- header.d: fix syntax mistake - Moved the end-of-session check to h2_process_pending_input() since the - only place the end-of-session state can change is after nghttp2 - processes additional input frames. + follow-up from 1144886f38fd0 + +- [Harry Sintonen brought this change] + + gnutls: fix memory leaks (certfields memory wasn't released) - This will likely fix the fuzzing error. While I don't have a root cause - the out-of-bounds read seems like a use after free, so moving the - nghttp2_session_check_request_allowed() call to a location with a - guaranteed nghttp2 session seems reasonable. + Closes #6153 + +- tests: add missing global_init/cleanup calls - Also updated a few nghttp2 callsites to include error messages and added - a few additional error checks. + Without the cleanup call in these test files, the mbedTLS backend leaks + memory. - Closes #5648 + Closes #6156 -- HISTORY: mention alt-svc added in 2019 +- tool_operate: --retry for HTTP 408 responses too - ... and make 1996 the first year subtitle - -- base64: also build for pop3 and imap + This was inadvertently dropped from the code when the parallel support + was added. - Follow-up to the fix in 20417a13fb8f83 + Regression since b88940850 (7.66.0) - Reported-by: Michael Olbrich - Fixes #5937 - Closes #5948 + Reviewed-by: Jay Satiro + Closes #6155 -- base64: enable in build with SMTP +- http: pass correct header size to debug callback for chunked post - The oauth2 support is used with SMTP and it uses base64 functions. + ... when the chunked framing was added, the size of the "body part" of + the data was calculated wrongly so the debug callback would get told a + header chunk a few bytes too big that would also contain the first few + bytes of the request body. - Reported-by: Michael Olbrich - Fixes #5937 - Closes #5938 + Reported-by: Dirk Wetter + Ref: #6144 + Closes #6147 -- curl_mime_headers.3: fix the example's use of curl_slist_append +- header.d: mention the "Transfer-Encoding: chunked" handling - Reported-by: sofaboss on github - Fixes #5942 - Closes #5943 + Ref: #6144 + Closes #6148 -- lib583: fix enum mixup +- acinclude: detect manually set minimum macos/ipod version - grrr the previous follow-up to 17fcdf6a31 was wrong - -- libtest: fix build errors + ... even if set in the CC or IPHONEOS/MACOSX_DEPLOYMENT_TARGET + variables. - Follow-up from 17fcdf6a310d4c8076 + Reported-by: hamstergene on github + Fixes #6138 + Closes #6140 -- lib: fix -Wassign-enum warnings +Jay Satiro (29 Oct 2020) +- tests: fix some http/2 tests for older versions of nghttpx - configure --enable-debug now enables -Wassign-enum with clang, - identifying several enum "abuses" also fixed. + - Add regex that strips http/2 server header name to those http/2 tests + that don't already have it. - Reported-by: Gisle Vanem - Bug: https://github.com/curl/curl/commit/879007f8118771f4896334731aaca5850a154675#commitcomment-42087553 + - Improve that regex in all http/2 tests. + + Tests 358 and 359 were failing for me before this change on a system + that uses an older version of nghttpx which includes its version number + in the server header. - Closes #5929 + Closes https://github.com/curl/curl/pull/6139 +Daniel Stenberg (30 Oct 2020) - RELEASE-NOTES: synced -- [Diven Qi brought this change] +- [Cristian Morales Vega brought this change] - url: use blank credentials when using proxy w/o username and password + configure: use pkgconfig to find openSSL when cross-compiling - Fixes proxy regression brought in commit ad829b21ae (7.71.0) + This reverts 736a40fec (November 2004), which doesn't explain why it was + done. - Fixed #5911 - Closes #5914 + Closes #6145 -- travis: add a build using libressl (from git master) +- tool_operate: bail out proper on errors for parallel setup - The v3.2.1 tag (latest release atm) results in a broken build. + ... otherwise for example trying to upload a missing file just causes a + loop. - Closes #5932 + Reported-by: BrumBrum on hackerone + Closes #6141 -- configure: let --enable-debug set -Wenum-conversion with gcc >= 10 - - Unfortunately, this option is not detecting the same issues as clang's - -Wassign-enum flag, but should still be useful to detect future - mistakes. - - Closes #5930 +- [Sergei Nikulov brought this change] -- openssl: consider ALERT_CERTIFICATE_EXPIRED a failed verification - - If the error reason from the lib is - SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED, libcurl will return - CURLE_PEER_FAILED_VERIFICATION and not CURLE_SSL_CONNECT_ERROR. + CMake: make BUILD_TESTING dependent option - This unifies the libcurl return code and makes libressl run test 313 - (CRL testing) fine. + CMake will now handle BUILD_TESTING depending on PERL_FOUND and + CURL_DISABLE_TESTING - Closes #5934 - -- FAQ: refreshed some very old language + Ref: #6036 + Closes #6072 -- cmake: make HTTP_ONLY also disable MQTT +- libssh2: fix transport over HTTPS proxy - ... and alphasort the order of disabling protocols to make it easier to - browse. + The fix in #6021 was not enough. This fix makes sure SCP/SFTP content + can also be transfered over a HTTPS proxy. - Closes #5931 + Fixes #6113 + Closes #6128 -- libtest: remove lib1541 leftovers +- curl.1: add an "OUTPUT" section at the top of the manpage - Caused automake errors. + Explain the basic concepts behind curl output. + + Inspired by #6124 - Follow-up to 8ca54a03ea08a + Closes #6134 -- tests/libtests: remove test 1900 and 2033 +- mailmap: set Viktor Szakats's email + +- runtests: show keywords when no tests ran - We already remove the test files, now remove the libtest codes as well. + To help out future debugging, runtests now outputs the list of keywords + when it fails because no tests ran. - Follow-up to e50a877df74 + Ref: #6120 + Closes #6126 -Marc Hoersken (7 Sep 2020) -- CI/azure: add test number to title for display in analytics +Jay Satiro (26 Oct 2020) +- CURLOPT_DNS_USE_GLOBAL_CACHE.3: fix typo - To ease identification of tests the test number is added to - the test case title in order to have it on the Azure DevOps - Analytics pages and reports which currently do not show it. + Reported-by: Rui LIU - Bump test case revision to make Azure DevOps update titles. + Closes https://github.com/curl/curl/issues/6131 + +- range.d: fix typo - Closes #5927 + Follow-up to 15ae039 from earlier today. -Daniel Stenberg (6 Sep 2020) -- altsvc: clone setting in curl_easy_duphandle +Daniel Stenberg (26 Oct 2020) +- CI/github: work-around for brew breakage on macOS - The cache content is not duplicated, like other caches, but the setting - and specified file name are. + ... and make it use OpenSSL 1.1 properly - Test 1908 is extended to verify this somewhat. Since the duplicated - handle gets the same file name, the test unfortunately overwrites the - same file twice (with different contents) which makes it hard to check - automatically. + Fixes #6130 + Closes #6129 + +- [José Joaquín Atria brought this change] + + range.d: clarify that curl will not parse multipart responses - Closes #5923 + Closes #6127 + Fixes #6124 + +- RELEASE-NOTES: synced + +- [Baruch Siach brought this change] -- test1541: remove since it is a known bug + libssh2: fix build with disabled proxy support + + Build breaks because the http_proxy field is missing: - A shared connection cache is not thread-safe is a known issue. Stop - testing this until we believe this issue is addressed. Reduces - occasional test failures we don't care about. + vssh/libssh2.c:3119:10: error: 'struct connectdata' has no member named 'http_proxy' - The test code in lib1541.c is left in git to allow us to restore it when - we get to fix this. + Regression from #6021, shipped in curl 7.73.0 - Closes #5922 + Closes #6125 -- tests: remove pipelining tests +- alt-svc: enable by default - Remove the tests 530, 584, 1900, 1901, 1902, 1903 and 2033. They were - previously disabled. + Remove CURLALTSVC_IMMEDIATELY, which was never implemented/supported. - The Pipelining code was removed from curl in commit 2f44e94efb3df8e, - April 2019. + alt-svc support in curl is no longer considered experimental - Closes #5921 + Closes #5868 -- curl: retry delays in parallel mode no longer sleeps blocking - - The previous sleep for retries would block all other concurrent - transfers. Starting now, the retry will instead be properly marked to - not get restarted until after the delay time but other transfers can - still continue in the mean time. - - Closes #5917 +- CI/appveyor: remove (unused) runtests.pl -b option -- curl:parallel_transfers: make sure retry readds the transfer - - Reported-by: htasta on github - Fixes #5905 - Closes #5917 +- [Emil Engler brought this change] -- build: drop support for building with Watcom + tool_help: make "output" description less confusing - These files are not maintained, they seem to have no users, Watcom - compilers look like not having users nor releases anymore. + Currently the description of "output" is misleading when comparing it + "verbose". - Closes #5918 + Closes #6118 -- winbuild/rundebug.cmd: remove +- CI/appveyor: disable test 571 in two cmake builds - Seems to have been added by mistake? Not included in dists. + ... they're simply too flaky there. - Closes #5919 + Closes #6119 -- curl: in retry output don't call all problems "transient" +- cmake: set the unicode feature in curl-config on Windows - ... because when --retry-all-errors is used, the error isn't necessarily - transient at all. + ... if built that way. To make it match curl -V output. - Closes #5916 + Reviewed-by: Marcel Raad + Closes #6117 -- easygetopt: pass a valid enum to avoid compiler warning - - "integer constant not in range of enumerated type 'CURLoption'" +- libssh2: require version 1.0 or later - Reported-by: Gisle Vanem - Bug: https://github.com/curl/curl/commit/6ebe63fac23f38df911edc348e8ccc72280f9434#commitcomment-42042843 + ... and simplify the code accordingly. libssh2 version 1.0 was released + in April 2009. - Closes #5915 + Closes #6116 -- [Emil Engler brought this change] +- KNOWN_BUGS: mention the individual cmake issues + + ... to make them easier to refer to and address separately and + one-by-one. - tests: Add tests for new --help +- CMake: store IDN2 information in curl_config.h - This commit is a part of "--help me if you can" + This allows the build to enable IDN properly and it makes test 1014 + happier. - Closes #5680 - -- [Emil Engler brought this change] + Ref: #6074 + Closes #6108 - tool: update --help with categories +- CMake: call the feature unixsockets without dash - This commit is a part of "--help me if you can" + ... so that curl-config gets correct and makes test 1014 happy! - Closes #5680 - -- [Emil Engler brought this change] + Ref: #6074 + Closes #6108 - docs: add categories to all cmdline opts +- CI/travis: add brotli and zstd to the libssh2 build - Adapted gen.pl with 'listcats' + ... to make sure such tests are run with valgrind. Suppress the zstd + valgrind warnings we get with version 1.3.3 on Ubuntu 18.04 (for debug + and non-debug builds). - This commit is a part of "--help me if you can" + Closes #6105 + +- runtests: revert the mistaken edit of $CURL - Closes #5680 + Regression from c4693adc62 - RELEASE-NOTES: synced -- [ihsinme brought this change] - - connect.c: remove superfluous 'else' in Curl_getconnectinfo +- curl_url_set.3: fix typo in the RETURN VALUE section - Closes #5912 + Reported-by: Basuke Suzuki + Fixes #6102 -- [Samuel Marks brought this change] +Jay Satiro (17 Oct 2020) +- [Daniel Stenberg brought this change] - CMake: remove explicit `CMAKE_ANSI_CFLAGS` - - This variable was removed from cmake in commit - https://gitlab.kitware.com/cmake/cmake/commit/5a834b0bb0bc288. A later - CMake commit removes the variable from the tests, claiming that it was - removed in CMake 2.6 + packages/OS400: make the source code-style compliant - Reviewed-By: Peter Wu - Closes #5439 - -- [cbe brought this change] - - libssh2: pass on the error from ssh_force_knownhost_key_type + ... and make sure 'make checksrc' in the root dir also verifies the + packages/OS400 sources. - Closes #5909 + Closes https://github.com/curl/curl/pull/6085 -- scripts/delta: add diffstat summary +- os400: Sync libcurl API options - ... and make output more table-like - -- [Martin Bašti brought this change] - - http_proxy: do not crash with HTTPS_PROXY and NO_PROXY set + This fixes the OS400 build and also an incorrect entry for + CURLINFO_APPCONNECT_TIME_T where it was treated as + CURLINFO_STARTTRANSFER_TIME_T. - ... in case NO_PROXY takes an effect + Reported-by: Jon Rumsey - Without this patch, the following command crashes: + Fixes https://github.com/curl/curl/issues/6083 + Closes https://github.com/curl/curl/pull/6084 + +Daniel Stenberg (16 Oct 2020) +- CURLOPT_NOBODY.3: fix typo - $ GIT_CURL_VERBOSE=1 NO_PROXY=github.com HTTPS_PROXY=https://example.com \ - git clone https://github.com/curl/curl.git + Reported-by: Basuke Suzuki + Fixes #6097 + +Marc Hoersken (16 Oct 2020) +- CI/azure: improve on flakiness by avoiding libtool wrappers - Minimal libcurl-based reproducer: + Install curl binaries into MinGW bin folder and use that + for the tests in order to avoid libtool wrapper binaries. - #include + The libtool wrapper binaries (not scripts) on Windows seem + to be one of the possible causes for the following issues: - int main() { - CURL *curl = curl_easy_init(); - if(curl) { - CURLcode ret; - curl_easy_setopt(curl, CURLOPT_URL, "https://github.com/"); - curl_easy_setopt(curl, CURLOPT_PROXY, "example.com"); - /* set the proxy type */ - curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); - curl_easy_setopt(curl, CURLOPT_NOPROXY, "github.com"); - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - ret = curl_easy_perform(curl); - curl_easy_cleanup(curl); - return ret; - } - return -1; - } + 1. Process output can be lost in the wrapper process chain. + 2. Killing the wrapper process does not kill the actual one. - Assisted-by: Kamil Dudka - Bug: https://bugzilla.redhat.com/1873327 - Closes #5902 + Derived from #5904 + Closes #6049 -- travis: add a CI job with openssl3 (from git master) - - Closes #5908 +Daniel Stenberg (16 Oct 2020) +- CURLOPT_URL.3: clarify SCP/SFTP URLs are for uploads as well -- openssl: avoid error conditions when importing native CA - - The code section that is OpenSSL 3+ specific now uses the same logic as - is used in the version < 3 section. It caused a compiler error without - it. - - Closes #5907 +- [Zenju brought this change] -- setopt: avoid curl_ on local variable + CURLOPT_TCP_NODELAY.3: fix comment in example code - Closes #5906 + Closes #6096 -- mqtt.c: avoid curl_ prefix on local variable +- openssl: acknowledge SRP disabling in configure properly - Closes #5906 - -- wildcard: strip "curl_" prefix from private symbols + Follow-up to 68a513247409 - Closes #5906 - -- vtls: make it 'struct Curl_ssl_session' + Use a new separate define that is the combination of both + HAVE_OPENSSL_SRP and USE_TLS_SRP: USE_OPENSSL_SRP - Use uppercase C for internal symbols. + Bug: https://curl.haxx.se/mail/lib-2020-10/0037.html - Closes #5906 + Closes #6094 -- curl_threads: make it 'struct Curl_actual_call' +Viktor Szakats (16 Oct 2020) +- http3: fix two build errors, silence warnings - Internal names should not be prefixed "curl_" + * fix two build errors due to mismatch between function + declarations and their definitions + * silence two mismatched signs warnings via casts - Closes #5906 + Approved-by: Daniel Stenberg + Closes #6093 -- schannel: make it 'struct Curl_schannel*' - - As internal global names should use captical C. +- Makefile.m32: add support for HTTP/3 via ngtcp2+nghttp3 - Closes #5906 + Approved-by: Daniel Stenberg + Closes #6092 -- hash: make it 'struct Curl_hash' - - As internal global names should use captical C. +Daniel Stenberg (16 Oct 2020) +- tool_operate: fix compiler warning when --libcurl is disabled - Closes #5906 + Closes #6095 -- llist: make it "struct Curl_llist" +- checksrc: warn on empty line before open brace - As internal global names should use captical C. + ... and fix a few occurances - Closes #5906 + Closes #6088 -Marc Hoersken (2 Sep 2020) -- telnet.c: depend on static requirement of WinSock version 2 - - Drop dynamic loading of ws2_32.dll and instead rely on the - imported version which is now required to be at least 2.2. +- urlapi: URL encode a '+' in the query part - Reviewed-by: Marcel Raad - Reviewed-by: Jay Satiro - Reviewed-by: Daniel Stenberg - Reviewed-by: Viktor Szakats + ... when asked to with CURLU_URLENCODE. - Closes #5854 + Extended test 1560 to verify. + Reported-by: Dietmar Hauser + Fixes #6086 + Closes #6087 -- win32: drop support for WinSock version 1, require version 2 - - IPv6, telnet and now also the multi API require WinSock - version 2 which is available starting with Windows 95. - - Therefore we think it is time to drop support for version 1. - - Reviewed-by: Marcel Raad - Reviewed-by: Jay Satiro - Reviewed-by: Daniel Stenberg - Reviewed-by: Viktor Szakats - - Follow up to #5634 - Closes #5854 +- [Cristian Morales Vega brought this change] -- select: align poll emulation to return all relevant events + libcurl.pc: make it relocatable - The poll emulation via select already consumes POLLRDNORM, - POLLWRNORM and POLLRDBAND as input events. Therefore it - should also return them as output events if signaled. + It supposes when people specify the libdir/includedir they do it to + change where under prefix/exec_prefix it should be, not to make it + independent of prefix/exec_prefix. - Also fix indentation in input event handling block. + Closes #6061 + +- runtests: return error if no tests ran - Assisted-by: Jay Satiro - Reviewed-by: Daniel Stenberg + ... and make TESTFAIL stand out a little better by adding newlines + before and after. - Replaces #5852 - Closes #5883 + Reported-by: Marc Hörsken + Issue: #6052 + Closes #6053 -- CI/azure: MQTT is now enabled by default +- docs/FEATURE: convert to markdown - Reviewed-by: Daniel Stenberg + ... and clean it up a bit. - Follow up to #5858 - Closes #5903 + Closes #6067 + +- [Philipp Klaus Krause brought this change] -Daniel Stenberg (2 Sep 2020) -- copyright.pl: ignore buildconf + strerror: use 'const' as the string should never be modified + + Closes #6068 -- test971: show test mismatches "inline" +- [Jay Satiro brought this change] -- lib/Makefile.am: bump VERSIONINFO due to new functions + connect: repair build without ipv6 availability - ... we're generally bad at this, but we are adding new functions for - this release. + Assisted-by: Daniel Stenberg + Reported-by: Tom G. Christensen - Closes #5899 + Fixes https://github.com/curl/curl/issues/6069 + Closes https://github.com/curl/curl/pull/6071 -- optiontable: use DEBUGBUILD +- RELEASE-NOTES: synced - Follow-up to commit 6e18568ba38 (#5877) + Started over for the journey to next release. -- cmdline-opts/gen.pl: generate nicer "See Also" in curl.1 - - If there are more than two items in the list, use commas for all but the - last separator which is set to 'and'. Reads better. +- src/tool_filetime: disable -Wformat on mingw for this file - Closes #5898 - -- curl.1: add see also no-progress-meter on two spots + With gcc 10 on mingw we otherwise get this warning: - Ref: #5894 + error: ISO C does not support the 'I' printf flag [-Werror=format=] - Closes #5897 - -- RELEASE-NOTES: synced + Fixes #6079 + Closes #6082 -- mqtt: enable by default +- test122[12]: remove these two tests - No longer considered experimental. + ... and remove the objnames scripts they tested. They're not used for + anything anymore so testing them serves no purpose! - Closes #5858 + Reported-by: Marc Hörsken + Fixes #6080 + Closes #6081 -- [Michael Baentsch brought this change] +Version 7.73.0 (14 Oct 2020) - tls: add CURLOPT_SSL_EC_CURVES and --curves +Daniel Stenberg (14 Oct 2020) +- RELEASE-NOTES: synced - Closes #5892 + for 7.73.0 + +- THANKS: from 7.73.0 and .mailmap fixes -- url: remove funny embedded comments in Curl_disonnect calls +- mailmap: fixups of some contributors -- [Chris Paulson-Ellis brought this change] +- projects/build-wolfssl.bat: fix the copyright year range - conn: check for connection being dead before reuse - - Prevents incorrect reuse of an HTTP connection that has been prematurely - shutdown() by the server. - - Partial revert of 755083d00deb16 - - Fixes #5884 - Closes #5893 +Marc Hoersken (14 Oct 2020) +- [Sergei Nikulov brought this change] -Marc Hoersken (29 Aug 2020) -- buildconf: exec autoreconf to avoid additional process + CI/tests: fix invocation of tests for CMake builds - Also make buildconf exit with the return code of autoreconf. + Update appveyor.yml to set env variable TFLAGS and run tests + Remove curly braces due to CMake error (${TFLAGS} -> $TFLAGS) + Move testdeps build to build step (per review comments) - Reviewed-by: Daniel Stenberg + Reviewed-by: Marc Hörsken - Follow up to #5853 - Closes #5890 + Closes #6066 + Fixes #6052 -- CI/azure: no longer ignore results of test 1013 +- tests/server/util.c: fix support for Windows Unicode builds - Follow up to #5771 - Closes #5889 + Detected via #6066 + Closes #6070 -- docs: add description about CI platforms to CONTRIBUTE.md - - Reviewed-by: Daniel Stenberg - Reviewed-by: Marcel Raad - Reviewed-by: Jay Satiro - - Closes #5882 +Daniel Stenberg (13 Oct 2020) +- [Jay Satiro brought this change] -Daniel Stenberg (29 Aug 2020) -- tests/getpart: use MIME::Base64 instead of home-cooked + strerror: Revert to local codepage for Windows error string - Since we already use the base64 package since a while back, we can just - as well switch to that here too. + - Change get_winapi_error() to return the error string in the local + codepage instead of UTF-8 encoding. - It also happens to use the exact same function name, which otherwise - causes a run-time warning. + Two weeks ago bed5f84 fixed get_winapi_error() to work on xbox, but it + also changed the error string's encoding from local codepage to UTF-8. - Reported-by: Marc Hörsken - Fixes #5885 - Closes #5887 - -Marcel Raad (29 Aug 2020) -- ntlm: fix condition for curl_ntlm_core usage + We return the local codepage version of the error string because if it + is output to the user's terminal it will likely be with functions which + expect the local codepage (eg fprintf, failf, infof). - `USE_WINDOWS_SSPI` without `USE_WIN32_CRYPTO` but with any other DES - backend is fine, but was excluded before. + This is essentially a partial revert of bed5f84. The support for xbox + remains but the error string is reverted back to local codepage. - This also fixes test 1013 as the condition for SMB support in - configure.ac didn't match the condition in the source code. Now it - does. + Ref: https://github.com/curl/curl/pull/6005 - Fixes https://github.com/curl/curl/issues/1262 - Closes https://github.com/curl/curl/pull/5771 + Reviewed-by: Marcel Raad + Closes #6065 -- AppVeyor: switch 64-bit Schannel Debug CMake builds to Unicode - - The Schannel builds are the most useful to verify as they make the most - use of the Windows API. Classic MinGW doesn't support Unicode at all, - only MinGW-w64 and MSVC do. +Marc Hoersken (13 Oct 2020) +- CI/tests: use verification curl for test reporting APIs - Closes https://github.com/curl/curl/pull/5843 - -- CMake: add option to enable Unicode on Windows + Avoid using our own, potentially installed, curl for + the test reporting APIs in case it is broken. - As already existing for winbuild. + Reviewed-by: Daniel Stenberg - Closes https://github.com/curl/curl/pull/5843 + Preparation for #6049 + Closes #6063 -Marc Hoersken (29 Aug 2020) -- select: simplify return code handling for poll and select - - poll and select already return -1 on error according to POSIX, - so there is no need to perform a <0 to -1 conversion in code. - - Also we can just use one check with <= 0 on the return code. +Viktor Szakats (12 Oct 2020) +- windows: fix comparison of mismatched types warning - Assisted-by: Daniel Stenberg - Reviewed-by: Jay Satiro + clang 10, mingw-w64: + ``` + vtls/openssl.c:2917:33: warning: comparison of integers of different signs: 'DWORD' (aka 'unsigned long') and 'HRESULT' (aka 'long') + [-Wsign-compare] + if(GetLastError() != CRYPT_E_NOT_FOUND) + ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~ + ``` - Replaces #5852 - Closes #5880 - -Daniel Stenberg (28 Aug 2020) -- RELEASE-NOTES: synced + Approved-by: Daniel Stenberg + Closes #6062 -- [Jeroen Ooms brought this change] +Daniel Stenberg (11 Oct 2020) +- [Viktor Szakats brought this change] - tests: add test1912 with typechecks + src/Makefile.m32: fix undefined curlx_dyn_* errors - Validates that gcc-typecheck macros match the new option type API. + by linking `lib/dynbuf.c` when building a static curl binary. + Previously this source file was only included when building + a dynamic curl binary. This was likely possibly because no + functions from the `src/Makefile.inc` / `CURLX_CFILES` sources + were actually required for a curl tool build. This has + recently changed with the introduction of `curlx_dyn_*()` + memory functions and their use by the tool sources. - Closes #5873 + Closes #6060 -- easyoptions: provide debug function when DEBUGBUILD - - ... not CURLDEBUG as they're not always set in conjunction. - - Follow-up to 6ebe63fac23f38df - - Fixes #5877 - Closes #5878 +- HISTORY: curl verifies SSL certs by default since version 7.10 -Marc Hoersken (28 Aug 2020) -- sockfilt: handle FD_CLOSE winsock event on write socket - - Learn from the way Cygwin handles and maps the WinSock events - to simulate correct and complete poll and select behaviour - according to Richard W. Stevens Network Programming book. +Marc Hoersken (8 Oct 2020) +- runtests.pl: use $LIBDIR variable instead of hardcoded path - Follow up to #5867 - Closes #5879 + Reviewed-by: Daniel Stenberg + Closes #6051 -- multi: handle connection state winsock events - - Learn from the way Cygwin handles and maps the WinSock events - to simulate correct and complete poll and select behaviour - according to Richard W. Stevens Network Programming book. +Daniel Stenberg (7 Oct 2020) +- checksrc: detect // comments on column 0 - Reviewed-by: Jay Satiro - Reviewed-by: Marcel Raad + Spotted while working on #6045 - Follow up to #5634 - Closes #5867 + Closes #6048 -Daniel Stenberg (28 Aug 2020) -- Curl_pgrsTime - return new time to avoid timeout integer overflow - - Setting a timeout to INT_MAX could cause an immediate error to get - returned as timeout because of an overflow when different values of - 'now' were used. - - This is primarily fixed by having Curl_pgrsTime() return the "now" when - TIMER_STARTSINGLE is set so that the parent function will continue using - that time. - - Reported-by: Ionuț-Francisc Oancea - Fixes #5583 - Closes #5847 +- [Frederik Wedel-Heinen brought this change] -- TLS: fix SRP detection by using the proper #ifdefs - - USE_TLS_SRP will be true if *any* selected TLS backend can use SRP - - HAVE_OPENSSL_SRP is defined when OpenSSL can use it - - HAVE_GNUTLS_SRP is defined when GnuTLS can use it - - Clarify in the curl_verison_info docs that CURL_VERSION_TLSAUTH_SRP is - set if at least one of the supported backends offers SRP. + mbedtls: add missing header when defining MBEDTLS_DEBUG - Reported-by: Stefan Strogin - Fixes #5865 - Closes #5870 - -- [Dan Kenigsberg brought this change] + Closes #6045 - docs: SSLCERTS: fix English syntax +- curl: make sure setopt CURLOPT_IPRESOLVE passes on a long - Signed-off-by: Dan Kenigsberg + Previously, it would pass on a define (int) which could make libcurl + read junk as a value - which prevented the CURLOPT_IPRESOLVE option to + "take". This could then make test 2100 do two DoH requests instead of + one! - Closes #5876 + Fixes #6042 + Closes #6043 -- [Alessandro Ghedini brought this change] +- RELEASE-NOTES: synced - docs: non-existing macros in man pages - - As reported by man(1) when invoked as: - - man --warnings -E UTF-8 -l -Tutf8 -Z >/dev/null +- scripts/release-notes.pl: don't "embed" $ in format string for printf() - Closes #5846 + ... since they might contain %-codes that mess up the output! -- [Alessandro Ghedini brought this change] +Jay Satiro (5 Oct 2020) +- [M.R.T brought this change] - curl.1: fix typo invokved -> invoked + build-wolfssl: fix build with Visual Studio 2019 - Closes #5846 + Closes https://github.com/curl/curl/pull/6033 -- buildconf: invoke 'autoreconf -fi' instead +Daniel Stenberg (4 Oct 2020) +- runtests: add %repeat[]% for test files - The custom script isn't necessary anymore - but remains for simplicity - and just invokes autoreconf. + ... and use this new keywords in all the test files larger than 50K to reduce + their sizes and make them a lot easier to read and understand. - Closes #5853 + Closes #6040 - [Emil Engler brought this change] - lib: make Curl_gethostname accept a const pointer + --help: move two options from the misc category - The address of that variable never gets changed, only the data in it so - why not make it a "char * const"? + The cmdline opts delegation and suppress-connect-headers + fit better into auth and proxy rather than misc. - Closes #5866 + Follow-up to aa8777f63febc + Closes #6038 -- docs/libcurl: update "Added in" version for curl_easy_option* - - Follow-up to 6ebe63fac23f38 +- [Samanta Navarro brought this change] -- scripts: improve the "get latest curl release tag" logic + docs/opts: fix typos in two manual pages - ... by insiting on it matching "^curl-". + Closes #6039 -- configure: added --disable-get-easy-options - - To allow disabling of the curl_easy_option APIs in a build. +- ldap: reduce the amount of #ifdefs needed - Closes #5365 + Closes #6035 -- options: API for meta-data about easy options - - const struct curl_easyoption *curl_easy_option_by_name(const char *name); - - const struct curl_easyoption *curl_easy_option_by_id (CURLoption id); +- runtests: provide curl's version string as %VERSION for tests - const struct curl_easyoption * - curl_easy_option_next(const struct curl_easyoption *prev); + ... so that we can check HTTP requests for User-Agent: curl/%VERSION - The purpose is to provide detailed enough information to allow for - example libcurl bindings to get option information at run-time about - what easy options that exist and what arguments they expect. + Update 600+ test cases accordingly. - Assisted-by: Jeroen Ooms - Closes #5365 - -- [Eric Curtin brought this change] + Closes #6037 - HTTP/3: update to OpenSSL_1_1_1g-quic-draft-29 +- checksrc: warn on space after exclamation mark - Closes #5871 + Closes #6034 -- RELEASE-NOTES: synced +- test1465: verify --libcurl with binary POST data -Jay Satiro (26 Aug 2020) -- openssl: Fix wincrypt symbols conflict with BoringSSL - - OpenSSL undefines the conflicting symbols but BoringSSL does not so we - must do it ourselves. - - Reported-by: Samuel Tranchet - Assisted-by: Javier Blazquez - - Ref: https://bugs.chromium.org/p/boringssl/issues/detail?id=371 - Ref: https://github.com/openssl/openssl/blob/OpenSSL_1_1_1g/include/openssl/ossl_typ.h#L66-L73 - - Fixes https://github.com/curl/curl/issues/5669 - Closes https://github.com/curl/curl/pull/5857 +- runtests: allow generating a binary sequence from hex -Daniel Stenberg (26 Aug 2020) -- socketpair: allow CURL_DISABLE_SOCKETPAIR - - ... to completely disable the use of socketpair - - Closes #5850 +- tool_setopt: escape binary data to hex, not octal -- curl_get_line: build only if cookies or alt-svc are enabled +- curl: make --libcurl show binary posts correctly - Closes #5851 - -- [fullincome brought this change] + Reported-by: Stephan Mühlstrasser + Fixes #6031 + Closes #6032 - schannel: fix memory leak when using get_cert_location +Jay Satiro (1 Oct 2020) +- strerror: fix null deref on winapi out-of-memory - The get_cert_location function allocates memory only on success. - Previously get_cert_location was able to allocate memory and return - error. It wasn't obvious and in this case the memory wasn't - released. + Follow-up to bed5f84 from several days ago. - Fixes #5855 - Closes #5860 + Ref: https://github.com/curl/curl/pull/6005 -- [Emil Engler brought this change] +Daniel Stenberg (1 Oct 2020) +- [Kamil Dudka brought this change] - git: ignore libtests in 3XXX area + vtls: deduplicate some DISABLE_PROXY ifdefs - Currently the file tests/libtest/lib3010 is not getting - ignored by git. This fixes it by adding the 3XXX area to - the according .gitignore file. + ... in the code of gtls, nss, and openssl - Closes #5859 + Closes #5735 + +- RELEASE-NOTES: synced - [Emil Engler brought this change] - doh: add error message for DOH_DNS_NAME_TOO_LONG - - When this error code was introduced in b6a53fff6c1d07e8a9, it was - forgotten to be added in the errors array and doh_strerror function. + TODO: Add OpenBSD libtool notice - Closes #5863 + See #5862 + Closes #6030 -- ngtcp2: adapt to the new pkt_info arguments +- tests/unit/README: convert to markdown - Guidance-by: Tatsuhiro Tsujikawa + ... and add to dist! - Closes #5864 + Closes #6028 -- winbuild/README.md: make visible +- tests/README: convert to markdown - Follow-up to be753add31c2d8c + Closes #6028 -- winbuild: convert the instruction text to README.md +- include/README: convert to markdown - Closes #5861 + Closes #6028 -- lib1560: verify "redirect" to double-slash leading URL +- examples/README: convert to markdown - Closes #5849 + Closes #6028 -Marc Hoersken (25 Aug 2020) -- multi: expand pre-check for socket readiness - - Check readiness of all sockets before waiting on them - to avoid locking in case the one-time event FD_WRITE - was already consumed by a previous wait operation. - - More information about WinSock network events: - https://docs.microsoft.com/en-us/windows/win32/api/ - winsock2/nf-winsock2-wsaeventselect#return-value +- configure: don't say HTTPS-proxy is enabled when disabled! - Closes #5634 - -- [rcombs brought this change] + Reported-by: Kamil Dudka + Reviewed-by: Kamil Dudka + Bug: https://github.com/curl/curl/pull/5735#issuecomment-701376388 + Closes #6029 - multi: implement wait using winsock events - - This avoids using a pair of TCP ports to provide wakeup functionality - for every multi instance on Windows, where socketpair() is emulated - using a TCP socket on loopback which could in turn lead to socket - resource exhaustion. - - A previous version of this patch failed to account for how in WinSock, - FD_WRITE is set only once when writing becomes possible and not again - until after a send has failed due to the buffer filling. This contrasts - to how FD_READ and FD_OOB continue to be set until the conditions they - refer to no longer apply. This meant that if a user wrote some data to - a socket, but not enough data to completely fill its send buffer, then - waited on that socket to become writable, we'd erroneously stall until - their configured timeout rather than returning immediately. - - This version of the patch addresses that issue by checking each socket - we're waiting on to become writable with select() before the wait, and - zeroing the timeout if it's already writable. +Daniel Gustafsson (30 Sep 2020) +- src: Consistently spell whitespace without whitespace - Assisted-by: Marc Hörsken - Reviewed-by: Marcel Raad - Reviewed-by: Daniel Stenberg - Tested-by: Gergely Nagy - Tested-by: Rasmus Melchior Jacobsen - Tested-by: Tomas Berger + Whitespace is spelled without a space between white and space, so + make sure to consistently spell it that way across the codebase. - Replaces #5397 - Reverts #5632 - Closes #5634 + Closes #6023 + Reviewed-by: Daniel Stenberg + Reviewed-by: Emil Engler -- select: reduce duplication of Curl_poll in Curl_socket_check - - Change Curl_socket_check to use select-fallback in Curl_poll - instead of implementing it in Curl_socket_check and Curl_poll. +- MANUAL: update examples to resolve without redirects - Reviewed-by: Daniel Stenberg - Reviewed-by: Jay Satiro + www.netscape.com is redirecting to a cookie consent form on Aol, and + cool.haxx.se isn't responding to FTP anymore. Replace with examples + that resolves in case users try out the commands when reading the + manual. - Replaces #5262 and #5492 - Closes #5707 + Closes #6024 + Reviewed-by: Daniel Stenberg + Reviewed-by: Emil Engler -- select: fix poll-based check not detecting connect failure - - This commit changes Curl_socket_check to use POLLPRI to - check for connect failure on the write socket, because - POLLPRI maps to fds_err. This is in line with select(2). - - The select-based socket check correctly checks for connect - failures by adding the write socket also to fds_err. - - The poll-based implementation (which internally can itself - fallback to select again) did not previously check for - connect failure by using POLLPRI with the write socket. - - See the follow up commit to this for more information. - - This commit makes sure connect failures can be detected - and handled if HAVE_POLL_FINE is defined, eg. on msys2-devel. - - Reviewed-by: Daniel Stenberg - Reviewed-by: Jay Satiro - - Replaces #5509 - Prepares #5707 +Daniel Stenberg (30 Sep 2020) +- HISTORY: add some 2020 events -- select.h: make socket validation macros test for INVALID_SOCKET +- sectransp: make it build with --disable-proxy - With Winsock the valid range is [0..INVALID_SOCKET-1] according to - https://docs.microsoft.com/en-us/windows/win32/winsock/socket-data-type-2 + Follow-up from #5466 and f3d501dc678d80 + Reported-by: Javier Navarro + Fixes #6025 + Closes #6026 + +- ECH: renamed from ESNI in docs and configure - Reviewed-by: Jay Satiro - Reviewed-by: Marcel Raad - Reviewed-by: Daniel Stenberg + Encrypted Client Hello (ECH) is the current name. - Closes #5760 + Closes #6022 -Daniel Stenberg (24 Aug 2020) -- docs: --output-dir is added in 7.73.0, nothing else +- configure: use "no" instead of "disabled" for the end summary - Follow-up to 5620d2cc78c0 + ... for consistency but also to make them more distinctly stand out next + to the "enabled" lines. -- curl: add --output-dir - - Works with --create-dirs and with -J - - Add test 3008, 3009, 3011, 3012 and 3013 to verify. +- TODO: SSH over HTTPS proxy with more backends - Closes #5637 + ... as right now only the libssh2 backend supports it. -- configure: fix pkg-config detecting wolfssl - - When amending the include path with "/wolfssl", this now properly strips - off all whitespace from the path variable! Previously this would lead to - pkg-config builds creating bad command lines. +- libssh2: handle the SSH protocols done over HTTPS proxy - Closes #5848 + Reported-by: Robin Douine + Fixes #4295 + Closes #6021 -- [Michael Musset brought this change] +- [Emil Engler brought this change] - sftp: add the option CURLKHSTAT_FINE_REPLACE + memdebug: remove 9 year old unused debug function - Replace the old fingerprint of the host with a new. + There used to be a way to have memdebug fill allocated memory. 9 years + later this has no value there (valgrind and ASAN etc are way better). If + people need to know about it they can have a look at VCS logs. - Closes #5685 + Closes #5973 -- RELEASE-NOTES: synced +- sendf: move Curl_sendf to dict.c and make it static + + ... as the only remaining user of that function. Also fix gopher.c to + instead use Curl_write() - The next release is now to become 7.73.0 + Closes #6020 -- checksrc: verify do-while and spaces between the braces +- ROADMAP: updates and cleanups - Updated mprintf.c to comply + Fix the HSTS PR - Closes #5845 + Remove DoT, thread-safe init and hard-coded localhost. I feel very + little interest for these with users so I downgrade them to plain "TODO" + entries again. -- curl: support XDG_CONFIG_HOME to find .curlrc +- schannel: return CURLE_PEER_FAILED_VERIFICATION for untrusted root - Added test433 to verify. Updated documentation. + This matches what is returned in other TLS backends in the same + situation. Reviewed-by: Jay Satiro - Suggested-by: Eli Schwartz - Fixes #5829 - Closes #5837 + Reviewed-by: Emil Engler + Follow-up to 5a3efb1 + Reported-by: iammrtau on github + Fixes #6003 + Closes #6018 -- etag: save and use the full received contents - - ... which makes it support weak tags and non-standard etags too! - - Added test case 347 to verify blank incoming ETag: - - Fixes #5610 - Closes #5833 +- RELEASE-NOTES: synced -- setopt: if the buffer exists, refuse the new BUFFERSIZE - - The buffer only exists during transfer and then we shouldn't change the - size (the setopt is not documented to work then). +- ftp: make a 552 response return CURLE_REMOTE_DISK_FULL - Reported-by: Harry Sintonen - Closes #5842 - -- [COFFEETALES brought this change] - - sftp: add new quote commands 'atime' and 'mtime' + Added test 348 to verify. Added a 'STOR' command to the test FTP + server to enable test 348. Documented the command in FILEFORMAT.md - Closes #5810 + Reported-by: Duncan Wilcox + Fixes #6016 + Closes #6017 -- CURLE_PROXY: new error code +- pause: only trigger a reread if the unpause sticks - Failures clearly returned from a (SOCKS) proxy now causes this return - code. Previously the situation was not very clear as what would be - returned and when. + As an unpause might itself get paused again and then triggering another + reread doesn't help. - In addition: when this error code is returned, an application can use - CURLINFO_PROXY_ERROR to query libcurl for the detailed error, which then - returns a value from the new 'CURLproxycode' enum. + Follow-up from e040146f22608fd9 (shipped since 7.69.1) - Closes #5770 + Bug: https://curl.haxx.se/mail/lib-2020-09/0081.html + Patch-by: Kunal Chandarana + Fixes #5988 + Closes #6013 -- runtests: make cleardir() erase dot files too +- test163[12]: require http to be built-in to run - Because test cases might use dot files. + ... as speaking over an HTTPS proxy implies http! - Closes #5838 + Closes #6014 -- KNOWN_BUGS: 'no_proxy' string-matches IPv6 numerical addreses - - Also: the current behavior is now documented in the curl.1 and - CURLOPT_NOPROXY.3 man pages. +- ngtcp2: adapt to new NGTCP2_PROTO_VER_MAX define - Reported-by: Andrew Barnes - Closes #5745 - Closes #5841 + Closes #6012 -Viktor Szakats (22 Aug 2020) -- Makefile.m32: add ability to override zstd libs [ci skip] - - Similarly to brotli, where this was already possible. - E.g. it allows to link zstd statically to libcurl.dll. - - Ref: https://github.com/curl/curl-for-win/issues/12 - Ref: https://github.com/curl/curl-for-win/commit/d9b266afd2e5d3f5604483010ef62340b5918c89 - - Closes https://github.com/curl/curl/pull/5840 +- [Javier Blazquez brought this change] -Daniel Stenberg (21 Aug 2020) -- runtests: avoid 'fail to start' repeated messages in attempt loops + strerror: honor Unicode API choice on Windows - Closes #5834 + Closes #6005 -- runtests: clear pid variables when failing to start a server - - ... as otherwise the parent doesn't detect the failure and believe it - actually worked to start. +- imap: make imap_send use dynbuf for the send buffer management - Reported-by: Christian Weisgerber - Bug: https://curl.haxx.se/mail/lib-2020-08/0018.html - Closes #5834 - -- TODO: Virtual external sockets + Reuses the buffer and thereby reduces number of mallocs over a transfer. - Closes #5835 - -- [Don J Olmstead brought this change] + Closes #6010 - dist: add missing CMake Find modules to the distribution +- Curl_send: return error when pre_receive_plain can't malloc - Closes #5836 - -- RELEASE-NOTES: synced + ... will probably trigger some false DEAD CODE positives on non-windows + code analyzers for the conditional code. - ... and version bumped to 7.72.1 + Closes #6011 -- tls: provide the CApath verbose log on its own line +- ftp: separate FTPS from FTP over "HTTPS proxy" - ... not newline separated from the previous line. This makes it output - asterisk prefixed properly like other verbose putput! + When using HTTPS proxy, SSL is used but not in the view of the FTP + protocol handler itself so separate the connection's use of SSL from the + FTP control connection's sue. - Reported-by: jmdavitt on github - Fixes #5826 - Closes #5827 - -Version 7.72.0 (19 Aug 2020) + Reported-by: Mingtao Yang + Fixes #5523 + Closes #6006 -Daniel Stenberg (19 Aug 2020) -- RELEASE-NOTES: synced +Dan Fandrich (23 Sep 2020) +- tests/data: Fix some mismatched XML tags in test cases - The curl 7.72.0 release - -- THANKS: add names from curl 7.72.0 release + This allows these test files to pass xmllint. -Jay Satiro (18 Aug 2020) -- KNOWN_BUGS: Schannel TLS 1.2 handshake bug in old Windows versions - - Reported-by: plujon@users.noreply.github.com +Daniel Stenberg (23 Sep 2020) +- pingpong: use a dynbuf for the *_pp_sendf() function - Closes https://github.com/curl/curl/issues/5488 - -Daniel Stenberg (17 Aug 2020) -- Curl_easy: remember last connection by id, not by pointer + ... reuses the same dynamic buffer instead of doing repeated malloc/free + cycles. - CVE-2020-8231 + Test case 100 (FTP dir list PASV) does 7 fewer memory allocation calls + after this change in my test setup (132 => 125), curl 7.72.0 needed 140 + calls for this. - Bug: https://curl.haxx.se/docs/CVE-2020-8231.html + Test case 103 makes 9 less allocations now (130). Down from 149 in + 7.72.0. - Reported-by: Marc Aldorasi - Closes #5824 - -- examples/rtsp.c: correct the copyright year - -- RELEASE-PROCEDURE.md: add more future release dates - -- [H3RSKO brought this change] + Closes #6004 - docs: change "web site" to "website" - - According to wikipedia: - - While "web site" was the original spelling, this variant has become - rarely used, and "website" has become the standard spelling +- dynbuf: add Curl_dyn_vaddf - Closes #5822 - -- [Bevan Weiss brought this change] + Closes #6004 - CMake: don't complain about missing nroff +- dynbuf: make *addf() not require extra mallocs - The curl_nroff_check() was always being called, and complaining if - *NROFF wasn't found, even when not making the manual. + ... by introducing a printf() function that appends directly into a + dynbuf: Curl_dyn_vprintf(). This avoids the mandatory extra malloc so if + the buffer is already big enough it can just printf directly into it. - Only check for nroff (and complain) if actually making the manual + Since this less-malloc version requires tthe use of a library internal + printf function, we only provide this version when building libcurl and + not for the dynbuf code that is used when building the curl tool. - Closes #5817 - -- [Brian Inglis brought this change] + Closes #5998 - libtest/Makefile.am: add -no-undefined for libstubgss for Cygwin - - copy the LDFLAGS approach for adding same option with `libhostname` in - `libtest/Makefile.am`: - - - init `libstubgss_la_LDFLAGS_EXTRA` variable, - - add option to variable inside conditional, - - use variable in `libstubgss_la_LDFLAGS` +- KNOWN_BUGS: Unable to use PKCS12 certificate with Secure Transport - Fixes #5819 - Closes #5820 + Closes #5403 -- docs: clarify MAX_SEND/RECV_SPEED functionality +- pingpong: remove a malloc per Curl_pp_vsendf call - ... in particular what happens if the maximum speed limit is set to a - value that's smaller than the transfer buffer size in use. + This typically makes 7-9 fewer mallocs per FTP transfer. - Reported-by: Tomas Berger - Fixes #5788 - Closes #5813 + Closes #5997 -- test1140: compare stdout +- symbian: drop support - To make problems more immediately obvious when tests fail. + The OS is deprecated. I see no traces of anyone having actually built + curl for Symbian after 2012. - Closes #5814 - -- asyn-ares: correct some bad comments + The public headers are unmodified. - Closes #5812 + Closes #5989 -- [Emil Engler brought this change] +- RELEASE-NOTES: synced - docs: Add video link to docs/CONTRIBUTE.md +- curl_krb5.h: rename from krb5.h + + Follow-up from f4873ebd0be32cf - Closes #5811 + Turns out some older openssl installations go bananas otherwise. + Reported-by: Tom van der Woerdt + Fixes #5995 + Closes #5996 + +- test1297: verify GOT_NOTHING with http proxy tunnel -- curl-config: ignore REQUIRE_LIB_DEPS in --libs output +- http_proxy: do not count proxy headers in the header bytecount - Fixes a curl-config issue on cygwin by making sure REQUIRE_LIB_DEPS is - not considered for the --libs output. + ... as that counter is subsequently used to detect if nothing was + returned from the peer. This made curl return CURLE_OK when it should + have returned CURLE_GOT_NOTHING. - Reported-by: ramsay-jones on github - Assisted-by: Brian Inglis and Ken Brown - Fixes #5793 - Closes #5808 - -- copyright: update/correct the year range on a few files - -- scripts/copyright.pl: ignore .muse files - -- [Emil Engler brought this change] + Fixes #5992 + Reported-by: Tom van der Woerdt + Closes #5994 - multi: Remove 10-year old out-commented code +- setopt: return CURLE_BAD_FUNCTION_ARGUMENT on bad argument - The code hasn't been touched since 2010-08-18 + Fixed two return code mixups. CURLE_UNKNOWN_OPTION is saved for when the + option is, yeah, not known. Clarified this in the setopt man page too. - Closes #5805 + Closes #5993 -- KNOWN_BUGS: A shared connection cache is not thread-safe +- krb5: merged security.c and krb specific FTP functions in here - Closes #4915 - Closes #5802 - -- CONTRIBUTE: extend git commit message description + These two files were always tightly connected and it was hard to + understand what went into which. This also allows us to make the + ftpsend() function static (moved from ftp.c). - In particular how the first line works. + Removed security.c + Renamed curl_sec.h to krb5.h - Closes #5803 - -- RELEASE-NOTES: synced - -- [Stefan Yohansson brought this change] + Closes #5987 - transfer: move retrycount from connect struct to easy handle +- Curl_handler: add 'family' to each protocol - This flag was applied to the connection struct that is released on - retry. These changes move the retry counter into Curl_easy struct that - lives across retries and retains the new connection. + Makes get_protocol_family() faster and it moves the knowledge about the + "families" to each protocol handler, where it belongs. - Reported-by: Cherish98 on github - Fixes #5794 - Closes #5800 + Closes #5986 -- libssh2: s/ssherr/sftperr/ - - The debug output used ssherr instead of sftperr which not only outputs - the wrong error code but also casues a warning on Windows. +- parsedate: tune the date to epoch conversion - Follow-up to 7370b4e39f1 + By avoiding an unnecessary error check and the temp use of the tm + struct, the time2epoch conversion function gets a little bit faster. + When repeating test 517, the updated version is perhaps 1% faster (on + one particular build on one particular architecture). - Reported-by: Gisle Vanem - Bug: https://github.com/curl/curl/commit/7370b4e39f1390e701f5b68d910c619151daf72b#r41334700 - Closes #5799 + Closes #5985 -- ftp: don't do ssl_shutdown instead of ssl_close +- cmake: remove scary warning - The shutdown function is for downgrading a connection from TLS to plain, - and this is not requested here. + Remove the text saying - Have ssl_close reset the TLS connection state. + "the curl cmake build system is poorly maintained. Be aware" - This partially reverts commit f002c850d98d + ... not because anything changed just now, but to encourage users to use + it and subsequently improve it. - Reported-by: Rasmus Melchior Jacobsen - Reported-by: Denis Goleshchikhin - Fixes #5797 + Closes #5984 -Marc Hoersken (9 Aug 2020) -- CI/azure: fix test outcome values and use latest API version - - This makes sure that tests ignored or skipped are not shown - just in the category "Other", but with their correct state. - - Closes #5796 +- docs/MQTT: remove outdated paaragraphs -- CI/azure: show runtime stats to investigate slowness - - Also avoid naming conflict of TFLAGS env and tflags variables. +- docs/MQTT: not experimental anymore - Closes #5776 + Follow-up to e37e4468688d8f -Daniel Stenberg (8 Aug 2020) -- TLS naming: fix more Winssl and Darwinssl leftovers +- docs/RESOURCES: remove - The CMake option is now called CMAKE_USE_SCHANNEL + This document is not maintained and rather than trying to refresh it, + let's kill it. A more up-to-date document with relevant RFCs is this + page on the curl website: https://curl.haxx.se/rfc/ - The winbuild flag is USE_SCHANNEL + Closes #5980 + +- docs/TheArtOfHttpScripting: convert to markdown - The CI jobs and build scripts only use the new names and the new name - options + Makes it easier to browse on github etc. Offers (better) links. - Tests now require 'Schannel' (when necessary) + It should be noted that this document is already mostly outdated and + "Everything curl" at https://ec.haxx.se/ is a better resource and + tutorial. - Closes #5795 + Closes #5981 -- smtp_parse_address: handle blank input string properly +- BUGS: convert document to markdown - Closes #5792 + Closes #5979 -- runtests: run the DICT server on a random port number +- --help: strdup the category - Removed support for -b (base port number) + ... since it is converted and the original pointer is freed on Windows + unicode handling. - Closes #5783 + Follow-up to aa8777f63febc + Fixes #5977 + Closes #5978 + Reported-by: xwxbug on github -- RELEASE-NOTES: synced +- CHECKSRC: document two missing warnings -- runtests: move the TELNET server to a dynamic port - - Rename the port variable to TELNETPORT to better match the existing - pattern. - - Closes #5785 +- RELEASE-NOTES: synced -- ngtcp2: adapt to error code rename +- ftp: avoid risk of reading uninitialized integers - Closes #5786 - -- runtests: move the smbserver to use a dynamic port number + If the received PASV response doesn't match the expected pattern, we + could end up reading uninitialized integers for IP address and port + number. - Closes #5782 + Issue pointed out by muse.dev + Closes #5972 -- runtests: run the http2 tests on a random port number - - Closes #5779 +- [Quentin Balland brought this change] -- gtls: survive not being able to get name/issuer + easy_reset: clear retry counter - Closes #5778 + Closes #5975 + Fixes #5974 -- runtests: move the gnutls-serv tests to a dynamic port +- ftp: get rid of the PPSENDF macro - Affects test 320, 321, 322 and 324. + The use of such a macro hides some of what's actually going on to the + reader and is generally disapproved of in the project. - Closes #5778 + Closes #5971 -- runtests: support dynamicly base64 encoded sections in tests - - This allows us to make test cases to use base64 at run-time and still - use and verify information determined at run-time, such as the IMAP test - server's port number in test 842. - - This change makes 12 tests run again that basically never ran since we - moved to dynamic port numbers. - - ftpserver.pl is adjusted to load test instructions and test number from - the preprocessed test file. +- man pages: switch to https://example.com URLs - FILEFORMAT.md now documents the new base64 encoding syntax. + Since HTTPS is "the new normal", this update changes a lot of man page + examples to use https://example.com instead of the previous "http://..." - Reported-by: Marcel Raad - Fixes #5761 - Closes #5775 + Closes #5969 -- curl.1: add a few missing valid exit codes +- github: remove the duplicate "Security vulnerability" entry - 93 - 96 can be returned as well. + ... since github adds an entry automatically by itself. - Closes #5777 + Closes #5970 -- TODO: Use multiple parallel transfers for a single download - - Closes #5774 +- [Emil Engler brought this change] -- TODO: Set the modification date on an uploaded file + github: use new issue template feature - Closes #5768 - -- [Thomas M. DuBuisson brought this change] - - CI: Add muse CI config + This helps us to avoid getting feature requests as well as security + bugs reported into the issue tracker. - Closes #5772 + Closes #5936 -- [Thomas M. DuBuisson brought this change] +- [Emil Engler brought this change] - travis/script.sh: fix use of `-n' with unquoted envvar - - Shellcheck tells us "-n doesn't work with unquoted arguments. quote or - use [[ ]]." - - And testing shows: - - ``` - docker run --rm -it ubuntu bash - root@fe85ce156856:/# [ -n $DOES_NOT_EXIST ] && echo "I ran" - I ran - root@fe85ce156856:/# [ -n "$DOES_NOT_EXIST" ] && echo "I ran" - root@fe85ce156856:/# - ``` + urlapi: use more Curl_safefree - Closes #5773 + Closes #5968 -- h2: repair trailer handling +Marc Hoersken (17 Sep 2020) +- multi: align WinSock mask variables in Curl_multi_wait - The previous h2 trailer fix in 54a2b63 was wrong and caused a - regression: it cannot deal with trailers immediately when read since - they may be read off the connection by the wrong 'data' owner. + Also skip pre-checking sockets to set timeout_ms to 0 + after the first socket has been detected to be ready. - This change reverts the logic back to gathering all trailers into a - single buffer, like before 54a2b63. + Reviewed-by: rcombs on github + Reviewed-by: Daniel Stenberg - Reported-by: Tadej Vengust - Fixes #5663 - Closes #5769 + Follow up to #5886 -Viktor Szakats (3 Aug 2020) -- windows: disable Unix Sockets for old mingw - - Classic mingw and 10y+ old versions of mingw-w64 don't ship with - Windows headers having the typedef necessary for Unix Sockets - support, so try detecting these environments to disable this - feature. +- multi: reuse WinSock events variable in Curl_multi_wait - Ref: https://sourceforge.net/p/mingw-w64/mingw-w64/ci/cf6afc57179a5910621215f8f4037d406892072c/ + Since the struct is quite large (1 long and 10 ints) we + declare it once at the beginning of the function instead + of multiple times inside loops to avoid stack movements. + Reviewed-by: Viktor Szakats Reviewed-by: Daniel Stenberg - Fixes #5674 - Closes #5758 + Closes #5886 -Marcel Raad (3 Aug 2020) -- test1908: treat file as text +Daniel Stenberg (16 Sep 2020) +- TODO: dynamically decide to use socketpair - Fixes the line endings on Windows. + Suggested-by: Anders Bakken - Closes https://github.com/curl/curl/pull/5767 + Closes #4829 -- TrackMemory tests: ignore realloc and free in getenv.c +- TODO: add PR reference for native IDN support on macOS - These are only called for WIN32. + As there was work started on this that never got completed. - Closes https://github.com/curl/curl/pull/5767 - -Daniel Stenberg (3 Aug 2020) -- tests/FILEFORMAT.md: mention %HTTP2PORT + Closes #5371 -- RELEASE-NOTES: synced +- tool_help.h: update copyright year range + + Follow-up from aa8777f63febca -- tlsv1.3.d. only for TLS-using connections +- CI/azure: disable test 571 in the msys2 builds - ... and rephrase that "not all" TLS backends support it. + It's just too flaky there - Closes #5764 + Reviewed-by: Marc Hoersken + Closes #5954 -- tls-max.d: this option is only for TLS-using connections +- tool_writeout: protect fputs() from NULL - Ref: #5763 - Closes #5764 - -Marcel Raad (2 Aug 2020) -- [Cameron Cawley brought this change] - - tool_doswin: Simplify Windows version detection + When the code was changed to do fputs() instead of fprintf() it got + sensitive for NULL pointers; add checks for that. - Closes https://github.com/curl/curl/pull/5754 - -- [Cameron Cawley brought this change] - - win32: Add Curl_verify_windows_version() to curlx + Follow-up from 0c1e767e83ec66 - Closes https://github.com/curl/curl/pull/5754 + Closes #5963 -- runtests.pl: treat LibreSSL and BoringSSL as OpenSSL +- test3015: verify stdout "as text" - This makes the tests that require the OpenSSL feature also run for - those two compatible libraries. + Follow-up from 0c1e767e83e to please win32 tests - Closes https://github.com/curl/curl/pull/5762 + Closes #5962 -Daniel Stenberg (1 Aug 2020) -- multi: Condition 'extrawait' is always true +- travis: use libressl v3.1.4 instead of master - Reported by Codacy. + ... as their git master seems too fragile to use (and 3.2.1 which is the + latest has a build failure). - Reviewed-by: Marcel Raad - Closes #5759 + Closes #5964 -Marcel Raad (1 Aug 2020) -- openssl: fix build with LibreSSL < 2.9.1 - - `SSL_CTX_add0_chain_cert` and `SSL_CTX_clear_chain_certs` were - introduced in LibreSSL 2.9.1 [0]. +- tests/FILEFORMAT: document type=shell for + +- tests/FILEFORMAT: document nonewline support for - [0] https://github.com/libressl-portable/openbsd/commit/0db809ee178457c8170abfae3931d7bd13abf3ef + The one in , that creates files. - Closes https://github.com/curl/curl/pull/5757 + Follow-up from b83947c8df7 -Daniel Stenberg (1 Aug 2020) -- [Marc Aldorasi brought this change] +- [anio brought this change] - multi_remove_handle: close unused connect-only connections + tool_writeout: add new writeout variable, %{num_headers} - Previously any connect-only connections in a multi handle would be kept - alive until the multi handle was closed. Since these connections cannot - be re-used, they can be marked for closure when the associated easy - handle is removed from the multi handle. + This variable gives the number of headers. - Closes #5749 + Closes #5947 -- checksrc: invoke script with -D to find .checksrc proper +- tool_urlglob: fix compiler warning "unreachable code" - Without the -D command line option, checksrc.pl won't know which - directory to load the ".checksrc" file from when building out of the - source tree. + (On Windows builds.) - Reported-by: Marcel Raad - Fixes #5715 - Closes #5755 + Follow-up to 70a3b003d9 -- [Carlo Marcelo Arenas Belón brought this change] +- [Gergely Nagy brought this change] - buildconf: retire ares buildconf invocation + vtls: deduplicate client certificates in ssl_config_data - no longer needed after 4259d2df7dd95637a4b1e3fb174fe5e5aef81069 - -- [Carlo Marcelo Arenas Belón brought this change] + Closes #5629 - buildconf: excempt defunct reference to ACLOCAL_FLAGS +- ftp: a 550 response to SIZE returns CURLE_REMOTE_FILE_NOT_FOUND - retired with 09f278121e815028adb24d228d8092fc6cb022aa but kept around as - the name is generic enough that it might be in use and relied upon from - the environment. - -- [Carlo Marcelo Arenas Belón brought this change] - - buildconf: avoid array concatenation in die() + This is primarily interesting for cases where CURLOPT_NOBODY is set as + previously curl would not return an error for this case. - reported as error SC2145[1] by shellcheck, but not expected to cause - any behavioural differences otherwise. + MDTM getting 550 now also returns this error (it returned + CURLE_FTP_COULDNT_RETR_FILE before) in order to unify return codes for + missing files across protocols and specific FTP commands. - [1] https://github.com/koalaman/shellcheck/wiki/SC2145 + libcurl already returns error on a 550 as a MDTM response (when + CURLOPT_FILETIME is set). If CURLOPT_NOBODY is not set, an error would + happen subsequently anyway since the RETR command would fail. - Closes #5701 - -- travis: add ppc64le and s390x builds + Add test 1913 and 1914 to verify. Updated several tests accordingly due + to the updated SIZE behavior. - Closes #5752 + Reported-by: Tomas Berger + Fixes #5953 + Closes #5957 -Marc Hoersken (31 Jul 2020) -- connect: remove redundant message about connect failure - - Reviewed-by: Daniel Stenberg +- curl: make checkpasswd use dynbuf - Closes #5708 + Closes #5952 -- tests/sshserver.pl: fix compatibility with OpenSSH for Windows +- curl: make glob_match_url use dynbuf - Follow up to #5721 + Closes #5952 -- CI/azure: install libssh2 for use with msys2-based builds - - This enables building and running the SFTP tests. - Unfortunately OpenSSH for Windows does not support SCP (yet). - - Reviewed-by: Daniel Stenberg +- curl: make file2memory use dynbuf - Closes #5721 + Closes #5952 -- CI/azure: increase Windows job timeout once again - - Avoid aborted jobs due to performance issues on Azure DevOps. - - Reviewed-by: Daniel Stenberg - Reviewed-by: Jay Satiro +- curl: make file2string use dynbuf - Closes #5738 + Closes #5952 -Jay Satiro (30 Jul 2020) -- TODO: Schannel: 'Add option to allow abrupt server closure' - - We should offer an option to allow abrupt server closures (server closes - SSL transfer without sending a known termination point such as length of - transfer or close_notify alert). Abrupt server closures are usually - because of misconfigured or very old servers. - - Closes https://github.com/curl/curl/issues/4427 +- [Antarpreet Singh brought this change] -- url: fix CURLU and location following + imap: set cselect_bits to CURL_CSELECT_IN initially - Prior to this change if the user set a URL handle (CURLOPT_CURLU) it was - incorrectly used for the location follow, resulting in infinite requests - to the original location. + ... when continuing a transfer from a FETCH response. - Reported-by: sspiri@users.noreply.github.com + When the size of the file was small enough that the entirety of the + transfer happens in a single go and schannel buffers holds the entire + data. However, it wasn't completely read in Curl_pp_readresp since a + line break was found before that could happen. So, by the time we are in + imap_state_fetch_resp - there's data in buffers that needs to be read + via Curl_read but nothing to read from the socket. After we setup a + transfer (Curl_setup_transfer), curl just waits on the socket state to + change - which doesn't happen since no new data ever comes. - Fixes https://github.com/curl/curl/issues/5709 - Closes https://github.com/curl/curl/pull/5713 + Closes #5961 -Daniel Stenberg (30 Jul 2020) - RELEASE-NOTES: synced -- [divinity76 brought this change] - - docs: add date of 7.20 to CURLM_CALL_MULTI_PERFORM mentions - - it helps make it obvious that most developers don't have to care about - the CURLM_CALL_MULTI_PERFORM value (last release using it is nearly 11 - years old, November 4 2009) +- test434: test -K use in a single line without newline - Closes #5744 + Closes #5946 -Jay Satiro (29 Jul 2020) -- tool_cb_wrt: fix outfile mode flags for Windows - - - Use S_IREAD and S_IWRITE mode permission flags to create the file - on Windows instead of S_IRUSR, S_IWUSR, etc. +- runtests: allow creating files without newlines - Windows only accepts a combination of S_IREAD and S_IWRITE. It does not - acknowledge other combinations, for which it may generate an assertion. + Closes #5946 + +- curl: use curlx_dynbuf for realloc when loading config files - This is a follow-up to 81b4e99 from yesterday, which improved the - existing file check with -J. + ... fixes an integer overflow at the same time. - Ref: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/open-wopen#remarks - Ref: https://github.com/curl/curl/pull/5731 + Reported-by: ihsinme on github + Assisted-by: Jay Satiro - Closes https://github.com/curl/curl/pull/5742 + Closes #5946 -Daniel Stenberg (28 Jul 2020) -- checksrc: ban gmtime/localtime - - They're not thread-safe so they should not be used in libcurl code. +- dynbuf: provide curlx_ names for reuse by the curl tool - Explictly enabled when deemed necessary and in examples and tests + Closes #5946 + +- dynbuf: make sure Curl_dyn_tail() zero terminates - Reviewed-by: Nicolas Sterchele - Closes #5732 + Closes #5959 diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS index 6f164a9adf..2844ef1564 100644 --- a/libs/libcurl/docs/THANKS +++ b/libs/libcurl/docs/THANKS @@ -7,6 +7,7 @@ 0xflotus on github 1ocalhost on github 3dyd on github +3eka on github Aaro Koskinen Aaron Oneal Aaron Orenstein @@ -141,6 +142,7 @@ Andrei Sedoi Andrei Valeriu BICA Andrei Virtosu Andrej E Baranov +Andrew Barnert Andrew Barnes Andrew Benham Andrew Biggs @@ -212,6 +214,7 @@ Avery Fay awesomenode on github Axel Tillequin Ayoub Boudhar +Ayushman Singh Chauhan b9a1 on github Balaji Parasuram Balaji S Rao @@ -243,6 +246,7 @@ Benjamin Gerard Benjamin Gilbert Benjamin Johnson Benjamin Kircher +Benjamin Riefenstahl Benjamin Ritcey Benjamin Sergeant Benoit Neil @@ -272,6 +276,7 @@ Bjorn Augustsson Bjorn Reese Björn Stenberg Blaise Potard +Blake Burkhart bnfp on github Bob Relyea Bob Richmond @@ -460,6 +465,7 @@ Dan Zitter Daniel at touchtunes Daniel Bankhead Daniel Black +Daniel Carpenter Daniel Cater Daniel Egger Daniel Gustafsson @@ -503,6 +509,7 @@ David Binderman David Blaikie David Byron David Cohen +David Cook David Demelier David E. Narváez David Earl @@ -583,6 +590,7 @@ dmitrmax on github Dmitry Bartsevich Dmitry Eremin-Solenikov Dmitry Falko +Dmitry Karpov Dmitry Kostjuchenko Dmitry Kurochkin Dmitry Mikhirev @@ -769,6 +777,7 @@ Gaz Iqbal Gaël Portay Geeknik Labs Geoff Beier +Georeth Zhou Georg Horn Georg Huettenegger Georg Lippitsch @@ -899,6 +908,7 @@ Iida Yosiaki Ikko Ashimine Ilguiz Latypov Ilja van Sprundel +Illarion Taev Ilya Kosarev imilli on github Immanuel Gregoire @@ -919,6 +929,7 @@ Ivan Avdeev IvanoG on github Ivo Bellin Salarin iz8mbw on github +J. Bromley Jack Boos Yu Jack Zhang Jackarain on github @@ -1047,6 +1058,7 @@ Joe Malicki Joe Mason Joel Chen Joel Depooter +Joel Jakobsson Joel Teichroeb joey-l-us on github Jofell Gallardo @@ -1054,6 +1066,7 @@ Johan Anderson Johan Lantz Johan Nilsson Johan van Selst +Johann150 on github Johannes Bauer Johannes Ernst Johannes G. Kristinsson @@ -1202,6 +1215,7 @@ Kenny To Kent Boortz Keshav Krity Kevin Baughman +Kevin Burke Kevin Fisk Kevin Ji Kevin Lussier @@ -1222,6 +1236,7 @@ Klaus Stein Klevtsov Vadim Kobi Gurkan Koen Dergent +Koichi Shiraishi kokke on github Konstantin Isakov Konstantin Kushnir @@ -1311,7 +1326,9 @@ Luan Cestari Luca Altea Luca Boccassi Lucas Adamski +Lucas Clemente Vella Lucas Pardue +Lucas Servén Marín Lucas Severo Lucien Zürcher Ludek Finstrle @@ -1401,12 +1418,14 @@ Martijn Koster Martin Ankerl Martin Bašti Martin C. Martin +Martin Dorey Martin Drasar Martin Dreher Martin Frodl Martin Galvan Martin Gartner Martin Hager +Martin Halle Martin Hedenfalk Martin Jansen Martin Kammerhofer @@ -1428,6 +1447,7 @@ Mateusz Loskot Mathias Axelsson Mathias Gumz Mathieu Legare +Matias N. Goldberg Mats Lidell Matt Arsenault Matt Ford @@ -1490,6 +1510,7 @@ Michael Jerris Michael Kalinin Michael Kaufmann Michael Kilburn +Michael Kolechkin Michael Kujawa Michael König Michael Lee @@ -1497,6 +1518,7 @@ Michael Maltese Michael Mealling Michael Mueller Michael Musset +Michael O'Farrell Michael Olbrich Michael Osipov Michael Schmid @@ -1508,6 +1530,7 @@ Michael Vittiglio Michael Wallner Michal Bonino Michal Marek +Michal Rus Michal Trybus Michal Čaplygin Michał Antoniak @@ -1557,6 +1580,7 @@ Mohammad Hasbini Mohun Biswas momala454 on github moohoorama on github +Morten Minde Neergaard Mostyn Bramley-Moore Moti Avrahami MrdUkk on github @@ -1717,11 +1741,13 @@ Pavel Volgarev Pavol Markovic Pawel A. Gajda Pawel Kierski +Paweł Wegner Pedro Larroy Pedro Monreal Pedro Neves pendrek at hackerone Peng Li +Peng-Yu Chen Per Jensen Per Lundberg Per Malmberg @@ -1781,6 +1807,7 @@ Pierre-Yves Bigourdan Piotr Dobrogost Piotr Komborski Po-Chuan Hsieh +Pontus Lundkvist Pooyan McSporran Poul T Lomholt Pramod Sharma @@ -1797,6 +1824,7 @@ Quanah Gibson-Mount Quentin Balland Quinn Slack R. Dennis Steed +Radek Zajic Radoslav Georgiev Radu Simionescu Rafa Muyo @@ -1812,6 +1840,7 @@ Rajesh Naganathan Rajkumar Mandal Ralf S. Engelschall Ralph Beckmann +Ralph Langendam Ralph Mitchell Ram Krushna Mishra ramsay-jones on github @@ -1846,6 +1875,7 @@ Reza Arbab Ricardo Cadime Ricardo Gomes Rich Burridge +Rich FitzJohn Rich Gray Rich Mirch Rich Rauenzahn @@ -1942,6 +1972,7 @@ Ruslan Gazizov Rutger Hofman Ruurd Beerstra RuurdBeerstra on github +Ryan Beck-Buysse Ryan Braud Ryan Chan Ryan Nelson @@ -1998,6 +2029,7 @@ Sebastian Rasmussen Senthil Raja Velu Sergei Kuzmin Sergei Nikulov +Sergey Markelov Sergey Ogryzkov Sergey Tatarincev Sergii Kavunenko @@ -2005,6 +2037,7 @@ Sergii Pylypenko Sergio Ballestrero Sergio Barresi Sergio Borghese +sergio-nsk on github Serj Kalichev Seshubabu Pasam Seth Mos @@ -2060,6 +2093,7 @@ Stefan Eissing Stefan Esser Stefan Grether Stefan Kanthak +Stefan Karpinski Stefan Krause Stefan Neis Stefan Strogin @@ -2171,14 +2205,17 @@ Tim Stack Tim Starling Tim Tassonis Tim Verhoeven +Timo Lange Timo Sirainen Timotej Lazar Timothe Litt +Timothy Gu Timothy Polich Tinus van den Berg TJ Saunders tmkk on github Tobias Blomberg +Tobias Gabriel Tobias Hieta Tobias Hintze Tobias Lindgren @@ -2218,6 +2255,7 @@ Tomasz Kojm Tomasz Lacki Tommie Gannert tommink[at]post.pl +Tommy Odom Tommy Petty Tommy Tam Ton Voon @@ -2238,6 +2276,7 @@ Trivikram Kamat Troels Walsted Hansen Troy Engel Tseng Jun +Tuomas Siipola Tuomo Rinne Tupone Alfredo Tyler Hall @@ -2248,6 +2287,7 @@ Ulrich Doehner Ulrich Telle Ulrich Zadow UrsusArctos on github +ustcqidi on github Valentin David Valentyn Korniienko Valerii Zapodovnikov @@ -2261,6 +2301,7 @@ Venkataramana Mokkapati Vicente Garcia Victor Magierski Victor Snezhko +Victor Vieux Vijay Panghal Vikram Saxena Viktor Szakats @@ -2298,6 +2339,7 @@ Wenchao Li Wenxiang Qian Werner Koch Werner Stolz +Wes Hinsley wesinator on github Wesley Laxton Wesley Miaw @@ -2336,6 +2378,7 @@ ygthien on github Yi Huang Yiming Jing Yingwei Liu +Ymir1711 on github Yonggang Luo youngchopin on github Yousuke Kimoto @@ -2344,6 +2387,7 @@ Yukihiro Kawada Yun SangHo Yuri Slobodyanyuk Yuriy Sosov +Yusuke Nakamura Yves Arrouye Yves Lejeune Zachary Seguin diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h index bed8068b0b..97de8c88ae 100644 --- a/libs/libcurl/include/curl/curl.h +++ b/libs/libcurl/include/curl/curl.h @@ -612,6 +612,7 @@ typedef enum { CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */ CURLE_QUIC_CONNECT_ERROR, /* 96 - QUIC connection error */ CURLE_PROXY, /* 97 - proxy handshake error */ + CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */ CURL_LAST /* never use! */ } CURLcode; @@ -888,6 +889,10 @@ typedef enum { operating system. Currently implemented under MS-Windows. */ #define CURLSSLOPT_NATIVE_CA (1<<4) +/* - CURLSSLOPT_AUTO_CLIENT_CERT tells libcurl to automatically locate and use + a client certificate for authentication. (Schannel) */ +#define CURLSSLOPT_AUTO_CLIENT_CERT (1<<5) + /* The default connection attempt delay in milliseconds for happy eyeballs. CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document this value, keep them in sync. */ @@ -1461,8 +1466,8 @@ typedef enum { #define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to - tell libcurl to resolve names to those IP versions only. This only has - affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + tell libcurl to use those IP versions only. This only has effect on + systems with support for more than one, i.e IPv4 _and_ IPv6. */ CURLOPT(CURLOPT_IPRESOLVE, CURLOPTTYPE_VALUES, 113), /* Set this option to limit the size of a file that will be downloaded from @@ -2088,6 +2093,14 @@ typedef enum { /* Same as CURLOPT_SSL_VERIFYSTATUS but for DOH (DNS-over-HTTPS) servers. */ CURLOPT(CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 308), + /* The CA certificates as "blob" used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_CAINFO_BLOB, CURLOPTTYPE_BLOB, 309), + + /* The CA certificates as "blob" used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CURLOPT(CURLOPT_PROXY_CAINFO_BLOB, CURLOPTTYPE_BLOB, 310), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -2122,10 +2135,10 @@ typedef enum { /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host name resolves addresses using more than one IP protocol version, this option might be handy to force libcurl to use a specific IP version. */ -#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP +#define CURL_IPRESOLVE_WHATEVER 0 /* default, uses addresses to all IP versions that your system allows */ -#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ -#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ +#define CURL_IPRESOLVE_V4 1 /* uses only IPv4 addresses/connections */ +#define CURL_IPRESOLVE_V6 2 /* uses only IPv6 addresses/connections */ /* three convenient "aliases" that follow the name scheme better */ #define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER @@ -2866,6 +2879,7 @@ typedef enum { CURLVERSION_SEVENTH, CURLVERSION_EIGHTH, CURLVERSION_NINTH, + CURLVERSION_TENTH, CURLVERSION_LAST /* never actually use this */ } CURLversion; @@ -2874,7 +2888,7 @@ typedef enum { meant to be a built-in version number for what kind of struct the caller expects. If the struct ever changes, we redefine the NOW to another enum from above. */ -#define CURLVERSION_NOW CURLVERSION_NINTH +#define CURLVERSION_NOW CURLVERSION_TENTH struct curl_version_info_data { CURLversion age; /* age of the returned struct */ @@ -2927,6 +2941,9 @@ struct curl_version_info_data { /* These fields were added in CURLVERSION_NINTH */ const char *hyper_version; /* human readable string. */ + + /* These fields were added in CURLVERSION_TENTH */ + const char *gsasl_version; /* human readable string. */ }; typedef struct curl_version_info_data curl_version_info_data; diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h index b74cdc1170..98f7d0cdf4 100644 --- a/libs/libcurl/include/curl/curlver.h +++ b/libs/libcurl/include/curl/curlver.h @@ -30,13 +30,13 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.76.1" +#define LIBCURL_VERSION "7.77.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 76 -#define LIBCURL_VERSION_PATCH 1 +#define LIBCURL_VERSION_MINOR 77 +#define LIBCURL_VERSION_PATCH 0 /* This is the numeric version of the libcurl version number, meant for easier parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will @@ -57,7 +57,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 0x074c01 +#define LIBCURL_VERSION_NUM 0x074d00 /* * This is the date and time when the full source package was created. The @@ -68,7 +68,7 @@ * * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "2021-04-14" +#define LIBCURL_TIMESTAMP "2021-05-26" #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) #define CURL_AT_LEAST_VERSION(x,y,z) \ diff --git a/libs/libcurl/libcurl.vcxproj b/libs/libcurl/libcurl.vcxproj index d601dbdd21..49e6a66c28 100644 --- a/libs/libcurl/libcurl.vcxproj +++ b/libs/libcurl/libcurl.vcxproj @@ -41,6 +41,9 @@ NotUsing + + NotUsing + NotUsing @@ -444,6 +447,7 @@ + diff --git a/libs/libcurl/libcurl.vcxproj.filters b/libs/libcurl/libcurl.vcxproj.filters index 9a6fcc2b65..4ade79b333 100644 --- a/libs/libcurl/libcurl.vcxproj.filters +++ b/libs/libcurl/libcurl.vcxproj.filters @@ -17,6 +17,9 @@ Source Files + + Source Files + Source Files @@ -463,6 +466,9 @@ Header Files + + Header Files + Header Files diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt index a58b47b865..2575288f70 100644 --- a/libs/libcurl/src/CMakeLists.txt +++ b/libs/libcurl/src/CMakeLists.txt @@ -20,6 +20,7 @@ # ########################################################################### set(LIB_NAME libcurl) +set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library") if(BUILD_SHARED_LIBS) set(CURL_STATICLIB NO) @@ -98,7 +99,10 @@ if(WIN32) add_definitions(-D_USRDLL) endif() -set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL) +set_target_properties(${LIB_NAME} PROPERTIES + COMPILE_DEFINITIONS BUILDING_LIBCURL + OUTPUT_NAME ${LIBCURL_OUTPUT_NAME} + ) if(HIDES_CURL_PRIVATE_SYMBOLS) set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in index c17ae17a51..d89f375a14 100644 --- a/libs/libcurl/src/Makefile.in +++ b/libs/libcurl/src/Makefile.in @@ -125,12 +125,22 @@ host_triplet = @host@ subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compile_check_sizeof.m4 \ + $(top_srcdir)/m4/curl-amissl.m4 \ + $(top_srcdir)/m4/curl-bearssl.m4 \ $(top_srcdir)/m4/curl-compilers.m4 \ $(top_srcdir)/m4/curl-confopts.m4 \ $(top_srcdir)/m4/curl-functions.m4 \ + $(top_srcdir)/m4/curl-gnutls.m4 \ + $(top_srcdir)/m4/curl-mbedtls.m4 \ + $(top_srcdir)/m4/curl-mesalink.m4 $(top_srcdir)/m4/curl-nss.m4 \ $(top_srcdir)/m4/curl-openssl.m4 \ $(top_srcdir)/m4/curl-override.m4 \ - $(top_srcdir)/m4/curl-reentrant.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/curl-reentrant.m4 \ + $(top_srcdir)/m4/curl-rustls.m4 \ + $(top_srcdir)/m4/curl-schannel.m4 \ + $(top_srcdir)/m4/curl-sectransp.m4 \ + $(top_srcdir)/m4/curl-sysconfig.m4 \ + $(top_srcdir)/m4/curl-wolfssl.m4 $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/xc-am-iface.m4 \ @@ -181,22 +191,23 @@ LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) libcurl_la_LIBADD = am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \ libcurl_la-asyn-ares.lo libcurl_la-asyn-thread.lo \ - libcurl_la-base64.lo libcurl_la-c-hyper.lo \ - libcurl_la-conncache.lo libcurl_la-connect.lo \ - libcurl_la-content_encoding.lo libcurl_la-cookie.lo \ - libcurl_la-curl_addrinfo.lo libcurl_la-curl_ctype.lo \ - libcurl_la-curl_des.lo libcurl_la-curl_endian.lo \ - libcurl_la-curl_fnmatch.lo libcurl_la-curl_get_line.lo \ - libcurl_la-curl_gethostname.lo libcurl_la-curl_gssapi.lo \ - libcurl_la-curl_memrchr.lo libcurl_la-curl_multibyte.lo \ - libcurl_la-curl_ntlm_core.lo libcurl_la-curl_ntlm_wb.lo \ - libcurl_la-curl_path.lo libcurl_la-curl_range.lo \ - libcurl_la-curl_rtmp.lo libcurl_la-curl_sasl.lo \ - libcurl_la-curl_sspi.lo libcurl_la-curl_threads.lo \ - libcurl_la-dict.lo libcurl_la-doh.lo libcurl_la-dotdot.lo \ - libcurl_la-dynbuf.lo libcurl_la-easy.lo \ - libcurl_la-easygetopt.lo libcurl_la-easyoptions.lo \ - libcurl_la-escape.lo libcurl_la-file.lo libcurl_la-fileinfo.lo \ + libcurl_la-base64.lo libcurl_la-bufref.lo \ + libcurl_la-c-hyper.lo libcurl_la-conncache.lo \ + libcurl_la-connect.lo libcurl_la-content_encoding.lo \ + libcurl_la-cookie.lo libcurl_la-curl_addrinfo.lo \ + libcurl_la-curl_ctype.lo libcurl_la-curl_des.lo \ + libcurl_la-curl_endian.lo libcurl_la-curl_fnmatch.lo \ + libcurl_la-curl_get_line.lo libcurl_la-curl_gethostname.lo \ + libcurl_la-curl_gssapi.lo libcurl_la-curl_memrchr.lo \ + libcurl_la-curl_multibyte.lo libcurl_la-curl_ntlm_core.lo \ + libcurl_la-curl_ntlm_wb.lo libcurl_la-curl_path.lo \ + libcurl_la-curl_range.lo libcurl_la-curl_rtmp.lo \ + libcurl_la-curl_sasl.lo libcurl_la-curl_sspi.lo \ + libcurl_la-curl_threads.lo libcurl_la-dict.lo \ + libcurl_la-doh.lo libcurl_la-dotdot.lo libcurl_la-dynbuf.lo \ + libcurl_la-easy.lo libcurl_la-easygetopt.lo \ + libcurl_la-easyoptions.lo libcurl_la-escape.lo \ + libcurl_la-file.lo libcurl_la-fileinfo.lo \ libcurl_la-formdata.lo libcurl_la-ftp.lo \ libcurl_la-ftplistparser.lo libcurl_la-getenv.lo \ libcurl_la-getinfo.lo libcurl_la-gopher.lo libcurl_la-hash.lo \ @@ -269,26 +280,27 @@ libcurl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ libcurlu_la_LIBADD = am__objects_9 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \ libcurlu_la-asyn-ares.lo libcurlu_la-asyn-thread.lo \ - libcurlu_la-base64.lo libcurlu_la-c-hyper.lo \ - libcurlu_la-conncache.lo libcurlu_la-connect.lo \ - libcurlu_la-content_encoding.lo libcurlu_la-cookie.lo \ - libcurlu_la-curl_addrinfo.lo libcurlu_la-curl_ctype.lo \ - libcurlu_la-curl_des.lo libcurlu_la-curl_endian.lo \ - libcurlu_la-curl_fnmatch.lo libcurlu_la-curl_get_line.lo \ - libcurlu_la-curl_gethostname.lo libcurlu_la-curl_gssapi.lo \ - libcurlu_la-curl_memrchr.lo libcurlu_la-curl_multibyte.lo \ - libcurlu_la-curl_ntlm_core.lo libcurlu_la-curl_ntlm_wb.lo \ - libcurlu_la-curl_path.lo libcurlu_la-curl_range.lo \ - libcurlu_la-curl_rtmp.lo libcurlu_la-curl_sasl.lo \ - libcurlu_la-curl_sspi.lo libcurlu_la-curl_threads.lo \ - libcurlu_la-dict.lo libcurlu_la-doh.lo libcurlu_la-dotdot.lo \ - libcurlu_la-dynbuf.lo libcurlu_la-easy.lo \ - libcurlu_la-easygetopt.lo libcurlu_la-easyoptions.lo \ - libcurlu_la-escape.lo libcurlu_la-file.lo \ - libcurlu_la-fileinfo.lo libcurlu_la-formdata.lo \ - libcurlu_la-ftp.lo libcurlu_la-ftplistparser.lo \ - libcurlu_la-getenv.lo libcurlu_la-getinfo.lo \ - libcurlu_la-gopher.lo libcurlu_la-hash.lo libcurlu_la-hmac.lo \ + libcurlu_la-base64.lo libcurlu_la-bufref.lo \ + libcurlu_la-c-hyper.lo libcurlu_la-conncache.lo \ + libcurlu_la-connect.lo libcurlu_la-content_encoding.lo \ + libcurlu_la-cookie.lo libcurlu_la-curl_addrinfo.lo \ + libcurlu_la-curl_ctype.lo libcurlu_la-curl_des.lo \ + libcurlu_la-curl_endian.lo libcurlu_la-curl_fnmatch.lo \ + libcurlu_la-curl_get_line.lo libcurlu_la-curl_gethostname.lo \ + libcurlu_la-curl_gssapi.lo libcurlu_la-curl_memrchr.lo \ + libcurlu_la-curl_multibyte.lo libcurlu_la-curl_ntlm_core.lo \ + libcurlu_la-curl_ntlm_wb.lo libcurlu_la-curl_path.lo \ + libcurlu_la-curl_range.lo libcurlu_la-curl_rtmp.lo \ + libcurlu_la-curl_sasl.lo libcurlu_la-curl_sspi.lo \ + libcurlu_la-curl_threads.lo libcurlu_la-dict.lo \ + libcurlu_la-doh.lo libcurlu_la-dotdot.lo libcurlu_la-dynbuf.lo \ + libcurlu_la-easy.lo libcurlu_la-easygetopt.lo \ + libcurlu_la-easyoptions.lo libcurlu_la-escape.lo \ + libcurlu_la-file.lo libcurlu_la-fileinfo.lo \ + libcurlu_la-formdata.lo libcurlu_la-ftp.lo \ + libcurlu_la-ftplistparser.lo libcurlu_la-getenv.lo \ + libcurlu_la-getinfo.lo libcurlu_la-gopher.lo \ + libcurlu_la-hash.lo libcurlu_la-hmac.lo \ libcurlu_la-hostasyn.lo libcurlu_la-hostcheck.lo \ libcurlu_la-hostip.lo libcurlu_la-hostip4.lo \ libcurlu_la-hostip6.lo libcurlu_la-hostsyn.lo \ @@ -373,6 +385,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurl_la-asyn-ares.Plo \ ./$(DEPDIR)/libcurl_la-asyn-thread.Plo \ ./$(DEPDIR)/libcurl_la-base64.Plo \ + ./$(DEPDIR)/libcurl_la-bufref.Plo \ ./$(DEPDIR)/libcurl_la-c-hyper.Plo \ ./$(DEPDIR)/libcurl_la-conncache.Plo \ ./$(DEPDIR)/libcurl_la-connect.Plo \ @@ -488,6 +501,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo \ ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo \ ./$(DEPDIR)/libcurlu_la-base64.Plo \ + ./$(DEPDIR)/libcurlu_la-bufref.Plo \ ./$(DEPDIR)/libcurlu_la-c-hyper.Plo \ ./$(DEPDIR)/libcurlu_la-conncache.Plo \ ./$(DEPDIR)/libcurlu_la-connect.Plo \ @@ -1088,6 +1102,7 @@ LIB_CFILES = \ asyn-ares.c \ asyn-thread.c \ base64.c \ + bufref.c \ c-hyper.c \ conncache.c \ connect.c \ @@ -1208,6 +1223,7 @@ LIB_HFILES = \ amigaos.h \ arpa_telnet.h \ asyn.h \ + bufref.h \ c-hyper.h \ conncache.h \ connect.h \ @@ -1626,6 +1642,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-asyn-ares.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-asyn-thread.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-base64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-bufref.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-c-hyper.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-conncache.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-connect.Plo@am__quote@ # am--include-marker @@ -1745,6 +1762,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-asyn-ares.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-asyn-thread.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-base64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-bufref.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-c-hyper.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-conncache.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-connect.Plo@am__quote@ # am--include-marker @@ -1993,6 +2011,13 @@ libcurl_la-base64.lo: base64.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +libcurl_la-bufref.lo: bufref.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-bufref.lo -MD -MP -MF $(DEPDIR)/libcurl_la-bufref.Tpo -c -o libcurl_la-bufref.lo `test -f 'bufref.c' || echo '$(srcdir)/'`bufref.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-bufref.Tpo $(DEPDIR)/libcurl_la-bufref.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bufref.c' object='libcurl_la-bufref.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-bufref.lo `test -f 'bufref.c' || echo '$(srcdir)/'`bufref.c + libcurl_la-c-hyper.lo: c-hyper.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-c-hyper.lo -MD -MP -MF $(DEPDIR)/libcurl_la-c-hyper.Tpo -c -o libcurl_la-c-hyper.lo `test -f 'c-hyper.c' || echo '$(srcdir)/'`c-hyper.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-c-hyper.Tpo $(DEPDIR)/libcurl_la-c-hyper.Plo @@ -3064,6 +3089,13 @@ libcurlu_la-base64.lo: base64.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-base64.lo `test -f 'base64.c' || echo '$(srcdir)/'`base64.c +libcurlu_la-bufref.lo: bufref.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-bufref.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-bufref.Tpo -c -o libcurlu_la-bufref.lo `test -f 'bufref.c' || echo '$(srcdir)/'`bufref.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-bufref.Tpo $(DEPDIR)/libcurlu_la-bufref.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bufref.c' object='libcurlu_la-bufref.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-bufref.lo `test -f 'bufref.c' || echo '$(srcdir)/'`bufref.c + libcurlu_la-c-hyper.lo: c-hyper.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-c-hyper.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-c-hyper.Tpo -c -o libcurlu_la-c-hyper.lo `test -f 'c-hyper.c' || echo '$(srcdir)/'`c-hyper.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-c-hyper.Tpo $(DEPDIR)/libcurlu_la-c-hyper.Plo @@ -4252,6 +4284,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurl_la-asyn-ares.Plo -rm -f ./$(DEPDIR)/libcurl_la-asyn-thread.Plo -rm -f ./$(DEPDIR)/libcurl_la-base64.Plo + -rm -f ./$(DEPDIR)/libcurl_la-bufref.Plo -rm -f ./$(DEPDIR)/libcurl_la-c-hyper.Plo -rm -f ./$(DEPDIR)/libcurl_la-conncache.Plo -rm -f ./$(DEPDIR)/libcurl_la-connect.Plo @@ -4371,6 +4404,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo -rm -f ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo -rm -f ./$(DEPDIR)/libcurlu_la-base64.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-bufref.Plo -rm -f ./$(DEPDIR)/libcurlu_la-c-hyper.Plo -rm -f ./$(DEPDIR)/libcurlu_la-conncache.Plo -rm -f ./$(DEPDIR)/libcurlu_la-connect.Plo @@ -4603,6 +4637,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurl_la-asyn-ares.Plo -rm -f ./$(DEPDIR)/libcurl_la-asyn-thread.Plo -rm -f ./$(DEPDIR)/libcurl_la-base64.Plo + -rm -f ./$(DEPDIR)/libcurl_la-bufref.Plo -rm -f ./$(DEPDIR)/libcurl_la-c-hyper.Plo -rm -f ./$(DEPDIR)/libcurl_la-conncache.Plo -rm -f ./$(DEPDIR)/libcurl_la-connect.Plo @@ -4722,6 +4757,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo -rm -f ./$(DEPDIR)/libcurlu_la-asyn-thread.Plo -rm -f ./$(DEPDIR)/libcurlu_la-base64.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-bufref.Plo -rm -f ./$(DEPDIR)/libcurlu_la-c-hyper.Plo -rm -f ./$(DEPDIR)/libcurlu_la-conncache.Plo -rm -f ./$(DEPDIR)/libcurlu_la-connect.Plo diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc index 90ec6aa05c..3e9ddec12c 100644 --- a/libs/libcurl/src/Makefile.inc +++ b/libs/libcurl/src/Makefile.inc @@ -97,6 +97,7 @@ LIB_CFILES = \ asyn-ares.c \ asyn-thread.c \ base64.c \ + bufref.c \ c-hyper.c \ conncache.c \ connect.c \ @@ -217,6 +218,7 @@ LIB_HFILES = \ amigaos.h \ arpa_telnet.h \ asyn.h \ + bufref.h \ c-hyper.h \ conncache.h \ connect.h \ diff --git a/libs/libcurl/src/amigaos.c b/libs/libcurl/src/amigaos.c index d3b00d9083..78bb22c7e2 100644 --- a/libs/libcurl/src/amigaos.c +++ b/libs/libcurl/src/amigaos.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -90,6 +90,33 @@ void Curl_amiga_X509_free(X509 *a) { X509_free(a); } + +/* AmiSSL replaces many functions with macros. Curl requires pointer + * to some of these functions. Thus, we have to encapsulate these macros. + */ + +#include "warnless.h" + +int (SHA256_Init)(SHA256_CTX *c) +{ + return SHA256_Init(c); +}; + +int (SHA256_Update)(SHA256_CTX *c, const void *data, size_t len) +{ + return SHA256_Update(c, data, curlx_uztoui(len)); +}; + +int (SHA256_Final)(unsigned char *md, SHA256_CTX *c) +{ + return SHA256_Final(md, c); +}; + +void (X509_INFO_free)(X509_INFO *a) +{ + X509_INFO_free(a); +}; + #endif /* USE_AMISSL */ #endif /* __AMIGA__ */ diff --git a/libs/libcurl/src/asyn-ares.c b/libs/libcurl/src/asyn-ares.c index c9bd9d16a5..7827847350 100644 --- a/libs/libcurl/src/asyn-ares.c +++ b/libs/libcurl/src/asyn-ares.c @@ -309,7 +309,7 @@ static int waitperform(struct Curl_easy *data, timediff_t timeout_ms) pfd[i].fd = socks[i]; pfd[i].events |= POLLWRNORM|POLLOUT; } - if(pfd[i].events != 0) + if(pfd[i].events) num++; else break; @@ -620,28 +620,9 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, int *waitp) { char *bufp; - int family = PF_INET; *waitp = 0; /* default to synchronous response */ -#ifdef ENABLE_IPV6 - switch(data->set.ipver) { - default: -#if ARES_VERSION >= 0x010601 - family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older - c-ares versions this just falls through and defaults - to PF_INET */ - break; -#endif - case CURL_IPRESOLVE_V4: - family = PF_INET; - break; - case CURL_IPRESOLVE_V6: - family = PF_INET6; - break; - } -#endif /* ENABLE_IPV6 */ - bufp = strdup(hostname); if(bufp) { struct thread_data *res = NULL; @@ -661,33 +642,27 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, /* initial status - failed */ res->last_status = ARES_ENOTFOUND; -#ifdef ENABLE_IPV6 - if(family == PF_UNSPEC) { - if(Curl_ipv6works(data)) { - res->num_pending = 2; - - /* areschannel is already setup in the Curl_open() function */ - ares_gethostbyname((ares_channel)data->state.async.resolver, hostname, - PF_INET, query_completed_cb, data); - ares_gethostbyname((ares_channel)data->state.async.resolver, hostname, - PF_INET6, query_completed_cb, data); - } - else { - res->num_pending = 1; - /* areschannel is already setup in the Curl_open() function */ - ares_gethostbyname((ares_channel)data->state.async.resolver, hostname, - PF_INET, query_completed_cb, data); - } +#if ARES_VERSION >= 0x010601 + /* IPv6 supported by c-ares since 1.6.1 */ + if(Curl_ipv6works(data)) { + /* The stack seems to be IPv6-enabled */ + res->num_pending = 2; + + /* areschannel is already setup in the Curl_open() function */ + ares_gethostbyname((ares_channel)data->state.async.resolver, hostname, + PF_INET, query_completed_cb, data); + ares_gethostbyname((ares_channel)data->state.async.resolver, hostname, + PF_INET6, query_completed_cb, data); } else -#endif /* ENABLE_IPV6 */ +#endif /* ARES_VERSION >= 0x010601 */ { res->num_pending = 1; /* areschannel is already setup in the Curl_open() function */ ares_gethostbyname((ares_channel)data->state.async.resolver, - hostname, family, + hostname, PF_INET, query_completed_cb, data); } diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c index c453203f75..36f68cb493 100644 --- a/libs/libcurl/src/asyn-thread.c +++ b/libs/libcurl/src/asyn-thread.c @@ -238,7 +238,7 @@ int init_thread_sync_data(struct thread_data *td, #endif tsd->mtx = malloc(sizeof(curl_mutex_t)); - if(tsd->mtx == NULL) + if(!tsd->mtx) goto err_exit; Curl_mutex_init(tsd->mtx); @@ -305,7 +305,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res); - if(rc != 0) { + if(rc) { tsd->sock_error = SOCKERRNO?SOCKERRNO:rc; if(tsd->sock_error == 0) tsd->sock_error = RESOLVER_ENOMEM; @@ -701,24 +701,9 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, *waitp = 0; /* default to synchronous response */ #ifdef CURLRES_IPV6 - /* - * Check if a limited name resolve has been requested. - */ - switch(data->set.ipver) { - case CURL_IPRESOLVE_V4: - pf = PF_INET; - break; - case CURL_IPRESOLVE_V6: - pf = PF_INET6; - break; - default: + if(Curl_ipv6works(data)) + /* The stack seems to be IPv6-enabled */ pf = PF_UNSPEC; - break; - } - - if((pf != PF_INET) && !Curl_ipv6works(data)) - /* The stack seems to be a non-IPv6 one */ - pf = PF_INET; #endif /* CURLRES_IPV6 */ memset(&hints, 0, sizeof(hints)); diff --git a/libs/libcurl/src/bufref.c b/libs/libcurl/src/bufref.c new file mode 100644 index 0000000000..b84511e185 --- /dev/null +++ b/libs/libcurl/src/bufref.c @@ -0,0 +1,127 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2021, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" +#include "urldata.h" +#include "bufref.h" + +#include "curl_memory.h" +#include "memdebug.h" + +#define SIGNATURE 0x5c48e9b2 /* Random pattern. */ + +/* + * Init a bufref struct. + */ +void Curl_bufref_init(struct bufref *br) +{ + DEBUGASSERT(br); + br->dtor = NULL; + br->ptr = NULL; + br->len = 0; + +#ifdef DEBUGBUILD + br->signature = SIGNATURE; +#endif +} + +/* + * Free the buffer and re-init the necessary fields. It doesn't touch the + * 'signature' field and thus this buffer reference can be reused. + */ + +void Curl_bufref_free(struct bufref *br) +{ + DEBUGASSERT(br); + DEBUGASSERT(br->signature == SIGNATURE); + DEBUGASSERT(br->ptr || !br->len); + + if(br->ptr && br->dtor) + br->dtor((void *) br->ptr); + + br->dtor = NULL; + br->ptr = NULL; + br->len = 0; +} + +/* + * Set the buffer reference to new values. The previously referenced buffer + * is released before assignment. + */ +void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len, + void (*dtor)(void *)) +{ + DEBUGASSERT(ptr || !len); + DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH); + + Curl_bufref_free(br); + br->ptr = (const unsigned char *) ptr; + br->len = len; + br->dtor = dtor; +} + +/* + * Get a pointer to the referenced buffer. + */ +const unsigned char *Curl_bufref_ptr(const struct bufref *br) +{ + DEBUGASSERT(br); + DEBUGASSERT(br->signature == SIGNATURE); + DEBUGASSERT(br->ptr || !br->len); + + return br->ptr; +} + +/* + * Get the length of the referenced buffer data. + */ +size_t Curl_bufref_len(const struct bufref *br) +{ + DEBUGASSERT(br); + DEBUGASSERT(br->signature == SIGNATURE); + DEBUGASSERT(br->ptr || !br->len); + + return br->len; +} + +CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len) +{ + unsigned char *cpy = NULL; + + DEBUGASSERT(br); + DEBUGASSERT(br->signature == SIGNATURE); + DEBUGASSERT(br->ptr || !br->len); + DEBUGASSERT(ptr || !len); + DEBUGASSERT(len <= CURL_MAX_INPUT_LENGTH); + + if(ptr) { + cpy = malloc(len + 1); + if(!cpy) + return CURLE_OUT_OF_MEMORY; + if(len) + memcpy(cpy, ptr, len); + cpy[len] = '\0'; + } + + Curl_bufref_set(br, cpy, len, curl_free); + return CURLE_OK; +} diff --git a/libs/libcurl/src/bufref.h b/libs/libcurl/src/bufref.h new file mode 100644 index 0000000000..25f65d894d --- /dev/null +++ b/libs/libcurl/src/bufref.h @@ -0,0 +1,46 @@ +#ifndef HEADER_CURL_BUFREF_H +#define HEADER_CURL_BUFREF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2021, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * Generic buffer reference. + */ +struct bufref { + void (*dtor)(void *); /* Associated destructor. */ + const unsigned char *ptr; /* Referenced data buffer. */ + size_t len; /* The data size in bytes. */ +#ifdef DEBUGBUILD + int signature; /* Detect API use mistakes. */ +#endif +}; + + +void Curl_bufref_init(struct bufref *br); +void Curl_bufref_set(struct bufref *br, const void *ptr, size_t len, + void (*dtor)(void *)); +const unsigned char *Curl_bufref_ptr(const struct bufref *br); +size_t Curl_bufref_len(const struct bufref *br); +CURLcode Curl_bufref_memdup(struct bufref *br, const void *ptr, size_t len); +void Curl_bufref_free(struct bufref *br); + +#endif diff --git a/libs/libcurl/src/c-hyper.c b/libs/libcurl/src/c-hyper.c index 5d370d7bda..81f589eb9e 100644 --- a/libs/libcurl/src/c-hyper.c +++ b/libs/libcurl/src/c-hyper.c @@ -175,6 +175,8 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk) } if(k->ignorebody) return HYPER_ITER_CONTINUE; + if(0 == len) + return HYPER_ITER_CONTINUE; Curl_debug(data, CURLINFO_DATA_IN, buf, len); if(!data->set.http_ce_skip && k->writer_stack) /* content-encoded data */ @@ -203,11 +205,8 @@ static CURLcode status_line(struct Curl_easy *data, const uint8_t *reason, size_t rlen) { CURLcode result; - size_t wrote; size_t len; const char *vstr; - curl_write_callback writeheader = - data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func; vstr = http_version == HYPER_HTTP_VERSION_1_1 ? "1.1" : (http_version == HYPER_HTTP_VERSION_2 ? "2" : "1.0"); conn->httpversion = @@ -230,12 +229,12 @@ static CURLcode status_line(struct Curl_easy *data, len = Curl_dyn_len(&data->state.headerb); Curl_debug(data, CURLINFO_HEADER_IN, Curl_dyn_ptr(&data->state.headerb), len); - Curl_set_in_callback(data, true); - wrote = writeheader(Curl_dyn_ptr(&data->state.headerb), 1, len, - data->set.writeheader); - Curl_set_in_callback(data, false); - if(wrote != len) - return CURLE_WRITE_ERROR; + result = Curl_client_write(data, CLIENTWRITE_HEADER, + Curl_dyn_ptr(&data->state.headerb), len); + if(result) { + data->state.hresult = CURLE_ABORTED_BY_CALLBACK; + return HYPER_ITER_BREAK; + } data->info.header_size += (long)len; data->req.headerbytecount += (long)len; @@ -332,7 +331,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, infof(data, "hyperstream is done!\n"); break; } - else if(t != HYPER_TASK_RESPONSE) { + else if(t != HYPER_TASK_RESPONSE && t != HYPER_TASK_EMPTY) { *didwhat = KEEP_RECV; break; } diff --git a/libs/libcurl/src/checksrc.pl b/libs/libcurl/src/checksrc.pl index 13f86ecd5a..a35535c191 100644 --- a/libs/libcurl/src/checksrc.pl +++ b/libs/libcurl/src/checksrc.pl @@ -6,7 +6,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 2011 - 2020, Daniel Stenberg, , et al. +# Copyright (C) 2011 - 2021, Daniel Stenberg, , et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -86,6 +86,8 @@ my %warnings = ( 'BRACEWHILE' => 'A single space between open brace and while', 'EXCLAMATIONSPACE' => 'Whitespace after exclamation mark in expression', 'EMPTYLINEBRACE' => 'Empty line before the open brace', + 'EQUALSNULL' => 'if/while comparison with == NULL', + 'NOTEQUALSZERO' => 'if/while comparison with != 0' ); sub readskiplist { @@ -471,6 +473,21 @@ sub scanfile { "$2 with space"); } } + # check for '== NULL' in if/while conditions but not if the thing on + # the left of it is a function call + if($nostr =~ /^(.*)(if|while)(\(.*[^)]) == NULL/) { + checkwarn("EQUALSNULL", $line, + length($1) + length($2) + length($3), + $file, $l, "we prefer !variable instead of \"== NULL\" comparisons"); + } + + # check for '!= 0' in if/while conditions but not if the thing on + # the left of it is a function call + if($nostr =~ /^(.*)(if|while)(\(.*[^)]) != 0[^x]/) { + checkwarn("NOTEQUALSZERO", $line, + length($1) + length($2) + length($3), + $file, $l, "we prefer if(rc) instead of \"rc != 0\" comparisons"); + } # check spaces in 'do {' if($nostr =~ /^( *)do( *)\{/ && length($2) != 1) { diff --git a/libs/libcurl/src/config-amigaos.h b/libs/libcurl/src/config-amigaos.h index 381bf302c9..c2f5bd20b0 100644 --- a/libs/libcurl/src/config-amigaos.h +++ b/libs/libcurl/src/config-amigaos.h @@ -128,13 +128,6 @@ # define LONG_MIN (-0x7fffffffL-1) #endif -#define HAVE_GETNAMEINFO 1 -#define GETNAMEINFO_QUAL_ARG1 const -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * -#define GETNAMEINFO_TYPE_ARG2 int -#define GETNAMEINFO_TYPE_ARG46 size_t -#define GETNAMEINFO_TYPE_ARG7 int - #define HAVE_RECV 1 #define RECV_TYPE_ARG1 long #define RECV_TYPE_ARG2 char * diff --git a/libs/libcurl/src/config-dos.h b/libs/libcurl/src/config-dos.h index 0fb98e385d..6859208ab3 100644 --- a/libs/libcurl/src/config-dos.h +++ b/libs/libcurl/src/config-dos.h @@ -45,7 +45,6 @@ #define HAVE_FCNTL_H 1 #define HAVE_FREEADDRINFO 1 #define HAVE_GETADDRINFO 1 -#define HAVE_GETNAMEINFO 1 #define HAVE_GETPROTOBYNAME 1 #define HAVE_GETTIMEOFDAY 1 #define HAVE_IO_H 1 @@ -93,7 +92,7 @@ #define STDC_HEADERS 1 #define TIME_WITH_SYS_TIME 1 -/* Qualifiers for send(), recv(), recvfrom() and getnameinfo(). */ +/* Qualifiers for send(), recv(), and recvfrom() */ #define SEND_TYPE_ARG1 int #define SEND_QUAL_ARG2 const @@ -117,12 +116,6 @@ #define RECVFROM_TYPE_RETV int #define RECVFROM_TYPE_ARG2_IS_VOID 1 -#define GETNAMEINFO_QUAL_ARG1 const -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * -#define GETNAMEINFO_TYPE_ARG2 int -#define GETNAMEINFO_TYPE_ARG46 int -#define GETNAMEINFO_TYPE_ARG7 int - #define BSD /* CURLDEBUG definition enables memory tracking */ diff --git a/libs/libcurl/src/config-mac.h b/libs/libcurl/src/config-mac.h index 163686ec94..c8833e3006 100644 --- a/libs/libcurl/src/config-mac.h +++ b/libs/libcurl/src/config-mac.h @@ -85,13 +85,6 @@ #define SIZEOF_SHORT 2 #define SIZEOF_SIZE_T 4 -#define HAVE_GETNAMEINFO 1 -#define GETNAMEINFO_QUAL_ARG1 const -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * -#define GETNAMEINFO_TYPE_ARG2 socklen_t -#define GETNAMEINFO_TYPE_ARG46 size_t -#define GETNAMEINFO_TYPE_ARG7 int - #define HAVE_RECV 1 #define RECV_TYPE_ARG1 int #define RECV_TYPE_ARG2 void * diff --git a/libs/libcurl/src/config-os400.h b/libs/libcurl/src/config-os400.h index b5a9823fd1..366db983f4 100644 --- a/libs/libcurl/src/config-os400.h +++ b/libs/libcurl/src/config-os400.h @@ -310,9 +310,6 @@ /* Define if you have the header file. */ #define HAVE_STRING_H -/* Define if you have the `strlcpy' function. */ -#undef HAVE_STRLCPY - /* Define if you have the header file. */ #undef HAVE_STROPTS_H @@ -452,25 +449,6 @@ /* Define if you have the ldap_url_parse procedure. */ /* #define HAVE_LDAP_URL_PARSE */ /* Disabled because of an IBM bug. */ -/* Define if you have the getnameinfo function. */ -/* OS400 has no ASCII version of this procedure: wrapped in setup-os400.h. */ -#define HAVE_GETNAMEINFO - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 socklen_t - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - /* Define if you have the recv function. */ #define HAVE_RECV diff --git a/libs/libcurl/src/config-plan9.h b/libs/libcurl/src/config-plan9.h index ecfc273722..ce89309bc1 100644 --- a/libs/libcurl/src/config-plan9.h +++ b/libs/libcurl/src/config-plan9.h @@ -54,13 +54,6 @@ #define SIZEOF_TIME_T 4 #endif -#define HAVE_GETNAMEINFO 1 -#define GETNAMEINFO_QUAL_ARG1 const -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * -#define GETNAMEINFO_TYPE_ARG2 int -#define GETNAMEINFO_TYPE_ARG46 long -#define GETNAMEINFO_TYPE_ARG7 int - #define HAVE_RECV 1 #define RECV_TYPE_ARG1 int #define RECV_TYPE_ARG2 void * diff --git a/libs/libcurl/src/config-riscos.h b/libs/libcurl/src/config-riscos.h index 2dc3c66311..13287e0a4c 100644 --- a/libs/libcurl/src/config-riscos.h +++ b/libs/libcurl/src/config-riscos.h @@ -296,9 +296,6 @@ /* Define if you have the header file. */ #define HAVE_STRING_H -/* Define if you have the `strlcpy' function. */ -#undef HAVE_STRLCPY - /* Define if you have the `strstr' function. */ #define HAVE_STRSTR @@ -408,24 +405,6 @@ /* to disable LDAP */ #define CURL_DISABLE_LDAP -/* Define if you have the getnameinfo function. */ -#define HAVE_GETNAMEINFO 1 - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 size_t - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - /* Define if you have the recv function. */ #define HAVE_RECV 1 diff --git a/libs/libcurl/src/config-tpf.h b/libs/libcurl/src/config-tpf.h index 3fdb8924c5..12c34e18e3 100644 --- a/libs/libcurl/src/config-tpf.h +++ b/libs/libcurl/src/config-tpf.h @@ -77,18 +77,6 @@ /* Define if struct sockaddr_in6 has the sin6_scope_id member */ /* #undef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID */ -/* Define to the type of arg 1 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG1 */ - -/* Define to the type of arg 2 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG2 */ - -/* Define to the type of args 4 and 6 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG46 */ - -/* Define to the type of arg 7 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG7 */ - /* Define to 1 if you have the alarm function. */ #define HAVE_ALARM 1 @@ -162,9 +150,6 @@ /* gethostbyname_r() takes 6 args */ /* #undef HAVE_GETHOSTBYNAME_R_6 1 */ -/* Define to 1 if you have the getnameinfo function. */ -/* #undef HAVE_GETNAMEINFO */ - /* Define to 1 if you have the `getpass_r' function. */ /* #undef HAVE_GETPASS_R */ @@ -450,9 +435,6 @@ /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 -/* Define to 1 if you have the `strlcpy' function. */ -/* #undef HAVE_STRLCPY */ - /* Define to 1 if you have the `strstr' function. */ #define HAVE_STRSTR 1 @@ -660,24 +642,6 @@ /* the signed version of size_t */ /* #undef ssize_t */ -/* Define to 1 if you have the getnameinfo function. */ -/* #undef HAVE_GETNAMEINFO 1 */ - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -/* #undef GETNAMEINFO_QUAL_ARG1 const */ - -/* Define to the type of arg 1 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG1 struct sockaddr * */ - -/* Define to the type of arg 2 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG2 socklen_t */ - -/* Define to the type of args 4 and 6 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG46 size_t */ - -/* Define to the type of arg 7 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG7 int */ - /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 diff --git a/libs/libcurl/src/config-vxworks.h b/libs/libcurl/src/config-vxworks.h index 916d023383..8911b05e24 100644 --- a/libs/libcurl/src/config-vxworks.h +++ b/libs/libcurl/src/config-vxworks.h @@ -80,21 +80,6 @@ /* Define if you want to enable IPv6 support */ #define ENABLE_IPV6 1 -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 size_t - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 unsigned int - /* Specifies the number of arguments to getservbyport_r */ #define GETSERVBYPORT_R_ARGS 6 @@ -206,9 +191,6 @@ /* Define to 1 if you have a working getifaddrs function. */ /* #undef HAVE_GETIFADDRS */ -/* Define to 1 if you have the getnameinfo function. */ -#define HAVE_GETNAMEINFO 1 - /* Define to 1 if you have the `getpass_r' function. */ /* #undef HAVE_GETPASS_R */ @@ -553,9 +535,6 @@ /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 -/* Define to 1 if you have the `strlcpy' function. */ -/* #undef HAVE_STRLCPY */ - /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index 98267a8033..fc81536835 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -246,10 +246,6 @@ /* Define if you have the socket function. */ #define HAVE_SOCKET 1 -/* Define if libSSH2 is in use */ -#define USE_LIBSSH2 1 -#define HAVE_LIBSSH2_H 1 - /* Define if you have the strcasecmp function. */ #ifdef __MINGW32__ #define HAVE_STRCASECMP 1 @@ -281,21 +277,6 @@ #define HAVE_UTIME 1 #endif -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 DWORD - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - /* Define if you have the recv function. */ #define HAVE_RECV 1 @@ -423,7 +404,6 @@ # undef HAVE_WS2TCPIP_H # undef HAVE_ERRNO_H # undef HAVE_GETHOSTNAME -# undef HAVE_GETNAMEINFO # undef LWIP_POSIX_SOCKETS_IO_NAMES # undef RECV_TYPE_ARG1 # undef RECV_TYPE_ARG3 @@ -454,7 +434,6 @@ #undef HAVE_WINSOCK2_H #undef HAVE_WS2TCPIP_H #define HAVE_GETADDRINFO - #define HAVE_GETNAMEINFO #define HAVE_SYS_IOCTL_H #define HAVE_SYS_SOCKET_H #define HAVE_NETINET_IN_H @@ -584,7 +563,7 @@ Vista # endif #endif -/* Availability of freeaddrinfo, getaddrinfo, getnameinfo and if_nametoindex +/* Availability of freeaddrinfo, getaddrinfo, and if_nametoindex functions is quite convoluted, compiler dependent and even build target dependent. */ #if defined(HAVE_WS2TCPIP_H) @@ -592,17 +571,14 @@ Vista # define HAVE_FREEADDRINFO 1 # define HAVE_GETADDRINFO 1 # define HAVE_GETADDRINFO_THREADSAFE 1 -# define HAVE_GETNAMEINFO 1 # elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) # define HAVE_FREEADDRINFO 1 # define HAVE_GETADDRINFO 1 # define HAVE_GETADDRINFO_THREADSAFE 1 -# define HAVE_GETNAMEINFO 1 # elif defined(_MSC_VER) && (_MSC_VER >= 1200) # define HAVE_FREEADDRINFO 1 # define HAVE_GETADDRINFO 1 # define HAVE_GETADDRINFO_THREADSAFE 1 -# define HAVE_GETNAMEINFO 1 # endif #endif @@ -712,9 +688,6 @@ Vista # define CURL_DISABLE_LDAP 1 #endif -/* if SSL is enabled */ -#define USE_OPENSSL 1 - /* Define to use the Windows crypto library. */ #if !defined(CURL_WINDOWS_APP) #define USE_WIN32_CRYPTO diff --git a/libs/libcurl/src/config-win32ce.h b/libs/libcurl/src/config-win32ce.h index fb29e088f6..44cc028874 100644 --- a/libs/libcurl/src/config-win32ce.h +++ b/libs/libcurl/src/config-win32ce.h @@ -219,24 +219,6 @@ /* Define if you have the utime function */ #define HAVE_UTIME 1 -/* Define if you have the getnameinfo function. */ -#define HAVE_GETNAMEINFO 1 - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 DWORD - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - /* Define if you have the recv function. */ #define HAVE_RECV 1 diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index 296fb62503..d9317f3783 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -660,7 +660,7 @@ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, #endif #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) case AF_UNIX: - if(salen > (curl_socklen_t)sizeof(sa_family_t)) { + if(salen > (curl_socklen_t)sizeof(CURL_SA_FAMILY_T)) { su = (struct sockaddr_un*)sa; msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path); } @@ -1367,14 +1367,31 @@ CURLcode Curl_connecthost(struct Curl_easy *data, conn->timeoutms_per_addr[1] = conn->tempaddr[1]->ai_next == NULL ? timeout_ms : timeout_ms / 2; - conn->tempfamily[0] = conn->tempaddr[0]? - conn->tempaddr[0]->ai_family:0; + if(conn->ip_version == CURL_IPRESOLVE_WHATEVER) { + /* any IP version is allowed */ + conn->tempfamily[0] = conn->tempaddr[0]? + conn->tempaddr[0]->ai_family:0; #ifdef ENABLE_IPV6 - conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ? - AF_INET : AF_INET6; + conn->tempfamily[1] = conn->tempfamily[0] == AF_INET6 ? + AF_INET : AF_INET6; #else - conn->tempfamily[1] = AF_UNSPEC; + conn->tempfamily[1] = AF_UNSPEC; #endif + } + else { + /* only one IP version is allowed */ + conn->tempfamily[0] = (conn->ip_version == CURL_IPRESOLVE_V4) ? + AF_INET : +#ifdef ENABLE_IPV6 + AF_INET6; +#else + AF_UNSPEC; +#endif + conn->tempfamily[1] = AF_UNSPEC; + + ainext(conn, 0, FALSE); /* find first address of the right type */ + } + ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */ DEBUGF(infof(data, "family0 == %s, family1 == %s\n", diff --git a/libs/libcurl/src/content_encoding.c b/libs/libcurl/src/content_encoding.c index f179b81796..a84ff543b9 100644 --- a/libs/libcurl/src/content_encoding.c +++ b/libs/libcurl/src/content_encoding.c @@ -178,7 +178,7 @@ static CURLcode inflate_stream(struct Curl_easy *data, /* Dynamically allocate a buffer for decompression because it's uncommonly large to hold on the stack */ decomp = malloc(DSIZ); - if(decomp == NULL) + if(!decomp) return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY); /* because the buffer size is fixed, iteratively decompress and transfer to @@ -487,7 +487,7 @@ static CURLcode gzip_unencode_write(struct Curl_easy *data, */ z->avail_in = (uInt) nbytes; z->next_in = malloc(z->avail_in); - if(z->next_in == NULL) { + if(!z->next_in) { return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY); } memcpy(z->next_in, buf, z->avail_in); @@ -509,7 +509,7 @@ static CURLcode gzip_unencode_write(struct Curl_easy *data, ssize_t hlen; z->avail_in += (uInt) nbytes; z->next_in = Curl_saferealloc(z->next_in, z->avail_in); - if(z->next_in == NULL) { + if(!z->next_in) { return exit_zlib(data, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY); } /* Append the new block of data to the previous one */ @@ -985,7 +985,8 @@ new_unencoding_writer(struct Curl_easy *data, return writer; } -/* Write data using an unencoding writer stack. */ +/* Write data using an unencoding writer stack. "nbytes" is not + allowed to be 0. */ CURLcode Curl_unencode_write(struct Curl_easy *data, struct contenc_writer *writer, const char *buf, size_t nbytes) diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c index b85e5e921c..941623f9d2 100644 --- a/libs/libcurl/src/cookie.c +++ b/libs/libcurl/src/cookie.c @@ -105,6 +105,8 @@ Example set of cookies: #include "curl_memory.h" #include "memdebug.h" +static void strstore(char **str, const char *newstr); + static void freecookie(struct Cookie *co) { free(co->expirestr); @@ -129,12 +131,13 @@ static bool tailmatch(const char *cooke_domain, const char *hostname) if(!strcasecompare(cooke_domain, hostname + hostname_len-cookie_domain_len)) return FALSE; - /* A lead char of cookie_domain is not '.'. - RFC6265 4.1.2.3. The Domain Attribute says: - For example, if the value of the Domain attribute is - "example.com", the user agent will include the cookie in the Cookie - header when making HTTP requests to example.com, www.example.com, and - www.corp.example.com. + /* + * A lead char of cookie_domain is not '.'. + * RFC6265 4.1.2.3. The Domain Attribute says: + * For example, if the value of the Domain attribute is + * "example.com", the user agent will include the cookie in the Cookie + * header when making HTTP requests to example.com, www.example.com, and + * www.corp.example.com. */ if(hostname_len == cookie_domain_len) return TRUE; @@ -144,7 +147,10 @@ static bool tailmatch(const char *cooke_domain, const char *hostname) } /* - * Return true if the given string is an IP(v4|v6) address. + * isip + * + * Returns true if the given string is an IPv4 or IPv6 address (if IPv6 has + * been enabled while building libcurl, and false otherwise. */ static bool isip(const char *domain) { @@ -193,19 +199,19 @@ static bool pathmatch(const char *cookie_path, const char *request_uri) /* #-fragments are already cut off! */ if(0 == strlen(uri_path) || uri_path[0] != '/') { - free(uri_path); - uri_path = strdup("/"); + strstore(&uri_path, "/"); if(!uri_path) return FALSE; } - /* here, RFC6265 5.1.4 says - 4. Output the characters of the uri-path from the first character up - to, but not including, the right-most %x2F ("/"). - but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site - without redirect. - Ignore this algorithm because /hoge is uri path for this case - (uri path is not /). + /* + * here, RFC6265 5.1.4 says + * 4. Output the characters of the uri-path from the first character up + * to, but not including, the right-most %x2F ("/"). + * but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site + * without redirect. + * Ignore this algorithm because /hoge is uri path for this case + * (uri path is not /). */ uri_path_len = strlen(uri_path); @@ -328,8 +334,7 @@ static char *sanitize_cookie_path(const char *cookie_path) /* RFC6265 5.2.4 The Path Attribute */ if(new_path[0] != '/') { /* Let cookie-path be the default-path. */ - free(new_path); - new_path = strdup("/"); + strstore(&new_path, "/"); return new_path; } @@ -357,7 +362,8 @@ void Curl_cookie_loadfiles(struct Curl_easy *data) data->cookies, data->set.cookiesession); if(!newcookies) - /* Failure may be due to OOM or a bad cookie; both are ignored + /* + * Failure may be due to OOM or a bad cookie; both are ignored * but only the first should be */ infof(data, "ignoring failed cookie_init for %s\n", list->data); @@ -372,10 +378,13 @@ void Curl_cookie_loadfiles(struct Curl_easy *data) } /* - * strstore() makes a strdup() on the 'newstr' and if '*str' is non-NULL - * that will be freed before the allocated string is stored there. + * strstore * - * It is meant to easily replace strdup() + * A thin wrapper around strdup which ensures that any memory allocated at + * *str will be freed before the string allocated by strdup is stored there. + * The intended usecase is repeated assignments to the same variable during + * parsing in a last-wins scenario. The caller is responsible for checking + * for OOM errors. */ static void strstore(char **str, const char *newstr) { @@ -384,7 +393,11 @@ static void strstore(char **str, const char *newstr) } /* - * remove_expired() removes expired cookies. + * remove_expired + * + * Remove expired cookies from the hash by inspecting the expires timestamp on + * each cookie in the hash, freeing and deleting any where the timestamp is in + * the past. */ static void remove_expired(struct CookieInfo *cookies) { @@ -421,25 +434,23 @@ static bool bad_domain(const char *domain) return !strchr(domain, '.') && !strcasecompare(domain, "localhost"); } -/**************************************************************************** - * - * Curl_cookie_add() - * - * Add a single cookie line to the cookie keeping object. +/* + * Curl_cookie_add * - * Be aware that sometimes we get an IP-only host name, and that might also be - * a numerical IPv6 address. + * Add a single cookie line to the cookie keeping object. Be aware that + * sometimes we get an IP-only host name, and that might also be a numerical + * IPv6 address. * * Returns NULL on out of memory or invalid cookie. This is suboptimal, * as they should be treated separately. - ***************************************************************************/ - + */ struct Cookie * Curl_cookie_add(struct Curl_easy *data, - /* The 'data' pointer here may be NULL at times, and thus - must only be used very carefully for things that can deal - with data being NULL. Such as infof() and similar */ - + /* + * The 'data' pointer here may be NULL at times, and thus + * must only be used very carefully for things that can deal + * with data being NULL. Such as infof() and similar + */ struct CookieInfo *c, bool httpheader, /* TRUE if HTTP header-style line */ bool noexpire, /* if TRUE, skip remove_expired() */ @@ -493,9 +504,11 @@ Curl_cookie_add(struct Curl_easy *data, if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n=] =%" MAX_NAME_TXT "[^;\r\n]", name, what)) { - /* Use strstore() below to properly deal with received cookie - headers that have the same string property set more than once, - and then we use the last one. */ + /* + * Use strstore() below to properly deal with received cookie + * headers that have the same string property set more than once, + * and then we use the last one. + */ const char *whatptr; bool done = FALSE; bool sep; @@ -503,11 +516,13 @@ Curl_cookie_add(struct Curl_easy *data, size_t nlen = strlen(name); const char *endofn = &ptr[ nlen ]; + /* + * Check for too long individual name or contents, or too long + * combination of name + contents. Chrome and Firefox support 4095 or + * 4096 bytes combo + */ if(nlen >= (MAX_NAME-1) || len >= (MAX_NAME-1) || ((nlen + len) > MAX_NAME)) { - /* too long individual name or contents, or too long combination of - name + contents. Chrome and Firefox support 4095 or 4096 bytes - combo. */ freecookie(co); infof(data, "oversized cookie dropped, name/val %zu + %zu bytes\n", nlen, len); @@ -569,8 +584,10 @@ Curl_cookie_add(struct Curl_easy *data, } } else if(!len) { - /* this was a "=" with no content, and we must allow - 'secure' and 'httponly' specified this weirdly */ + /* + * this was a "=" with no content, and we must allow + * 'secure' and 'httponly' specified this weirdly + */ done = TRUE; /* * secure cookies are only allowed to be set when the connection is @@ -610,8 +627,10 @@ Curl_cookie_add(struct Curl_easy *data, else if(strcasecompare("domain", name)) { bool is_ip; - /* Now, we make sure that our host is within the given domain, - or the given domain is not valid and thus cannot be set. */ + /* + * Now, we make sure that our host is within the given domain, or + * the given domain is not valid and thus cannot be set. + */ if('.' == whatptr[0]) whatptr++; /* ignore preceding dot */ @@ -641,9 +660,10 @@ Curl_cookie_add(struct Curl_easy *data, given */ } else { - /* we did not get a tailmatch and then the attempted set domain - is not a domain to which the current host belongs. Mark as - bad. */ + /* + * We did not get a tailmatch and then the attempted set domain is + * not a domain to which the current host belongs. Mark as bad. + */ badcookie = TRUE; infof(data, "skipped cookie with bad tailmatch domain: %s\n", whatptr); @@ -657,15 +677,15 @@ Curl_cookie_add(struct Curl_easy *data, } } else if(strcasecompare("max-age", name)) { - /* Defined in RFC2109: - - Optional. The Max-Age attribute defines the lifetime of the - cookie, in seconds. The delta-seconds value is a decimal non- - negative integer. After delta-seconds seconds elapse, the - client should discard the cookie. A value of zero means the - cookie should be discarded immediately. - - */ + /* + * Defined in RFC2109: + * + * Optional. The Max-Age attribute defines the lifetime of the + * cookie, in seconds. The delta-seconds value is a decimal non- + * negative integer. After delta-seconds seconds elapse, the + * client should discard the cookie. A value of zero means the + * cookie should be discarded immediately. + */ strstore(&co->maxage, whatptr); if(!co->maxage) { badcookie = TRUE; @@ -679,9 +699,10 @@ Curl_cookie_add(struct Curl_easy *data, break; } } + /* - else this is the second (or more) name we don't know - about! */ + * Else, this is the second (or more) name we don't know about! + */ } else { /* this is an "illegal" = pair */ @@ -699,8 +720,10 @@ Curl_cookie_add(struct Curl_easy *data, semiptr = strchr(ptr, ';'); /* now, find the next semicolon */ if(!semiptr && *ptr) - /* There are no more semicolons, but there's a final name=value pair - coming up */ + /* + * There are no more semicolons, but there's a final name=value pair + * coming up + */ semiptr = strchr(ptr, '\0'); } while(semiptr); @@ -724,13 +747,16 @@ Curl_cookie_add(struct Curl_easy *data, } } else if(co->expirestr) { - /* Note that if the date couldn't get parsed for whatever reason, - the cookie will be treated as a session cookie */ + /* + * Note that if the date couldn't get parsed for whatever reason, the + * cookie will be treated as a session cookie + */ co->expires = Curl_getdate_capped(co->expirestr); - /* Session cookies have expires set to 0 so if we get that back - from the date parser let's add a second to make it a - non-session cookie */ + /* + * Session cookies have expires set to 0 so if we get that back from the + * date parser let's add a second to make it a non-session cookie + */ if(co->expires == 0) co->expires = 1; else if(co->expires < 0) @@ -747,13 +773,17 @@ Curl_cookie_add(struct Curl_easy *data, } if(!badcookie && !co->path && path) { - /* No path was given in the header line, set the default. - Note that the passed-in path to this function MAY have a '?' and - following part that MUST not be stored as part of the path. */ + /* + * No path was given in the header line, set the default. Note that the + * passed-in path to this function MAY have a '?' and following part that + * MUST NOT be stored as part of the path. + */ char *queryp = strchr(path, '?'); - /* queryp is where the interesting part of the path ends, so now we - want to the find the last */ + /* + * queryp is where the interesting part of the path ends, so now we + * want to the find the last + */ char *endslash; if(!queryp) endslash = strrchr(path, '/'); @@ -774,29 +804,34 @@ Curl_cookie_add(struct Curl_easy *data, } } + /* + * If we didn't get a cookie name, or a bad one, the this is an illegal + * line so bail out. + */ if(badcookie || !co->name) { - /* we didn't get a cookie name or a bad one, - this is an illegal line, bail out */ freecookie(co); return NULL; } } else { - /* This line is NOT a HTTP header style line, we do offer support for - reading the odd netscape cookies-file format here */ + /* + * This line is NOT a HTTP header style line, we do offer support for + * reading the odd netscape cookies-file format here + */ char *ptr; char *firstptr; char *tok_buf = NULL; int fields; - /* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies - marked with httpOnly after the domain name are not accessible - from javascripts, but since curl does not operate at javascript - level, we include them anyway. In Firefox's cookie files, these - lines are preceded with #HttpOnly_ and then everything is - as usual, so we skip 10 characters of the line.. - */ + /* + * IE introduced HTTP-only cookies to prevent XSS attacks. Cookies marked + * with httpOnly after the domain name are not accessible from javascripts, + * but since curl does not operate at javascript level, we include them + * anyway. In Firefox's cookie files, these lines are preceded with + * #HttpOnly_ and then everything is as usual, so we skip 10 characters of + * the line.. + */ if(strncmp(lineptr, "#HttpOnly_", 10) == 0) { lineptr += 10; co->httponly = TRUE; @@ -817,8 +852,10 @@ Curl_cookie_add(struct Curl_easy *data, firstptr = strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */ - /* Now loop through the fields and init the struct we already have - allocated */ + /* + * Now loop through the fields and init the struct we already have + * allocated + */ for(ptr = firstptr, fields = 0; ptr && !badcookie; ptr = strtok_r(NULL, "\t", &tok_buf), fields++) { switch(fields) { @@ -830,10 +867,11 @@ Curl_cookie_add(struct Curl_easy *data, badcookie = TRUE; break; case 1: - /* 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 - */ + /* + * 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 + */ co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE; break; case 2: @@ -942,9 +980,11 @@ Curl_cookie_add(struct Curl_easy *data, co->livecookie = c->running; co->creationtime = ++c->lastct; - /* now, we have parsed the incoming line, we must now check if this - supersedes an already existing cookie, which it may if the previous have - the same domain and path as this */ + /* + * Now we have parsed the incoming line, we must now check if this supersedes + * an already existing cookie, which it may if the previous have the same + * domain and path as this. + */ /* at first, remove expired cookies */ if(!noexpire) @@ -1032,12 +1072,12 @@ Curl_cookie_add(struct Curl_easy *data, } if(replace_old && !co->livecookie && clist->livecookie) { - /* Both cookies matched fine, except that the already present - cookie is "live", which means it was set from a header, while - the new one isn't "live" and thus only read from a file. We let - live cookies stay alive */ - - /* Free the newcomer and get out of here! */ + /* + * Both cookies matched fine, except that the already present cookie is + * "live", which means it was set from a header, while the new one was + * read from a file and thus isn't "live". "live" cookies are preferred + * so the new cookie is freed. + */ freecookie(co); return NULL; } @@ -1063,8 +1103,10 @@ Curl_cookie_add(struct Curl_easy *data, free(co); /* free the newly allocated memory */ co = clist; /* point to the previous struct instead */ - /* We have replaced a cookie, now skip the rest of the list but - make sure the 'lastc' pointer is properly set */ + /* + * We have replaced a cookie, now skip the rest of the list but make + * sure the 'lastc' pointer is properly set + */ do { lastc = clist; clist = clist->next; @@ -1096,19 +1138,19 @@ Curl_cookie_add(struct Curl_easy *data, } -/***************************************************************************** - * +/* * Curl_cookie_init() * * Inits a cookie struct to read data from a local file. This is always - * called before any cookies are set. File may be NULL. + * called before any cookies are set. File may be NULL in which case only the + * struct is initialized. Is file is "-" then STDIN is read. * * If 'newsession' is TRUE, discard all "session cookies" on read from file. * * Note that 'data' might be called as NULL pointer. * * Returns NULL on out of memory. Invalid cookies are ignored. - ****************************************************************************/ + */ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, const char *file, struct CookieInfo *inc, @@ -1170,7 +1212,12 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, Curl_cookie_add(data, c, headerline, TRUE, lineptr, NULL, NULL, TRUE); } free(line); /* free the line buffer */ - remove_expired(c); /* run this once, not on every cookie */ + + /* + * Remove expired cookies from the hash. We must make sure to run this + * after reading the file, and not not on every cookie. + */ + remove_expired(c); if(fromfile) fclose(fp); @@ -1184,16 +1231,24 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, fail: free(line); + /* + * Only clean up if we allocated it here, as the original could still be in + * use by a share handle. + */ if(!inc) - /* Only clean up if we allocated it here, as the original could still be in - * use by a share handle */ Curl_cookie_cleanup(c); if(fromfile && fp) fclose(fp); return NULL; /* out of memory */ } -/* sort this so that the longest path gets before the shorter path */ +/* + * cookie_sort + * + * Helper function to sort cookies such that the longest path gets before the + * shorter path. Path, domain and name lengths are considered in that order, + * with tge creationtime as the tiebreaker. + */ static int cookie_sort(const void *p1, const void *p2) { struct Cookie *c1 = *(struct Cookie **)p1; @@ -1225,7 +1280,11 @@ static int cookie_sort(const void *p1, const void *p2) return (c2->creationtime > c1->creationtime) ? 1 : -1; } -/* sort cookies only according to creation time */ +/* + * cookie_sort_ct + * + * Helper function to sort cookies according to creation time. + */ static int cookie_sort_ct(const void *p1, const void *p2) { struct Cookie *c1 = *(struct Cookie **)p1; @@ -1269,18 +1328,15 @@ static struct Cookie *dup_cookie(struct Cookie *src) return NULL; } -/***************************************************************************** - * - * Curl_cookie_getlist() +/* + * Curl_cookie_getlist * - * For a given host and path, return a linked list of cookies that the - * client should send to the server if used now. The secure boolean informs - * the cookie if a secure connection is achieved or not. + * For a given host and path, return a linked list of cookies that the client + * should send to the server if used now. The secure boolean informs the cookie + * if a secure connection is achieved or not. * * It shall only return cookies that haven't expired. - * - ****************************************************************************/ - + */ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, const char *host, const char *path, bool secure) @@ -1311,15 +1367,21 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, if(!co->domain || (co->tailmatch && !is_ip && tailmatch(co->domain, host)) || ((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) { - /* the right part of the host matches the domain stuff in the - cookie data */ + /* + * the right part of the host matches the domain stuff in the + * cookie data + */ - /* now check the left part of the path with the cookies path - requirement */ + /* + * now check the left part of the path with the cookies path + * requirement + */ if(!co->spath || pathmatch(co->spath, path) ) { - /* and now, we know this is a match and we should create an - entry for the return-linked-list */ + /* + * and now, we know this is a match and we should create an + * entry for the return-linked-list + */ newco = dup_cookie(co); if(newco) { @@ -1340,9 +1402,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, } if(matches) { - /* Now we need to make sure that if there is a name appearing more than - once, the longest specified path version comes first. To make this - the swiftest way, we just sort them all based on path length. */ + /* + * Now we need to make sure that if there is a name appearing more than + * once, the longest specified path version comes first. To make this + * the swiftest way, we just sort them all based on path length. + */ struct Cookie **array; size_t i; @@ -1377,13 +1441,11 @@ fail: return NULL; } -/***************************************************************************** - * - * Curl_cookie_clearall() +/* + * Curl_cookie_clearall * * Clear all existing cookies and reset the counter. - * - ****************************************************************************/ + */ void Curl_cookie_clearall(struct CookieInfo *cookies) { if(cookies) { @@ -1396,14 +1458,11 @@ void Curl_cookie_clearall(struct CookieInfo *cookies) } } -/***************************************************************************** - * - * Curl_cookie_freelist() +/* + * Curl_cookie_freelist * * Free a list of cookies previously returned by Curl_cookie_getlist(); - * - ****************************************************************************/ - + */ void Curl_cookie_freelist(struct Cookie *co) { struct Cookie *next; @@ -1414,14 +1473,11 @@ void Curl_cookie_freelist(struct Cookie *co) } } - -/***************************************************************************** - * - * Curl_cookie_clearsess() +/* + * Curl_cookie_clearsess * * Free all session cookies in the cookies list. - * - ****************************************************************************/ + */ void Curl_cookie_clearsess(struct CookieInfo *cookies) { struct Cookie *first, *curr, *next, *prev = NULL; @@ -1458,14 +1514,11 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies) } } - -/***************************************************************************** - * +/* * Curl_cookie_cleanup() * * Free a "cookie object" previous created with Curl_cookie_init(). - * - ****************************************************************************/ + */ void Curl_cookie_cleanup(struct CookieInfo *c) { if(c) { @@ -1477,12 +1530,13 @@ void Curl_cookie_cleanup(struct CookieInfo *c) } } -/* get_netscape_format() +/* + * get_netscape_format() * * Formats a string for Netscape output file, w/o a newline at the end. - * - * Function returns a char * to a formatted line. Has to be free()d -*/ + * Function returns a char * to a formatted line. The caller is responsible + * for freeing the returned pointer. + */ static char *get_netscape_format(const struct Cookie *co) { return aprintf( @@ -1495,8 +1549,10 @@ static char *get_netscape_format(const struct Cookie *co) "%s\t" /* name */ "%s", /* value */ co->httponly?"#HttpOnly_":"", - /* Make sure all domains are prefixed with a dot if they allow - tailmatching. This is Mozilla-style. */ + /* + * Make sure all domains are prefixed with a dot if they allow + * tailmatching. This is Mozilla-style. + */ (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"", co->domain?co->domain:"unknown", co->tailmatch?"TRUE":"FALSE", @@ -1515,18 +1571,18 @@ static char *get_netscape_format(const struct Cookie *co) * * The function returns non-zero on write failure. */ -static int cookie_output(struct Curl_easy *data, - struct CookieInfo *c, const char *filename) +static CURLcode cookie_output(struct Curl_easy *data, + struct CookieInfo *c, const char *filename) { struct Cookie *co; FILE *out = NULL; bool use_stdout = FALSE; char *tempstore = NULL; - bool error = false; + CURLcode error = CURLE_OK; if(!c) /* no cookie engine alive */ - return 0; + return CURLE_OK; /* at first, remove expired cookies */ remove_expired(c); @@ -1544,11 +1600,13 @@ static int cookie_output(struct Curl_easy *data, tempstore = aprintf("%s.%s.tmp", filename, randsuffix); if(!tempstore) - return 1; + return CURLE_OUT_OF_MEMORY; out = fopen(tempstore, FOPEN_WRITETEXT); - if(!out) + if(!out) { + error = CURLE_WRITE_ERROR; goto error; + } } fputs("# Netscape HTTP Cookie File\n" @@ -1563,6 +1621,7 @@ static int cookie_output(struct Curl_easy *data, array = calloc(1, sizeof(struct Cookie *) * c->numcookies); if(!array) { + error = CURLE_OUT_OF_MEMORY; goto error; } @@ -1579,9 +1638,9 @@ static int cookie_output(struct Curl_easy *data, for(i = 0; i < nvalid; i++) { char *format_ptr = get_netscape_format(array[i]); - if(format_ptr == NULL) { - fprintf(out, "#\n# Fatal libcurl error\n"); + if(!format_ptr) { free(array); + error = CURLE_OUT_OF_MEMORY; goto error; } fprintf(out, "%s\n", format_ptr); @@ -1596,18 +1655,24 @@ static int cookie_output(struct Curl_easy *data, out = NULL; if(Curl_rename(tempstore, filename)) { unlink(tempstore); + error = CURLE_WRITE_ERROR; goto error; } } - goto cleanup; + /* + * If we reach here we have successfully written a cookie file so theree is + * no need to inspect the error, any error case should have jumped into the + * error block below. + */ + free(tempstore); + return CURLE_OK; + error: - error = true; -cleanup: if(out && !use_stdout) fclose(out); free(tempstore); - return error ? 1 : 0; + return error; } static struct curl_slist *cookie_list(struct Curl_easy *data) @@ -1618,8 +1683,7 @@ static struct curl_slist *cookie_list(struct Curl_easy *data) char *line; unsigned int i; - if((data->cookies == NULL) || - (data->cookies->numcookies == 0)) + if(!data->cookies || (data->cookies->numcookies == 0)) return NULL; for(i = 0; i < COOKIE_HASH_SIZE; i++) { @@ -1655,6 +1719,8 @@ struct curl_slist *Curl_cookie_list(struct Curl_easy *data) void Curl_flush_cookies(struct Curl_easy *data, bool cleanup) { + CURLcode res; + if(data->set.str[STRING_COOKIEJAR]) { if(data->state.cookielist) { /* If there is a list of cookie files to read, do it first so that @@ -1666,9 +1732,10 @@ void Curl_flush_cookies(struct Curl_easy *data, bool cleanup) Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); /* if we have a destination file for all the cookies to get dumped to */ - if(cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR])) - infof(data, "WARNING: failed to save cookies in %s\n", - data->set.str[STRING_COOKIEJAR]); + res = cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR]); + if(res) + infof(data, "WARNING: failed to save cookies in %s: %s\n", + data->set.str[STRING_COOKIEJAR], curl_easy_strerror(res)); } else { if(cleanup && data->state.cookielist) { diff --git a/libs/libcurl/src/curl_addrinfo.c b/libs/libcurl/src/curl_addrinfo.c index 06537b275f..1d5067bc00 100644 --- a/libs/libcurl/src/curl_addrinfo.c +++ b/libs/libcurl/src/curl_addrinfo.c @@ -50,6 +50,12 @@ # define in_addr_t unsigned long #endif +#if defined(USE_UNIX_SOCKETS) && defined(WINAPI_FAMILY) && \ + (WINAPI_FAMILY == WINAPI_FAMILY_APP) + /* Required for sockaddr_un type */ +# include +#endif + #include #include "curl_addrinfo.h" @@ -141,7 +147,7 @@ Curl_getaddrinfo_ex(const char *nodename, continue; /* ignore elements without required address info */ - if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0)) + if(!ai->ai_addr || !(ai->ai_addrlen > 0)) continue; /* ignore elements with bogus address size */ diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake index fbe17bc5b0..96a19afc51 100644 --- a/libs/libcurl/src/curl_config.h.cmake +++ b/libs/libcurl/src/curl_config.h.cmake @@ -112,21 +112,6 @@ /* Define if you want to enable IPv6 support */ #cmakedefine ENABLE_IPV6 1 -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1} - -/* Define to the type of arg 1 for getnameinfo. */ -#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1} - -/* Define to the type of arg 2 for getnameinfo. */ -#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2} - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46} - -/* Define to the type of arg 7 for getnameinfo. */ -#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7} - /* Specifies the number of arguments to getservbyport_r */ #cmakedefine GETSERVBYPORT_R_ARGS ${GETSERVBYPORT_R_ARGS} @@ -208,6 +193,9 @@ /* Define to 1 if you have the `geteuid' function. */ #cmakedefine HAVE_GETEUID 1 +/* Define to 1 if you have the `getppid' function. */ +#cmakedefine HAVE_GETPPID 1 + /* Define to 1 if you have the gethostbyaddr function. */ #cmakedefine HAVE_GETHOSTBYADDR 1 @@ -244,9 +232,6 @@ /* Define to 1 if you have a working getifaddrs function. */ #cmakedefine HAVE_GETIFADDRS 1 -/* Define to 1 if you have the getnameinfo function. */ -#cmakedefine HAVE_GETNAMEINFO 1 - /* Define to 1 if you have the `getpass_r' function. */ #cmakedefine HAVE_GETPASS_R 1 @@ -328,6 +313,12 @@ /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #cmakedefine HAVE_INET_PTON 1 +/* Define to 1 if symbol `sa_family_t' exists */ +#cmakedefine HAVE_SA_FAMILY_T 1 + +/* Define to 1 if symbol `ADDRESS_FAMILY' exists */ +#cmakedefine HAVE_ADDRESS_FAMILY 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_INTTYPES_H 1 @@ -500,9 +491,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_PEM_H 1 -/* Define to 1 if you have the `perror' function. */ -#cmakedefine HAVE_PERROR 1 - /* Define to 1 if you have the `pipe' function. */ #cmakedefine HAVE_PIPE 1 @@ -644,12 +632,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING_H 1 -/* Define to 1 if you have the strlcat function. */ -#cmakedefine HAVE_STRLCAT 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#cmakedefine HAVE_STRLCPY 1 - /* Define to 1 if you have the strncmpi function. */ #cmakedefine HAVE_STRNCMPI 1 @@ -740,6 +722,9 @@ /* Define to 1 if you have the `utime' function. */ #cmakedefine HAVE_UTIME 1 +/* Define to 1 if you have the `utimes' function. */ +#cmakedefine HAVE_UTIMES 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UTIME_H 1 diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in index ae942fbfb8..d5f8ba9b00 100644 --- a/libs/libcurl/src/curl_config.h.in +++ b/libs/libcurl/src/curl_config.h.in @@ -42,6 +42,9 @@ /* to disable Gopher */ #undef CURL_DISABLE_GOPHER +/* disable alt-svc */ +#undef CURL_DISABLE_HSTS + /* to disable HTTP */ #undef CURL_DISABLE_HTTP @@ -807,9 +810,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_WOLFSSH_SSH_H -/* Define to 1 if you have the `wolfSSLv3_client_method' function. */ -#undef HAVE_WOLFSSLV3_CLIENT_METHOD - /* if you have wolfSSL_DES_ecb_encrypt */ #undef HAVE_WOLFSSL_DES_ECB_ENCRYPT @@ -987,9 +987,6 @@ /* GSASL support enabled */ #undef USE_GSASL -/* to enable HSTS */ -#undef USE_HSTS - /* if hyper is in use */ #undef USE_HYPER diff --git a/libs/libcurl/src/curl_get_line.c b/libs/libcurl/src/curl_get_line.c index 438ede7046..8f3b0bd8c1 100644 --- a/libs/libcurl/src/curl_get_line.c +++ b/libs/libcurl/src/curl_get_line.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -23,7 +23,7 @@ #include "curl_setup.h" #if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \ - defined(USE_HSTS) + !defined(CURL_DISABLE_HSTS) #include "curl_get_line.h" #include "curl_memory.h" diff --git a/libs/libcurl/src/curl_gssapi.c b/libs/libcurl/src/curl_gssapi.c index 6445fbad09..acaaa1c683 100644 --- a/libs/libcurl/src/curl_gssapi.c +++ b/libs/libcurl/src/curl_gssapi.c @@ -102,7 +102,7 @@ static size_t display_gss_error(OM_uint32 status, int type, (char *)status_string.value); } gss_release_buffer(&min_stat, &status_string); - } while(!GSS_ERROR(maj_stat) && msg_ctx != 0); + } while(!GSS_ERROR(maj_stat) && msg_ctx); return len; } diff --git a/libs/libcurl/src/curl_krb5.h b/libs/libcurl/src/curl_krb5.h index 3f40f9a6ca..ca06840742 100644 --- a/libs/libcurl/src/curl_krb5.h +++ b/libs/libcurl/src/curl_krb5.h @@ -29,7 +29,6 @@ struct Curl_sec_client_mech { int (*auth)(void *, struct Curl_easy *data, struct connectdata *); void (*end)(void *); int (*check_prot)(void *, int); - int (*overhead)(void *, int, int); int (*encode)(void *, const void *, int, int, void **); int (*decode)(void *, void *, int, int, struct connectdata *); }; diff --git a/libs/libcurl/src/curl_path.c b/libs/libcurl/src/curl_path.c index 6100d77bd9..65106188c7 100644 --- a/libs/libcurl/src/curl_path.c +++ b/libs/libcurl/src/curl_path.c @@ -48,7 +48,7 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data, /* Check for /~/, indicating relative to the user's home directory */ if(data->conn->handler->protocol & CURLPROTO_SCP) { real_path = malloc(working_path_len + 1); - if(real_path == NULL) { + if(!real_path) { free(working_path); return CURLE_OUT_OF_MEMORY; } @@ -62,7 +62,7 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data, if((working_path_len > 1) && (working_path[1] == '~')) { size_t homelen = strlen(homedir); real_path = malloc(homelen + working_path_len + 1); - if(real_path == NULL) { + if(!real_path) { free(working_path); return CURLE_OUT_OF_MEMORY; } @@ -78,7 +78,7 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data, } else { real_path = malloc(working_path_len + 1); - if(real_path == NULL) { + if(!real_path) { free(working_path); return CURLE_OUT_OF_MEMORY; } @@ -130,7 +130,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) /* Allocate enough space for home directory and filename + separator */ fullPathLength = strlen(cp) + strlen(homedir) + 2; *path = malloc(fullPathLength); - if(*path == NULL) + if(!*path) return CURLE_OUT_OF_MEMORY; /* Check for quoted filenames */ @@ -169,7 +169,7 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) else { /* Read to end of filename - either to whitespace or terminator */ end = strpbrk(cp, WHITESPACE); - if(end == NULL) + if(!end) end = strchr(cp, '\0'); /* return pointer to second parameter if it exists */ *cpp = end + strspn(end, WHITESPACE); diff --git a/libs/libcurl/src/curl_rtmp.c b/libs/libcurl/src/curl_rtmp.c index 1360f335fc..2fa026796e 100644 --- a/libs/libcurl/src/curl_rtmp.c +++ b/libs/libcurl/src/curl_rtmp.c @@ -79,6 +79,7 @@ const struct Curl_handler Curl_handler_rtmp = { rtmp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_RTMP, /* defport */ CURLPROTO_RTMP, /* protocol */ CURLPROTO_RTMP, /* family */ @@ -101,6 +102,7 @@ const struct Curl_handler Curl_handler_rtmpt = { rtmp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_RTMPT, /* defport */ CURLPROTO_RTMPT, /* protocol */ CURLPROTO_RTMPT, /* family */ @@ -123,6 +125,7 @@ const struct Curl_handler Curl_handler_rtmpe = { rtmp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_RTMP, /* defport */ CURLPROTO_RTMPE, /* protocol */ CURLPROTO_RTMPE, /* family */ @@ -145,6 +148,7 @@ const struct Curl_handler Curl_handler_rtmpte = { rtmp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_RTMPT, /* defport */ CURLPROTO_RTMPTE, /* protocol */ CURLPROTO_RTMPTE, /* family */ @@ -167,6 +171,7 @@ const struct Curl_handler Curl_handler_rtmps = { rtmp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_RTMPS, /* defport */ CURLPROTO_RTMPS, /* protocol */ CURLPROTO_RTMP, /* family */ @@ -189,6 +194,7 @@ const struct Curl_handler Curl_handler_rtmpts = { rtmp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_RTMPS, /* defport */ CURLPROTO_RTMPTS, /* protocol */ CURLPROTO_RTMPT, /* family */ diff --git a/libs/libcurl/src/curl_sasl.c b/libs/libcurl/src/curl_sasl.c index 2cba185470..a4d1059cb9 100644 --- a/libs/libcurl/src/curl_sasl.c +++ b/libs/libcurl/src/curl_sasl.c @@ -58,7 +58,7 @@ static const struct { const char *name; /* Name */ size_t len; /* Name length */ - unsigned int bit; /* Flag bit */ + unsigned short bit; /* Flag bit */ } mechtable[] = { { "LOGIN", 5, SASL_MECH_LOGIN }, { "PLAIN", 5, SASL_MECH_PLAIN }, @@ -128,7 +128,8 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) * * Returns the SASL mechanism token or 0 if no match. */ -unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len) +unsigned short Curl_sasl_decode_mech(const char *ptr, size_t maxlen, + size_t *len) { unsigned int i; char c; @@ -173,7 +174,7 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, if(!strncmp(value, "*", len)) sasl->prefmech = SASL_AUTH_DEFAULT; else { - unsigned int mechbit = Curl_sasl_decode_mech(value, len, &mechlen); + unsigned short mechbit = Curl_sasl_decode_mech(value, len, &mechlen); if(mechbit && mechlen == len) sasl->prefmech |= mechbit; else @@ -242,6 +243,49 @@ static void state(struct SASL *sasl, struct Curl_easy *data, sasl->state = newstate; } +/* Get the SASL server message and convert it to binary. */ +static CURLcode get_server_message(struct SASL *sasl, struct Curl_easy *data, + struct bufref *out) +{ + unsigned char *msg; + size_t msglen; + char *serverdata = NULL; + CURLcode result = CURLE_OK; + + sasl->params->getmessage(data->state.buffer, &serverdata); + if(!serverdata) + result = CURLE_BAD_CONTENT_ENCODING; + else if(!*serverdata || *serverdata == '=') + Curl_bufref_set(out, NULL, 0, NULL); + else { + result = Curl_base64_decode(serverdata, &msg, &msglen); + if(!result) + Curl_bufref_set(out, msg, msglen, curl_free); + } + return result; +} + +/* Encode the outgoing SASL message. */ +static CURLcode build_message(struct Curl_easy *data, struct bufref *msg) +{ + CURLcode result = CURLE_OK; + char *base64; + size_t base64len; + + if(!Curl_bufref_ptr(msg)) /* Empty mesage. */ + Curl_bufref_set(msg, "", 0, NULL); + else if(!Curl_bufref_len(msg)) /* Explicit empty response. */ + Curl_bufref_set(msg, "=", 1, NULL); + else { + result = Curl_base64_encode(data, (const char *) Curl_bufref_ptr(msg), + Curl_bufref_len(msg), &base64, &base64len); + if(!result) + Curl_bufref_set(msg, base64, base64len, curl_free); + } + + return result; +} + /* * Curl_sasl_can_authenticate() * @@ -272,25 +316,21 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, CURLcode result = CURLE_OK; unsigned int enabledmechs; const char *mech = NULL; - char *resp = NULL; - size_t len = 0; + struct bufref resp; saslstate state1 = SASL_STOP; saslstate state2 = SASL_FINAL; -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const char * const hostname = conn->host.name; - const long int port = conn->remote_port; -#endif + const char * const hostname = SSL_HOST_NAME(); + const long int port = SSL_HOST_PORT(); #if defined(USE_KERBEROS5) || defined(USE_NTLM) const char *service = data->set.str[STRING_SERVICE_NAME] ? data->set.str[STRING_SERVICE_NAME] : sasl->params->service; #endif const char *oauth_bearer = data->set.str[STRING_BEARER]; + struct bufref nullmsg; + Curl_bufref_init(&nullmsg); + Curl_bufref_init(&resp); sasl->force_ir = force_ir; /* Latch for future use */ sasl->authused = 0; /* No mechanism used yet */ enabledmechs = sasl->authmechs & sasl->prefmech; @@ -304,8 +344,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, sasl->authused = SASL_MECH_EXTERNAL; if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_external_message(data, conn->user, &resp, - &len); + result = Curl_auth_create_external_message(conn->user, &resp); } else if(conn->bits.user_passwd) { #if defined(USE_KERBEROS5) @@ -321,10 +360,10 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, result = Curl_auth_create_gssapi_user_message(data, conn->user, conn->passwd, service, - data->conn->host.name, + conn->host.name, sasl->mutual_auth, NULL, &conn->krb5, - &resp, &len); + &resp); } else #endif @@ -340,8 +379,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, result = Curl_auth_gsasl_start(data, conn->user, conn->passwd, &conn->gsasl); if(result == CURLE_OK && (force_ir || data->set.sasl_ir)) - result = Curl_auth_gsasl_token(data, NULL, &conn->gsasl, - &resp, &len); + result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp); } else if((enabledmechs & SASL_MECH_SCRAM_SHA_1) && Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1, @@ -354,8 +392,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, result = Curl_auth_gsasl_start(data, conn->user, conn->passwd, &conn->gsasl); if(result == CURLE_OK && (force_ir || data->set.sasl_ir)) - result = Curl_auth_gsasl_token(data, NULL, &conn->gsasl, - &resp, &len); + result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp); } else #endif @@ -385,8 +422,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, conn->user, conn->passwd, service, hostname, - &conn->ntlm, &resp, - &len); + &conn->ntlm, &resp); } else #endif @@ -397,11 +433,11 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, sasl->authused = SASL_MECH_OAUTHBEARER; if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_oauth_bearer_message(data, conn->user, + result = Curl_auth_create_oauth_bearer_message(conn->user, hostname, port, oauth_bearer, - &resp, &len); + &resp); } else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) { mech = SASL_MECH_STRING_XOAUTH2; @@ -409,9 +445,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, sasl->authused = SASL_MECH_XOAUTH2; if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_xoauth_bearer_message(data, conn->user, + result = Curl_auth_create_xoauth_bearer_message(conn->user, oauth_bearer, - &resp, &len); + &resp); } else if(enabledmechs & SASL_MECH_PLAIN) { mech = SASL_MECH_STRING_PLAIN; @@ -419,9 +455,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, sasl->authused = SASL_MECH_PLAIN; if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_plain_message(data, conn->sasl_authzid, + result = Curl_auth_create_plain_message(conn->sasl_authzid, conn->user, conn->passwd, - &resp, &len); + &resp); } else if(enabledmechs & SASL_MECH_LOGIN) { mech = SASL_MECH_STRING_LOGIN; @@ -430,26 +466,29 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, sasl->authused = SASL_MECH_LOGIN; if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_login_message(data, conn->user, &resp, &len); + result = Curl_auth_create_login_message(conn->user, &resp); } } if(!result && mech) { - if(resp && sasl->params->maxirlen && - strlen(mech) + len > sasl->params->maxirlen) { - free(resp); - resp = NULL; - } + if(Curl_bufref_ptr(&resp)) + result = build_message(data, &resp); + + if(sasl->params->maxirlen && + strlen(mech) + Curl_bufref_len(&resp) > sasl->params->maxirlen) + Curl_bufref_free(&resp); + + if(!result) + result = sasl->params->sendauth(data, conn, mech, + (const char *) Curl_bufref_ptr(&resp)); - result = sasl->params->sendauth(data, conn, mech, resp); if(!result) { *progress = SASL_INPROGRESS; - state(sasl, data, resp ? state2 : state1); + state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1); } } - free(resp); - + Curl_bufref_free(&resp); return result; } @@ -464,29 +503,20 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, { CURLcode result = CURLE_OK; saslstate newstate = SASL_FINAL; - char *resp = NULL; -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const char * const hostname = conn->host.name; - const long int port = conn->remote_port; -#endif -#if !defined(CURL_DISABLE_CRYPTO_AUTH) - char *chlg = NULL; - size_t chlglen = 0; -#endif + struct bufref resp; + const char * const hostname = SSL_HOST_NAME(); + const long int port = SSL_HOST_PORT(); #if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \ defined(USE_NTLM) const char *service = data->set.str[STRING_SERVICE_NAME] ? data->set.str[STRING_SERVICE_NAME] : sasl->params->service; - char *serverdata; #endif - size_t len = 0; const char *oauth_bearer = data->set.str[STRING_BEARER]; + struct bufref serverdata; + Curl_bufref_init(&serverdata); + Curl_bufref_init(&resp); *progress = SASL_INPROGRESS; if(sasl->state == SASL_FINAL) { @@ -509,50 +539,45 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, *progress = SASL_DONE; return result; case SASL_PLAIN: - result = Curl_auth_create_plain_message(data, conn->sasl_authzid, - conn->user, conn->passwd, - &resp, &len); + result = Curl_auth_create_plain_message(conn->sasl_authzid, + conn->user, conn->passwd, &resp); break; case SASL_LOGIN: - result = Curl_auth_create_login_message(data, conn->user, &resp, &len); + result = Curl_auth_create_login_message(conn->user, &resp); newstate = SASL_LOGIN_PASSWD; break; case SASL_LOGIN_PASSWD: - result = Curl_auth_create_login_message(data, conn->passwd, &resp, &len); + result = Curl_auth_create_login_message(conn->passwd, &resp); break; case SASL_EXTERNAL: - result = Curl_auth_create_external_message(data, conn->user, &resp, &len); + result = Curl_auth_create_external_message(conn->user, &resp); break; #ifndef CURL_DISABLE_CRYPTO_AUTH #ifdef USE_GSASL case SASL_GSASL: - sasl->params->getmessage(data->state.buffer, &serverdata); - result = Curl_auth_gsasl_token(data, serverdata, &conn->gsasl, - &resp, &len); - if(len > 0) + result = get_server_message(sasl, data, &serverdata); + if(!result) + result = Curl_auth_gsasl_token(data, &serverdata, &conn->gsasl, &resp); + if(!result && Curl_bufref_len(&resp) > 0) newstate = SASL_GSASL; break; #endif case SASL_CRAMMD5: - sasl->params->getmessage(data->state.buffer, &serverdata); - result = Curl_auth_decode_cram_md5_message(serverdata, &chlg, &chlglen); + result = get_server_message(sasl, data, &serverdata); if(!result) - result = Curl_auth_create_cram_md5_message(data, chlg, conn->user, - conn->passwd, &resp, &len); - free(chlg); + result = Curl_auth_create_cram_md5_message(&serverdata, conn->user, + conn->passwd, &resp); break; case SASL_DIGESTMD5: - sasl->params->getmessage(data->state.buffer, &serverdata); - result = Curl_auth_create_digest_md5_message(data, serverdata, - conn->user, conn->passwd, - service, - &resp, &len); + result = get_server_message(sasl, data, &serverdata); + if(!result) + result = Curl_auth_create_digest_md5_message(data, &serverdata, + conn->user, conn->passwd, + service, &resp); newstate = SASL_DIGESTMD5_RESP; break; case SASL_DIGESTMD5_RESP: - resp = strdup(""); - if(!resp) - result = CURLE_OUT_OF_MEMORY; + /* Keep response NULL to output an empty line. */ break; #endif @@ -562,18 +587,19 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, result = Curl_auth_create_ntlm_type1_message(data, conn->user, conn->passwd, service, hostname, - &conn->ntlm, &resp, &len); + &conn->ntlm, &resp); newstate = SASL_NTLM_TYPE2MSG; break; case SASL_NTLM_TYPE2MSG: /* Decode the type-2 message */ - sasl->params->getmessage(data->state.buffer, &serverdata); - result = Curl_auth_decode_ntlm_type2_message(data, serverdata, - &conn->ntlm); + result = get_server_message(sasl, data, &serverdata); + if(!result) + result = Curl_auth_decode_ntlm_type2_message(data, &serverdata, + &conn->ntlm); if(!result) result = Curl_auth_create_ntlm_type3_message(data, conn->user, conn->passwd, &conn->ntlm, - &resp, &len); + &resp); break; #endif @@ -582,55 +608,59 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, result = Curl_auth_create_gssapi_user_message(data, conn->user, conn->passwd, service, - data->conn->host.name, + conn->host.name, sasl->mutual_auth, NULL, &conn->krb5, - &resp, &len); + &resp); newstate = SASL_GSSAPI_TOKEN; break; case SASL_GSSAPI_TOKEN: - sasl->params->getmessage(data->state.buffer, &serverdata); - if(sasl->mutual_auth) { - /* Decode the user token challenge and create the optional response - message */ - result = Curl_auth_create_gssapi_user_message(data, NULL, NULL, - NULL, NULL, - sasl->mutual_auth, - serverdata, &conn->krb5, - &resp, &len); - newstate = SASL_GSSAPI_NO_DATA; + result = get_server_message(sasl, data, &serverdata); + if(!result) { + if(sasl->mutual_auth) { + /* Decode the user token challenge and create the optional response + message */ + result = Curl_auth_create_gssapi_user_message(data, NULL, NULL, + NULL, NULL, + sasl->mutual_auth, + &serverdata, + &conn->krb5, + &resp); + newstate = SASL_GSSAPI_NO_DATA; + } + else + /* Decode the security challenge and create the response message */ + result = Curl_auth_create_gssapi_security_message(data, &serverdata, + &conn->krb5, + &resp); } - else - /* Decode the security challenge and create the response message */ - result = Curl_auth_create_gssapi_security_message(data, serverdata, - &conn->krb5, - &resp, &len); break; case SASL_GSSAPI_NO_DATA: - sasl->params->getmessage(data->state.buffer, &serverdata); /* Decode the security challenge and create the response message */ - result = Curl_auth_create_gssapi_security_message(data, serverdata, - &conn->krb5, - &resp, &len); + result = get_server_message(sasl, data, &serverdata); + if(!result) + result = Curl_auth_create_gssapi_security_message(data, &serverdata, + &conn->krb5, + &resp); break; #endif case SASL_OAUTH2: /* Create the authorisation message */ if(sasl->authused == SASL_MECH_OAUTHBEARER) { - result = Curl_auth_create_oauth_bearer_message(data, conn->user, + result = Curl_auth_create_oauth_bearer_message(conn->user, hostname, port, oauth_bearer, - &resp, &len); + &resp); /* Failures maybe sent by the server as continuations for OAUTHBEARER */ newstate = SASL_OAUTH2_RESP; } else - result = Curl_auth_create_xoauth_bearer_message(data, conn->user, + result = Curl_auth_create_xoauth_bearer_message(conn->user, oauth_bearer, - &resp, &len); + &resp); break; case SASL_OAUTH2_RESP: @@ -642,11 +672,8 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, return result; } else if(code == sasl->params->contcode) { - /* Acknowledge the continuation by sending a 0x01 response base64 - encoded */ - resp = strdup("AQ=="); - if(!resp) - result = CURLE_OUT_OF_MEMORY; + /* Acknowledge the continuation by sending a 0x01 response. */ + Curl_bufref_set(&resp, "\x01", 1, NULL); break; } else { @@ -660,15 +687,15 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, sasl->authmechs ^= sasl->authused; /* Start an alternative SASL authentication */ - result = Curl_sasl_start(sasl, data, conn, sasl->force_ir, progress); - newstate = sasl->state; /* Use state from Curl_sasl_start() */ - break; + return Curl_sasl_start(sasl, data, conn, sasl->force_ir, progress); default: failf(data, "Unsupported SASL authentication mechanism"); result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */ break; } + Curl_bufref_free(&serverdata); + switch(result) { case CURLE_BAD_CONTENT_ENCODING: /* Cancel dialog */ @@ -676,8 +703,10 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, newstate = SASL_CANCEL; break; case CURLE_OK: - if(resp) - result = sasl->params->sendcont(data, conn, resp); + result = build_message(data, &resp); + if(!result) + result = sasl->params->sendcont(data, conn, + (const char *) Curl_bufref_ptr(&resp)); break; default: newstate = SASL_STOP; /* Stop on error */ @@ -685,7 +714,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, break; } - free(resp); + Curl_bufref_free(&resp); state(sasl, data, newstate); diff --git a/libs/libcurl/src/curl_sasl.h b/libs/libcurl/src/curl_sasl.h index 8648c632b6..e17d323eba 100644 --- a/libs/libcurl/src/curl_sasl.h +++ b/libs/libcurl/src/curl_sasl.h @@ -42,7 +42,7 @@ struct connectdata; /* Authentication mechanism values */ #define SASL_AUTH_NONE 0 -#define SASL_AUTH_ANY ~0U +#define SASL_AUTH_ANY 0xffff #define SASL_AUTH_DEFAULT (SASL_AUTH_ANY & ~SASL_MECH_EXTERNAL) /* Authentication mechanism strings */ @@ -108,9 +108,9 @@ struct SASLproto { struct SASL { const struct SASLproto *params; /* Protocol dependent parameters */ saslstate state; /* Current machine state */ - unsigned int authmechs; /* Accepted authentication mechanisms */ - unsigned int prefmech; /* Preferred authentication mechanism */ - unsigned int authused; /* Auth mechanism used for the connection */ + unsigned short authmechs; /* Accepted authentication mechanisms */ + unsigned short prefmech; /* Preferred authentication mechanism */ + unsigned short authused; /* Auth mechanism used for the connection */ bool resetprefs; /* For URL auth option parsing. */ bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */ bool force_ir; /* Protocol always supports initial response */ @@ -126,8 +126,8 @@ struct SASL { void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused); /* Convert a mechanism name to a token */ -unsigned int Curl_sasl_decode_mech(const char *ptr, - size_t maxlen, size_t *len); +unsigned short Curl_sasl_decode_mech(const char *ptr, + size_t maxlen, size_t *len); /* Parse the URL login options */ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index cf1c26a14e..be4a58d4b6 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -247,7 +247,11 @@ * performing this task will result in a synthesized IPv6 address. */ #if defined(__APPLE__) && !defined(USE_ARES) +#include #define USE_RESOLVE_ON_IPS 1 +# if defined(TARGET_OS_OSX) && TARGET_OS_OSX +# define CURL_OSX_CALL_COPYPROXIES 1 +# endif #endif #ifdef USE_LWIPSOCK @@ -517,7 +521,6 @@ # undef HAVE_GETADDRINFO_THREADSAFE # undef HAVE_FREEADDRINFO # undef HAVE_GETADDRINFO -# undef HAVE_GETNAMEINFO # undef ENABLE_IPV6 # endif #endif @@ -715,13 +718,19 @@ int netware_init(void); #endif /* - * Portable symbolic names for Winsock shutdown() mode flags. + * shutdown() flags for systems that don't define them */ -#ifdef USE_WINSOCK -# define SHUT_RD 0x00 -# define SHUT_WR 0x01 -# define SHUT_RDWR 0x02 +#ifndef SHUT_RD +#define SHUT_RD 0x00 +#endif + +#ifndef SHUT_WR +#define SHUT_WR 0x01 +#endif + +#ifndef SHUT_RDWR +#define SHUT_RDWR 0x02 #endif /* Define S_ISREG if not defined by system headers, f.e. MSVC */ @@ -772,9 +781,16 @@ endings either CRLF or LF so 't' is appropriate. # endif #endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */ -/* for systems that don't detect this in configure, use a sensible default */ +/* for systems that don't detect this in configure */ #ifndef CURL_SA_FAMILY_T -#define CURL_SA_FAMILY_T unsigned short +# if defined(HAVE_SA_FAMILY_T) +# define CURL_SA_FAMILY_T sa_family_t +# elif defined(HAVE_ADDRESS_FAMILY) +# define CURL_SA_FAMILY_T ADDRESS_FAMILY +# else +/* use a sensible default */ +# define CURL_SA_FAMILY_T unsigned short +# endif #endif /* Some convenience macros to get the larger/smaller value out of two given. @@ -795,6 +811,10 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, #define UNITTEST static #endif +#if defined(USE_NGHTTP2) || defined(USE_HYPER) +#define USE_HTTP2 +#endif + #if defined(USE_NGTCP2) || defined(USE_QUICHE) #define ENABLE_QUIC #endif diff --git a/libs/libcurl/src/dict.c b/libs/libcurl/src/dict.c index 4319dadba5..625b057774 100644 --- a/libs/libcurl/src/dict.c +++ b/libs/libcurl/src/dict.c @@ -89,6 +89,7 @@ const struct Curl_handler Curl_handler_dict = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_DICT, /* defport */ CURLPROTO_DICT, /* protocol */ CURLPROTO_DICT, /* family */ @@ -214,14 +215,14 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) } } - if((word == NULL) || (*word == (char)0)) { + if(!word || (*word == (char)0)) { infof(data, "lookup word is missing\n"); word = (char *)"default"; } - if((database == NULL) || (*database == (char)0)) { + if(!database || (*database == (char)0)) { database = (char *)"!"; } - if((strategy == NULL) || (*strategy == (char)0)) { + if(!strategy || (*strategy == (char)0)) { strategy = (char *)"."; } @@ -265,11 +266,11 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) } } - if((word == NULL) || (*word == (char)0)) { + if(!word || (*word == (char)0)) { infof(data, "lookup word is missing\n"); word = (char *)"default"; } - if((database == NULL) || (*database == (char)0)) { + if(!database || (*database == (char)0)) { database = (char *)"!"; } diff --git a/libs/libcurl/src/doh.c b/libs/libcurl/src/doh.c index 52388cba3e..36f8cd58dc 100644 --- a/libs/libcurl/src/doh.c +++ b/libs/libcurl/src/doh.c @@ -313,6 +313,10 @@ static CURLcode dohprobe(struct Curl_easy *data, ERROR_CHECK_SETOPT(CURLOPT_CAINFO, data->set.str[STRING_SSL_CAFILE]); } + if(data->set.blobs[BLOB_CAINFO]) { + ERROR_CHECK_SETOPT(CURLOPT_CAINFO_BLOB, + data->set.blobs[BLOB_CAINFO]); + } if(data->set.str[STRING_SSL_CAPATH]) { ERROR_CHECK_SETOPT(CURLOPT_CAPATH, data->set.str[STRING_SSL_CAPATH]); @@ -351,7 +355,10 @@ static CURLcode dohprobe(struct Curl_easy *data, (data->set.ssl.revoke_best_effort ? CURLSSLOPT_REVOKE_BEST_EFFORT : 0) | (data->set.ssl.native_ca_store ? - CURLSSLOPT_NATIVE_CA : 0); + CURLSSLOPT_NATIVE_CA : 0) | + (data->set.ssl.auto_client_cert ? + CURLSSLOPT_AUTO_CLIENT_CERT : 0); + curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask); } @@ -413,17 +420,15 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, if(!dohp->headers) goto error; - if(conn->ip_version != CURL_IPRESOLVE_V6) { - /* create IPv4 DOH request */ - result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V4], - DNS_TYPE_A, hostname, data->set.str[STRING_DOH], - data->multi, dohp->headers); - if(result) - goto error; - dohp->pending++; - } + /* create IPv4 DOH request */ + result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V4], + DNS_TYPE_A, hostname, data->set.str[STRING_DOH], + data->multi, dohp->headers); + if(result) + goto error; + dohp->pending++; - if(conn->ip_version != CURL_IPRESOLVE_V4) { + if(Curl_ipv6works(data)) { /* create IPv6 DOH request */ result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6], DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH], diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c index 4ce1bbf63b..530b7c73f2 100644 --- a/libs/libcurl/src/easy.c +++ b/libs/libcurl/src/easy.c @@ -789,7 +789,6 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) /* duplicate all blobs */ for(j = (enum dupblob)0; j < BLOB_LAST; j++) { result = Curl_setblobopt(&dst->set.blobs[j], src->set.blobs[j]); - /* Curl_setstropt return CURLE_BAD_FUNCTION_ARGUMENT with blob */ if(result) return result; } @@ -895,7 +894,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) (void)Curl_altsvc_load(outcurl->asi, outcurl->set.str[STRING_ALTSVC]); } #endif -#ifdef USE_HSTS +#ifndef CURL_DISABLE_HSTS if(data->hsts) { outcurl->hsts = Curl_hsts_init(); if(!outcurl->hsts) @@ -1105,7 +1104,7 @@ static CURLcode easy_connection(struct Curl_easy *data, curl_socket_t *sfd, struct connectdata **connp) { - if(data == NULL) + if(!data) return CURLE_BAD_FUNCTION_ARGUMENT; /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */ @@ -1171,6 +1170,7 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, CURLcode result; ssize_t n1; struct connectdata *c = NULL; + SIGPIPE_VARIABLE(pipe_st); if(Curl_is_in_callback(data)) return CURLE_RECURSIVE_API_CALL; @@ -1185,7 +1185,9 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, Curl_attach_connnection(data, c); *n = 0; + sigpipe_ignore(data, &pipe_st); result = Curl_write(data, sfd, buffer, buflen, &n1); + sigpipe_restore(&pipe_st); if(n1 == -1) return CURLE_SEND_ERROR; diff --git a/libs/libcurl/src/easyoptions.c b/libs/libcurl/src/easyoptions.c index db8337b044..4e65e3525b 100644 --- a/libs/libcurl/src/easyoptions.c +++ b/libs/libcurl/src/easyoptions.c @@ -38,6 +38,7 @@ struct curl_easyoption Curl_easyopts[] = { {"AWS_SIGV4", CURLOPT_AWS_SIGV4, CURLOT_STRING, 0}, {"BUFFERSIZE", CURLOPT_BUFFERSIZE, CURLOT_LONG, 0}, {"CAINFO", CURLOPT_CAINFO, CURLOT_STRING, 0}, + {"CAINFO_BLOB", CURLOPT_CAINFO_BLOB, CURLOT_BLOB, 0}, {"CAPATH", CURLOPT_CAPATH, CURLOT_STRING, 0}, {"CERTINFO", CURLOPT_CERTINFO, CURLOT_LONG, 0}, {"CHUNK_BGN_FUNCTION", CURLOPT_CHUNK_BGN_FUNCTION, CURLOT_FUNCTION, 0}, @@ -205,6 +206,7 @@ struct curl_easyoption Curl_easyopts[] = { {"PROXYUSERNAME", CURLOPT_PROXYUSERNAME, CURLOT_STRING, 0}, {"PROXYUSERPWD", CURLOPT_PROXYUSERPWD, CURLOT_STRING, 0}, {"PROXY_CAINFO", CURLOPT_PROXY_CAINFO, CURLOT_STRING, 0}, + {"PROXY_CAINFO_BLOB", CURLOPT_PROXY_CAINFO_BLOB, CURLOT_BLOB, 0}, {"PROXY_CAPATH", CURLOPT_PROXY_CAPATH, CURLOT_STRING, 0}, {"PROXY_CRLFILE", CURLOPT_PROXY_CRLFILE, CURLOT_STRING, 0}, {"PROXY_ISSUERCERT", CURLOPT_PROXY_ISSUERCERT, CURLOT_STRING, 0}, @@ -352,6 +354,6 @@ struct curl_easyoption Curl_easyopts[] = { */ int Curl_easyopts_check(void) { - return ((CURLOPT_LASTENTRY%10000) != (308 + 1)); + return ((CURLOPT_LASTENTRY%10000) != (310 + 1)); } #endif diff --git a/libs/libcurl/src/file.c b/libs/libcurl/src/file.c index 1d174e519e..0420db3454 100644 --- a/libs/libcurl/src/file.c +++ b/libs/libcurl/src/file.c @@ -111,6 +111,7 @@ const struct Curl_handler Curl_handler_file = { file_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ 0, /* defport */ CURLPROTO_FILE, /* protocol */ CURLPROTO_FILE, /* family */ @@ -410,16 +411,18 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) struct tm buffer; const struct tm *tm = &buffer; char header[80]; + int headerlen; + char accept_ranges[24]= { "Accept-ranges: bytes\r\n" }; if(expected_size >= 0) { - msnprintf(header, sizeof(header), + headerlen = msnprintf(header, sizeof(header), "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size); - result = Curl_client_write(data, CLIENTWRITE_HEADER, header, 0); + result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen); if(result) return result; result = Curl_client_write(data, CLIENTWRITE_HEADER, - (char *)"Accept-ranges: bytes\r\n", 0); + accept_ranges, strlen(accept_ranges)); if(result != CURLE_OK) return result; } @@ -430,7 +433,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) return result; /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - msnprintf(header, sizeof(header), + headerlen = msnprintf(header, sizeof(header), "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n%s", Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], tm->tm_mday, @@ -440,7 +443,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) tm->tm_min, tm->tm_sec, data->set.opt_no_body ? "": "\r\n"); - result = Curl_client_write(data, CLIENTWRITE_HEADER, header, 0); + result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen); if(result) return result; /* set the file size to make it available post transfer */ diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c index 5bf44f1180..444cf35f55 100644 --- a/libs/libcurl/src/ftp.c +++ b/libs/libcurl/src/ftp.c @@ -175,6 +175,7 @@ const struct Curl_handler Curl_handler_ftp = { ftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_FTP, /* defport */ CURLPROTO_FTP, /* protocol */ CURLPROTO_FTP, /* family */ @@ -205,6 +206,7 @@ const struct Curl_handler Curl_handler_ftps = { ftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_FTPS, /* defport */ CURLPROTO_FTPS, /* protocol */ CURLPROTO_FTP, /* family */ @@ -1090,7 +1092,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, else res = NULL; /* failure! */ - if(res == NULL) { + if(!res) { failf(data, "failed to resolve the address provided to PORT: %s", host); free(addr); return CURLE_FTP_PORT_FAILED; @@ -2098,6 +2100,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, data->set.get_filetime && (data->info.filetime >= 0) ) { char headerbuf[128]; + int headerbuflen; time_t filetime = data->info.filetime; struct tm buffer; const struct tm *tm = &buffer; @@ -2107,7 +2110,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, return result; /* format: "Tue, 15 Nov 1994 12:45:26" */ - msnprintf(headerbuf, sizeof(headerbuf), + headerbuflen = msnprintf(headerbuf, sizeof(headerbuf), "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], tm->tm_mday, @@ -2116,7 +2119,8 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, tm->tm_hour, tm->tm_min, tm->tm_sec); - result = Curl_client_write(data, CLIENTWRITE_BOTH, headerbuf, 0); + result = Curl_client_write(data, CLIENTWRITE_BOTH, headerbuf, + headerbuflen); if(result) return result; } /* end of a ridiculous amount of conditionals */ @@ -2321,9 +2325,9 @@ static CURLcode ftp_state_size_resp(struct Curl_easy *data, #ifdef CURL_FTP_HTTPSTYLE_HEAD if(-1 != filesize) { char clbuf[128]; - msnprintf(clbuf, sizeof(clbuf), + int clbuflen = msnprintf(clbuf, sizeof(clbuf), "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize); - result = Curl_client_write(data, CLIENTWRITE_BOTH, clbuf, 0); + result = Curl_client_write(data, CLIENTWRITE_BOTH, clbuf, clbuflen); if(result) return result; } @@ -2357,7 +2361,8 @@ static CURLcode ftp_state_rest_resp(struct Curl_easy *data, #ifdef CURL_FTP_HTTPSTYLE_HEAD if(ftpcode == 350) { char buffer[24]= { "Accept-ranges: bytes\r\n" }; - result = Curl_client_write(data, CLIENTWRITE_BOTH, buffer, 0); + result = Curl_client_write(data, CLIENTWRITE_BOTH, buffer, + strlen(buffer)); if(result) return result; } diff --git a/libs/libcurl/src/ftplistparser.c b/libs/libcurl/src/ftplistparser.c index 81825e6ff6..716ff38172 100644 --- a/libs/libcurl/src/ftplistparser.c +++ b/libs/libcurl/src/ftplistparser.c @@ -424,7 +424,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, endptr++; while(ISDIGIT(*endptr)) endptr++; - if(*endptr != 0) { + if(*endptr) { parser->error = CURLE_FTP_BAD_FILE_LIST; goto fail; } diff --git a/libs/libcurl/src/gopher.c b/libs/libcurl/src/gopher.c index a39cc7e6b4..f61232ff56 100644 --- a/libs/libcurl/src/gopher.c +++ b/libs/libcurl/src/gopher.c @@ -74,6 +74,7 @@ const struct Curl_handler Curl_handler_gopher = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_GOPHER, /* defport */ CURLPROTO_GOPHER, /* protocol */ CURLPROTO_GOPHER, /* family */ @@ -97,6 +98,7 @@ const struct Curl_handler Curl_handler_gophers = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_GOPHER, /* defport */ CURLPROTO_GOPHERS, /* protocol */ CURLPROTO_GOPHER, /* family */ diff --git a/libs/libcurl/src/hash.c b/libs/libcurl/src/hash.c index 5d433ad1fb..12e7aa5f27 100644 --- a/libs/libcurl/src/hash.c +++ b/libs/libcurl/src/hash.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -245,7 +245,7 @@ Curl_hash_clean_with_criterium(struct Curl_hash *h, void *user, struct Curl_hash_element *he = le->ptr; lnext = le->next; /* ask the callback function if we shall remove this entry or not */ - if(comp == NULL || comp(user, he->ptr)) { + if(!comp || comp(user, he->ptr)) { Curl_llist_remove(list, le, (void *) h); --h->size; /* one less entry in the hash now */ } diff --git a/libs/libcurl/src/hostcheck.c b/libs/libcurl/src/hostcheck.c index 0fef98b2ad..49dbab3472 100644 --- a/libs/libcurl/src/hostcheck.c +++ b/libs/libcurl/src/hostcheck.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -81,7 +81,7 @@ static int hostmatch(char *hostname, char *pattern) pattern[len-1] = 0; pattern_wildcard = strchr(pattern, '*'); - if(pattern_wildcard == NULL) + if(!pattern_wildcard) return strcasecompare(pattern, hostname) ? CURL_HOST_MATCH : CURL_HOST_NOMATCH; @@ -97,7 +97,7 @@ static int hostmatch(char *hostname, char *pattern) match. */ wildcard_enabled = 1; pattern_label_end = strchr(pattern, '.'); - if(pattern_label_end == NULL || strchr(pattern_label_end + 1, '.') == NULL || + if(!pattern_label_end || strchr(pattern_label_end + 1, '.') == NULL || pattern_wildcard > pattern_label_end || strncasecompare(pattern, "xn--", 4)) { wildcard_enabled = 0; @@ -107,7 +107,7 @@ static int hostmatch(char *hostname, char *pattern) CURL_HOST_MATCH : CURL_HOST_NOMATCH; hostname_label_end = strchr(hostname, '.'); - if(hostname_label_end == NULL || + if(!hostname_label_end || !strcasecompare(pattern_label_end, hostname_label_end)) return CURL_HOST_NOMATCH; diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c index 05c09f6835..e0e3cfc2cb 100644 --- a/libs/libcurl/src/hostip.c +++ b/libs/libcurl/src/hostip.c @@ -68,6 +68,10 @@ #include "curl_memory.h" #include "memdebug.h" +#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES) +#include +#endif + #if defined(CURLRES_SYNCH) && \ defined(HAVE_ALARM) && defined(SIGALRM) && defined(HAVE_SIGSETJMP) /* alarm-based timeouts can only be used with all the dependencies satisfied */ @@ -466,10 +470,6 @@ Curl_cache_addr(struct Curl_easy *data, * function is used. You MUST call Curl_resolv_unlock() later (when you're * done using this struct) to decrease the counter again. * - * In debug mode, we specifically test for an interface name "LocalHost" - * and resolve "localhost" instead as a means to permit test cases - * to connect to a local test server with any host name. - * * Return codes: * * CURLRESOLV_ERROR (-1) = error, no pointer @@ -533,6 +533,19 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, return CURLRESOLV_ERROR; } +#if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES) + /* + * The automagic conversion from IPv4 literals to IPv6 literals only works + * if the SCDynamicStoreCopyProxies system function gets called first. As + * Curl currently doesn't support system-wide HTTP proxies, we therefore + * don't use any value this function might return. + * + * This function is only available on a macOS and is not needed for + * IPv4-only builds, hence the conditions above. + */ + SCDynamicStoreCopyProxies(NULL); +#endif + #ifndef USE_RESOLVE_ON_IPS /* First check if this is an IPv4 address string */ if(Curl_inet_pton(AF_INET, hostname, &in) > 0) @@ -578,13 +591,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a non-zero value indicating that we need to wait for the response to the resolve call */ - addr = Curl_getaddrinfo(data, -#ifdef DEBUGBUILD - (data->set.str[STRING_DEVICE] - && !strcmp(data->set.str[STRING_DEVICE], - "LocalHost"))?"localhost": -#endif - hostname, port, &respwait); + addr = Curl_getaddrinfo(data, hostname, port, &respwait); } } if(!addr) { diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h index c0fd3c8c46..d178976aa1 100644 --- a/libs/libcurl/src/hostip.h +++ b/libs/libcurl/src/hostip.h @@ -136,15 +136,6 @@ void Curl_hostcache_prune(struct Curl_easy *data); /* Return # of addresses in a Curl_addrinfo struct */ int Curl_num_addresses(const struct Curl_addrinfo *addr); -#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) -int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa, - GETNAMEINFO_TYPE_ARG2 salen, - char *host, GETNAMEINFO_TYPE_ARG46 hostlen, - char *serv, GETNAMEINFO_TYPE_ARG46 servlen, - GETNAMEINFO_TYPE_ARG7 flags, - int line, const char *source); -#endif - /* IPv4 threadsafe resolve function used for synch and asynch builds */ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port); diff --git a/libs/libcurl/src/hostip6.c b/libs/libcurl/src/hostip6.c index 53b3c67223..9791d86468 100644 --- a/libs/libcurl/src/hostip6.c +++ b/libs/libcurl/src/hostip6.c @@ -140,26 +140,13 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, #ifndef USE_RESOLVE_ON_IPS char addrbuf[128]; #endif - int pf; + int pf = PF_INET; *waitp = 0; /* synchronous response only */ - /* Check if a limited name resolve has been requested */ - switch(data->set.ipver) { - case CURL_IPRESOLVE_V4: - pf = PF_INET; - break; - case CURL_IPRESOLVE_V6: - pf = PF_INET6; - break; - default: + if(Curl_ipv6works(data)) + /* The stack seems to be IPv6-enabled */ pf = PF_UNSPEC; - break; - } - - if((pf != PF_INET) && !Curl_ipv6works(data)) - /* The stack seems to be a non-IPv6 one */ - pf = PF_INET; memset(&hints, 0, sizeof(hints)); hints.ai_family = pf; diff --git a/libs/libcurl/src/hsts.c b/libs/libcurl/src/hsts.c index fd4926f36b..ef166f196c 100644 --- a/libs/libcurl/src/hsts.c +++ b/libs/libcurl/src/hsts.c @@ -25,7 +25,7 @@ */ #include "curl_setup.h" -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HSTS) +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HSTS) #include #include "urldata.h" #include "llist.h" @@ -37,6 +37,7 @@ #include "parsedate.h" #include "rand.h" #include "rename.h" +#include "strtoofft.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -58,7 +59,10 @@ static time_t debugtime(void *unused) char *timestr = getenv("CURL_TIME"); (void)unused; if(timestr) { - unsigned long val = strtol(timestr, NULL, 10) + deltatime; + curl_off_t val; + (void)curlx_strtoofft(timestr, NULL, 10, &val); + + val += (curl_off_t)deltatime; return (time_t)val; } return time(NULL); @@ -274,7 +278,7 @@ static CURLcode hsts_push(struct Curl_easy *data, e.namelen = strlen(sts->host); e.includeSubDomains = sts->includeSubDomains; - result = Curl_gmtime(sts->expires, &stamp); + result = Curl_gmtime((time_t)sts->expires, &stamp); if(result) return result; @@ -294,7 +298,7 @@ static CURLcode hsts_push(struct Curl_easy *data, static CURLcode hsts_out(struct stsentry *sts, FILE *fp) { struct tm stamp; - CURLcode result = Curl_gmtime(sts->expires, &stamp); + CURLcode result = Curl_gmtime((time_t)sts->expires, &stamp); if(result) return result; @@ -439,7 +443,10 @@ static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h) expires = Curl_getdate_capped(e.expire); else expires = TIME_T_MAX; /* the end of time */ - result = hsts_create(h, e.name, e.includeSubDomains, expires); + result = hsts_create(h, e.name, + /* bitfield to bool conversion: */ + e.includeSubDomains ? TRUE : FALSE, + expires); if(result) return result; } @@ -517,4 +524,4 @@ CURLcode Curl_hsts_loadcb(struct Curl_easy *data, struct hsts *h) return hsts_pull(data, h); } -#endif /* CURL_DISABLE_HTTP || USE_HSTS */ +#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */ diff --git a/libs/libcurl/src/hsts.h b/libs/libcurl/src/hsts.h index ae5db74a24..baa582864a 100644 --- a/libs/libcurl/src/hsts.h +++ b/libs/libcurl/src/hsts.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2020, Daniel Stenberg, , et al. + * Copyright (C) 2020 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -23,7 +23,7 @@ ***************************************************************************/ #include "curl_setup.h" -#if !defined(CURL_DISABLE_HTTP) && defined(USE_HSTS) +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HSTS) #include #include "llist.h" @@ -35,7 +35,7 @@ struct stsentry { struct Curl_llist_element node; const char *host; bool includeSubDomains; - time_t expires; /* the timestamp of this entry's expiry */ + curl_off_t expires; /* the timestamp of this entry's expiry */ }; /* The HSTS cache. Needs to be able to tailmatch host names. */ @@ -61,5 +61,5 @@ CURLcode Curl_hsts_loadcb(struct Curl_easy *data, #define Curl_hsts_cleanup(x) #define Curl_hsts_loadcb(x,y) #define Curl_hsts_save(x,y,z) -#endif /* CURL_DISABLE_HTTP || USE_HSTS */ +#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_HSTS */ #endif /* HEADER_CURL_HSTS_H */ diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c index 02c81c419b..628dd73703 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.c @@ -133,6 +133,7 @@ const struct Curl_handler Curl_handler_http = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_HTTP, /* defport */ CURLPROTO_HTTP, /* protocol */ CURLPROTO_HTTP, /* family */ @@ -160,6 +161,7 @@ const struct Curl_handler Curl_handler_https = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_HTTPS, /* defport */ CURLPROTO_HTTPS, /* protocol */ CURLPROTO_HTTP, /* family */ @@ -740,7 +742,7 @@ output_auth_headers(struct Curl_easy *data, if(authstatus->picked == CURLAUTH_BEARER) { /* Bearer */ if((!proxy && data->set.str[STRING_BEARER] && - !Curl_checkheaders(data, "Authorization:"))) { + !Curl_checkheaders(data, "Authorization"))) { auth = "Bearer"; result = http_output_bearer(data); if(result) @@ -897,6 +899,11 @@ Curl_http_output_auth(struct Curl_easy *data, * proxy CONNECT loop. */ +static int is_valid_auth_separator(char ch) +{ + return ch == '\0' || ch == ',' || ISSPACE(ch); +} + CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, const char *auth) /* the first non-space */ { @@ -940,7 +947,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, while(*auth) { #ifdef USE_SPNEGO - if(checkprefix("Negotiate", auth)) { + if(checkprefix("Negotiate", auth) && is_valid_auth_separator(auth[9])) { if((authp->avail & CURLAUTH_NEGOTIATE) || Curl_auth_is_spnego_supported()) { *availp |= CURLAUTH_NEGOTIATE; @@ -966,7 +973,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, #endif #ifdef USE_NTLM /* NTLM support requires the SSL crypto libs */ - if(checkprefix("NTLM", auth)) { + if(checkprefix("NTLM", auth) && is_valid_auth_separator(auth[4])) { if((authp->avail & CURLAUTH_NTLM) || (authp->avail & CURLAUTH_NTLM_WB) || Curl_auth_is_ntlm_supported()) { @@ -1004,7 +1011,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, else #endif #ifndef CURL_DISABLE_CRYPTO_AUTH - if(checkprefix("Digest", auth)) { + if(checkprefix("Digest", auth) && is_valid_auth_separator(auth[6])) { if((authp->avail & CURLAUTH_DIGEST) != 0) infof(data, "Ignoring duplicate digest auth header.\n"); else if(Curl_auth_is_digest_supported()) { @@ -1026,7 +1033,8 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, } else #endif - if(checkprefix("Basic", auth)) { + if(checkprefix("Basic", auth) && + is_valid_auth_separator(auth[5])) { *availp |= CURLAUTH_BASIC; authp->avail |= CURLAUTH_BASIC; if(authp->picked == CURLAUTH_BASIC) { @@ -1039,7 +1047,8 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, } } else - if(checkprefix("Bearer", auth)) { + if(checkprefix("Bearer", auth) && + is_valid_auth_separator(auth[6])) { *availp |= CURLAUTH_BEARER; authp->avail |= CURLAUTH_BEARER; if(authp->picked == CURLAUTH_BEARER) { @@ -1266,14 +1275,6 @@ CURLcode Curl_buffer_send(struct dynbuf *in, else sendsize = size; - /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk - when we speak HTTPS, as if only a fraction of it is sent now, this data - needs to fit into the normal read-callback buffer later on and that - buffer is using this size. - */ - if(sendsize > CURL_MAX_WRITE_SIZE) - sendsize = CURL_MAX_WRITE_SIZE; - /* OpenSSL is very picky and we must send the SAME buffer pointer to the library when we attempt to re-send this buffer. Sending the same data is not enough, we must use the exact same address. For this reason, we @@ -1286,6 +1287,14 @@ CURLcode Curl_buffer_send(struct dynbuf *in, Curl_dyn_free(in); return result; } + /* We never send more than upload_buffer_size bytes in one single chunk + when we speak HTTPS, as if only a fraction of it is sent now, this data + needs to fit into the normal read-callback buffer later on and that + buffer is using this size. + */ + if(sendsize > (size_t)data->set.upload_buffer_size) + sendsize = (size_t)data->set.upload_buffer_size; + memcpy(data->state.ulbuf, ptr, sendsize); ptr = data->state.ulbuf; } @@ -3113,6 +3122,10 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) /* initialize a dynamic send-buffer */ Curl_dyn_init(&req, DYN_HTTP_REQUEST); + /* make sure the header buffer is reset - if there are leftovers from a + previous transfer */ + Curl_dyn_reset(&data->state.headerb); + /* add the main request stuff */ /* GET/HEAD/POST/PUT */ result = Curl_dyn_addf(&req, "%s ", request); @@ -3375,7 +3388,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, if(!k->http_bodyless && !data->set.ignorecl && checkprefix("Content-Length:", headp)) { curl_off_t contentlength; - CURLofft offt = curlx_strtoofft(headp + 15, NULL, 10, &contentlength); + CURLofft offt = curlx_strtoofft(headp + strlen("Content-Length:"), + NULL, 10, &contentlength); if(offt == CURL_OFFT_OK) { if(data->set.max_filesize && @@ -3474,7 +3488,9 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, * of chunks, and a chunk-data set to zero signals the * end-of-chunks. */ - result = Curl_build_unencoding_stack(data, headp + 18, TRUE); + result = Curl_build_unencoding_stack(data, + headp + strlen("Transfer-Encoding:"), + TRUE); if(result) return result; } @@ -3487,17 +3503,20 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, * 2616). zlib cannot handle compress. However, errors are * handled further down when the response body is processed */ - result = Curl_build_unencoding_stack(data, headp + 17, FALSE); + result = Curl_build_unencoding_stack(data, + headp + strlen("Content-Encoding:"), + FALSE); if(result) return result; } else if(checkprefix("Retry-After:", headp)) { /* Retry-After = HTTP-date / delay-seconds */ curl_off_t retry_after = 0; /* zero for unknown or "now" */ - time_t date = Curl_getdate_capped(&headp[12]); + time_t date = Curl_getdate_capped(headp + strlen("Retry-After:")); if(-1 == date) { /* not a date, try it as a decimal number */ - (void)curlx_strtoofft(&headp[12], NULL, 10, &retry_after); + (void)curlx_strtoofft(headp + strlen("Retry-After:"), + NULL, 10, &retry_after); } else /* convert date to number of seconds into the future */ @@ -3516,7 +3535,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, The forth means the requested range was unsatisfied. */ - char *ptr = headp + 14; + char *ptr = headp + strlen("Content-Range:"); /* Move forward until first digit or asterisk */ while(*ptr && !ISDIGIT(*ptr) && *ptr != '*') @@ -3539,7 +3558,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); Curl_cookie_add(data, - data->cookies, TRUE, FALSE, headp + 11, + data->cookies, TRUE, FALSE, + headp + strlen("Set-Cookie:"), /* If there is a custom-set Host: name, use it here, or else use real peer host name. */ data->state.aptr.cookiehost? @@ -3574,7 +3594,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, return result; } #ifdef USE_SPNEGO - else if(checkprefix("Persistent-Auth", headp)) { + else if(checkprefix("Persistent-Auth:", headp)) { struct negotiatedata *negdata = &conn->negotiate; struct auth *authp = &data->state.authhost; if(authp->picked == CURLAUTH_NEGOTIATE) { @@ -3618,13 +3638,13 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, } } -#ifdef USE_HSTS +#ifndef CURL_DISABLE_HSTS /* If enabled, the header is incoming and this is over HTTPS */ else if(data->hsts && checkprefix("Strict-Transport-Security:", headp) && (conn->handler->flags & PROTOPT_SSL)) { CURLcode check = Curl_hsts_parse(data->hsts, data->state.up.hostname, - &headp[ sizeof("Strict-Transport-Security:") -1 ]); + headp + strlen("Strict-Transport-Security:")); if(check) infof(data, "Illegal STS header skipped\n"); #ifdef DEBUGBUILD @@ -3648,7 +3668,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, /* the ALPN of the current request */ enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1; result = Curl_altsvc_parse(data, data->asi, - &headp[ strlen("Alt-Svc:") ], + headp + strlen("Alt-Svc:"), id, conn->host.name, curlx_uitous(conn->remote_port)); if(result) diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h index 36e2152fe3..2a3834ae11 100644 --- a/libs/libcurl/src/http.h +++ b/libs/libcurl/src/http.h @@ -184,8 +184,7 @@ struct HTTP { enum { HTTPSEND_NADA, /* init */ HTTPSEND_REQUEST, /* sending a request */ - HTTPSEND_BODY, /* sending body */ - HTTPSEND_LAST /* never use this */ + HTTPSEND_BODY /* sending body */ } sending; #ifndef CURL_DISABLE_HTTP @@ -211,6 +210,7 @@ struct HTTP { char **push_headers; /* allocated array */ size_t push_headers_used; /* number of entries filled in */ size_t push_headers_alloc; /* number of entries allocated */ + uint32_t error; /* HTTP/2 stream error code */ #endif #if defined(USE_NGHTTP2) || defined(USE_NGHTTP3) bool closed; /* TRUE on HTTP2 stream close */ @@ -281,7 +281,6 @@ struct http_conn { /* list of settings that will be sent */ nghttp2_settings_entry local_settings[3]; size_t local_settings_num; - uint32_t error_code; /* HTTP/2 error code */ #else int unused; /* prevent a compiler warning */ #endif diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index ce9a0d393c..f194c18b23 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -288,6 +288,7 @@ void Curl_http2_setup_req(struct Curl_easy *data) http->mem = NULL; http->len = 0; http->memlen = 0; + http->error = NGHTTP2_NO_ERROR; } /* called from http_setup_conn */ @@ -295,7 +296,6 @@ void Curl_http2_setup_conn(struct connectdata *conn) { conn->proto.httpc.settings.max_concurrent_streams = DEFAULT_MAX_CONCURRENT_STREAMS; - conn->proto.httpc.error_code = NGHTTP2_NO_ERROR; } /* @@ -319,6 +319,7 @@ static const struct Curl_handler Curl_handler_http2 = { http2_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ http2_conncheck, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_HTTP, /* defport */ CURLPROTO_HTTP, /* protocol */ CURLPROTO_HTTP, /* family */ @@ -341,6 +342,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = { http2_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ http2_conncheck, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_HTTP, /* defport */ CURLPROTO_HTTPS, /* protocol */ CURLPROTO_HTTP, /* family */ @@ -499,33 +501,43 @@ static int set_transfer_url(struct Curl_easy *data, const char *v; CURLU *u = curl_url(); CURLUcode uc; - char *url; + char *url = NULL; + int rc = 0; v = curl_pushheader_byname(hp, ":scheme"); if(v) { uc = curl_url_set(u, CURLUPART_SCHEME, v, 0); - if(uc) - return 1; + if(uc) { + rc = 1; + goto fail; + } } v = curl_pushheader_byname(hp, ":authority"); if(v) { uc = curl_url_set(u, CURLUPART_HOST, v, 0); - if(uc) - return 2; + if(uc) { + rc = 2; + goto fail; + } } v = curl_pushheader_byname(hp, ":path"); if(v) { uc = curl_url_set(u, CURLUPART_PATH, v, 0); - if(uc) - return 3; + if(uc) { + rc = 3; + goto fail; + } } uc = curl_url_get(u, CURLUPART_URL, &url, 0); if(uc) - return 4; + rc = 4; + fail: curl_url_cleanup(u); + if(rc) + return rc; if(data->state.url_alloc) free(data->state.url); @@ -571,6 +583,7 @@ static int push_promise(struct Curl_easy *data, rv = set_transfer_url(newhandle, &heads); if(rv) { + (void)Curl_close(&newhandle); rv = CURL_PUSH_DENY; goto fail; } @@ -877,7 +890,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, httpc = &conn->proto.httpc; drain_this(data_s, httpc); Curl_expire(data_s, 0, EXPIRE_RUN_NOW); - httpc->error_code = error_code; + stream->error = error_code; /* remove the entry from the hash as the stream is now gone */ rv = nghttp2_session_set_stream_user_data(session, stream_id, 0); @@ -1242,7 +1255,7 @@ static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn) nghttp2_session_callbacks *callbacks; conn->proto.httpc.inbuf = malloc(H2_BUFSIZE); - if(conn->proto.httpc.inbuf == NULL) + if(!conn->proto.httpc.inbuf) return CURLE_OUT_OF_MEMORY; rc = nghttp2_session_callbacks_new(&callbacks); @@ -1383,7 +1396,7 @@ static int h2_process_pending_input(struct Curl_easy *data, } rv = h2_session_send(data, httpc->h2); - if(rv != 0) { + if(rv) { *err = CURLE_SEND_ERROR; return -1; } @@ -1397,9 +1410,10 @@ static int h2_process_pending_input(struct Curl_easy *data, } if(should_close_session(httpc)) { + struct HTTP *stream = data->req.p.http; H2BUGF(infof(data, "h2_process_pending_input: nothing to do in this session\n")); - if(httpc->error_code) + if(stream->error) *err = CURLE_HTTP2; else { /* not an error per se, but should still close the connection */ @@ -1422,9 +1436,7 @@ CURLcode Curl_http2_done_sending(struct Curl_easy *data, if((conn->handler == &Curl_handler_http2_ssl) || (conn->handler == &Curl_handler_http2)) { /* make sure this is only attempted for HTTP/2 transfers */ - struct HTTP *stream = data->req.p.http; - struct http_conn *httpc = &conn->proto.httpc; nghttp2_session *h2 = httpc->h2; @@ -1448,7 +1460,7 @@ CURLcode Curl_http2_done_sending(struct Curl_easy *data, /* and attempt to send the pending frames */ rv = h2_session_send(data, h2); - if(rv != 0) + if(rv) result = CURLE_SEND_ERROR; if(nghttp2_session_want_write(h2)) { @@ -1482,7 +1494,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn, /* Reset to FALSE to prevent infinite loop in readwrite_data function. */ stream->closed = FALSE; - if(httpc->error_code == NGHTTP2_REFUSED_STREAM) { + if(stream->error == NGHTTP2_REFUSED_STREAM) { H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!\n", stream->stream_id)); connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */ @@ -1490,10 +1502,10 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn, *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */ return -1; } - else if(httpc->error_code != NGHTTP2_NO_ERROR) { + else if(stream->error != NGHTTP2_NO_ERROR) { failf(data, "HTTP/2 stream %d was not closed cleanly: %s (err %u)", - stream->stream_id, nghttp2_http2_strerror(httpc->error_code), - httpc->error_code); + stream->stream_id, nghttp2_http2_strerror(stream->error), + stream->error); *err = CURLE_HTTP2_STREAM; return -1; } @@ -1609,6 +1621,10 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, return -1; } + if(stream->closed) + /* closed overrides paused */ + return http2_handle_stream_close(conn, data, stream, err); + /* Nullify here because we call nghttp2_session_send() and they might refer to the old buffer. */ stream->upload_mem = NULL; @@ -1760,7 +1776,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, nread)); } - if(h2_process_pending_input(data, httpc, err) != 0) + if(h2_process_pending_input(data, httpc, err)) return -1; } if(stream->memlen) { @@ -1785,7 +1801,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, return retlen; } if(stream->closed) - return 0; + return http2_handle_stream_close(conn, data, stream, err); *err = CURLE_AGAIN; H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n", stream->stream_id)); @@ -1960,7 +1976,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, more space. */ nheader += 1; nva = malloc(sizeof(nghttp2_nv) * nheader); - if(nva == NULL) { + if(!nva) { *err = CURLE_OUT_OF_MEMORY; return -1; } @@ -2083,7 +2099,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, } /* :authority must come before non-pseudo header fields */ - if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { + if(authority_idx && authority_idx != AUTHORITY_DST_IDX) { nghttp2_nv authority = nva[authority_idx]; for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { nva[i] = nva[i - 1]; @@ -2153,7 +2169,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, stream->stream_id = stream_id; rv = h2_session_send(data, h2); - if(rv != 0) { + if(rv) { H2BUGF(infof(data, "http2_send() nghttp2_session_send error (%s)%d\n", nghttp2_strerror(rv), rv)); @@ -2259,10 +2275,10 @@ CURLcode Curl_http2_switched(struct Curl_easy *data, /* stream 1 is opened implicitly on upgrade */ stream->stream_id = 1; /* queue SETTINGS frame (again) */ - rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings, - httpc->binlen, NULL); - if(rv != 0) { - failf(data, "nghttp2_session_upgrade() failed: %s(%d)", + rv = nghttp2_session_upgrade2(httpc->h2, httpc->binsettings, httpc->binlen, + data->state.httpreq == HTTPREQ_HEAD, NULL); + if(rv) { + failf(data, "nghttp2_session_upgrade2() failed: %s(%d)", nghttp2_strerror(rv), rv); return CURLE_HTTP2; } @@ -2284,7 +2300,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data, rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, httpc->local_settings, httpc->local_settings_num); - if(rv != 0) { + if(rv) { failf(data, "nghttp2_submit_settings() failed: %s(%d)", nghttp2_strerror(rv), rv); return CURLE_HTTP2; @@ -2293,7 +2309,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data, rv = nghttp2_session_set_local_window_size(httpc->h2, NGHTTP2_FLAG_NONE, 0, HTTP2_HUGE_WINDOW_SIZE); - if(rv != 0) { + if(rv) { failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)", nghttp2_strerror(rv), rv); return CURLE_HTTP2; @@ -2321,8 +2337,15 @@ CURLcode Curl_http2_switched(struct Curl_easy *data, DEBUGASSERT(httpc->nread_inbuf == 0); - if(-1 == h2_process_pending_input(data, httpc, &result)) - return CURLE_HTTP2; + /* Good enough to call it an end once the remaining payload is copied to the + * connection buffer. + * Some servers (e.g. nghttpx v1.43.0) may fulfill stream 1 immediately + * following the protocol switch other than waiting for the client-side + * connection preface. If h2_process_pending_input is invoked here to parse + * the remaining payload, stream 1 would be marked as closed too early and + * thus ignored in http2_recv (following 252790c53). + * The logic in lib/http.c and lib/transfer.c guarantees a following + * http2_recv would be invoked very soon. */ return CURLE_OK; } @@ -2332,7 +2355,8 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause) DEBUGASSERT(data); DEBUGASSERT(data->conn); /* if it isn't HTTP/2, we're done */ - if(!data->conn->proto.httpc.h2) + if(!(data->conn->handler->protocol & PROTO_FAMILY_HTTP) || + !data->conn->proto.httpc.h2) return CURLE_OK; #ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE else { @@ -2456,10 +2480,10 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data) /* Only call this function for a transfer that already got a HTTP/2 CURLE_HTTP2_STREAM error! */ -bool Curl_h2_http_1_1_error(struct connectdata *conn) +bool Curl_h2_http_1_1_error(struct Curl_easy *data) { - struct http_conn *httpc = &conn->proto.httpc; - return (httpc->error_code == NGHTTP2_HTTP_1_1_REQUIRED); + struct HTTP *stream = data->req.p.http; + return (stream->error == NGHTTP2_HTTP_1_1_REQUIRED); } #else /* !USE_NGHTTP2 */ diff --git a/libs/libcurl/src/http2.h b/libs/libcurl/src/http2.h index 114b382718..21e2c086a3 100644 --- a/libs/libcurl/src/http2.h +++ b/libs/libcurl/src/http2.h @@ -62,7 +62,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data); CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause); /* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */ -bool Curl_h2_http_1_1_error(struct connectdata *conn); +bool Curl_h2_http_1_1_error(struct Curl_easy *data); #else /* USE_NGHTTP2 */ #define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_setup(x,y) CURLE_UNSUPPORTED_PROTOCOL diff --git a/libs/libcurl/src/http_digest.c b/libs/libcurl/src/http_digest.c index 132f3930c8..049b232e01 100644 --- a/libs/libcurl/src/http_digest.c +++ b/libs/libcurl/src/http_digest.c @@ -56,7 +56,7 @@ CURLcode Curl_input_digest(struct Curl_easy *data, digest = &data->state.digest; } - if(!checkprefix("Digest", header)) + if(!checkprefix("Digest", header) || !ISSPACE(header[6])) return CURLE_BAD_CONTENT_ENCODING; header += strlen("Digest"); diff --git a/libs/libcurl/src/http_negotiate.c b/libs/libcurl/src/http_negotiate.c index d759748f2e..68cce1bbb2 100644 --- a/libs/libcurl/src/http_negotiate.c +++ b/libs/libcurl/src/http_negotiate.c @@ -179,7 +179,7 @@ CURLcode Curl_output_negotiate(struct Curl_easy *data, free(base64); - if(userp == NULL) { + if(!userp) { return CURLE_OUT_OF_MEMORY; } diff --git a/libs/libcurl/src/http_ntlm.c b/libs/libcurl/src/http_ntlm.c index 4fa38f0b09..e200fdb1da 100644 --- a/libs/libcurl/src/http_ntlm.c +++ b/libs/libcurl/src/http_ntlm.c @@ -39,6 +39,7 @@ #include "http_ntlm.h" #include "curl_ntlm_core.h" #include "curl_ntlm_wb.h" +#include "curl_base64.h" #include "vauth/vauth.h" #include "url.h" @@ -80,7 +81,18 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data, header++; if(*header) { - result = Curl_auth_decode_ntlm_type2_message(data, header, ntlm); + unsigned char *hdr; + size_t hdrlen; + + result = Curl_base64_decode(header, &hdr, &hdrlen); + if(!result) { + struct bufref hdrbuf; + + Curl_bufref_init(&hdrbuf); + Curl_bufref_set(&hdrbuf, hdr, hdrlen, curl_free); + result = Curl_auth_decode_ntlm_type2_message(data, &hdrbuf, ntlm); + Curl_bufref_free(&hdrbuf); + } if(result) return result; @@ -116,7 +128,8 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) { char *base64 = NULL; size_t len = 0; - CURLcode result; + CURLcode result = CURLE_OK; + struct bufref ntlmmsg; /* point to the address of the pointer that holds the string to send to the server, which is for a plain host or for a HTTP proxy */ @@ -173,10 +186,10 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) passwdp = ""; #ifdef USE_WINDOWS_SSPI - if(s_hSecDll == NULL) { + if(!s_hSecDll) { /* not thread safe and leaks - use curl_global_init() to avoid */ CURLcode err = Curl_sspi_global_init(); - if(s_hSecDll == NULL) + if(!s_hSecDll) return err; } #ifdef SECPKG_ATTR_ENDPOINT_BINDINGS @@ -184,50 +197,52 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) #endif #endif + Curl_bufref_init(&ntlmmsg); switch(*state) { case NTLMSTATE_TYPE1: default: /* for the weird cases we (re)start here */ /* Create a type-1 message */ result = Curl_auth_create_ntlm_type1_message(data, userp, passwdp, service, hostname, - ntlm, &base64, - &len); - if(result) - return result; - - if(base64) { - free(*allocuserpwd); - *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", - proxy ? "Proxy-" : "", - base64); - free(base64); - if(!*allocuserpwd) - return CURLE_OUT_OF_MEMORY; - - DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); + ntlm, &ntlmmsg); + if(!result) { + DEBUGASSERT(Curl_bufref_len(&ntlmmsg) != 0); + result = Curl_base64_encode(data, + (const char *) Curl_bufref_ptr(&ntlmmsg), + Curl_bufref_len(&ntlmmsg), &base64, &len); + if(!result) { + free(*allocuserpwd); + *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", + proxy ? "Proxy-" : "", + base64); + free(base64); + if(!*allocuserpwd) + result = CURLE_OUT_OF_MEMORY; + } } break; case NTLMSTATE_TYPE2: /* We already received the type-2 message, create a type-3 message */ result = Curl_auth_create_ntlm_type3_message(data, userp, passwdp, - ntlm, &base64, &len); - if(result) - return result; - - if(base64) { - free(*allocuserpwd); - *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", - proxy ? "Proxy-" : "", - base64); - free(base64); - if(!*allocuserpwd) - return CURLE_OUT_OF_MEMORY; - - DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); - - *state = NTLMSTATE_TYPE3; /* we send a type-3 */ - authp->done = TRUE; + ntlm, &ntlmmsg); + if(!result && Curl_bufref_len(&ntlmmsg)) { + result = Curl_base64_encode(data, + (const char *) Curl_bufref_ptr(&ntlmmsg), + Curl_bufref_len(&ntlmmsg), &base64, &len); + if(!result) { + free(*allocuserpwd); + *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", + proxy ? "Proxy-" : "", + base64); + free(base64); + if(!*allocuserpwd) + result = CURLE_OUT_OF_MEMORY; + else { + *state = NTLMSTATE_TYPE3; /* we send a type-3 */ + authp->done = TRUE; + } + } } break; @@ -241,8 +256,9 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) authp->done = TRUE; break; } + Curl_bufref_free(&ntlmmsg); - return CURLE_OK; + return result; } void Curl_http_auth_cleanup_ntlm(struct connectdata *conn) diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c index f403ffc0e0..a3a62c1cad 100644 --- a/libs/libcurl/src/http_proxy.c +++ b/libs/libcurl/src/http_proxy.c @@ -39,6 +39,8 @@ #include "connect.h" #include "curlx.h" #include "vtls/vtls.h" +#include "transfer.h" +#include "multiif.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -88,29 +90,12 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex) if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { #ifndef CURL_DISABLE_PROXY /* for [protocol] tunneled through HTTP proxy */ - struct HTTP http_proxy; - void *prot_save; const char *hostname; int remote_port; CURLcode result; - /* BLOCKING */ /* We want "seamless" operations through HTTP proxy tunnel */ - /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the - * member conn->proto.http; we want [protocol] through HTTP and we have - * to change the member temporarily for connecting to the HTTP - * proxy. After Curl_proxyCONNECT we have to set back the member to the - * original pointer - * - * This function might be called several times in the multi interface case - * if the proxy's CONNECT response is not instant. - */ - prot_save = data->req.p.http; - memset(&http_proxy, 0, sizeof(http_proxy)); - data->req.p.http = &http_proxy; - connkeep(conn, "HTTP proxy CONNECT"); - /* for the secondary socket (FTP), use the "connect to host" * but ignore the "connect to port" (use the secondary port) */ @@ -128,8 +113,8 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex) remote_port = conn->conn_to_port; else remote_port = conn->remote_port; + result = Curl_proxyCONNECT(data, sockindex, hostname, remote_port); - data->req.p.http = prot_save; if(CURLE_OK != result) return result; Curl_safefree(data->state.aptr.proxyuserpwd); @@ -153,18 +138,53 @@ bool Curl_connect_ongoing(struct connectdata *conn) (conn->connect_state->tunnel_state != TUNNEL_COMPLETE); } +/* when we've sent a CONNECT to a proxy, we should rather either wait for the + socket to become readable to be able to get the response headers or if + we're still sending the request, wait for write. */ +int Curl_connect_getsock(struct connectdata *conn) +{ + struct HTTP *http; + DEBUGASSERT(conn); + DEBUGASSERT(conn->connect_state); + http = &conn->connect_state->http_proxy; + + if(http->sending) + return GETSOCK_WRITESOCK(0); + + return GETSOCK_READSOCK(0); +} + static CURLcode connect_init(struct Curl_easy *data, bool reinit) { struct http_connect_state *s; struct connectdata *conn = data->conn; if(!reinit) { + CURLcode result; DEBUGASSERT(!conn->connect_state); + /* we might need the upload buffer for streaming a partial request */ + result = Curl_get_upload_buffer(data); + if(result) + return result; + s = calloc(1, sizeof(struct http_connect_state)); if(!s) return CURLE_OUT_OF_MEMORY; infof(data, "allocate connect buffer!\n"); conn->connect_state = s; Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS); + + /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the + * member conn->proto.http; we want [protocol] through HTTP and we have + * to change the member temporarily for connecting to the HTTP + * proxy. After Curl_proxyCONNECT we have to set back the member to the + * original pointer + * + * This function might be called several times in the multi interface case + * if the proxy's CONNECT response is not instant. + */ + s->prot_save = data->req.p.http; + data->req.p.http = &s->http_proxy; + connkeep(conn, "HTTP proxy CONNECT"); } else { DEBUGASSERT(conn->connect_state); @@ -184,6 +204,10 @@ static void connect_done(struct Curl_easy *data) struct http_connect_state *s = conn->connect_state; s->tunnel_state = TUNNEL_COMPLETE; Curl_dyn_free(&s->rcvbuf); + Curl_dyn_free(&s->req); + + /* retore the protocol pointer */ + data->req.p.http = s->prot_save; infof(data, "CONNECT phase completed!\n"); } @@ -231,6 +255,7 @@ static CURLcode CONNECT(struct Curl_easy *data, struct connectdata *conn = data->conn; curl_socket_t tunnelsocket = conn->sock[sockindex]; struct http_connect_state *s = conn->connect_state; + struct HTTP *http = data->req.p.http; char *linep; size_t perline; @@ -246,7 +271,7 @@ static CURLcode CONNECT(struct Curl_easy *data, timediff_t check; if(TUNNEL_INIT == s->tunnel_state) { /* BEGIN CONNECT PHASE */ - struct dynbuf req; + struct dynbuf *req = &s->req; char *hostheader = NULL; char *host = NULL; @@ -259,8 +284,8 @@ static CURLcode CONNECT(struct Curl_easy *data, free(data->req.newurl); data->req.newurl = NULL; - /* initialize a dynamic send-buffer */ - Curl_dyn_init(&req, DYN_HTTP_REQUEST); + /* initialize send-buffer */ + Curl_dyn_init(req, DYN_HTTP_REQUEST); result = CONNECT_host(data, conn, hostname, remote_port, &hostheader, &host); @@ -285,7 +310,7 @@ static CURLcode CONNECT(struct Curl_easy *data, useragent = data->state.aptr.uagent; result = - Curl_dyn_addf(&req, + Curl_dyn_addf(req, "CONNECT %s HTTP/%s\r\n" "%s" /* Host: */ "%s" /* Proxy-Authorization */ @@ -300,16 +325,15 @@ static CURLcode CONNECT(struct Curl_easy *data, proxyconn); if(!result) - result = Curl_add_custom_headers(data, TRUE, &req); + result = Curl_add_custom_headers(data, TRUE, req); if(!result) /* CRLF terminate the request */ - result = Curl_dyn_add(&req, "\r\n"); + result = Curl_dyn_add(req, "\r\n"); if(!result) { /* Send the connect request to the proxy */ - /* BLOCKING */ - result = Curl_buffer_send(&req, data, &data->info.request_size, 0, + result = Curl_buffer_send(req, data, &data->info.request_size, 0, sockindex); } if(result) @@ -317,7 +341,6 @@ static CURLcode CONNECT(struct Curl_easy *data, } free(host); free(hostheader); - Curl_dyn_free(&req); if(result) return result; @@ -330,12 +353,42 @@ static CURLcode CONNECT(struct Curl_easy *data, return CURLE_OPERATION_TIMEDOUT; } - if(!Curl_conn_data_pending(conn, sockindex)) + if(!Curl_conn_data_pending(conn, sockindex) && !http->sending) /* return so we'll be called again polling-style */ return CURLE_OK; /* at this point, the tunnel_connecting phase is over. */ + if(http->sending == HTTPSEND_REQUEST) { + if(!s->nsend) { + size_t fillcount; + k->upload_fromhere = data->state.ulbuf; + result = Curl_fillreadbuffer(data, data->set.upload_buffer_size, + &fillcount); + if(result) + return result; + s->nsend = fillcount; + } + if(s->nsend) { + ssize_t bytes_written; + /* write to socket (send away data) */ + result = Curl_write(data, + conn->writesockfd, /* socket to send to */ + k->upload_fromhere, /* buffer pointer */ + s->nsend, /* buffer size */ + &bytes_written); /* actually sent */ + + if(!result) + /* send to debug callback! */ + result = Curl_debug(data, CURLINFO_HEADER_OUT, + k->upload_fromhere, bytes_written); + + s->nsend -= bytes_written; + k->upload_fromhere += bytes_written; + return result; + } + /* if nothing left to send, continue */ + } { /* READING RESPONSE PHASE */ int error = SELECT_OK; diff --git a/libs/libcurl/src/http_proxy.h b/libs/libcurl/src/http_proxy.h index a78db0d046..f5a4cb07cf 100644 --- a/libs/libcurl/src/http_proxy.h +++ b/libs/libcurl/src/http_proxy.h @@ -38,15 +38,39 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex); bool Curl_connect_complete(struct connectdata *conn); bool Curl_connect_ongoing(struct connectdata *conn); +int Curl_connect_getsock(struct connectdata *conn); #else #define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN #define Curl_proxy_connect(x,y) CURLE_OK #define Curl_connect_complete(x) CURLE_OK #define Curl_connect_ongoing(x) FALSE +#define Curl_connect_getsock(x) 0 #endif void Curl_connect_free(struct Curl_easy *data); void Curl_connect_done(struct Curl_easy *data); +/* struct for HTTP CONNECT state data */ +struct http_connect_state { + struct HTTP http_proxy; + struct HTTP *prot_save; + struct dynbuf rcvbuf; + struct dynbuf req; + size_t nsend; + enum keeponval { + KEEPON_DONE, + KEEPON_CONNECT, + KEEPON_IGNORE + } keepon; + curl_off_t cl; /* size of content to read and ignore */ + enum { + TUNNEL_INIT, /* init/default/no tunnel state */ + TUNNEL_CONNECT, /* CONNECT has been sent off */ + TUNNEL_COMPLETE /* CONNECT response received completely */ + } tunnel_state; + BIT(chunked_encoding); + BIT(close_connection); +}; + #endif /* HEADER_CURL_HTTP_PROXY_H */ diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c index e887357e1c..d85bcc391d 100644 --- a/libs/libcurl/src/imap.c +++ b/libs/libcurl/src/imap.c @@ -136,6 +136,7 @@ const struct Curl_handler Curl_handler_imap = { imap_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_IMAP, /* defport */ CURLPROTO_IMAP, /* protocol */ CURLPROTO_IMAP, /* family */ @@ -164,6 +165,7 @@ const struct Curl_handler Curl_handler_imaps = { imap_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_IMAPS, /* defport */ CURLPROTO_IMAPS, /* protocol */ CURLPROTO_IMAP, /* family */ @@ -919,7 +921,7 @@ static CURLcode imap_state_capability_resp(struct Curl_easy *data, /* Do we have a SASL based authentication mechanism? */ else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) { size_t llen; - unsigned int mechbit; + unsigned short mechbit; line += 5; wordlen -= 5; diff --git a/libs/libcurl/src/inet_ntop.c b/libs/libcurl/src/inet_ntop.c index 9a5af7f421..4c3e9e4dad 100644 --- a/libs/libcurl/src/inet_ntop.c +++ b/libs/libcurl/src/inet_ntop.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1996-2019 Internet Software Consortium. + * Copyright (C) 1996-2021 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -134,7 +134,7 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size) /* Are we following an initial run of 0x00s or any real hex? */ - if(i != 0) + if(i) *tp++ = ':'; /* Is this address an encapsulated IPv4? diff --git a/libs/libcurl/src/krb5.c b/libs/libcurl/src/krb5.c index eb83566d6b..4d1102da36 100644 --- a/libs/libcurl/src/krb5.c +++ b/libs/libcurl/src/krb5.c @@ -159,16 +159,6 @@ krb5_decode(void *app_data, void *buf, int len, return len; } -static int -krb5_overhead(void *app_data, int level, int len) -{ - /* no arguments are used */ - (void)app_data; - (void)level; - (void)len; - return 0; -} - static int krb5_encode(void *app_data, const void *from, int length, int level, void **to) { @@ -305,7 +295,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn) break; } - if(output_buffer.length != 0) { + if(output_buffer.length) { char *cmd; result = Curl_base64_encode(data, (char *)output_buffer.value, @@ -392,7 +382,7 @@ static struct Curl_sec_client_mech Curl_krb5_client_mech = { krb5_auth, krb5_end, krb5_check_prot, - krb5_overhead, + krb5_encode, krb5_decode }; @@ -412,7 +402,7 @@ name_to_level(const char *name) { int i; for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++) - if(checkprefix(name, level_names[i].name)) + if(curl_strequal(name, level_names[i].name)) return level_names[i].level; return PROT_NONE; } @@ -657,8 +647,6 @@ static ssize_t sec_write(struct Curl_easy *data, struct connectdata *conn, { ssize_t tx = 0, len = conn->buffer_size; - len -= conn->mech->overhead(conn->app_data, conn->data_prot, - curlx_sztosi(len)); if(len <= 0) len = length; while(length) { @@ -760,7 +748,7 @@ static int sec_set_protection_level(struct Curl_easy *data) if(level) { char *pbsz; - static unsigned int buffer_size = 1 << 20; /* 1048576 */ + unsigned int buffer_size = 1 << 20; /* 1048576 */ code = ftp_send_command(data, "PBSZ %u", buffer_size); if(code < 0) @@ -817,7 +805,7 @@ static CURLcode choose_mech(struct Curl_easy *data, struct connectdata *conn) const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech; tmp_allocation = realloc(conn->app_data, mech->size); - if(tmp_allocation == NULL) { + if(!tmp_allocation) { failf(data, "Failed realloc of size %zu", mech->size); mech = NULL; return CURLE_OUT_OF_MEMORY; diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c index 860a4a851a..ed16423026 100644 --- a/libs/libcurl/src/ldap.c +++ b/libs/libcurl/src/ldap.c @@ -149,6 +149,7 @@ const struct Curl_handler Curl_handler_ldap = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_LDAP, /* defport */ CURLPROTO_LDAP, /* protocol */ CURLPROTO_LDAP, /* family */ @@ -176,6 +177,7 @@ const struct Curl_handler Curl_handler_ldaps = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_LDAPS, /* defport */ CURLPROTO_LDAPS, /* protocol */ CURLPROTO_LDAP, /* family */ @@ -303,7 +305,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) #else rc = _ldap_url_parse(data, conn, &ludp); #endif - if(rc != 0) { + if(rc) { failf(data, "LDAP local: %s", ldap_err2string(rc)); result = CURLE_LDAP_INVALID_URL; goto quit; @@ -387,7 +389,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } server = ldapssl_init(host, (int)conn->port, 1); - if(server == NULL) { + if(!server) { failf(data, "LDAP local: Cannot connect to %s:%ld", conn->host.dispname, conn->port); result = CURLE_COULDNT_CONNECT; @@ -428,7 +430,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } server = ldap_init(host, (int)conn->port); - if(server == NULL) { + if(!server) { failf(data, "LDAP local: Cannot connect to %s:%ld", conn->host.dispname, conn->port); result = CURLE_COULDNT_CONNECT; @@ -464,7 +466,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) } else { server = ldap_init(host, (int)conn->port); - if(server == NULL) { + if(!server) { failf(data, "LDAP local: Cannot connect to %s:%ld", conn->host.dispname, conn->port); result = CURLE_COULDNT_CONNECT; @@ -477,7 +479,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) #else rc = ldap_simple_bind_s(server, user, passwd); #endif - if(!ldap_ssl && rc != 0) { + if(!ldap_ssl && rc) { ldap_proto = LDAP_VERSION2; ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); #ifdef USE_WIN32_LDAP @@ -486,7 +488,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) rc = ldap_simple_bind_s(server, user, passwd); #endif } - if(rc != 0) { + if(rc) { #ifdef USE_WIN32_LDAP failf(data, "LDAP local: bind via ldap_win_bind %s", ldap_err2string(rc)); @@ -501,7 +503,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg); - if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) { + if(rc && rc != LDAP_SIZELIMIT_EXCEEDED) { failf(data, "LDAP remote: %s", ldap_err2string(rc)); result = CURLE_LDAP_SEARCH_FAILED; goto quit; @@ -581,7 +583,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) result = CURLE_OUT_OF_MEMORY; goto quit; - } + } #else char *attr = attribute; #endif @@ -1061,13 +1063,23 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp) if(!ludp) return; +#if defined(USE_WIN32_LDAP) + curlx_unicodefree(ludp->lud_dn); + curlx_unicodefree(ludp->lud_filter); +#else free(ludp->lud_dn); free(ludp->lud_filter); +#endif if(ludp->lud_attrs) { size_t i; - for(i = 0; i < ludp->lud_attrs_dups; i++) + for(i = 0; i < ludp->lud_attrs_dups; i++) { +#if defined(USE_WIN32_LDAP) + curlx_unicodefree(ludp->lud_attrs[i]); +#else free(ludp->lud_attrs[i]); +#endif + } free(ludp->lud_attrs); } diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index f787761ced..b3afa9f8a2 100644 --- a/libs/libcurl/src/libcurl.plist +++ b/libs/libcurl/src/libcurl.plist @@ -15,7 +15,7 @@ se.curl.libcurl CFBundleVersion - 7.76.1 + 7.77.0 CFBundleName libcurl @@ -27,9 +27,9 @@ ???? CFBundleShortVersionString - libcurl 7.76.1 + libcurl 7.77.0 CFBundleGetInfoString - libcurl.plist 7.76.1 + libcurl.plist 7.77.0 diff --git a/libs/libcurl/src/llist.c b/libs/libcurl/src/llist.c index 17a7be1667..e0ec7393d2 100644 --- a/libs/libcurl/src/llist.c +++ b/libs/libcurl/src/llist.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -94,13 +94,13 @@ Curl_llist_remove(struct Curl_llist *list, struct Curl_llist_element *e, void *user) { void *ptr; - if(e == NULL || list->size == 0) + if(!e || list->size == 0) return; if(e == list->head) { list->head = e->next; - if(list->head == NULL) + if(!list->head) list->tail = NULL; else e->next->prev = NULL; diff --git a/libs/libcurl/src/md4.c b/libs/libcurl/src/md4.c index e731e123d3..c651ddf669 100644 --- a/libs/libcurl/src/md4.c +++ b/libs/libcurl/src/md4.c @@ -174,7 +174,7 @@ static void MD4_Init(MD4_CTX *ctx) static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) { - if(ctx->data == NULL) { + if(!ctx->data) { ctx->data = malloc(size); if(ctx->data != NULL) { memcpy(ctx->data, data, size); diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c index abadcb02cb..0bf1b46a4c 100644 --- a/libs/libcurl/src/mime.c +++ b/libs/libcurl/src/mime.c @@ -152,14 +152,14 @@ curl_off_t VmsRealFileSize(const char *name, FILE * file; file = fopen(name, FOPEN_READTEXT); /* VMS */ - if(file == NULL) + if(!file) return 0; count = 0; ret_stat = 1; while(ret_stat > 0) { ret_stat = fread(buffer, 1, sizeof(buffer), file); - if(ret_stat != 0) + if(ret_stat) count += ret_stat; } fclose(file); diff --git a/libs/libcurl/src/mprintf.c b/libs/libcurl/src/mprintf.c index c681248dee..5292026861 100644 --- a/libs/libcurl/src/mprintf.c +++ b/libs/libcurl/src/mprintf.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1999 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1999 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -815,7 +815,7 @@ static int dprintf_formatf( size_t len; str = (char *) p->data.str; - if(str == NULL) { + if(!str) { /* Write null[] if there's space. */ if(prec == -1 || prec >= (long) sizeof(null) - 1) { str = null; diff --git a/libs/libcurl/src/mqtt.c b/libs/libcurl/src/mqtt.c index 2134409cda..d88fa737df 100644 --- a/libs/libcurl/src/mqtt.c +++ b/libs/libcurl/src/mqtt.c @@ -86,6 +86,7 @@ const struct Curl_handler Curl_handler_mqtt = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_MQTT, /* defport */ CURLPROTO_MQTT, /* protocol */ CURLPROTO_MQTT, /* family */ diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index be3e41f8bb..1b3e261c68 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -381,6 +381,11 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ multi->max_concurrent_streams = 100; multi->ipv6_works = Curl_ipv6works(NULL); +#ifdef USE_WINSOCK + multi->wsa_event = WSACreateEvent(); + if(multi->wsa_event == WSA_INVALID_EVENT) + goto error; +#else #ifdef ENABLE_WAKEUP if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) { multi->wakeup_pair[0] = CURL_SOCKET_BAD; @@ -393,6 +398,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ multi->wakeup_pair[0] = CURL_SOCKET_BAD; multi->wakeup_pair[1] = CURL_SOCKET_BAD; } +#endif #endif return multi; @@ -872,8 +878,10 @@ bool Curl_multiplex_wanted(const struct Curl_multi *multi) void Curl_detach_connnection(struct Curl_easy *data) { struct connectdata *conn = data->conn; - if(conn) + if(conn) { Curl_llist_remove(&conn->easyq, &data->conn_queue, NULL); + Curl_ssl_detach_conn(data, conn); + } data->conn = NULL; } @@ -890,6 +898,9 @@ void Curl_attach_connnection(struct Curl_easy *data, data->conn = conn; Curl_llist_insert_next(&conn->easyq, conn->easyq.tail, data, &data->conn_queue); + if(conn->handler->attach) + conn->handler->attach(data, conn); + Curl_ssl_associate_conn(data, conn); } static int waitconnect_getsock(struct connectdata *conn, @@ -930,10 +941,8 @@ static int waitproxyconnect_getsock(struct connectdata *conn, { sock[0] = conn->sock[FIRSTSOCKET]; - /* when we've sent a CONNECT to a proxy, we should rather wait for the - socket to become readable to be able to get the response headers */ if(conn->connect_state) - return GETSOCK_READSOCK(0); + return Curl_connect_getsock(conn); return GETSOCK_WRITESOCK(0); } @@ -1083,6 +1092,10 @@ static CURLMcode multi_wait(struct Curl_multi *multi, struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; struct pollfd *ufds = &a_few_on_stack[0]; bool ufds_malloc = FALSE; +#ifdef USE_WINSOCK + WSANETWORKEVENTS wsa_events; + DEBUGASSERT(multi->wsa_event != WSA_INVALID_EVENT); +#endif if(!GOOD_MULTI_HANDLE(multi)) return CURLM_BAD_HANDLE; @@ -1101,11 +1114,11 @@ static CURLMcode multi_wait(struct Curl_multi *multi, for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) { curl_socket_t s = CURL_SOCKET_BAD; - if(bitmap & GETSOCK_READSOCK(i)) { + if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) { ++nfds; s = sockbunch[i]; } - if(bitmap & GETSOCK_WRITESOCK(i)) { + if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) { ++nfds; s = sockbunch[i]; } @@ -1128,7 +1141,11 @@ static CURLMcode multi_wait(struct Curl_multi *multi, nfds += extra_nfds; /* add the externally provided ones */ #ifdef ENABLE_WAKEUP +#ifdef USE_WINSOCK + if(use_wakeup) { +#else if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { +#endif ++nfds; } #endif @@ -1156,22 +1173,40 @@ static CURLMcode multi_wait(struct Curl_multi *multi, for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) { curl_socket_t s = CURL_SOCKET_BAD; - +#ifdef USE_WINSOCK + long mask = 0; +#endif if(bitmap & GETSOCK_READSOCK(i)) { - ufds[nfds].fd = sockbunch[i]; + s = sockbunch[i]; +#ifdef USE_WINSOCK + mask |= FD_READ|FD_ACCEPT|FD_CLOSE; +#endif + ufds[nfds].fd = s; ufds[nfds].events = POLLIN; ++nfds; - s = sockbunch[i]; } if(bitmap & GETSOCK_WRITESOCK(i)) { - ufds[nfds].fd = sockbunch[i]; + s = sockbunch[i]; +#ifdef USE_WINSOCK + mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; + send(s, NULL, 0, 0); /* reset FD_WRITE */ +#endif + ufds[nfds].fd = s; ufds[nfds].events = POLLOUT; ++nfds; - s = sockbunch[i]; } + /* s is only set if either being readable or writable is checked */ if(s == CURL_SOCKET_BAD) { + /* break on entry not checked for being readable or writable */ break; } +#ifdef USE_WINSOCK + if(WSAEventSelect(s, multi->wsa_event, mask) != 0) { + if(ufds_malloc) + free(ufds); + return CURLM_INTERNAL_ERROR; + } +#endif } data = data->next; /* check next handle */ @@ -1180,6 +1215,22 @@ static CURLMcode multi_wait(struct Curl_multi *multi, /* Add external file descriptions from poll-like struct curl_waitfd */ for(i = 0; i < extra_nfds; i++) { +#ifdef USE_WINSOCK + long mask = 0; + if(extra_fds[i].events & CURL_WAIT_POLLIN) + mask |= FD_READ|FD_ACCEPT|FD_CLOSE; + if(extra_fds[i].events & CURL_WAIT_POLLPRI) + mask |= FD_OOB; + if(extra_fds[i].events & CURL_WAIT_POLLOUT) { + mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; + send(extra_fds[i].fd, NULL, 0, 0); /* reset FD_WRITE */ + } + if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) { + if(ufds_malloc) + free(ufds); + return CURLM_INTERNAL_ERROR; + } +#endif ufds[nfds].fd = extra_fds[i].fd; ufds[nfds].events = 0; if(extra_fds[i].events & CURL_WAIT_POLLIN) @@ -1192,25 +1243,62 @@ static CURLMcode multi_wait(struct Curl_multi *multi, } #ifdef ENABLE_WAKEUP +#ifndef USE_WINSOCK if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { ufds[nfds].fd = multi->wakeup_pair[0]; ufds[nfds].events = POLLIN; ++nfds; } #endif +#endif +#if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK) + if(nfds || use_wakeup) { +#else if(nfds) { - /* wait... */ - int pollrc = Curl_poll(ufds, nfds, timeout_ms); +#endif + int pollrc; +#ifdef USE_WINSOCK + if(nfds) + pollrc = Curl_poll(ufds, nfds, 0); /* just pre-check with WinSock */ + else + pollrc = 0; + if(pollrc <= 0) /* now wait... if not ready during the pre-check above */ + WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE); +#else + pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */ +#endif + if(pollrc > 0) { retcode = pollrc; +#ifdef USE_WINSOCK + } + /* With WinSock, we have to run the following section unconditionally + to call WSAEventSelect(fd, event, 0) on all the sockets */ + { +#endif /* copy revents results from the poll to the curl_multi_wait poll struct, the bit values of the actual underlying poll() implementation may not be the same as the ones in the public libcurl API! */ for(i = 0; i < extra_nfds; i++) { - unsigned short mask = 0; unsigned r = ufds[curlfds + i].revents; - + unsigned short mask = 0; +#ifdef USE_WINSOCK + wsa_events.lNetworkEvents = 0; + if(WSAEnumNetworkEvents(extra_fds[i].fd, NULL, &wsa_events) == 0) { + if(wsa_events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)) + mask |= CURL_WAIT_POLLIN; + if(wsa_events.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE)) + mask |= CURL_WAIT_POLLOUT; + if(wsa_events.lNetworkEvents & FD_OOB) + mask |= CURL_WAIT_POLLPRI; + if(ret && pollrc <= 0 && wsa_events.lNetworkEvents) + retcode++; + } + WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0); + if(pollrc <= 0) + continue; +#endif if(r & POLLIN) mask |= CURL_WAIT_POLLIN; if(r & POLLOUT) @@ -1220,6 +1308,35 @@ static CURLMcode multi_wait(struct Curl_multi *multi, extra_fds[i].revents = mask; } +#ifdef USE_WINSOCK + /* Count up all our own sockets that had activity, + and remove them from the event. */ + if(curlfds) { + data = multi->easyp; + while(data) { + bitmap = multi_getsock(data, sockbunch); + + for(i = 0; i < MAX_SOCKSPEREASYHANDLE; i++) { + if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) { + wsa_events.lNetworkEvents = 0; + if(WSAEnumNetworkEvents(sockbunch[i], NULL, &wsa_events) == 0) { + if(ret && pollrc <= 0 && wsa_events.lNetworkEvents) + retcode++; + } + WSAEventSelect(sockbunch[i], multi->wsa_event, 0); + } + else { + /* break on entry not checked for being readable or writable */ + break; + } + } + + data = data->next; + } + } + + WSAResetEvent(multi->wsa_event); +#else #ifdef ENABLE_WAKEUP if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { if(ufds[curlfds + extra_nfds].revents & POLLIN) { @@ -1232,10 +1349,8 @@ static CURLMcode multi_wait(struct Curl_multi *multi, when there is no more data, breaking the loop. */ nread = sread(multi->wakeup_pair[0], buf, sizeof(buf)); if(nread <= 0) { -#ifndef USE_WINSOCK if(nread < 0 && EINTR == SOCKERRNO) continue; -#endif break; } } @@ -1243,6 +1358,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, retcode--; } } +#endif #endif } } @@ -1251,10 +1367,11 @@ static CURLMcode multi_wait(struct Curl_multi *multi, free(ufds); if(ret) *ret = retcode; - if(!extrawait || nfds) - /* if any socket was checked */ - ; - else { +#if defined(ENABLE_WAKEUP) && defined(USE_WINSOCK) + if(extrawait && !nfds && !use_wakeup) { +#else + if(extrawait && !nfds) { +#endif long sleep_ms = 0; /* Avoid busy-looping when there's nothing particular to wait for */ @@ -1303,6 +1420,10 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi) return CURLM_BAD_HANDLE; #ifdef ENABLE_WAKEUP +#ifdef USE_WINSOCK + if(WSASetEvent(multi->wsa_event)) + return CURLM_OK; +#else /* the wakeup_pair variable is only written during init and cleanup, making it safe to access from another thread after the init part and before cleanup */ @@ -1335,6 +1456,7 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi) return CURLM_OK; } } +#endif #endif return CURLM_WAKEUP_FAILURE; } @@ -2153,12 +2275,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } } else if((CURLE_HTTP2_STREAM == result) && - Curl_h2_http_1_1_error(data->conn)) { + Curl_h2_http_1_1_error(data)) { CURLcode ret = Curl_retry_request(data, &newurl); if(!ret) { infof(data, "Downgrades to HTTP/1.1!\n"); - connclose(data->conn, "Disconnect HTTP/2 for HTTP/1"); + streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1"); data->state.httpwant = CURL_HTTP_VERSION_1_1; /* clear the error message bit too as we ignore the one we got */ data->state.errorbuf = FALSE; @@ -2478,9 +2600,13 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) Curl_hash_destroy(&multi->hostcache); Curl_psl_destroy(&multi->psl); +#ifdef USE_WINSOCK + WSACloseEvent(multi->wsa_event); +#else #ifdef ENABLE_WAKEUP sclose(multi->wakeup_pair[0]); sclose(multi->wakeup_pair[1]); +#endif #endif free(multi); diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h index edf790132a..96b84749fc 100644 --- a/libs/libcurl/src/multihandle.h +++ b/libs/libcurl/src/multihandle.h @@ -140,9 +140,13 @@ struct Curl_multi { previous callback */ unsigned int max_concurrent_streams; +#ifdef USE_WINSOCK + WSAEVENT wsa_event; /* winsock event used for waits */ +#else #ifdef ENABLE_WAKEUP curl_socket_t wakeup_pair[2]; /* socketpair() used for wakeup 0 is used for read, 1 is used for write */ +#endif #endif /* multiplexing wanted */ bool multiplexing; diff --git a/libs/libcurl/src/non-ascii.c b/libs/libcurl/src/non-ascii.c index 30c240b637..932cf89eef 100644 --- a/libs/libcurl/src/non-ascii.c +++ b/libs/libcurl/src/non-ascii.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -127,7 +127,7 @@ CURLcode Curl_convert_to_network(struct Curl_easy *data, &output_ptr, &out_bytes); if(!data) iconv_close(tmpcd); - if((rc == ICONV_ERROR) || (in_bytes != 0)) { + if((rc == ICONV_ERROR) || (in_bytes)) { failf(data, "The Curl_convert_to_network iconv call failed with errno %i: %s", errno, strerror(errno)); @@ -193,7 +193,7 @@ CURLcode Curl_convert_from_network(struct Curl_easy *data, &output_ptr, &out_bytes); if(!data) iconv_close(tmpcd); - if((rc == ICONV_ERROR) || (in_bytes != 0)) { + if((rc == ICONV_ERROR) || (in_bytes)) { failf(data, "Curl_convert_from_network iconv call failed with errno %i: %s", errno, strerror(errno)); @@ -260,7 +260,7 @@ CURLcode Curl_convert_from_utf8(struct Curl_easy *data, &output_ptr, &out_bytes); if(!data) iconv_close(tmpcd); - if((rc == ICONV_ERROR) || (in_bytes != 0)) { + if((rc == ICONV_ERROR) || (in_bytes)) { failf(data, "The Curl_convert_from_utf8 iconv call failed with errno %i: %s", errno, strerror(errno)); diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c index b6980c5900..0b8bc34a03 100644 --- a/libs/libcurl/src/openldap.c +++ b/libs/libcurl/src/openldap.c @@ -76,16 +76,16 @@ extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url, LDAP **ld); #endif -static CURLcode ldap_setup_connection(struct Curl_easy *data, - struct connectdata *conn); -static CURLcode ldap_do(struct Curl_easy *data, bool *done); -static CURLcode ldap_done(struct Curl_easy *data, CURLcode, bool); -static CURLcode ldap_connect(struct Curl_easy *data, bool *done); -static CURLcode ldap_connecting(struct Curl_easy *data, bool *done); -static CURLcode ldap_disconnect(struct Curl_easy *data, - struct connectdata *conn, bool dead); +static CURLcode oldap_setup_connection(struct Curl_easy *data, + struct connectdata *conn); +static CURLcode oldap_do(struct Curl_easy *data, bool *done); +static CURLcode oldap_done(struct Curl_easy *data, CURLcode, bool); +static CURLcode oldap_connect(struct Curl_easy *data, bool *done); +static CURLcode oldap_connecting(struct Curl_easy *data, bool *done); +static CURLcode oldap_disconnect(struct Curl_easy *data, + struct connectdata *conn, bool dead); -static Curl_recv ldap_recv; +static Curl_recv oldap_recv; /* * LDAP protocol handler. @@ -93,20 +93,21 @@ static Curl_recv ldap_recv; const struct Curl_handler Curl_handler_ldap = { "LDAP", /* scheme */ - ldap_setup_connection, /* setup_connection */ - ldap_do, /* do_it */ - ldap_done, /* done */ + oldap_setup_connection, /* setup_connection */ + oldap_do, /* do_it */ + oldap_done, /* done */ ZERO_NULL, /* do_more */ - ldap_connect, /* connect_it */ - ldap_connecting, /* connecting */ + oldap_connect, /* connect_it */ + oldap_connecting, /* connecting */ ZERO_NULL, /* doing */ ZERO_NULL, /* proto_getsock */ ZERO_NULL, /* doing_getsock */ ZERO_NULL, /* domore_getsock */ ZERO_NULL, /* perform_getsock */ - ldap_disconnect, /* disconnect */ + oldap_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_LDAP, /* defport */ CURLPROTO_LDAP, /* protocol */ CURLPROTO_LDAP, /* family */ @@ -120,20 +121,21 @@ const struct Curl_handler Curl_handler_ldap = { const struct Curl_handler Curl_handler_ldaps = { "LDAPS", /* scheme */ - ldap_setup_connection, /* setup_connection */ - ldap_do, /* do_it */ - ldap_done, /* done */ + oldap_setup_connection, /* setup_connection */ + oldap_do, /* do_it */ + oldap_done, /* done */ ZERO_NULL, /* do_more */ - ldap_connect, /* connect_it */ - ldap_connecting, /* connecting */ + oldap_connect, /* connect_it */ + oldap_connecting, /* connecting */ ZERO_NULL, /* doing */ ZERO_NULL, /* proto_getsock */ ZERO_NULL, /* doing_getsock */ ZERO_NULL, /* domore_getsock */ ZERO_NULL, /* perform_getsock */ - ldap_disconnect, /* disconnect */ + oldap_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_LDAPS, /* defport */ CURLPROTO_LDAPS, /* protocol */ CURLPROTO_LDAP, /* family */ @@ -171,8 +173,8 @@ struct ldapreqinfo { int nument; }; -static CURLcode ldap_setup_connection(struct Curl_easy *data, - struct connectdata *conn) +static CURLcode oldap_setup_connection(struct Curl_easy *data, + struct connectdata *conn) { struct ldapconninfo *li; LDAPURLDesc *lud; @@ -207,7 +209,7 @@ static CURLcode ldap_setup_connection(struct Curl_easy *data, static Sockbuf_IO ldapsb_tls; #endif -static CURLcode ldap_connect(struct Curl_easy *data, bool *done) +static CURLcode oldap_connect(struct Curl_easy *data, bool *done) { struct connectdata *conn = data->conn; struct ldapconninfo *li = conn->proto.ldapc; @@ -255,7 +257,7 @@ static CURLcode ldap_connect(struct Curl_easy *data, bool *done) return CURLE_OK; } -static CURLcode ldap_connecting(struct Curl_easy *data, bool *done) +static CURLcode oldap_connecting(struct Curl_easy *data, bool *done) { struct connectdata *conn = data->conn; struct ldapconninfo *li = conn->proto.ldapc; @@ -354,25 +356,28 @@ static CURLcode ldap_connecting(struct Curl_easy *data, bool *done) if(info) ldap_memfree(info); - conn->recv[FIRSTSOCKET] = ldap_recv; + conn->recv[FIRSTSOCKET] = oldap_recv; *done = TRUE; return CURLE_OK; } -static CURLcode ldap_disconnect(struct Curl_easy *data, - struct connectdata *conn, bool dead_connection) +static CURLcode oldap_disconnect(struct Curl_easy *data, + struct connectdata *conn, + bool dead_connection) { struct ldapconninfo *li = conn->proto.ldapc; (void) dead_connection; if(li) { if(li->ld) { +#ifdef USE_SSL if(conn->ssl[FIRSTSOCKET].use) { Sockbuf *sb; ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb); ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data); } +#endif ldap_unbind_ext(li->ld, NULL, NULL); li->ld = NULL; } @@ -382,7 +387,7 @@ static CURLcode ldap_disconnect(struct Curl_easy *data, return CURLE_OK; } -static CURLcode ldap_do(struct Curl_easy *data, bool *done) +static CURLcode oldap_do(struct Curl_easy *data, bool *done) { struct connectdata *conn = data->conn; struct ldapconninfo *li = conn->proto.ldapc; @@ -427,8 +432,8 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) return CURLE_OK; } -static CURLcode ldap_done(struct Curl_easy *data, CURLcode res, - bool premature) +static CURLcode oldap_done(struct Curl_easy *data, CURLcode res, + bool premature) { struct connectdata *conn = data->conn; struct ldapreqinfo *lr = data->req.p.ldap; @@ -450,8 +455,8 @@ static CURLcode ldap_done(struct Curl_easy *data, CURLcode res, return CURLE_OK; } -static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf, - size_t len, CURLcode *err) +static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf, + size_t len, CURLcode *err) { struct connectdata *conn = data->conn; struct ldapconninfo *li = conn->proto.ldapc; @@ -547,7 +552,7 @@ static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf, rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals)) { int i; - if(bv.bv_val == NULL) + if(!bv.bv_val) break; if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7)) @@ -555,7 +560,7 @@ static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf, else binary = 0; - if(bvals == NULL) { + if(!bvals) { writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\t", 1); if(writeerr) { *err = writeerr; @@ -664,7 +669,7 @@ static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf, data->req.bytecount += bvals[i].bv_len + 1; } - writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0); + writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); if(writeerr) { *err = writeerr; return -1; @@ -673,14 +678,14 @@ static ssize_t ldap_recv(struct Curl_easy *data, int sockindex, char *buf, data->req.bytecount++; } ber_memfree(bvals); - writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0); + writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); if(writeerr) { *err = writeerr; return -1; } data->req.bytecount++; } - writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0); + writeerr = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); if(writeerr) { *err = writeerr; return -1; diff --git a/libs/libcurl/src/pop3.c b/libs/libcurl/src/pop3.c index ccfebd02af..9b6ea64804 100644 --- a/libs/libcurl/src/pop3.c +++ b/libs/libcurl/src/pop3.c @@ -131,6 +131,7 @@ const struct Curl_handler Curl_handler_pop3 = { pop3_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_POP3, /* defport */ CURLPROTO_POP3, /* protocol */ CURLPROTO_POP3, /* family */ @@ -159,6 +160,7 @@ const struct Curl_handler Curl_handler_pop3s = { pop3_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_POP3S, /* defport */ CURLPROTO_POP3S, /* protocol */ CURLPROTO_POP3, /* family */ @@ -709,7 +711,7 @@ static CURLcode pop3_state_capa_resp(struct Curl_easy *data, int pop3code, for(;;) { size_t llen; size_t wordlen; - unsigned int mechbit; + unsigned short mechbit; while(len && (*line == ' ' || *line == '\t' || @@ -1515,8 +1517,17 @@ CURLcode Curl_pop3_write(struct Curl_easy *data, char *str, size_t nread) if(prev) { /* If the partial match was the CRLF and dot then only write the CRLF as the server would have inserted the dot */ - result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB, - strip_dot ? prev - 1 : prev); + if(strip_dot && prev - 1 > 0) { + result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB, + prev - 1); + } + else if(!strip_dot) { + result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)POP3_EOB, + prev); + } + else { + result = CURLE_OK; + } if(result) return result; diff --git a/libs/libcurl/src/progress.c b/libs/libcurl/src/progress.c index cc040a8733..4bcd615eba 100644 --- a/libs/libcurl/src/progress.c +++ b/libs/libcurl/src/progress.c @@ -241,6 +241,8 @@ void Curl_pgrsStartNow(struct Curl_easy *data) data->progress.is_t_startransfer_set = false; data->progress.ul_limit_start = data->progress.start; data->progress.dl_limit_start = data->progress.start; + data->progress.ul_limit_size = 0; + data->progress.dl_limit_size = 0; data->progress.downloaded = 0; data->progress.uploaded = 0; /* clear all bits except HIDE and HEADERS_OUT */ @@ -369,94 +371,82 @@ void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size) } } +/* returns the average speed in bytes / second */ +static curl_off_t trspeed(curl_off_t size, /* number of bytes */ + curl_off_t us) /* microseconds */ +{ + if(us < 1) + return size * 1000000; + return (curl_off_t)((long double)size/us * 1000000); +} + /* returns TRUE if it's time to show the progress meter */ static bool progress_calc(struct Curl_easy *data, struct curltime now) { - curl_off_t timespent; - curl_off_t timespent_ms; /* milliseconds */ - curl_off_t dl = data->progress.downloaded; - curl_off_t ul = data->progress.uploaded; bool timetoshow = FALSE; + struct Progress * const p = &data->progress; - /* The time spent so far (from the start) */ - data->progress.timespent = Curl_timediff_us(now, data->progress.start); - timespent = (curl_off_t)data->progress.timespent/1000000; /* seconds */ - timespent_ms = (curl_off_t)data->progress.timespent/1000; /* ms */ - - /* The average download speed this far */ - if(dl < CURL_OFF_T_MAX/1000) - data->progress.dlspeed = (dl * 1000 / (timespent_ms>0?timespent_ms:1)); - else - data->progress.dlspeed = (dl / (timespent>0?timespent:1)); - - /* The average upload speed this far */ - if(ul < CURL_OFF_T_MAX/1000) - data->progress.ulspeed = (ul * 1000 / (timespent_ms>0?timespent_ms:1)); - else - data->progress.ulspeed = (ul / (timespent>0?timespent:1)); + /* The time spent so far (from the start) in microseconds */ + p->timespent = Curl_timediff_us(now, p->start); + p->dlspeed = trspeed(p->downloaded, p->timespent); + p->ulspeed = trspeed(p->uploaded, p->timespent); /* Calculations done at most once a second, unless end is reached */ - if(data->progress.lastshow != now.tv_sec) { + if(p->lastshow != now.tv_sec) { int countindex; /* amount of seconds stored in the speeder array */ - int nowindex = data->progress.speeder_c% CURR_TIME; - data->progress.lastshow = now.tv_sec; + int nowindex = p->speeder_c% CURR_TIME; + p->lastshow = now.tv_sec; timetoshow = TRUE; /* Let's do the "current speed" thing, with the dl + ul speeds combined. Store the speed at entry 'nowindex'. */ - data->progress.speeder[ nowindex ] = - data->progress.downloaded + data->progress.uploaded; + p->speeder[ nowindex ] = p->downloaded + p->uploaded; /* remember the exact time for this moment */ - data->progress.speeder_time [ nowindex ] = now; + p->speeder_time [ nowindex ] = now; /* advance our speeder_c counter, which is increased every time we get here and we expect it to never wrap as 2^32 is a lot of seconds! */ - data->progress.speeder_c++; + p->speeder_c++; /* figure out how many index entries of data we have stored in our speeder array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of transfer. Imagine, after one second we have filled in two entries, after two seconds we've filled in three entries etc. */ - countindex = ((data->progress.speeder_c >= CURR_TIME)? - CURR_TIME:data->progress.speeder_c) - 1; + countindex = ((p->speeder_c >= CURR_TIME)? CURR_TIME:p->speeder_c) - 1; /* first of all, we don't do this if there's no counted seconds yet */ if(countindex) { int checkindex; timediff_t span_ms; + curl_off_t amount; /* Get the index position to compare with the 'nowindex' position. Get the oldest entry possible. While we have less than CURR_TIME entries, the first entry will remain the oldest. */ - checkindex = (data->progress.speeder_c >= CURR_TIME)? - data->progress.speeder_c%CURR_TIME:0; + checkindex = (p->speeder_c >= CURR_TIME)? p->speeder_c%CURR_TIME:0; /* Figure out the exact time for the time span */ - span_ms = Curl_timediff(now, data->progress.speeder_time[checkindex]); + span_ms = Curl_timediff(now, p->speeder_time[checkindex]); if(0 == span_ms) span_ms = 1; /* at least one millisecond MUST have passed */ /* Calculate the average speed the last 'span_ms' milliseconds */ - { - curl_off_t amount = data->progress.speeder[nowindex]- - data->progress.speeder[checkindex]; - - if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */) - /* the 'amount' value is bigger than would fit in 32 bits if - multiplied with 1000, so we use the double math for this */ - data->progress.current_speed = (curl_off_t) - ((double)amount/((double)span_ms/1000.0)); - else - /* the 'amount' value is small enough to fit within 32 bits even - when multiplied with 1000 */ - data->progress.current_speed = amount*CURL_OFF_T_C(1000)/span_ms; - } + amount = p->speeder[nowindex]- p->speeder[checkindex]; + + if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */) + /* the 'amount' value is bigger than would fit in 32 bits if + multiplied with 1000, so we use the double math for this */ + p->current_speed = (curl_off_t) + ((double)amount/((double)span_ms/1000.0)); + else + /* the 'amount' value is small enough to fit within 32 bits even + when multiplied with 1000 */ + p->current_speed = amount*CURL_OFF_T_C(1000)/span_ms; } else /* the first second we use the average */ - data->progress.current_speed = - data->progress.ulspeed + data->progress.dlspeed; + p->current_speed = p->ulspeed + p->dlspeed; } /* Calculations end */ return timetoshow; diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c index 3029ff5264..007d5c50b6 100644 --- a/libs/libcurl/src/rtsp.c +++ b/libs/libcurl/src/rtsp.c @@ -109,6 +109,7 @@ const struct Curl_handler Curl_handler_rtsp = { rtsp_disconnect, /* disconnect */ rtsp_rtp_readwrite, /* readwrite */ rtsp_conncheck, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_RTSP, /* defport */ CURLPROTO_RTSP, /* protocol */ CURLPROTO_RTSP, /* family */ @@ -680,7 +681,7 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data, } } - if(rtp_dataleft != 0 && rtp[0] == '$') { + if(rtp_dataleft && rtp[0] == '$') { DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft, *readmore ? "(READMORE)" : "")); @@ -824,7 +825,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header) /* Copy the id substring into a new buffer */ data->set.str[STRING_RTSP_SESSION_ID] = malloc(idlen + 1); - if(data->set.str[STRING_RTSP_SESSION_ID] == NULL) + if(!data->set.str[STRING_RTSP_SESSION_ID]) return CURLE_OUT_OF_MEMORY; memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, idlen); (data->set.str[STRING_RTSP_SESSION_ID])[idlen] = '\0'; diff --git a/libs/libcurl/src/select.c b/libs/libcurl/src/select.c index d7346b195f..52dca5a2c0 100644 --- a/libs/libcurl/src/select.c +++ b/libs/libcurl/src/select.c @@ -442,7 +442,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) if(ufds[i].events & POLLPRI) ufds[i].revents |= POLLPRI; } - if(ufds[i].revents != 0) + if(ufds[i].revents) r++; } diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index b57b7878c2..e41bb805f5 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -65,7 +65,7 @@ static size_t convert_lineends(struct Curl_easy *data, char *inPtr, *outPtr; /* sanity check */ - if((startPtr == NULL) || (size < 1)) { + if(!startPtr || (size < 1)) { return size; } @@ -309,6 +309,18 @@ CURLcode Curl_write(struct Curl_easy *data, conn = data->conn; num = (sockfd == conn->sock[SECONDARYSOCKET]); +#ifdef CURLDEBUG + { + /* Allow debug builds to override this logic to force short sends + */ + char *p = getenv("CURL_SMALLSENDS"); + if(p) { + size_t altsize = (size_t)strtoul(p, NULL, 10); + if(altsize) + len = CURLMIN(len, altsize); + } + } +#endif bytes_written = conn->send[num](data, num, mem, len, &result); *written = bytes_written; @@ -604,7 +616,7 @@ static CURLcode chop_write(struct Curl_easy *data, /* Curl_client_write() sends data to the write callback(s) The bit pattern defines to what "streams" to write to. Body and/or header. - The defines are in sendf.h of course. + The defines are in sendf.h of course. "len" is not allowed to be 0. If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the local character encoding. This is a problem and should be changed in @@ -616,9 +628,8 @@ CURLcode Curl_client_write(struct Curl_easy *data, size_t len) { struct connectdata *conn = data->conn; - if(0 == len) - len = strlen(ptr); + DEBUGASSERT(len); DEBUGASSERT(type <= 3); /* FTP data may need conversion. */ diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index 022dd38003..fb8b86d474 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -426,6 +426,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) version_max = C_SSLVERSION_MAX_VALUE(arg); if(version < CURL_SSLVERSION_DEFAULT || + version == CURL_SSLVERSION_SSLv2 || + version == CURL_SSLVERSION_SSLv3 || version >= CURL_SSLVERSION_LAST || version_max < CURL_SSLVERSION_MAX_NONE || version_max >= CURL_SSLVERSION_MAX_LAST) @@ -752,6 +754,20 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) } data->state.cookielist = cl; /* store the list for later use */ } + else { + /* clear the list of cookie files */ + curl_slist_free_all(data->state.cookielist); + data->state.cookielist = NULL; + + if(!data->share || !data->share->cookies) { + /* throw away all existing cookies if this isn't a shared cookie + container */ + Curl_cookie_clearall(data->cookies); + Curl_cookie_cleanup(data->cookies); + } + /* disable the cookie engine */ + data->cookies = NULL; + } break; case CURLOPT_COOKIEJAR: @@ -797,7 +813,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_COOKIELIST: argptr = va_arg(param, char *); - if(argptr == NULL) + if(!argptr) break; if(strcasecompare(argptr, "ALL")) { @@ -2025,6 +2041,20 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], va_arg(param, char *)); break; + case CURLOPT_CAINFO_BLOB: + /* + * Blob that holds CA info for SSL connection. + * Specify entire PEM of the CA certificate + */ +#ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_CAINFO_BLOB) + result = Curl_setblobopt(&data->set.blobs[BLOB_CAINFO], + va_arg(param, struct curl_blob *)); + else +#endif + return CURLE_NOT_BUILT_IN; + + break; #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_CAINFO: /* @@ -2034,6 +2064,19 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY], va_arg(param, char *)); break; + case CURLOPT_PROXY_CAINFO_BLOB: + /* + * Blob that holds CA info for SSL connection proxy. + * Specify entire PEM of the CA certificate + */ +#ifdef USE_SSL + if(Curl_ssl->supports & SSLSUPP_CAINFO_BLOB) + result = Curl_setblobopt(&data->set.blobs[BLOB_CAINFO_PROXY], + va_arg(param, struct curl_blob *)); + else +#endif + return CURLE_NOT_BUILT_IN; + break; #endif case CURLOPT_CAPATH: /* @@ -2155,7 +2198,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) else if(arg < UPLOADBUFFER_MIN) arg = UPLOADBUFFER_MIN; - data->set.upload_buffer_size = arg; + data->set.upload_buffer_size = (unsigned int)arg; Curl_safefree(data->state.ulbuf); /* force a realloc next opportunity */ break; @@ -2268,12 +2311,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_SSL_OPTIONS: arg = va_arg(param, long); - data->set.ssl.enable_beast = - (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); + data->set.ssl.enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST); data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); data->set.ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT); data->set.ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA); + data->set.ssl.auto_client_cert = !!(arg & CURLSSLOPT_AUTO_CLIENT_CERT); /* If a setting is added here it should also be added in dohprobe() which sets its own CURLOPT_SSL_OPTIONS based on these settings. */ break; @@ -2281,13 +2324,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_OPTIONS: arg = va_arg(param, long); - data->set.proxy_ssl.enable_beast = - (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); + data->set.proxy_ssl.enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST); data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); - data->set.proxy_ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA); data->set.proxy_ssl.revoke_best_effort = !!(arg & CURLSSLOPT_REVOKE_BEST_EFFORT); + data->set.proxy_ssl.native_ca_store = !!(arg & CURLSSLOPT_NATIVE_CA); + data->set.proxy_ssl.auto_client_cert = + !!(arg & CURLSSLOPT_AUTO_CLIENT_CERT); break; #endif @@ -2895,7 +2939,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.trailer_data = va_arg(param, void *); #endif break; -#ifdef USE_HSTS +#ifndef CURL_DISABLE_HSTS case CURLOPT_HSTSREADFUNCTION: data->set.hsts_read = va_arg(param, curl_hstsread_callback); break; diff --git a/libs/libcurl/src/setup-vms.h b/libs/libcurl/src/setup-vms.h index ba75dc295b..a6710d9076 100644 --- a/libs/libcurl/src/setup-vms.h +++ b/libs/libcurl/src/setup-vms.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -87,7 +87,7 @@ static char *vms_translate_path(const char *path) /* See if the result is in VMS format, if not, we are done */ /* Assume that this is a PATH, not just some data */ test_str = strpbrk(path, ":[<^"); - if(test_str == NULL) { + if(!test_str) { return (char *)path; } @@ -119,7 +119,7 @@ static char *vms_getenv(const char *envvar) /* first use the DECC getenv() function */ result = decc$getenv(envvar); - if(result == NULL) { + if(!result) { return result; } @@ -154,7 +154,7 @@ static struct passwd *vms_getpwuid(uid_t uid) #endif my_passwd = decc_getpwuid(uid); - if(my_passwd == NULL) { + if(!my_passwd) { return my_passwd; } diff --git a/libs/libcurl/src/share.c b/libs/libcurl/src/share.c index 4f1804dbd2..9c43c8f705 100644 --- a/libs/libcurl/src/share.c +++ b/libs/libcurl/src/share.c @@ -235,7 +235,7 @@ Curl_share_lock(struct Curl_easy *data, curl_lock_data type, { struct Curl_share *share = data->share; - if(share == NULL) + if(!share) return CURLSHE_INVALID; if(share->specifier & (1<share; - if(share == NULL) + if(!share) return CURLSHE_INVALID; if(share->specifier & (1<, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -24,7 +24,7 @@ #include "curl_setup.h" #if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && \ - (defined(USE_OPENSSL) || defined(USE_MBEDTLS)) + (defined(USE_OPENSSL) || defined(USE_MBEDTLS) || defined(USE_WOLFSSL)) #include struct sigpipe_ignore { diff --git a/libs/libcurl/src/smb.c b/libs/libcurl/src/smb.c index 183bc12a51..39facb267d 100644 --- a/libs/libcurl/src/smb.c +++ b/libs/libcurl/src/smb.c @@ -88,6 +88,7 @@ const struct Curl_handler Curl_handler_smb = { smb_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SMB, /* defport */ CURLPROTO_SMB, /* protocol */ CURLPROTO_SMB, /* family */ @@ -114,6 +115,7 @@ const struct Curl_handler Curl_handler_smbs = { smb_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SMBS, /* defport */ CURLPROTO_SMBS, /* protocol */ CURLPROTO_SMB, /* family */ @@ -627,9 +629,8 @@ static CURLcode smb_send_and_recv(struct Curl_easy *data, void **msg) /* Check if there is data in the transfer buffer */ if(!smbc->send_size && smbc->upload_size) { - size_t nread = smbc->upload_size > data->set.upload_buffer_size ? - data->set.upload_buffer_size : - smbc->upload_size; + size_t nread = smbc->upload_size > (size_t)data->set.upload_buffer_size ? + (size_t)data->set.upload_buffer_size : smbc->upload_size; data->req.upload_fromhere = data->state.ulbuf; result = Curl_fillreadbuffer(data, nread, &nread); if(result && result != CURLE_AGAIN) diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c index be4cd675ca..feffc05bc9 100644 --- a/libs/libcurl/src/smtp.c +++ b/libs/libcurl/src/smtp.c @@ -136,6 +136,7 @@ const struct Curl_handler Curl_handler_smtp = { smtp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SMTP, /* defport */ CURLPROTO_SMTP, /* protocol */ CURLPROTO_SMTP, /* family */ @@ -164,6 +165,7 @@ const struct Curl_handler Curl_handler_smtps = { smtp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SMTPS, /* defport */ CURLPROTO_SMTPS, /* protocol */ CURLPROTO_SMTP, /* family */ @@ -894,7 +896,7 @@ static CURLcode smtp_state_ehlo_resp(struct Curl_easy *data, for(;;) { size_t llen; size_t wordlen; - unsigned int mechbit; + unsigned short mechbit; while(len && (*line == ' ' || *line == '\t' || @@ -1821,7 +1823,7 @@ CURLcode Curl_smtp_escape_eob(struct Curl_easy *data, const ssize_t nread) return CURLE_OUT_OF_MEMORY; } } - DEBUGASSERT(data->set.upload_buffer_size >= (size_t)nread); + DEBUGASSERT((size_t)data->set.upload_buffer_size >= (size_t)nread); /* Have we already sent part of the EOB? */ eob_sent = smtp->eob; diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c index d1c2a2ed14..5cde4a46a1 100644 --- a/libs/libcurl/src/socks.c +++ b/libs/libcurl/src/socks.c @@ -426,7 +426,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user, */ /* wrong version ? */ - if(socksreq[0] != 0) { + if(socksreq[0]) { failf(data, "SOCKS4 reply has wrong version, version should be 0."); return CURLPX_BAD_VERSION; @@ -742,7 +742,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user, return CURLPX_OK; } /* ignore the first (VER) byte */ - else if(socksreq[1] != 0) { /* status */ + else if(socksreq[1]) { /* status */ failf(data, "User was rejected by the SOCKS5 server (%d %d).", socksreq[0], socksreq[1]); return CURLPX_USER_REJECTED; @@ -927,7 +927,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user, "SOCKS5 reply has wrong version, version should be 5."); return CURLPX_BAD_VERSION; } - else if(socksreq[1] != 0) { /* Anything besides 0 is an error */ + else if(socksreq[1]) { /* Anything besides 0 is an error */ CURLproxycode rc = CURLPX_REPLY_UNASSIGNED; int code = socksreq[1]; failf(data, "Can't complete SOCKS5 connection to %s. (%d)", diff --git a/libs/libcurl/src/socks_gssapi.c b/libs/libcurl/src/socks_gssapi.c index 3ab786d0bd..10b942a984 100644 --- a/libs/libcurl/src/socks_gssapi.c +++ b/libs/libcurl/src/socks_gssapi.c @@ -195,7 +195,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, return CURLE_COULDNT_CONNECT; } - if(gss_send_token.length != 0) { + if(gss_send_token.length) { socksreq[0] = 1; /* GSS-API subnegotiation version */ socksreq[1] = 1; /* authentication message type */ us_length = htons((short)gss_send_token.length); diff --git a/libs/libcurl/src/socks_sspi.c b/libs/libcurl/src/socks_sspi.c index b343538f0c..813c6be574 100644 --- a/libs/libcurl/src/socks_sspi.c +++ b/libs/libcurl/src/socks_sspi.c @@ -198,7 +198,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, return CURLE_COULDNT_CONNECT; } - if(sspi_send_token.cbBuffer != 0) { + if(sspi_send_token.cbBuffer) { socksreq[0] = 1; /* GSS-API subnegotiation version */ socksreq[1] = 1; /* authentication message type */ us_length = htons((short)sspi_send_token.cbBuffer); diff --git a/libs/libcurl/src/splay.c b/libs/libcurl/src/splay.c index 98baf5d871..a94e2c85e9 100644 --- a/libs/libcurl/src/splay.c +++ b/libs/libcurl/src/splay.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1997 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1997 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -42,7 +42,7 @@ struct Curl_tree *Curl_splay(struct curltime i, { struct Curl_tree N, *l, *r, *y; - if(t == NULL) + if(!t) return t; N.smaller = N.larger = NULL; l = r = &N; @@ -50,14 +50,14 @@ struct Curl_tree *Curl_splay(struct curltime i, for(;;) { long comp = compare(i, t->key); if(comp < 0) { - if(t->smaller == NULL) + if(!t->smaller) break; if(compare(i, t->smaller->key) < 0) { y = t->smaller; /* rotate smaller */ t->smaller = y->larger; y->larger = t; t = y; - if(t->smaller == NULL) + if(!t->smaller) break; } r->smaller = t; /* link smaller */ @@ -65,14 +65,14 @@ struct Curl_tree *Curl_splay(struct curltime i, t = t->smaller; } else if(comp > 0) { - if(t->larger == NULL) + if(!t->larger) break; if(compare(i, t->larger->key) > 0) { y = t->larger; /* rotate larger */ t->larger = y->smaller; y->smaller = t; t = y; - if(t->larger == NULL) + if(!t->larger) break; } l->larger = t; /* link larger */ @@ -104,7 +104,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i, (time_t)-1, (unsigned int)-1 }; /* will *NEVER* appear */ - if(node == NULL) + if(!node) return t; if(t != NULL) { @@ -125,7 +125,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i, } } - if(t == NULL) { + if(!t) { node->smaller = node->larger = NULL; } else if(compare(i, t->key) < 0) { @@ -262,7 +262,7 @@ int Curl_splayremove(struct Curl_tree *t, } else { /* Remove the root node */ - if(t->smaller == NULL) + if(!t->smaller) x = t->larger; else { x = Curl_splay(removenode->key, t->smaller); diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c index 3862aabd6f..5298a0d76c 100644 --- a/libs/libcurl/src/strerror.c +++ b/libs/libcurl/src/strerror.c @@ -320,9 +320,12 @@ curl_easy_strerror(CURLcode error) case CURLE_QUIC_CONNECT_ERROR: return "QUIC connection error"; - case CURLE_PROXY: + case CURLE_PROXY: return "proxy handshake error"; + case CURLE_SSL_CLIENTCERT: + return "SSL Client Certificate required"; + /* error codes not used by current libcurl */ case CURLE_OBSOLETE20: case CURLE_OBSOLETE24: diff --git a/libs/libcurl/src/system_win32.c b/libs/libcurl/src/system_win32.c index 2132f43ef7..2939fd0d74 100644 --- a/libs/libcurl/src/system_win32.c +++ b/libs/libcurl/src/system_win32.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2016 - 2020, Steve Holme, . + * Copyright (C) 2016 - 2021, Steve Holme, . * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -58,7 +58,7 @@ CURLcode Curl_win32_init(long flags) wVersionRequested = MAKEWORD(2, 2); res = WSAStartup(wVersionRequested, &wsaData); - if(res != 0) + if(res) /* Tell the user that we couldn't find a usable */ /* winsock.dll. */ return CURLE_FAILED_INIT; diff --git a/libs/libcurl/src/telnet.c b/libs/libcurl/src/telnet.c index f96a4cb4c5..fdd137fb0c 100644 --- a/libs/libcurl/src/telnet.c +++ b/libs/libcurl/src/telnet.c @@ -185,6 +185,7 @@ const struct Curl_handler Curl_handler_telnet = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_TELNET, /* defport */ CURLPROTO_TELNET, /* protocol */ CURLPROTO_TELNET, /* family */ @@ -921,7 +922,7 @@ static void suboption(struct Curl_easy *data) size_t tmplen = (strlen(v->data) + 1); /* Add the variable only if it fits */ if(len + tmplen < (int)sizeof(temp)-6) { - if(sscanf(v->data, "%127[^,],%127s", varname, varval)) { + if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) { msnprintf((char *)&temp[len], sizeof(temp) - len, "%c%s%c%s", CURL_NEW_ENV_VAR, varname, CURL_NEW_ENV_VALUE, varval); diff --git a/libs/libcurl/src/tftp.c b/libs/libcurl/src/tftp.c index 76d3ff4515..11150af361 100644 --- a/libs/libcurl/src/tftp.c +++ b/libs/libcurl/src/tftp.c @@ -182,6 +182,7 @@ const struct Curl_handler Curl_handler_tftp = { tftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_TFTP, /* defport */ CURLPROTO_TFTP, /* protocol */ CURLPROTO_TFTP, /* family */ @@ -319,7 +320,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state, const char *option, *value; tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value); - if(tmp == NULL) { + if(!tmp) { failf(data, "Malformed ACK packet, rejecting"); return CURLE_TFTP_ILLEGAL; } @@ -776,7 +777,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event) return result; state->sbytes += (int)cb; state->data->req.upload_fromhere += cb; - } while(state->sbytes < state->blksize && cb != 0); + } while(state->sbytes < state->blksize && cb); sbytes = sendto(state->sockfd, (void *) state->spacket.data, 4 + state->sbytes, SEND_4TH_ARG, @@ -1256,7 +1257,7 @@ static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done) failf(data, "%s", Curl_strerror(error, buffer, sizeof(buffer))); state->event = TFTP_EVENT_ERROR; } - else if(rc != 0) { + else if(rc) { result = tftp_receive_packet(data); if(result) return result; diff --git a/libs/libcurl/src/timeval.c b/libs/libcurl/src/timeval.c index 8523dad400..ca98fe50e5 100644 --- a/libs/libcurl/src/timeval.c +++ b/libs/libcurl/src/timeval.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -78,14 +78,16 @@ struct curltime Curl_now(void) ** code compiles but fails during run-time if clock_gettime() is ** called on unsupported OS version. */ -#if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1) +#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \ + (HAVE_BUILTIN_AVAILABLE == 1) bool have_clock_gettime = FALSE; if(__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *)) have_clock_gettime = TRUE; #endif if( -#if defined(__APPLE__) && (HAVE_BUILTIN_AVAILABLE == 1) +#if defined(__APPLE__) && defined(HAVE_BUILTIN_AVAILABLE) && \ + (HAVE_BUILTIN_AVAILABLE == 1) have_clock_gettime && #endif (0 == clock_gettime(CLOCK_MONOTONIC, &tsnow))) { diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index 56ad5e612e..bca4e548fa 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -99,6 +99,8 @@ char *Curl_checkheaders(const struct Curl_easy *data, { struct curl_slist *head; size_t thislen = strlen(thisheader); + DEBUGASSERT(thislen); + DEBUGASSERT(thisheader[thislen-1] != ':'); for(head = data->set.headers; head; head = head->next) { if(strncasecompare(head->data, thisheader, thislen) && @@ -495,11 +497,13 @@ static int data_pending(const struct Curl_easy *data) return Curl_quic_data_pending(data); #endif + if(conn->handler->protocol&PROTO_FAMILY_FTP) + return Curl_ssl_data_pending(conn, SECONDARYSOCKET); + /* in the case of libssh2, we can never be really sure that we have emptied its internal buffers so we MUST always try until we get EAGAIN back */ return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) || #if defined(USE_NGHTTP2) - Curl_ssl_data_pending(conn, FIRSTSOCKET) || /* For HTTP/2, we may read up everything including response body with header fields in Curl_http_readwrite_headers. If no content-length is provided, curl waits for the connection @@ -507,10 +511,9 @@ static int data_pending(const struct Curl_easy *data) TRUE. The thing is if we read everything, then http2_recv won't be called and we cannot signal the HTTP/2 stream has closed. As a workaround, we return nonzero here to call http2_recv. */ - ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20); -#else - Curl_ssl_data_pending(conn, FIRSTSOCKET); + ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20) || #endif + Curl_ssl_data_pending(conn, FIRSTSOCKET); } /* @@ -830,7 +833,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, Make sure that ALL_CONTENT_ENCODINGS contains all the encodings handled here. */ if(data->set.http_ce_skip || !k->writer_stack) { - if(!k->ignorebody) { + if(!k->ignorebody && nread) { #ifndef CURL_DISABLE_POP3 if(conn->handler->protocol & PROTO_FAMILY_POP3) result = Curl_pop3_write(data, k->str, nread); @@ -840,7 +843,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, nread); } } - else if(!k->ignorebody) + else if(!k->ignorebody && nread) result = Curl_unencode_write(data, k->writer_stack, k->str, nread); } k->badheader = HEADER_NORMAL; /* taken care of now */ diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index 19fcfb842c..1ee38af0d5 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -292,6 +292,7 @@ static const struct Curl_handler Curl_handler_dummy = { ZERO_NULL, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ 0, /* defport */ 0, /* protocol */ 0, /* family */ @@ -923,14 +924,14 @@ socks_proxy_info_matches(const struct proxy_info *data, /* the user information is case-sensitive or at least it is not defined as case-insensitive see https://tools.ietf.org/html/rfc3986#section-3.2.1 */ - if((data->user == NULL) != (needle->user == NULL)) + if(!data->user != !needle->user) return FALSE; /* curl_strequal does a case insentive comparison, so do not use it here! */ if(data->user && needle->user && strcmp(data->user, needle->user) != 0) return FALSE; - if((data->passwd == NULL) != (needle->passwd == NULL)) + if(!data->passwd != !needle->passwd) return FALSE; /* curl_strequal does a case insentive comparison, so do not use it here! */ if(data->passwd && @@ -1171,6 +1172,12 @@ ConnectionExists(struct Curl_easy *data, continue; } + if(data->set.ipver != CURL_IPRESOLVE_WHATEVER + && data->set.ipver != check->ip_version) { + /* skip because the connection is not via the requested IP version */ + continue; + } + if(bundle->multiuse == BUNDLE_MULTIPLEX) multiplexed = CONN_INUSE(check); @@ -1315,6 +1322,13 @@ ConnectionExists(struct Curl_easy *data, } } + /* If multiplexing isn't enabled on the h2 connection and h1 is + explicitly requested, handle it: */ + if((needle->handler->protocol & PROTO_FAMILY_HTTP) && + (check->httpversion >= 20) && + (data->state.httpwant < CURL_HTTP_VERSION_2_0)) + continue; + if((needle->handler->flags&PROTOPT_SSL) #ifndef CURL_DISABLE_PROXY || !needle->bits.httpproxy || needle->bits.tunnel_proxy @@ -1944,7 +1958,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; } -#ifdef USE_HSTS +#ifndef CURL_DISABLE_HSTS if(data->hsts && strcasecompare("http", data->state.up.scheme)) { if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) { char *url; @@ -3556,7 +3570,7 @@ static CURLcode create_conn(struct Curl_easy *data, #ifdef USE_UNIX_SOCKETS if(data->set.str[STRING_UNIX_SOCKET_PATH]) { conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]); - if(conn->unix_domain_socket == NULL) { + if(!conn->unix_domain_socket) { result = CURLE_OUT_OF_MEMORY; goto out; } @@ -3731,6 +3745,7 @@ static CURLcode create_conn(struct Curl_easy *data, data->set.ssl.primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT]; + data->set.ssl.primary.ca_info_blob = data->set.blobs[BLOB_CAINFO]; data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES]; #ifndef CURL_DISABLE_PROXY @@ -3746,6 +3761,8 @@ static CURLcode create_conn(struct Curl_easy *data, data->set.proxy_ssl.primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; + data->set.proxy_ssl.primary.ca_info_blob = + data->set.blobs[BLOB_CAINFO_PROXY]; data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c index e3a788221b..6483208ec7 100644 --- a/libs/libcurl/src/urlapi.c +++ b/libs/libcurl/src/urlapi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -667,6 +667,94 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname) #define HOSTNAME_END(x) (((x) == '/') || ((x) == '?') || ((x) == '#')) +/* + * Handle partial IPv4 numerical addresses and different bases, like + * '16843009', '0x7f', '0x7f.1' '0177.1.1.1' etc. + * + * If the given input string is syntactically wrong or any part for example is + * too big, this function returns FALSE and doesn't create any output. + * + * Output the "normalized" version of that input string in plain quad decimal + * integers and return TRUE. + */ +static bool ipv4_normalize(const char *hostname, char *outp, size_t olen) +{ + bool done = FALSE; + int n = 0; + const char *c = hostname; + unsigned long parts[4] = {0, 0, 0, 0}; + + while(!done) { + char *endp; + unsigned long l; + if((*c < '0') || (*c > '9')) + /* most importantly this doesn't allow a leading plus or minus */ + return FALSE; + l = strtoul(c, &endp, 0); + + /* overflow or nothing parsed at all */ + if(((l == ULONG_MAX) && (errno == ERANGE)) || (endp == c)) + return FALSE; + +#if SIZEOF_LONG > 4 + /* a value larger than 32 bits */ + if(l > UINT_MAX) + return FALSE; +#endif + + parts[n] = l; + c = endp; + + switch (*c) { + case '.' : + if(n == 3) + return FALSE; + n++; + c++; + break; + + case '\0': + done = TRUE; + break; + + default: + return FALSE; + } + } + + /* this is deemed a valid IPv4 numerical address */ + + switch(n) { + case 0: /* a -- 32 bits */ + msnprintf(outp, olen, "%u.%u.%u.%u", + parts[0] >> 24, (parts[0] >> 16) & 0xff, + (parts[0] >> 8) & 0xff, parts[0] & 0xff); + break; + case 1: /* a.b -- 8.24 bits */ + if((parts[0] > 0xff) || (parts[1] > 0xffffff)) + return FALSE; + msnprintf(outp, olen, "%u.%u.%u.%u", + parts[0], (parts[1] >> 16) & 0xff, + (parts[1] >> 8) & 0xff, parts[1] & 0xff); + break; + case 2: /* a.b.c -- 8.8.16 bits */ + if((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xffff)) + return FALSE; + msnprintf(outp, olen, "%u.%u.%u.%u", + parts[0], parts[1], (parts[2] >> 8) & 0xff, + parts[2] & 0xff); + break; + case 3: /* a.b.c.d -- 8.8.8.8 bits */ + if((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff) || + (parts[3] > 0xff)) + return FALSE; + msnprintf(outp, olen, "%u.%u.%u.%u", + parts[0], parts[1], parts[2], parts[3]); + break; + } + return TRUE; +} + static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) { char *path; @@ -899,6 +987,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) } if(hostname) { + char normalized_ipv4[sizeof("255.255.255.255") + 1]; /* * Parse the login details and strip them out of the host name. */ @@ -922,7 +1011,10 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) return result; } - u->host = strdup(hostname); + if(ipv4_normalize(hostname, normalized_ipv4, sizeof(normalized_ipv4))) + u->host = strdup(normalized_ipv4); + else + u->host = strdup(hostname); if(!u->host) return CURLUE_OUT_OF_MEMORY; diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index fec875652c..fb905c36c5 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -253,6 +253,7 @@ struct ssl_primary_config { char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ char *pinned_key; struct curl_blob *cert_blob; + struct curl_blob *ca_info_blob; char *curves; /* list of curves to use */ BIT(verifypeer); /* set TRUE if this is desired */ BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */ @@ -286,6 +287,8 @@ struct ssl_config_data { BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation list errors */ BIT(native_ca_store); /* use the native ca store of operating system */ + BIT(auto_client_cert); /* automatically locate and use a client + certificate for authentication (Schannel) */ }; struct ssl_general_config { @@ -791,12 +794,16 @@ struct Curl_handler { struct connectdata *conn, unsigned int checks_to_perform); + /* attach() attaches this transfer to this connection */ + void (*attach)(struct Curl_easy *data, struct connectdata *conn); + int defport; /* Default port. */ unsigned int protocol; /* See CURLPROTO_* - this needs to be the single specific protocol bit */ unsigned int family; /* single bit for protocol family; basically the non-TLS name of the protocol this is */ unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */ + }; #define PROTOPT_NONE 0 /* nothing extra */ @@ -855,25 +862,8 @@ struct proxy_info { char *passwd; /* proxy password string, allocated */ }; -/* struct for HTTP CONNECT state data */ -struct http_connect_state { - struct dynbuf rcvbuf; - enum keeponval { - KEEPON_DONE, - KEEPON_CONNECT, - KEEPON_IGNORE - } keepon; - curl_off_t cl; /* size of content to read and ignore */ - enum { - TUNNEL_INIT, /* init/default/no tunnel state */ - TUNNEL_CONNECT, /* CONNECT has been sent off */ - TUNNEL_COMPLETE /* CONNECT response received completely */ - } tunnel_state; - BIT(chunked_encoding); - BIT(close_connection); -}; - struct ldapconninfo; +struct http_connect_state; /* for the (SOCKS) connect state machine */ enum connect_t { @@ -1602,6 +1592,8 @@ enum dupblob { BLOB_KEY_PROXY, BLOB_SSL_ISSUERCERT, BLOB_SSL_ISSUERCERT_PROXY, + BLOB_CAINFO, + BLOB_CAINFO_PROXY, BLOB_LAST }; @@ -1664,7 +1656,7 @@ struct UserDefined { curl_conv_callback convtonetwork; /* function to convert from UTF-8 encoding: */ curl_conv_callback convfromutf8; -#ifdef USE_HSTS +#ifndef CURL_DISABLE_HSTS curl_hstsread_callback hsts_read; void *hsts_read_userp; curl_hstswrite_callback hsts_write; @@ -1717,8 +1709,8 @@ struct UserDefined { struct ssl_general_config general_ssl; /* general user defined SSL stuff */ long dns_cache_timeout; /* DNS cache timeout */ long buffer_size; /* size of receive buffer to use */ - size_t upload_buffer_size; /* size of upload buffer to use, - keep it >= CURL_MAX_WRITE_SIZE */ + unsigned int upload_buffer_size; /* size of upload buffer to use, + keep it >= CURL_MAX_WRITE_SIZE */ void *private_data; /* application-private data */ struct curl_slist *http200aliases; /* linked list of aliases for http200 */ unsigned char ipver; /* the CURL_IPRESOLVE_* defines in the public header @@ -1926,7 +1918,7 @@ struct Curl_easy { NOTE that the 'cookie' field in the UserDefined struct defines if the "engine" is to be used or not. */ -#ifdef USE_HSTS +#ifndef CURL_DISABLE_HSTS struct hsts *hsts; #endif #ifndef CURL_DISABLE_ALTSVC diff --git a/libs/libcurl/src/vauth/cleartext.c b/libs/libcurl/src/vauth/cleartext.c index 620dba03ef..d17e16f108 100644 --- a/libs/libcurl/src/vauth/cleartext.c +++ b/libs/libcurl/src/vauth/cleartext.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -32,7 +32,6 @@ #include "urldata.h" #include "vauth/vauth.h" -#include "curl_base64.h" #include "curl_md5.h" #include "warnless.h" #include "strtok.h" @@ -51,31 +50,24 @@ * * Parameters: * - * data [in] - The session handle. * authzid [in] - The authorization identity. * authcid [in] - The authentication identity. * passwd [in] - The password. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ -CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, - const char *authzid, +CURLcode Curl_auth_create_plain_message(const char *authzid, const char *authcid, const char *passwd, - char **outptr, size_t *outlen) + struct bufref *out) { - CURLcode result; char *plainauth; + size_t plainlen; size_t zlen; size_t clen; size_t plen; - size_t plainlen; - *outlen = 0; - *outptr = NULL; zlen = (authzid == NULL ? 0 : strlen(authzid)); clen = strlen(authcid); plen = strlen(passwd); @@ -86,23 +78,20 @@ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; plainlen = zlen + clen + plen + 2; - plainauth = malloc(plainlen); + plainauth = malloc(plainlen + 1); if(!plainauth) return CURLE_OUT_OF_MEMORY; /* Calculate the reply */ - if(zlen != 0) + if(zlen) memcpy(plainauth, authzid, zlen); plainauth[zlen] = '\0'; memcpy(plainauth + zlen + 1, authcid, clen); plainauth[zlen + clen + 1] = '\0'; memcpy(plainauth + zlen + clen + 2, passwd, plen); - - /* Base64 encode the reply */ - result = Curl_base64_encode(data, plainauth, plainlen, outptr, outlen); - free(plainauth); - - return result; + plainauth[plainlen] = '\0'; + Curl_bufref_set(out, plainauth, plainlen, curl_free); + return CURLE_OK; } /* @@ -113,34 +102,15 @@ CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, * * Parameters: * - * data [in] - The session handle. * valuep [in] - The user name or user's password. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ -CURLcode Curl_auth_create_login_message(struct Curl_easy *data, - const char *valuep, char **outptr, - size_t *outlen) +CURLcode Curl_auth_create_login_message(const char *valuep, struct bufref *out) { - size_t vlen = strlen(valuep); - - if(!vlen) { - /* Calculate an empty reply */ - *outptr = strdup("="); - if(*outptr) { - *outlen = (size_t) 1; - return CURLE_OK; - } - - *outlen = 0; - return CURLE_OUT_OF_MEMORY; - } - - /* Base64 encode the value */ - return Curl_base64_encode(data, valuep, vlen, outptr, outlen); + Curl_bufref_set(out, valuep, strlen(valuep), NULL); + return CURLE_OK; } /* @@ -151,20 +121,16 @@ CURLcode Curl_auth_create_login_message(struct Curl_easy *data, * * Parameters: * - * data [in] - The session handle. * user [in] - The user name. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ -CURLcode Curl_auth_create_external_message(struct Curl_easy *data, - const char *user, char **outptr, - size_t *outlen) +CURLcode Curl_auth_create_external_message(const char *user, + struct bufref *out) { /* This is the same formatting as the login message */ - return Curl_auth_create_login_message(data, user, outptr, outlen); + return Curl_auth_create_login_message(user, out); } #endif /* if no users */ diff --git a/libs/libcurl/src/vauth/cram.c b/libs/libcurl/src/vauth/cram.c index 1a376259a8..9ddb0ac379 100644 --- a/libs/libcurl/src/vauth/cram.c +++ b/libs/libcurl/src/vauth/cram.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,7 +30,6 @@ #include "urldata.h" #include "vauth/vauth.h" -#include "curl_base64.h" #include "curl_hmac.h" #include "curl_md5.h" #include "warnless.h" @@ -40,69 +39,31 @@ #include "curl_memory.h" #include "memdebug.h" -/* - * Curl_auth_decode_cram_md5_message() - * - * This is used to decode an already encoded CRAM-MD5 challenge message. - * - * Parameters: - * - * chlg64 [in] - The base64 encoded challenge message. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr, - size_t *outlen) -{ - CURLcode result = CURLE_OK; - size_t chlg64len = strlen(chlg64); - - *outptr = NULL; - *outlen = 0; - - /* Decode the challenge if necessary */ - if(chlg64len && *chlg64 != '=') - result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen); - - return result; -} /* * Curl_auth_create_cram_md5_message() * - * This is used to generate an already encoded CRAM-MD5 response message ready - * for sending to the recipient. + * This is used to generate a CRAM-MD5 response message ready for sending to + * the recipient. * * Parameters: * - * data [in] - The session handle. * chlg [in] - The challenge. * userp [in] - The user name. * passwdp [in] - The user's password. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ -CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data, - const char *chlg, +CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg, const char *userp, const char *passwdp, - char **outptr, size_t *outlen) + struct bufref *out) { - CURLcode result = CURLE_OK; - size_t chlglen = 0; struct HMAC_context *ctxt; unsigned char digest[MD5_DIGEST_LEN]; char *response; - if(chlg) - chlglen = strlen(chlg); - /* Compute the digest using the password as the key */ ctxt = Curl_HMAC_init(Curl_HMAC_MD5, (const unsigned char *) passwdp, @@ -111,9 +72,9 @@ CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; /* Update the digest with the given challenge */ - if(chlglen > 0) - Curl_HMAC_update(ctxt, (const unsigned char *) chlg, - curlx_uztoui(chlglen)); + if(Curl_bufref_len(chlg)) + Curl_HMAC_update(ctxt, Curl_bufref_ptr(chlg), + curlx_uztoui(Curl_bufref_len(chlg))); /* Finalise the digest */ Curl_HMAC_final(ctxt, digest); @@ -127,12 +88,8 @@ CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data, if(!response) return CURLE_OUT_OF_MEMORY; - /* Base64 encode the response */ - result = Curl_base64_encode(data, response, 0, outptr, outlen); - - free(response); - - return result; + Curl_bufref_set(out, response, strlen(response), curl_free); + return CURLE_OK; } #endif /* !CURL_DISABLE_CRYPTO_AUTH */ diff --git a/libs/libcurl/src/vauth/digest.c b/libs/libcurl/src/vauth/digest.c index 559852fcba..a04ffab6fb 100644 --- a/libs/libcurl/src/vauth/digest.c +++ b/libs/libcurl/src/vauth/digest.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -254,7 +254,7 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value) * * Parameters: * - * chlg64 [in] - The base64 encoded challenge message. + * chlgref [in] - The challenge message. * nonce [in/out] - The buffer where the nonce will be stored. * nlen [in] - The length of the nonce buffer. * realm [in/out] - The buffer where the realm will be stored. @@ -266,55 +266,35 @@ static CURLcode auth_digest_get_qop_values(const char *options, int *value) * * Returns CURLE_OK on success. */ -static CURLcode auth_decode_digest_md5_message(const char *chlg64, +static CURLcode auth_decode_digest_md5_message(const struct bufref *chlgref, char *nonce, size_t nlen, char *realm, size_t rlen, char *alg, size_t alen, char *qop, size_t qlen) { - CURLcode result = CURLE_OK; - unsigned char *chlg = NULL; - size_t chlglen = 0; - size_t chlg64len = strlen(chlg64); - - /* Decode the base-64 encoded challenge message */ - if(chlg64len && *chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } + const char *chlg = (const char *) Curl_bufref_ptr(chlgref); /* Ensure we have a valid challenge message */ - if(!chlg) + if(!Curl_bufref_len(chlgref)) return CURLE_BAD_CONTENT_ENCODING; /* Retrieve nonce string from the challenge */ - if(!auth_digest_get_key_value((char *) chlg, "nonce=\"", nonce, nlen, - '\"')) { - free(chlg); + if(!auth_digest_get_key_value(chlg, "nonce=\"", nonce, nlen, '\"')) return CURLE_BAD_CONTENT_ENCODING; - } /* Retrieve realm string from the challenge */ - if(!auth_digest_get_key_value((char *) chlg, "realm=\"", realm, rlen, - '\"')) { + if(!auth_digest_get_key_value(chlg, "realm=\"", realm, rlen, '\"')) { /* Challenge does not have a realm, set empty string [RFC2831] page 6 */ strcpy(realm, ""); } /* Retrieve algorithm string from the challenge */ - if(!auth_digest_get_key_value((char *) chlg, "algorithm=", alg, alen, ',')) { - free(chlg); + if(!auth_digest_get_key_value(chlg, "algorithm=", alg, alen, ',')) return CURLE_BAD_CONTENT_ENCODING; - } /* Retrieve qop-options string from the challenge */ - if(!auth_digest_get_key_value((char *) chlg, "qop=\"", qop, qlen, '\"')) { - free(chlg); + if(!auth_digest_get_key_value(chlg, "qop=\"", qop, qlen, '\"')) return CURLE_BAD_CONTENT_ENCODING; - } - - free(chlg); return CURLE_OK; } @@ -342,22 +322,20 @@ bool Curl_auth_is_digest_supported(void) * Parameters: * * data [in] - The session handle. - * chlg64 [in] - The base64 encoded challenge message. + * chlg [in] - The challenge message. * userp [in] - The user name. * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, - const char *chlg64, + const struct bufref *chlg, const char *userp, const char *passwdp, const char *service, - char **outptr, size_t *outlen) + struct bufref *out) { size_t i; struct MD5_context *ctxt; @@ -378,9 +356,10 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, char *spn = NULL; /* Decode the challenge message */ - CURLcode result = auth_decode_digest_md5_message(chlg64, nonce, - sizeof(nonce), realm, - sizeof(realm), algorithm, + CURLcode result = auth_decode_digest_md5_message(chlg, + nonce, sizeof(nonce), + realm, sizeof(realm), + algorithm, sizeof(algorithm), qop_options, sizeof(qop_options)); @@ -500,11 +479,8 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, if(!response) return CURLE_OUT_OF_MEMORY; - /* Base64 encode the response */ - result = Curl_base64_encode(data, response, 0, outptr, outlen); - - free(response); - + /* Return the response. */ + Curl_bufref_set(out, response, strlen(response), curl_free); return result; } diff --git a/libs/libcurl/src/vauth/digest_sspi.c b/libs/libcurl/src/vauth/digest_sspi.c index dad947a37e..2602ffd363 100644 --- a/libs/libcurl/src/vauth/digest_sspi.c +++ b/libs/libcurl/src/vauth/digest_sspi.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2014 - 2016, Steve Holme, . - * Copyright (C) 2015 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 2015 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -32,7 +32,6 @@ #include "vauth/vauth.h" #include "vauth/digest.h" #include "urldata.h" -#include "curl_base64.h" #include "warnless.h" #include "curl_multibyte.h" #include "sendf.h" @@ -79,28 +78,24 @@ bool Curl_auth_is_digest_supported(void) * Parameters: * * data [in] - The session handle. - * chlg64 [in] - The base64 encoded challenge message. + * chlg [in] - The challenge message. * userp [in] - The user name in the format User or Domain\User. * passwdp [in] - The user's password. * service [in] - The service type such as http, smtp, pop or imap. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, - const char *chlg64, + const struct bufref *chlg, const char *userp, const char *passwdp, const char *service, - char **outptr, size_t *outlen) + struct bufref *out) { CURLcode result = CURLE_OK; TCHAR *spn = NULL; - size_t chlglen = 0; size_t token_max = 0; - unsigned char *input_token = NULL; unsigned char *output_token = NULL; CredHandle credentials; CtxtHandle context; @@ -115,17 +110,9 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, unsigned long attrs; TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ - /* Decode the base-64 encoded challenge message */ - if(strlen(chlg64) && *chlg64 != '=') { - result = Curl_base64_decode(chlg64, &input_token, &chlglen); - if(result) - return result; - } - /* Ensure we have a valid challenge message */ - if(!input_token) { + if(!Curl_bufref_len(chlg)) { infof(data, "DIGEST-MD5 handshake failure (empty challenge message)\n"); - return CURLE_BAD_CONTENT_ENCODING; } @@ -133,8 +120,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), &SecurityPackage); if(status != SEC_E_OK) { - free(input_token); - failf(data, "SSPI: couldn't get auth info"); return CURLE_AUTH_ERROR; } @@ -146,18 +131,13 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, /* Allocate our response buffer */ output_token = malloc(token_max); - if(!output_token) { - free(input_token); - + if(!output_token) return CURLE_OUT_OF_MEMORY; - } /* Generate our SPN */ spn = Curl_auth_build_spn(service, data->conn->host.name, NULL); if(!spn) { free(output_token); - free(input_token); - return CURLE_OUT_OF_MEMORY; } @@ -167,8 +147,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, if(result) { free(spn); free(output_token); - free(input_token); - return result; } @@ -190,8 +168,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, Curl_sspi_free_identity(p_identity); free(spn); free(output_token); - free(input_token); - return CURLE_LOGIN_DENIED; } @@ -200,8 +176,8 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, chlg_desc.cBuffers = 1; chlg_desc.pBuffers = &chlg_buf; chlg_buf.BufferType = SECBUFFER_TOKEN; - chlg_buf.pvBuffer = input_token; - chlg_buf.cbBuffer = curlx_uztoul(chlglen); + chlg_buf.pvBuffer = (void *) Curl_bufref_ptr(chlg); + chlg_buf.cbBuffer = curlx_uztoul(Curl_bufref_len(chlg)); /* Setup the response "output" security buffer */ resp_desc.ulVersion = SECBUFFER_VERSION; @@ -227,7 +203,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, Curl_sspi_free_identity(p_identity); free(spn); free(output_token); - free(input_token); if(status == SEC_E_INSUFFICIENT_MEMORY) return CURLE_OUT_OF_MEMORY; @@ -238,9 +213,8 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, return CURLE_AUTH_ERROR; } - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) output_token, resp_buf.cbBuffer, - outptr, outlen); + /* Return the response. */ + Curl_bufref_set(out, output_token, resp_buf.cbBuffer, curl_free); /* Free our handles */ s_pSecFn->DeleteSecurityContext(&context); @@ -252,12 +226,6 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, /* Free the SPN */ free(spn); - /* Free the response buffer */ - free(output_token); - - /* Free the decoded challenge message */ - free(input_token); - return result; } diff --git a/libs/libcurl/src/vauth/gsasl.c b/libs/libcurl/src/vauth/gsasl.c index 02a06357f0..40fef53c93 100644 --- a/libs/libcurl/src/vauth/gsasl.c +++ b/libs/libcurl/src/vauth/gsasl.c @@ -28,7 +28,6 @@ #include -#include "curl_base64.h" #include "vauth/vauth.h" #include "urldata.h" #include "sendf.h" @@ -94,42 +93,24 @@ CURLcode Curl_auth_gsasl_start(struct Curl_easy *data, } CURLcode Curl_auth_gsasl_token(struct Curl_easy *data, - const char *chlg64, + const struct bufref *chlg, struct gsasldata *gsasl, - char **outptr, size_t *outlen) + struct bufref *out) { - unsigned char *chlg = NULL; - size_t chlglen = 0; - CURLcode result = CURLE_OK; int res; char *response; - - if(chlg64) { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } + size_t outlen; res = gsasl_step(gsasl->client, - (const char *)chlg, chlglen, &response, outlen); + (const char *) Curl_bufref_ptr(chlg), Curl_bufref_len(chlg), + &response, &outlen); if(res != GSASL_OK && res != GSASL_NEEDS_MORE) { - if(chlg64) - free(chlg); failf(data, "GSASL step: %s\n", gsasl_strerror(res)); return CURLE_BAD_CONTENT_ENCODING; } - if(*outlen > 0) { - result = Curl_base64_encode(data, response, 0, outptr, outlen); - gsasl_free(response); - } - else { - *outptr = strdup(""); - if(!*outptr) - result = CURLE_OUT_OF_MEMORY; - } - - return result; + Curl_bufref_set(out, response, outlen, gsasl_free); + return CURLE_OK; } void Curl_auth_gsasl_cleanup(struct gsasldata *gsasl) diff --git a/libs/libcurl/src/vauth/krb5_gssapi.c b/libs/libcurl/src/vauth/krb5_gssapi.c index 0412815e93..b43982b9bd 100644 --- a/libs/libcurl/src/vauth/krb5_gssapi.c +++ b/libs/libcurl/src/vauth/krb5_gssapi.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2014 - 2019, Steve Holme, . - * Copyright (C) 2015 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 2015 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -32,7 +32,6 @@ #include "vauth/vauth.h" #include "curl_sasl.h" #include "urldata.h" -#include "curl_base64.h" #include "curl_gssapi.h" #include "sendf.h" #include "curl_printf.h" @@ -70,12 +69,9 @@ bool Curl_auth_is_gssapi_supported(void) * host [in[ - The host name. * mutual_auth [in] - Flag specifying whether or not mutual authentication * is enabled. - * chlg64 [in] - Pointer to the optional base64 encoded challenge - * message. + * chlg [in] - Optional challenge message. * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ @@ -85,13 +81,11 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, const char *service, const char *host, const bool mutual_auth, - const char *chlg64, + const struct bufref *chlg, struct kerberos5data *krb5, - char **outptr, size_t *outlen) + struct bufref *out) { CURLcode result = CURLE_OK; - size_t chlglen = 0; - unsigned char *chlg = NULL; OM_uint32 major_status; OM_uint32 minor_status; OM_uint32 unused_status; @@ -127,24 +121,13 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, free(spn); } - if(chlg64 && *chlg64) { - /* Decode the base-64 encoded challenge message */ - if(*chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { + if(chlg) { + if(!Curl_bufref_len(chlg)) { infof(data, "GSSAPI handshake failure (empty challenge message)\n"); - return CURLE_BAD_CONTENT_ENCODING; } - - /* Setup the challenge "input" security buffer */ - input_token.value = chlg; - input_token.length = chlglen; + input_token.value = (void *) Curl_bufref_ptr(chlg); + input_token.length = Curl_bufref_len(chlg); } major_status = Curl_gss_init_sec_context(data, @@ -158,9 +141,6 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, mutual_auth, NULL); - /* Free the decoded challenge as it is not required anymore */ - free(input_token.value); - if(GSS_ERROR(major_status)) { if(output_token.value) gss_release_buffer(&unused_status, &output_token); @@ -172,17 +152,11 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, } if(output_token.value && output_token.length) { - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) output_token.value, - output_token.length, outptr, outlen); - + result = Curl_bufref_memdup(out, output_token.value, output_token.length); gss_release_buffer(&unused_status, &output_token); } - else if(mutual_auth) { - *outptr = strdup(""); - if(!*outptr) - result = CURLE_OUT_OF_MEMORY; - } + else + Curl_bufref_set(out, mutual_auth? "": NULL, 0, NULL); return result; } @@ -196,24 +170,19 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, * Parameters: * * data [in] - The session handle. - * chlg64 [in] - Pointer to the optional base64 encoded challenge message. + * chlg [in] - Optional challenge message. * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, - const char *chlg64, + const struct bufref *chlg, struct kerberos5data *krb5, - char **outptr, - size_t *outlen) + struct bufref *out) { CURLcode result = CURLE_OK; - size_t chlglen = 0; size_t messagelen = 0; - unsigned char *chlg = NULL; unsigned char *message = NULL; OM_uint32 major_status; OM_uint32 minor_status; @@ -228,17 +197,9 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, gss_name_t username = GSS_C_NO_NAME; gss_buffer_desc username_token; - /* Decode the base-64 encoded input message */ - if(strlen(chlg64) && *chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - /* Ensure we have a valid challenge message */ - if(!chlg) { + if(!Curl_bufref_len(chlg)) { infof(data, "GSSAPI handshake failure (empty security message)\n"); - return CURLE_BAD_CONTENT_ENCODING; } @@ -249,9 +210,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, if(GSS_ERROR(major_status)) { Curl_gss_log_error(data, "gss_inquire_context() failed: ", major_status, minor_status); - - free(chlg); - return CURLE_AUTH_ERROR; } @@ -261,15 +219,12 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, if(GSS_ERROR(major_status)) { Curl_gss_log_error(data, "gss_display_name() failed: ", major_status, minor_status); - - free(chlg); - return CURLE_AUTH_ERROR; } /* Setup the challenge "input" security buffer */ - input_token.value = chlg; - input_token.length = chlglen; + input_token.value = (void *) Curl_bufref_ptr(chlg); + input_token.length = Curl_bufref_len(chlg); /* Decrypt the inbound challenge and obtain the qop */ major_status = gss_unwrap(&minor_status, krb5->context, &input_token, @@ -277,27 +232,20 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, if(GSS_ERROR(major_status)) { Curl_gss_log_error(data, "gss_unwrap() failed: ", major_status, minor_status); - gss_release_buffer(&unused_status, &username_token); - free(chlg); - return CURLE_BAD_CONTENT_ENCODING; } /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ if(output_token.length != 4) { infof(data, "GSSAPI handshake failure (invalid security data)\n"); - gss_release_buffer(&unused_status, &username_token); - free(chlg); - return CURLE_BAD_CONTENT_ENCODING; } /* Copy the data out and free the challenge as it is not required anymore */ memcpy(&indata, output_token.value, 4); gss_release_buffer(&unused_status, &output_token); - free(chlg); /* Extract the security layer */ sec_layer = indata & 0x000000FF; @@ -305,7 +253,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, infof(data, "GSSAPI handshake failure (invalid security layer)\n"); gss_release_buffer(&unused_status, &username_token); - return CURLE_BAD_CONTENT_ENCODING; } @@ -323,7 +270,6 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, message = malloc(messagelen); if(!message) { gss_release_buffer(&unused_status, &username_token); - return CURLE_OUT_OF_MEMORY; } @@ -352,16 +298,12 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, if(GSS_ERROR(major_status)) { Curl_gss_log_error(data, "gss_wrap() failed: ", major_status, minor_status); - free(message); - return CURLE_AUTH_ERROR; } - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) output_token.value, - output_token.length, outptr, outlen); - + /* Return the response. */ + result = Curl_bufref_memdup(out, output_token.value, output_token.length); /* Free the output buffer */ gss_release_buffer(&unused_status, &output_token); diff --git a/libs/libcurl/src/vauth/krb5_sspi.c b/libs/libcurl/src/vauth/krb5_sspi.c index b2d1635343..e110644225 100644 --- a/libs/libcurl/src/vauth/krb5_sspi.c +++ b/libs/libcurl/src/vauth/krb5_sspi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2014 - 2020, Steve Holme, . + * Copyright (C) 2014 - 2021, Steve Holme, . * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,7 +30,6 @@ #include "vauth/vauth.h" #include "urldata.h" -#include "curl_base64.h" #include "warnless.h" #include "curl_multibyte.h" #include "sendf.h" @@ -81,11 +80,9 @@ bool Curl_auth_is_gssapi_supported(void) * host [in] - The host name. * mutual_auth [in] - Flag specifying whether or not mutual authentication * is enabled. - * chlg64 [in] - The optional base64 encoded challenge message. + * chlg [in] - Optional challenge message. * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ @@ -95,13 +92,11 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, const char *service, const char *host, const bool mutual_auth, - const char *chlg64, + const struct bufref *chlg, struct kerberos5data *krb5, - char **outptr, size_t *outlen) + struct bufref *out) { CURLcode result = CURLE_OK; - size_t chlglen = 0; - unsigned char *chlg = NULL; CtxtHandle context; PSecPkgInfo SecurityPackage; SecBuffer chlg_buf; @@ -176,18 +171,9 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; } - if(chlg64 && *chlg64) { - /* Decode the base-64 encoded challenge message */ - if(*chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { + if(chlg) { + if(!Curl_bufref_len(chlg)) { infof(data, "GSSAPI handshake failure (empty challenge message)\n"); - return CURLE_BAD_CONTENT_ENCODING; } @@ -196,8 +182,8 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, chlg_desc.cBuffers = 1; chlg_desc.pBuffers = &chlg_buf; chlg_buf.BufferType = SECBUFFER_TOKEN; - chlg_buf.pvBuffer = chlg; - chlg_buf.cbBuffer = curlx_uztoul(chlglen); + chlg_buf.pvBuffer = (void *) Curl_bufref_ptr(chlg); + chlg_buf.cbBuffer = curlx_uztoul(Curl_bufref_len(chlg)); } /* Setup the response "output" security buffer */ @@ -220,16 +206,11 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, &resp_desc, &attrs, &expiry); - /* Free the decoded challenge as it is not required anymore */ - free(chlg); - - if(status == SEC_E_INSUFFICIENT_MEMORY) { + if(status == SEC_E_INSUFFICIENT_MEMORY) return CURLE_OUT_OF_MEMORY; - } - if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { + if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) return CURLE_AUTH_ERROR; - } if(memcmp(&context, krb5->context, sizeof(context))) { s_pSecFn->DeleteSecurityContext(krb5->context); @@ -238,15 +219,12 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, } if(resp_buf.cbBuffer) { - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) resp_buf.pvBuffer, - resp_buf.cbBuffer, outptr, outlen); - } - else if(mutual_auth) { - *outptr = strdup(""); - if(!*outptr) - result = CURLE_OUT_OF_MEMORY; + result = Curl_bufref_memdup(out, resp_buf.pvBuffer, resp_buf.cbBuffer); } + else if(mutual_auth) + Curl_bufref_set(out, "", 0, NULL); + else + Curl_bufref_set(out, NULL, 0, NULL); return result; } @@ -260,26 +238,20 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, * Parameters: * * data [in] - The session handle. - * chlg64 [in] - The optional base64 encoded challenge message. + * chlg [in] - The optional challenge message. * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, - const char *chlg64, + const struct bufref *chlg, struct kerberos5data *krb5, - char **outptr, - size_t *outlen) + struct bufref *out) { - CURLcode result = CURLE_OK; size_t offset = 0; - size_t chlglen = 0; size_t messagelen = 0; size_t appdatalen = 0; - unsigned char *chlg = NULL; unsigned char *trailer = NULL; unsigned char *message = NULL; unsigned char *padding = NULL; @@ -298,17 +270,9 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, SECURITY_STATUS status; char *user_name; - /* Decode the base-64 encoded input message */ - if(strlen(chlg64) && *chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - /* Ensure we have a valid challenge message */ - if(!chlg) { + if(!Curl_bufref_len(chlg)) { infof(data, "GSSAPI handshake failure (empty security message)\n"); - return CURLE_BAD_CONTENT_ENCODING; } @@ -316,35 +280,31 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, status = s_pSecFn->QueryContextAttributes(krb5->context, SECPKG_ATTR_SIZES, &sizes); - if(status != SEC_E_OK) { - free(chlg); - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; + if(status == SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + if(status != SEC_E_OK) return CURLE_AUTH_ERROR; - } /* Get the fully qualified username back from the context */ status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials, SECPKG_CRED_ATTR_NAMES, &names); - if(status != SEC_E_OK) { - free(chlg); - if(status == SEC_E_INSUFFICIENT_MEMORY) - return CURLE_OUT_OF_MEMORY; + if(status == SEC_E_INSUFFICIENT_MEMORY) + return CURLE_OUT_OF_MEMORY; + if(status != SEC_E_OK) return CURLE_AUTH_ERROR; - } /* Setup the "input" security buffer */ input_desc.ulVersion = SECBUFFER_VERSION; input_desc.cBuffers = 2; input_desc.pBuffers = input_buf; input_buf[0].BufferType = SECBUFFER_STREAM; - input_buf[0].pvBuffer = chlg; - input_buf[0].cbBuffer = curlx_uztoul(chlglen); + input_buf[0].pvBuffer = (void *) Curl_bufref_ptr(chlg); + input_buf[0].cbBuffer = curlx_uztoul(Curl_bufref_len(chlg)); input_buf[1].BufferType = SECBUFFER_DATA; input_buf[1].pvBuffer = NULL; input_buf[1].cbBuffer = 0; @@ -353,31 +313,23 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop); if(status != SEC_E_OK) { infof(data, "GSSAPI handshake failure (empty security message)\n"); - - free(chlg); - return CURLE_BAD_CONTENT_ENCODING; } /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ if(input_buf[1].cbBuffer != 4) { infof(data, "GSSAPI handshake failure (invalid security data)\n"); - - free(chlg); - return CURLE_BAD_CONTENT_ENCODING; } /* Copy the data out and free the challenge as it is not required anymore */ memcpy(&indata, input_buf[1].pvBuffer, 4); s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer); - free(chlg); /* Extract the security layer */ sec_layer = indata & 0x000000FF; if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) { infof(data, "GSSAPI handshake failure (invalid security layer)\n"); - return CURLE_BAD_CONTENT_ENCODING; } @@ -479,17 +431,14 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, offset += wrap_buf[1].cbBuffer; memcpy(appdata + offset, wrap_buf[2].pvBuffer, wrap_buf[2].cbBuffer); - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) appdata, appdatalen, outptr, - outlen); - /* Free all of our local buffers */ - free(appdata); free(padding); free(message); free(trailer); - return result; + /* Return the response. */ + Curl_bufref_set(out, appdata, appdatalen, curl_free); + return CURLE_OK; } /* diff --git a/libs/libcurl/src/vauth/ntlm.c b/libs/libcurl/src/vauth/ntlm.c index 4adf49704f..47e53572cb 100644 --- a/libs/libcurl/src/vauth/ntlm.c +++ b/libs/libcurl/src/vauth/ntlm.c @@ -36,7 +36,6 @@ #include "urldata.h" #include "non-ascii.h" #include "sendf.h" -#include "curl_base64.h" #include "curl_ntlm_core.h" #include "curl_gethostname.h" #include "curl_multibyte.h" @@ -157,31 +156,31 @@ static void ntlm_print_hex(FILE *handle, const char *buf, size_t len) * Parameters: * * data [in] - The session handle. - * buffer [in] - The decoded type-2 message. - * size [in] - The input buffer size, at least 32 bytes. + * type2ref [in] - The type-2 message. * ntlm [in/out] - The NTLM data struct being used and modified. * * Returns CURLE_OK on success. */ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, - unsigned char *buffer, - size_t size, + const struct bufref *type2ref, struct ntlmdata *ntlm) { unsigned short target_info_len = 0; unsigned int target_info_offset = 0; + const unsigned char *type2 = Curl_bufref_ptr(type2ref); + size_t type2len = Curl_bufref_len(type2ref); #if defined(CURL_DISABLE_VERBOSE_STRINGS) (void) data; #endif - if(size >= 48) { - target_info_len = Curl_read16_le(&buffer[40]); - target_info_offset = Curl_read32_le(&buffer[44]); + if(type2len >= 48) { + target_info_len = Curl_read16_le(&type2[40]); + target_info_offset = Curl_read32_le(&type2[44]); if(target_info_len > 0) { - if((target_info_offset >= size) || - ((target_info_offset + target_info_len) > size) || - (target_info_offset < 48)) { + if((target_info_offset > type2len) || + (target_info_offset + target_info_len) > type2len || + target_info_offset < 48) { infof(data, "NTLM handshake failure (bad type-2 message). " "Target Info Offset Len is set incorrect by the peer\n"); return CURLE_BAD_CONTENT_ENCODING; @@ -192,7 +191,7 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, if(!ntlm->target_info) return CURLE_OUT_OF_MEMORY; - memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len); + memcpy(ntlm->target_info, &type2[target_info_offset], target_info_len); } } @@ -234,21 +233,20 @@ bool Curl_auth_is_ntlm_supported(void) /* * Curl_auth_decode_ntlm_type2_message() * - * This is used to decode an already encoded NTLM type-2 message. The message - * is first decoded from a base64 string into a raw NTLM message and checked - * for validity before the appropriate data for creating a type-3 message is - * written to the given NTLM data structure. + * This is used to decode an NTLM type-2 message. The raw NTLM message is + * checked * for validity before the appropriate data for creating a type-3 + * message is * written to the given NTLM data structure. * * Parameters: * * data [in] - The session handle. - * type2msg [in] - The base64 encoded type-2 message. + * type2ref [in] - The type-2 message. * ntlm [in/out] - The NTLM data struct being used and modified. * * Returns CURLE_OK on success. */ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, - const char *type2msg, + const struct bufref *type2ref, struct ntlmdata *ntlm) { static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 }; @@ -270,8 +268,8 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, */ CURLcode result = CURLE_OK; - unsigned char *type2 = NULL; - size_t type2_len = 0; + const unsigned char *type2 = Curl_bufref_ptr(type2ref); + size_t type2len = Curl_bufref_len(type2ref); #if defined(NTLM_NEEDS_NSS_INIT) /* Make sure the crypto backend is initialized */ @@ -282,26 +280,12 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, (void)data; #endif - /* Decode the base-64 encoded type-2 message */ - if(strlen(type2msg) && *type2msg != '=') { - result = Curl_base64_decode(type2msg, &type2, &type2_len); - if(result) - return result; - } - - /* Ensure we have a valid type-2 message */ - if(!type2) { - infof(data, "NTLM handshake failure (empty type-2 message)\n"); - return CURLE_BAD_CONTENT_ENCODING; - } - ntlm->flags = 0; - if((type2_len < 32) || + if((type2len < 32) || (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) || (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) { /* This was not a good enough type-2 message */ - free(type2); infof(data, "NTLM handshake failure (bad type-2 message)\n"); return CURLE_BAD_CONTENT_ENCODING; } @@ -310,9 +294,8 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, memcpy(ntlm->nonce, &type2[24], 8); if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) { - result = ntlm_decode_type2_target(data, type2, type2_len, ntlm); + result = ntlm_decode_type2_target(data, type2ref, ntlm); if(result) { - free(type2); infof(data, "NTLM handshake failure (bad type-2 message)\n"); return result; } @@ -327,8 +310,6 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, fprintf(stderr, "**** Header %s\n ", header); }); - free(type2); - return result; } @@ -346,8 +327,8 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length) /* * Curl_auth_create_ntlm_type1_message() * - * This is used to generate an already encoded NTLM type-1 message ready for - * sending to the recipient using the appropriate compile time crypto API. + * This is used to generate an NTLM type-1 message ready for sending to the + * recipient using the appropriate compile time crypto API. * * Parameters: * @@ -357,9 +338,7 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length) * service [in] - The service type such as http, smtp, pop or imap. * host [in] - The host name. * ntlm [in/out] - The NTLM data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ @@ -369,7 +348,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, const char *service, const char *hostname, struct ntlmdata *ntlm, - char **outptr, size_t *outlen) + struct bufref *out) { /* NTLM type-1 message structure: @@ -387,7 +366,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, size_t size; - unsigned char ntlmbuf[NTLM_BUFSIZE]; + char *ntlmbuf; const char *host = ""; /* empty */ const char *domain = ""; /* empty */ size_t hostlen = 0; @@ -395,6 +374,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, size_t hostoff = 0; size_t domoff = hostoff + hostlen; /* This is 0: remember that host and domain are empty */ + (void)data; (void)userp; (void)passwdp; (void)service, @@ -409,38 +389,40 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, #else #define NTLM2FLAG 0 #endif - msnprintf((char *)ntlmbuf, NTLM_BUFSIZE, - NTLMSSP_SIGNATURE "%c" - "\x01%c%c%c" /* 32-bit type = 1 */ - "%c%c%c%c" /* 32-bit NTLM flag field */ - "%c%c" /* domain length */ - "%c%c" /* domain allocated space */ - "%c%c" /* domain name offset */ - "%c%c" /* 2 zeroes */ - "%c%c" /* host length */ - "%c%c" /* host allocated space */ - "%c%c" /* host name offset */ - "%c%c" /* 2 zeroes */ - "%s" /* host name */ - "%s", /* domain string */ - 0, /* trailing zero */ - 0, 0, 0, /* part of type-1 long */ - - LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | - NTLMFLAG_REQUEST_TARGET | - NTLMFLAG_NEGOTIATE_NTLM_KEY | - NTLM2FLAG | - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), - SHORTPAIR(domlen), - SHORTPAIR(domlen), - SHORTPAIR(domoff), - 0, 0, - SHORTPAIR(hostlen), - SHORTPAIR(hostlen), - SHORTPAIR(hostoff), - 0, 0, - host, /* this is empty */ - domain /* this is empty */); + ntlmbuf = aprintf(NTLMSSP_SIGNATURE "%c" + "\x01%c%c%c" /* 32-bit type = 1 */ + "%c%c%c%c" /* 32-bit NTLM flag field */ + "%c%c" /* domain length */ + "%c%c" /* domain allocated space */ + "%c%c" /* domain name offset */ + "%c%c" /* 2 zeroes */ + "%c%c" /* host length */ + "%c%c" /* host allocated space */ + "%c%c" /* host name offset */ + "%c%c" /* 2 zeroes */ + "%s" /* host name */ + "%s", /* domain string */ + 0, /* trailing zero */ + 0, 0, 0, /* part of type-1 long */ + + LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), + SHORTPAIR(domlen), + SHORTPAIR(domlen), + SHORTPAIR(domoff), + 0, 0, + SHORTPAIR(hostlen), + SHORTPAIR(hostlen), + SHORTPAIR(hostoff), + 0, 0, + host, /* this is empty */ + domain /* this is empty */); + + if(!ntlmbuf) + return CURLE_OUT_OF_MEMORY; /* Initial packet length */ size = 32 + hostlen + domlen; @@ -467,8 +449,8 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, fprintf(stderr, "\n****\n"); }); - /* Return with binary blob encoded into base64 */ - return Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen); + Curl_bufref_set(out, ntlmbuf, size, curl_free); + return CURLE_OK; } /* @@ -483,9 +465,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, * userp [in] - The user name in the format User or Domain\User. * passwdp [in] - The user's password. * ntlm [in/out] - The NTLM data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ @@ -493,7 +473,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, const char *userp, const char *passwdp, struct ntlmdata *ntlm, - char **outptr, size_t *outlen) + struct bufref *out) { /* NTLM type-3 message structure: @@ -847,8 +827,8 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, if(result) return CURLE_CONV_FAILED; - /* Return with binary blob encoded into base64 */ - result = Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen); + /* Return the binary blob. */ + result = Curl_bufref_memdup(out, ntlmbuf, size); Curl_auth_cleanup_ntlm(ntlm); diff --git a/libs/libcurl/src/vauth/ntlm_sspi.c b/libs/libcurl/src/vauth/ntlm_sspi.c index 07dc97398e..1b1a176301 100644 --- a/libs/libcurl/src/vauth/ntlm_sspi.c +++ b/libs/libcurl/src/vauth/ntlm_sspi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -28,7 +28,6 @@ #include "vauth/vauth.h" #include "urldata.h" -#include "curl_base64.h" #include "curl_ntlm_core.h" #include "warnless.h" #include "curl_multibyte.h" @@ -78,9 +77,7 @@ bool Curl_auth_is_ntlm_supported(void) * service [in] - The service type such as http, smtp, pop or imap. * host [in] - The host name. * ntlm [in/out] - The NTLM data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ @@ -90,7 +87,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, const char *service, const char *host, struct ntlmdata *ntlm, - char **outptr, size_t *outlen) + struct bufref *out) { PSecPkgInfo SecurityPackage; SecBuffer type_1_buf; @@ -181,9 +178,9 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) return CURLE_AUTH_ERROR; - /* Base64 encode the response */ - return Curl_base64_encode(data, (char *) ntlm->output_token, - type_1_buf.cbBuffer, outptr, outlen); + /* Return the response. */ + Curl_bufref_set(out, ntlm->output_token, type_1_buf.cbBuffer, NULL); + return CURLE_OK; } /* @@ -194,42 +191,34 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, * Parameters: * * data [in] - The session handle. - * type2msg [in] - The base64 encoded type-2 message. + * type2 [in] - The type-2 message. * ntlm [in/out] - The NTLM data struct being used and modified. * * Returns CURLE_OK on success. */ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, - const char *type2msg, + const struct bufref *type2, struct ntlmdata *ntlm) { - CURLcode result = CURLE_OK; - unsigned char *type2 = NULL; - size_t type2_len = 0; - #if defined(CURL_DISABLE_VERBOSE_STRINGS) (void) data; #endif - /* Decode the base-64 encoded type-2 message */ - if(strlen(type2msg) && *type2msg != '=') { - result = Curl_base64_decode(type2msg, &type2, &type2_len); - if(result) - return result; - } - /* Ensure we have a valid type-2 message */ - if(!type2) { + if(!Curl_bufref_len(type2)) { infof(data, "NTLM handshake failure (empty type-2 message)\n"); - return CURLE_BAD_CONTENT_ENCODING; } - /* Simply store the challenge for use later */ - ntlm->input_token = type2; - ntlm->input_token_len = type2_len; + /* Store the challenge for later use */ + ntlm->input_token = malloc(Curl_bufref_len(type2) + 1); + if(!ntlm->input_token) + return CURLE_OUT_OF_MEMORY; + memcpy(ntlm->input_token, Curl_bufref_ptr(type2), Curl_bufref_len(type2)); + ntlm->input_token[Curl_bufref_len(type2)] = '\0'; + ntlm->input_token_len = Curl_bufref_len(type2); - return result; + return CURLE_OK; } /* @@ -245,9 +234,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, * userp [in] - The user name in the format User or Domain\User. * passwdp [in] - The user's password. * ntlm [in/out] - The NTLM data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. + * out [out] - The result storage. * * Returns CURLE_OK on success. */ @@ -255,7 +242,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, const char *userp, const char *passwdp, struct ntlmdata *ntlm, - char **outptr, size_t *outlen) + struct bufref *out) { CURLcode result = CURLE_OK; SecBuffer type_2_bufs[2]; @@ -331,12 +318,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, return CURLE_AUTH_ERROR; } - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) ntlm->output_token, - type_3_buf.cbBuffer, outptr, outlen); - + /* Return the response. */ + result = Curl_bufref_memdup(out, ntlm->output_token, type_3_buf.cbBuffer); Curl_auth_cleanup_ntlm(ntlm); - return result; } diff --git a/libs/libcurl/src/vauth/oauth2.c b/libs/libcurl/src/vauth/oauth2.c index ca5842a7c0..a5f16a0bf4 100644 --- a/libs/libcurl/src/vauth/oauth2.c +++ b/libs/libcurl/src/vauth/oauth2.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -31,7 +31,6 @@ #include "urldata.h" #include "vauth/vauth.h" -#include "curl_base64.h" #include "warnless.h" #include "curl_printf.h" @@ -42,31 +41,26 @@ /* * Curl_auth_create_oauth_bearer_message() * - * This is used to generate an already encoded OAuth 2.0 message ready for - * sending to the recipient. + * This is used to generate an OAuth 2.0 message ready for sending to the + * recipient. * * Parameters: * - * data[in] - The session handle. * user[in] - The user name. * host[in] - The host name. * port[in] - The port(when not Port 80). * bearer[in] - The bearer token. - * outptr[in / out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen[out] - The length of the output message. + * out[out] - The result storage. * * Returns CURLE_OK on success. */ -CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data, - const char *user, +CURLcode Curl_auth_create_oauth_bearer_message(const char *user, const char *host, const long port, const char *bearer, - char **outptr, size_t *outlen) + struct bufref *out) { - CURLcode result = CURLE_OK; - char *oauth = NULL; + char *oauth; /* Generate the message */ if(port == 0 || port == 80) @@ -78,49 +72,34 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data, if(!oauth) return CURLE_OUT_OF_MEMORY; - /* Base64 encode the reply */ - result = Curl_base64_encode(data, oauth, strlen(oauth), outptr, outlen); - - free(oauth); - - return result; + Curl_bufref_set(out, oauth, strlen(oauth), curl_free); + return CURLE_OK; } /* * Curl_auth_create_xoauth_bearer_message() * - * This is used to generate an already encoded XOAuth 2.0 message ready for - * sending to the recipient. + * This is used to generate a XOAuth 2.0 message ready for * sending to the + * recipient. * * Parameters: * - * data[in] - The session handle. * user[in] - The user name. * bearer[in] - The bearer token. - * outptr[in / out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen[out] - The length of the output message. + * out[out] - The result storage. * * Returns CURLE_OK on success. */ -CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data, - const char *user, +CURLcode Curl_auth_create_xoauth_bearer_message(const char *user, const char *bearer, - char **outptr, size_t *outlen) + struct bufref *out) { - CURLcode result = CURLE_OK; - /* Generate the message */ char *xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer); if(!xoauth) return CURLE_OUT_OF_MEMORY; - /* Base64 encode the reply */ - result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen); - - free(xoauth); - - return result; + Curl_bufref_set(out, xoauth, strlen(xoauth), curl_free); + return CURLE_OK; } #endif /* disabled, no users */ - diff --git a/libs/libcurl/src/vauth/vauth.c b/libs/libcurl/src/vauth/vauth.c index 129b8f8b57..3624fb0c4a 100644 --- a/libs/libcurl/src/vauth/vauth.c +++ b/libs/libcurl/src/vauth/vauth.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2014 - 2020, Steve Holme, . + * Copyright (C) 2014 - 2021, Steve Holme, . * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -72,6 +72,7 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host, { char *utf8_spn = NULL; TCHAR *tchar_spn = NULL; + TCHAR *dupe_tchar_spn = NULL; (void) realm; @@ -84,23 +85,19 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host, /* Generate our UTF8 based SPN */ utf8_spn = aprintf("%s/%s", service, host); - if(!utf8_spn) { + if(!utf8_spn) return NULL; - } - /* Allocate our TCHAR based SPN */ + /* Allocate and return a TCHAR based SPN. Since curlx_convert_UTF8_to_tchar + must be freed by curlx_unicodefree we'll dupe the result so that the + pointer this function returns can be normally free'd. */ tchar_spn = curlx_convert_UTF8_to_tchar(utf8_spn); - if(!tchar_spn) { - free(utf8_spn); - + free(utf8_spn); + if(!tchar_spn) return NULL; - } - - /* Release the UTF8 variant when operating with Unicode */ - curlx_unicodefree(utf8_spn); - - /* Return our newly allocated SPN */ - return tchar_spn; + dupe_tchar_spn = _tcsdup(tchar_spn); + curlx_unicodefree(tchar_spn); + return dupe_tchar_spn; } #endif /* USE_WINDOWS_SSPI */ diff --git a/libs/libcurl/src/vauth/vauth.h b/libs/libcurl/src/vauth/vauth.h index 03a5f8adb5..ec5b0007f5 100644 --- a/libs/libcurl/src/vauth/vauth.h +++ b/libs/libcurl/src/vauth/vauth.h @@ -24,6 +24,8 @@ #include +#include "bufref.h" + struct Curl_easy; #if !defined(CURL_DISABLE_CRYPTO_AUTH) @@ -62,45 +64,37 @@ TCHAR *Curl_auth_build_spn(const char *service, const char *host, /* This is used to test if the user contains a Windows domain name */ bool Curl_auth_user_contains_domain(const char *user); -/* This is used to generate a base64 encoded PLAIN cleartext message */ -CURLcode Curl_auth_create_plain_message(struct Curl_easy *data, - const char *authzid, +/* This is used to generate a PLAIN cleartext message */ +CURLcode Curl_auth_create_plain_message(const char *authzid, const char *authcid, const char *passwd, - char **outptr, size_t *outlen); + struct bufref *out); -/* This is used to generate a base64 encoded LOGIN cleartext message */ -CURLcode Curl_auth_create_login_message(struct Curl_easy *data, - const char *valuep, char **outptr, - size_t *outlen); +/* This is used to generate a LOGIN cleartext message */ +CURLcode Curl_auth_create_login_message(const char *value, + struct bufref *out); -/* This is used to generate a base64 encoded EXTERNAL cleartext message */ -CURLcode Curl_auth_create_external_message(struct Curl_easy *data, - const char *user, char **outptr, - size_t *outlen); +/* This is used to generate an EXTERNAL cleartext message */ +CURLcode Curl_auth_create_external_message(const char *user, + struct bufref *out); #if !defined(CURL_DISABLE_CRYPTO_AUTH) -/* This is used to decode a CRAM-MD5 challenge message */ -CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr, - size_t *outlen); - /* This is used to generate a CRAM-MD5 response message */ -CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data, - const char *chlg, +CURLcode Curl_auth_create_cram_md5_message(const struct bufref *chlg, const char *userp, const char *passwdp, - char **outptr, size_t *outlen); + struct bufref *out); /* This is used to evaluate if DIGEST is supported */ bool Curl_auth_is_digest_supported(void); /* This is used to generate a base64 encoded DIGEST-MD5 response message */ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, - const char *chlg64, + const struct bufref *chlg, const char *userp, const char *passwdp, const char *service, - char **outptr, size_t *outlen); + struct bufref *out); /* This is used to decode a HTTP DIGEST challenge message */ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, @@ -132,9 +126,9 @@ CURLcode Curl_auth_gsasl_start(struct Curl_easy *data, /* This is used to process and generate a new SASL token */ CURLcode Curl_auth_gsasl_token(struct Curl_easy *data, - const char *chlg64, + const struct bufref *chlg, struct gsasldata *gsasl, - char **outptr, size_t *outlen); + struct bufref *out); /* This is used to clean up the gsasl specific data */ void Curl_auth_gsasl_cleanup(struct gsasldata *digest); @@ -151,12 +145,11 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, const char *service, const char *host, struct ntlmdata *ntlm, - char **outptr, - size_t *outlen); + struct bufref *out); /* This is used to decode a base64 encoded NTLM type-2 message */ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, - const char *type2msg, + const struct bufref *type2, struct ntlmdata *ntlm); /* This is used to generate a base64 encoded NTLM type-3 message */ @@ -164,25 +157,23 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, const char *userp, const char *passwdp, struct ntlmdata *ntlm, - char **outptr, size_t *outlen); + struct bufref *out); /* This is used to clean up the NTLM specific data */ void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm); #endif /* USE_NTLM */ /* This is used to generate a base64 encoded OAuth 2.0 message */ -CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data, - const char *user, +CURLcode Curl_auth_create_oauth_bearer_message(const char *user, const char *host, const long port, const char *bearer, - char **outptr, size_t *outlen); + struct bufref *out); /* This is used to generate a base64 encoded XOAuth 2.0 message */ -CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data, - const char *user, +CURLcode Curl_auth_create_xoauth_bearer_message(const char *user, const char *bearer, - char **outptr, size_t *outlen); + struct bufref *out); #if defined(USE_KERBEROS5) /* This is used to evaluate if GSSAPI (Kerberos V5) is supported */ @@ -196,17 +187,16 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, const char *service, const char *host, const bool mutual, - const char *chlg64, + const struct bufref *chlg, struct kerberos5data *krb5, - char **outptr, size_t *outlen); + struct bufref *out); /* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security token message */ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, - const char *input, + const struct bufref *chlg, struct kerberos5data *krb5, - char **outptr, - size_t *outlen); + struct bufref *out); /* This is used to clean up the GSSAPI specific data */ void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5); diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c index b33f2fe83b..b67b9a4660 100644 --- a/libs/libcurl/src/version.c +++ b/libs/libcurl/src/version.c @@ -66,6 +66,14 @@ #include #endif +#ifdef USE_GSASL +#include +#endif + +#ifdef USE_OPENLDAP +#include +#endif + #ifdef HAVE_BROTLI static size_t brotli_version(char *buf, size_t bufsz) { @@ -100,7 +108,7 @@ static size_t zstd_version(char *buf, size_t bufsz) * zeros in the data. */ -#define VERSION_PARTS 16 /* number of substrings we can concatenate */ +#define VERSION_PARTS 17 /* number of substrings we can concatenate */ char *curl_version(void) { @@ -149,6 +157,9 @@ char *curl_version(void) #endif #ifdef USE_GSASL char gsasl_buf[30]; +#endif +#ifdef USE_OPENLDAP + char ldap_buf[30]; #endif int i = 0; int j; @@ -243,6 +254,24 @@ char *curl_version(void) gsasl_check_version(NULL)); src[i++] = gsasl_buf; #endif +#ifdef USE_OPENLDAP + { + LDAPAPIInfo api; + api.ldapai_info_version = LDAP_API_INFO_VERSION; + + if(ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) == LDAP_OPT_SUCCESS) { + unsigned int patch = api.ldapai_vendor_version % 100; + unsigned int major = api.ldapai_vendor_version / 10000; + unsigned int minor = + ((api.ldapai_vendor_version - major * 10000) - patch) / 100; + msnprintf(ldap_buf, sizeof(ldap_buf), "%s/%u.%u.%u", + api.ldapai_vendor_name, major, minor, patch); + src[i++] = ldap_buf; + ldap_memfree(api.ldapai_vendor_name); + ber_memvfree((void **)api.ldapai_extensions); + } + } +#endif DEBUGASSERT(i <= VERSION_PARTS); @@ -436,7 +465,7 @@ static curl_version_info_data version_info = { #ifndef CURL_DISABLE_ALTSVC | CURL_VERSION_ALTSVC #endif -#if defined(USE_HSTS) +#ifndef CURL_DISABLE_HSTS | CURL_VERSION_HSTS #endif #if defined(USE_GSASL) @@ -469,7 +498,8 @@ static curl_version_info_data version_info = { #endif 0, /* zstd_ver_num */ NULL, /* zstd version */ - NULL /* Hyper version */ + NULL, /* Hyper version */ + NULL /* gsasl version */ }; curl_version_info_data *curl_version_info(CURLversion stamp) @@ -573,6 +603,12 @@ curl_version_info_data *curl_version_info(CURLversion stamp) } #endif +#ifdef USE_GSASL + { + version_info.gsasl_version = gsasl_check_version(NULL); + } +#endif + (void)stamp; /* avoid compiler warnings, we don't use this */ return &version_info; } diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c index 3d64519987..7f076759b8 100644 --- a/libs/libcurl/src/vquic/ngtcp2.c +++ b/libs/libcurl/src/vquic/ngtcp2.c @@ -226,7 +226,7 @@ static int write_client_handshake(struct quicsocket *qs, int rv; crypto_data = &qs->crypto_data[level]; - if(crypto_data->buf == NULL) { + if(!crypto_data->buf) { crypto_data->buf = malloc(4096); if(!crypto_data->buf) return 0; @@ -603,7 +603,7 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags, static int cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id, - uint64_t offset, size_t datalen, void *user_data, + uint64_t offset, uint64_t datalen, void *user_data, void *stream_user_data) { struct quicsocket *qs = (struct quicsocket *)user_data; @@ -615,7 +615,7 @@ cb_acked_stream_data_offset(ngtcp2_conn *tconn, int64_t stream_id, (void)stream_user_data; rv = nghttp3_conn_add_ack_offset(qs->h3conn, stream_id, datalen); - if(rv != 0) { + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -634,7 +634,7 @@ static int cb_stream_close(ngtcp2_conn *tconn, int64_t stream_id, rv = nghttp3_conn_close_stream(qs->h3conn, stream_id, app_error_code); - if(rv != 0) { + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -653,7 +653,7 @@ static int cb_stream_reset(ngtcp2_conn *tconn, int64_t stream_id, (void)stream_user_data; rv = nghttp3_conn_reset_stream(qs->h3conn, stream_id); - if(rv != 0) { + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -682,7 +682,7 @@ static int cb_extend_max_stream_data(ngtcp2_conn *tconn, int64_t stream_id, (void)stream_user_data; rv = nghttp3_conn_unblock_stream(qs->h3conn, stream_id); - if(rv != 0) { + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -934,6 +934,7 @@ static const struct Curl_handler Curl_handler_http3 = { ng_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ng_conncheck, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_HTTP, /* defport */ CURLPROTO_HTTPS, /* protocol */ CURLPROTO_HTTP, /* family */ @@ -1309,7 +1310,7 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, if(stream->h3out->used == 0) { int rv = nghttp3_conn_resume_stream(conn, stream_id); - if(rv != 0) { + if(rv) { return NGTCP2_ERR_CALLBACK_FAILURE; } } @@ -1545,7 +1546,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, } /* :authority must come before non-pseudo header fields */ - if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { + if(authority_idx && authority_idx != AUTHORITY_DST_IDX) { nghttp3_nv authority = nva[authority_idx]; for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { nva[i] = nva[i - 1]; @@ -1741,7 +1742,7 @@ static CURLcode ng_process_ingress(struct Curl_easy *data, remote_addrlen); rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts); - if(rv != 0) { + if(rv) { /* TODO Send CONNECTION_CLOSE if possible */ return CURLE_RECV_ERROR; } @@ -1785,7 +1786,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, } rv = ngtcp2_conn_handle_expiry(qs->qconn, ts); - if(rv != 0) { + if(rv) { failf(data, "ngtcp2_conn_handle_expiry returned error: %s", ngtcp2_strerror(rv)); return CURLE_SEND_ERROR; @@ -1821,7 +1822,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, outlen == NGTCP2_ERR_STREAM_SHUT_WR) { assert(ndatalen == -1); rv = nghttp3_conn_block_stream(qs->h3conn, stream_id); - if(rv != 0) { + if(rv) { failf(data, "nghttp3_conn_block_stream returned error: %s\n", nghttp3_strerror(rv)); return CURLE_SEND_ERROR; @@ -1831,7 +1832,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, else if(outlen == NGTCP2_ERR_WRITE_MORE) { assert(ndatalen >= 0); rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen); - if(rv != 0) { + if(rv) { failf(data, "nghttp3_conn_add_write_offset returned error: %s\n", nghttp3_strerror(rv)); return CURLE_SEND_ERROR; @@ -1847,7 +1848,7 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, } else if(ndatalen >= 0) { rv = nghttp3_conn_add_write_offset(qs->h3conn, stream_id, ndatalen); - if(rv != 0) { + if(rv) { failf(data, "nghttp3_conn_add_write_offset returned error: %s\n", nghttp3_strerror(rv)); return CURLE_SEND_ERROR; diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c index a3870749b5..b62d88437a 100644 --- a/libs/libcurl/src/vquic/quiche.c +++ b/libs/libcurl/src/vquic/quiche.c @@ -157,6 +157,7 @@ static const struct Curl_handler Curl_handler_http3 = { quiche_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ quiche_conncheck, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_HTTP, /* defport */ CURLPROTO_HTTPS, /* protocol */ CURLPROTO_HTTP, /* family */ @@ -225,7 +226,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, quiche_config_log_keys(qs->cfg); qs->conn = quiche_connect(conn->host.name, (const uint8_t *) qs->scid, - sizeof(qs->scid), qs->cfg); + sizeof(qs->scid), addr, addrlen, qs->cfg); if(!qs->conn) { failf(data, "can't create quiche connection"); return CURLE_OUT_OF_MEMORY; @@ -359,6 +360,9 @@ static CURLcode process_ingress(struct Curl_easy *data, int sockfd, ssize_t recvd; uint8_t *buf = (uint8_t *)data->state.buffer; size_t bufsize = data->set.buffer_size; + struct sockaddr_storage from; + socklen_t from_len; + quiche_recv_info recv_info; DEBUGASSERT(qs->conn); @@ -366,17 +370,24 @@ static CURLcode process_ingress(struct Curl_easy *data, int sockfd, quiche_conn_on_timeout(qs->conn); do { - recvd = recv(sockfd, buf, bufsize, 0); + from_len = sizeof(from); + + recvd = recvfrom(sockfd, buf, bufsize, 0, + (struct sockaddr *)&from, &from_len); + if((recvd < 0) && ((SOCKERRNO == EAGAIN) || (SOCKERRNO == EWOULDBLOCK))) break; if(recvd < 0) { - failf(data, "quiche: recv() unexpectedly returned %zd " + failf(data, "quiche: recvfrom() unexpectedly returned %zd " "(errno: %d, socket %d)", recvd, SOCKERRNO, sockfd); return CURLE_RECV_ERROR; } - recvd = quiche_conn_recv(qs->conn, buf, recvd); + recv_info.from = (struct sockaddr *) &from; + recv_info.from_len = from_len; + + recvd = quiche_conn_recv(qs->conn, buf, recvd, &recv_info); if(recvd == QUICHE_ERR_DONE) break; @@ -399,9 +410,10 @@ static CURLcode flush_egress(struct Curl_easy *data, int sockfd, ssize_t sent; uint8_t out[1200]; int64_t timeout_ns; + quiche_send_info send_info; do { - sent = quiche_conn_send(qs->conn, out, sizeof(out)); + sent = quiche_conn_send(qs->conn, out, sizeof(out), &send_info); if(sent == QUICHE_ERR_DONE) break; @@ -410,9 +422,10 @@ static CURLcode flush_egress(struct Curl_easy *data, int sockfd, return CURLE_SEND_ERROR; } - sent = send(sockfd, out, sent, 0); + sent = sendto(sockfd, out, sent, 0, + (struct sockaddr *)&send_info.to, send_info.to_len); if(sent < 0) { - failf(data, "send() returned %zd", sent); + failf(data, "sendto() returned %zd", sent); return CURLE_SEND_ERROR; } } while(1); @@ -750,7 +763,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, } /* :authority must come before non-pseudo header fields */ - if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { + if(authority_idx && authority_idx != AUTHORITY_DST_IDX) { quiche_h3_header authority = nva[authority_idx]; for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { nva[i] = nva[i - 1]; diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c index 4644f4cb96..d146d15fdf 100644 --- a/libs/libcurl/src/vssh/libssh.c +++ b/libs/libcurl/src/vssh/libssh.c @@ -159,6 +159,7 @@ const struct Curl_handler Curl_handler_scp = { scp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SSH, /* defport */ CURLPROTO_SCP, /* protocol */ CURLPROTO_SCP, /* family */ @@ -185,6 +186,7 @@ const struct Curl_handler Curl_handler_sftp = { sftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SSH, /* defport */ CURLPROTO_SFTP, /* protocol */ CURLPROTO_SFTP, /* family */ @@ -549,49 +551,48 @@ cleanup: return rc; } -#define MOVE_TO_ERROR_STATE(_r) { \ - state(data, SSH_SESSION_DISCONNECT); \ - sshc->actualcode = _r; \ - rc = SSH_ERROR; \ - break; \ -} +#define MOVE_TO_ERROR_STATE(_r) do { \ + state(data, SSH_SESSION_DISCONNECT); \ + sshc->actualcode = _r; \ + rc = SSH_ERROR; \ + } while(0) -#define MOVE_TO_SFTP_CLOSE_STATE() { \ - state(data, SSH_SFTP_CLOSE); \ - sshc->actualcode = sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \ - rc = SSH_ERROR; \ - break; \ -} +#define MOVE_TO_SFTP_CLOSE_STATE() do { \ + state(data, SSH_SFTP_CLOSE); \ + sshc->actualcode = \ + sftp_error_to_CURLE(sftp_get_error(sshc->sftp_session)); \ + rc = SSH_ERROR; \ + } while(0) -#define MOVE_TO_LAST_AUTH \ - if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ - rc = SSH_OK; \ - state(data, SSH_AUTH_PASS_INIT); \ - break; \ - } \ - else { \ - MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ - } +#define MOVE_TO_LAST_AUTH do { \ + if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \ + rc = SSH_OK; \ + state(data, SSH_AUTH_PASS_INIT); \ + } \ + else { \ + MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \ + } \ + } while(0) -#define MOVE_TO_TERTIARY_AUTH \ - if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ - rc = SSH_OK; \ - state(data, SSH_AUTH_KEY_INIT); \ - break; \ - } \ - else { \ - MOVE_TO_LAST_AUTH; \ - } +#define MOVE_TO_TERTIARY_AUTH do { \ + if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \ + rc = SSH_OK; \ + state(data, SSH_AUTH_KEY_INIT); \ + } \ + else { \ + MOVE_TO_LAST_AUTH; \ + } \ + } while(0) -#define MOVE_TO_SECONDARY_AUTH \ - if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ - rc = SSH_OK; \ - state(data, SSH_AUTH_GSSAPI); \ - break; \ - } \ - else { \ - MOVE_TO_TERTIARY_AUTH; \ - } +#define MOVE_TO_SECONDARY_AUTH do { \ + if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \ + rc = SSH_OK; \ + state(data, SSH_AUTH_GSSAPI); \ + } \ + else { \ + MOVE_TO_TERTIARY_AUTH; \ + } \ + } while(0) static int myssh_auth_interactive(struct connectdata *conn) @@ -629,7 +630,7 @@ restart: rc = SSH_OK; else if(rc == SSH_AUTH_INFO) { nprompts = ssh_userauth_kbdint_getnprompts(sshc->ssh_session); - if(nprompts != 0) + if(nprompts) return SSH_ERROR; sshc->kbd_state = 2; @@ -704,6 +705,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc != SSH_OK) { failf(data, "Failure establishing ssh session"); MOVE_TO_ERROR_STATE(CURLE_FAILED_INIT); + break; } state(data, SSH_HOSTKEY); @@ -714,6 +716,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) rc = myssh_is_known(data); if(rc != SSH_OK) { MOVE_TO_ERROR_STATE(CURLE_PEER_FAILED_VERIFICATION); + break; } state(data, SSH_AUTHLIST); @@ -735,6 +738,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } else if(rc == SSH_AUTH_ERROR) { MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; } sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); @@ -753,6 +757,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } else { /* unsupported authentication method */ MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; } break; @@ -760,6 +765,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_AUTH_PKEY_INIT: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) { MOVE_TO_SECONDARY_AUTH; + break; } /* Two choices, (1) private key was given on CMD, @@ -775,6 +781,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc != SSH_OK) { MOVE_TO_SECONDARY_AUTH; + break; } } @@ -833,6 +840,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_AUTH_GSSAPI: if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) { MOVE_TO_TERTIARY_AUTH; + break; } rc = ssh_userauth_gssapi(sshc->ssh_session); @@ -879,6 +887,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) { /* Host key authentication is intentionally not implemented */ MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); + break; } state(data, SSH_AUTH_PASS); /* FALLTHROUGH */ @@ -951,8 +960,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) * Get the "home" directory */ sshc->homedir = sftp_canonicalize_path(sshc->sftp_session, "."); - if(sshc->homedir == NULL) { + if(!sshc->homedir) { MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + break; } data->state.most_recent_ftp_entrypath = sshc->homedir; @@ -1025,7 +1035,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_SETSTAT: rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2, sshc->quote_attrs); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "Attempt to set SFTP stats failed: %s", @@ -1044,7 +1054,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_SYMLINK: rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2, sshc->quote_path1); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "symlink command failed: %s", @@ -1060,7 +1070,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_MKDIR: rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1, (mode_t)data->set.new_directory_perms); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); failf(data, "mkdir command failed: %s", ssh_get_error(sshc->ssh_session)); @@ -1075,7 +1085,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_RENAME: rc = sftp_rename(sshc->sftp_session, sshc->quote_path1, sshc->quote_path2); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "rename command failed: %s", @@ -1090,7 +1100,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_RMDIR: rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); failf(data, "rmdir command failed: %s", ssh_get_error(sshc->ssh_session)); @@ -1104,7 +1114,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_QUOTE_UNLINK: rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1); - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); failf(data, "rm command failed: %s", ssh_get_error(sshc->ssh_session)); @@ -1179,7 +1189,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) sftp_attributes attrs; attrs = sftp_stat(sshc->sftp_session, protop->path); - if(attrs != 0) { + if(attrs) { data->info.filetime = attrs->mtime; sftp_attributes_free(attrs); } @@ -1203,16 +1213,17 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) { int flags; - if(data->state.resume_from != 0) { + if(data->state.resume_from) { sftp_attributes attrs; if(data->state.resume_from < 0) { attrs = sftp_stat(sshc->sftp_session, protop->path); - if(attrs != 0) { + if(attrs) { curl_off_t size = attrs->size; if(size < 0) { failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); MOVE_TO_ERROR_STATE(CURLE_BAD_DOWNLOAD_RESUME); + break; } data->state.resume_from = attrs->size; @@ -1254,6 +1265,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } else { MOVE_TO_SFTP_CLOSE_STATE(); + break; } } @@ -1292,8 +1304,11 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) CURL_READFUNC_ABORT return code still aborts */ failf(data, "Failed to read data"); MOVE_TO_ERROR_STATE(CURLE_FTP_COULDNT_USE_REST); + break; } } while(passed < data->state.resume_from); + if(rc) + break; } /* now, decrease the size of the read */ @@ -1304,8 +1319,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); - if(rc != 0) { + if(rc) { MOVE_TO_SFTP_CLOSE_STATE(); + break; } } if(data->state.infilesize > 0) { @@ -1375,6 +1391,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) (err != SSH_FX_FAILURE) && (err != SSH_FX_PERMISSION_DENIED)) { MOVE_TO_SFTP_CLOSE_STATE(); + break; } rc = 0; /* clear rc and continue */ } @@ -1398,6 +1415,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) failf(data, "Could not open directory for reading: %s", ssh_get_error(sshc->ssh_session)); MOVE_TO_SFTP_CLOSE_STATE(); + break; } state(data, SSH_SFTP_READDIR); break; @@ -1417,7 +1435,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) char *tmpLine; tmpLine = aprintf("%s\n", sshc->readdir_filename); - if(tmpLine == NULL) { + if(!tmpLine) { state(data, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; @@ -1456,7 +1474,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) sshc->readdir_linkPath = aprintf("%s%s", protop->path, sshc->readdir_filename); - if(sshc->readdir_linkPath == NULL) { + if(!sshc->readdir_linkPath) { state(data, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; @@ -1491,12 +1509,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) failf(data, "Could not read symlink for reading: %s", ssh_get_error(sshc->ssh_session)); MOVE_TO_SFTP_CLOSE_STATE(); + break; } - if(sshc->readdir_link_attrs->name == NULL) { + if(!sshc->readdir_link_attrs->name) { sshc->readdir_tmp = sftp_readlink(sshc->sftp_session, sshc->readdir_linkPath); - if(sshc->readdir_filename == NULL) + if(!sshc->readdir_filename) sshc->readdir_len = 0; else sshc->readdir_len = strlen(sshc->readdir_tmp); @@ -1586,6 +1605,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) ssh_get_error(sshc->ssh_session)); MOVE_TO_SFTP_CLOSE_STATE(); + break; } state(data, SSH_SFTP_DOWNLOAD_STAT); @@ -1661,8 +1681,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } rc = sftp_seek64(sshc->sftp_file, from); - if(rc != 0) { + if(rc) { MOVE_TO_SFTP_CLOSE_STATE(); + break; } } data->req.size = size; @@ -1699,8 +1720,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) size - data->state.resume_from); rc = sftp_seek64(sshc->sftp_file, data->state.resume_from); - if(rc != 0) { + if(rc) { MOVE_TO_SFTP_CLOSE_STATE(); + break; } } } @@ -1795,6 +1817,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) failf(data, "SCP requires a known file size for upload"); sshc->actualcode = CURLE_UPLOAD_FAILED; MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + break; } sshc->scp_session = @@ -1822,6 +1845,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + break; } rc = ssh_scp_push_file(sshc->scp_session, protop->path, @@ -1831,6 +1855,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); MOVE_TO_ERROR_STATE(CURLE_UPLOAD_FAILED); + break; } /* upload data */ @@ -1859,6 +1884,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) err_msg = ssh_get_error(sshc->ssh_session); failf(data, "%s", err_msg); MOVE_TO_ERROR_STATE(CURLE_COULDNT_CONNECT); + break; } state(data, SSH_SCP_DOWNLOAD); /* FALLTHROUGH */ @@ -2163,7 +2189,7 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done) ssh = &conn->proto.sshc; ssh->ssh_session = ssh_new(); - if(ssh->ssh_session == NULL) { + if(!ssh->ssh_session) { failf(data, "Failure initialising ssh session"); return CURLE_FAILED_INIT; } @@ -2661,7 +2687,7 @@ static void sftp_quote(struct Curl_easy *data) * command with a space so we can check for it unconditionally */ cp = strchr(cmd, ' '); - if(cp == NULL) { + if(!cp) { failf(data, "Syntax error in SFTP command. Supply parameter(s)!"); state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; @@ -2810,7 +2836,7 @@ static void sftp_quote_stat(struct Curl_easy *data) if(sshc->quote_attrs) sftp_attributes_free(sshc->quote_attrs); sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2); - if(sshc->quote_attrs == NULL) { + if(!sshc->quote_attrs) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "Attempt to get SFTP stats failed: %d", diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c index 9d188d0582..8a6345b948 100644 --- a/libs/libcurl/src/vssh/libssh2.c +++ b/libs/libcurl/src/vssh/libssh2.c @@ -121,6 +121,7 @@ static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn, curl_socket_t *sock); static CURLcode ssh_setup_connection(struct Curl_easy *data, struct connectdata *conn); +static void ssh_attach(struct Curl_easy *data, struct connectdata *conn); /* * SCP protocol handler. @@ -142,6 +143,7 @@ const struct Curl_handler Curl_handler_scp = { scp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ssh_attach, PORT_SSH, /* defport */ CURLPROTO_SCP, /* protocol */ CURLPROTO_SCP, /* family */ @@ -170,6 +172,7 @@ const struct Curl_handler Curl_handler_sftp = { sftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ssh_attach, PORT_SSH, /* defport */ CURLPROTO_SFTP, /* protocol */ CURLPROTO_SFTP, /* family */ @@ -956,7 +959,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) out_of_memory = TRUE; } - if(out_of_memory || sshc->rsa == NULL) { + if(out_of_memory || !sshc->rsa) { Curl_safefree(sshc->rsa); Curl_safefree(sshc->rsa_pub); state(data, SSH_SESSION_FREE); @@ -1359,7 +1362,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) * command with a space so we can check for it unconditionally */ cp = strchr(cmd, ' '); - if(cp == NULL) { + if(!cp) { failf(data, "Syntax error command '%s'. Missing parameter!", cmd); state(data, SSH_SFTP_CLOSE); @@ -1534,7 +1537,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { /* get those attributes */ + if(rc && !sshc->acceptfail) { /* get those attributes */ sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); @@ -1633,7 +1636,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); @@ -1656,7 +1659,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); @@ -1677,7 +1680,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); failf(data, "mkdir command failed: %s", @@ -1702,7 +1705,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); @@ -1722,7 +1725,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); failf(data, "rmdir command failed: %s", @@ -1741,7 +1744,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); failf(data, "rm command failed: %s", sftp_libssh2_strerror(sftperr)); @@ -1764,7 +1767,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - if(rc != 0 && !sshc->acceptfail) { + if(rc && !sshc->acceptfail) { sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); failf(data, "statvfs command failed: %s", @@ -1857,7 +1860,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) * same name as the last directory in the path. */ - if(data->state.resume_from != 0) { + if(data->state.resume_from) { LIBSSH2_SFTP_ATTRIBUTES attrs; if(data->state.resume_from < 0) { rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path, @@ -2931,7 +2934,7 @@ static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done) static CURLcode ssh_block_statemach(struct Curl_easy *data, struct connectdata *conn, - bool duringconnect) + bool disconnect) { struct ssh_conn *sshc = &conn->proto.sshc; CURLcode result = CURLE_OK; @@ -2945,17 +2948,19 @@ static CURLcode ssh_block_statemach(struct Curl_easy *data, if(result) break; - if(Curl_pgrsUpdate(data)) - return CURLE_ABORTED_BY_CALLBACK; + if(!disconnect) { + if(Curl_pgrsUpdate(data)) + return CURLE_ABORTED_BY_CALLBACK; - result = Curl_speedcheck(data, now); - if(result) - break; + result = Curl_speedcheck(data, now); + if(result) + break; - left = Curl_timeleft(data, NULL, duringconnect); - if(left < 0) { - failf(data, "Operation timed out"); - return CURLE_OPERATION_TIMEDOUT; + left = Curl_timeleft(data, NULL, FALSE); + if(left < 0) { + failf(data, "Operation timed out"); + return CURLE_OPERATION_TIMEDOUT; + } } if(block) { @@ -3054,17 +3059,15 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) #ifdef CURL_LIBSSH2_DEBUG curl_socket_t sock; #endif - struct SSHPROTO *sshp = data->req.p.ssh; struct ssh_conn *sshc; CURLcode result; struct connectdata *conn = data->conn; /* initialize per-handle data if not already */ - if(!sshp) { + if(!data->req.p.ssh) { result = ssh_setup_connection(data, conn); if(result) return result; - sshp = data->req.p.ssh; } /* We default to persistent connections. We set this already in this connect @@ -3086,7 +3089,7 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc, my_libssh2_free, my_libssh2_realloc, data); - if(sshc->ssh_session == NULL) { + if(!sshc->ssh_session) { failf(data, "Failure initialising ssh session"); return CURLE_FAILED_INIT; } @@ -3280,10 +3283,8 @@ static CURLcode scp_disconnect(struct Curl_easy *data, if(sshc->ssh_session) { /* only if there's a session still around to use! */ - state(data, SSH_SESSION_DISCONNECT); - - result = ssh_block_statemach(data, conn, FALSE); + result = ssh_block_statemach(data, conn, TRUE); } return result; @@ -3297,10 +3298,9 @@ static CURLcode ssh_done(struct Curl_easy *data, CURLcode status) struct SSHPROTO *sshp = data->req.p.ssh; struct connectdata *conn = data->conn; - if(!status) { + if(!status) /* run the state-machine */ result = ssh_block_statemach(data, conn, FALSE); - } else result = status; @@ -3440,7 +3440,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, if(sshc->ssh_session) { /* only if there's a session still around to use! */ state(data, SSH_SFTP_SHUTDOWN); - result = ssh_block_statemach(data, conn, FALSE); + result = ssh_block_statemach(data, conn, TRUE); } DEBUGF(infof(data, "SSH DISCONNECT is done\n")); @@ -3607,4 +3607,21 @@ size_t Curl_ssh_version(char *buffer, size_t buflen) return msnprintf(buffer, buflen, "libssh2/%s", LIBSSH2_VERSION); } +/* The SSH session is associated with the *CONNECTION* but the callback user + * pointer is an easy handle pointer. This function allows us to reassign the + * user pointer to the *CURRENT* (new) easy handle. + */ +static void ssh_attach(struct Curl_easy *data, struct connectdata *conn) +{ + DEBUGASSERT(data); + DEBUGASSERT(conn); + if(conn->handler->protocol & PROTO_FAMILY_SSH) { + struct ssh_conn *sshc = &conn->proto.sshc; + if(sshc->ssh_session) { + /* only re-attach if the session already exists */ + void **abstract = libssh2_session_abstract(sshc->ssh_session); + *abstract = data; + } + } +} #endif /* USE_LIBSSH2 */ diff --git a/libs/libcurl/src/vssh/ssh.h b/libs/libcurl/src/vssh/ssh.h index 52e1ee6c20..505b0787c5 100644 --- a/libs/libcurl/src/vssh/ssh.h +++ b/libs/libcurl/src/vssh/ssh.h @@ -263,9 +263,12 @@ extern const struct Curl_handler Curl_handler_sftp; CURLcode Curl_ssh_init(void); void Curl_ssh_cleanup(void); size_t Curl_ssh_version(char *buffer, size_t buflen); +void Curl_ssh_attach(struct Curl_easy *data, + struct connectdata *conn); #else /* for non-SSH builds */ #define Curl_ssh_cleanup() +#define Curl_ssh_attach(x,y) #endif #endif /* HEADER_CURL_SSH_H */ diff --git a/libs/libcurl/src/vssh/wolfssh.c b/libs/libcurl/src/vssh/wolfssh.c index de0b1c7776..9f3266a24d 100644 --- a/libs/libcurl/src/vssh/wolfssh.c +++ b/libs/libcurl/src/vssh/wolfssh.c @@ -91,6 +91,7 @@ const struct Curl_handler Curl_handler_scp = { wscp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SSH, /* defport */ CURLPROTO_SCP, /* protocol */ PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION @@ -119,6 +120,7 @@ const struct Curl_handler Curl_handler_sftp = { wsftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ PORT_SSH, /* defport */ CURLPROTO_SFTP, /* protocol */ CURLPROTO_SFTP, /* family */ @@ -388,7 +390,7 @@ static CURLcode wssh_connect(struct Curl_easy *data, bool *done) } sshc->ssh_session = wolfSSH_new(sshc->ctx); - if(sshc->ssh_session == NULL) { + if(!sshc->ssh_session) { failf(data, "No wolfSSH session"); goto error; } @@ -861,7 +863,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) char *line = aprintf("%s\n", data->set.list_only ? name->fName : name->lName); - if(line == NULL) { + if(!line) { state(data, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; diff --git a/libs/libcurl/src/vtls/bearssl.c b/libs/libcurl/src/vtls/bearssl.c index a63056d4ef..7f729713d8 100644 --- a/libs/libcurl/src/vtls/bearssl.c +++ b/libs/libcurl/src/vtls/bearssl.c @@ -300,12 +300,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); -#ifndef CURL_DISABLE_PROXY - const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - const char *hostname = conn->host.name; -#endif + const char * const hostname = SSL_HOST_NAME(); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const bool verifyhost = SSL_CONN_CONFIG(verifyhost); CURLcode ret; @@ -390,14 +385,14 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, * protocols array in `struct ssl_backend_data`. */ -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { - backend->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + backend->protocols[cur++] = ALPN_H2; + infof(data, "ALPN, offering %s\n", ALPN_H2); } #endif @@ -545,8 +540,8 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data, if(protocol) { infof(data, "ALPN, server accepted to use %s\n", protocol); -#ifdef USE_NGHTTP2 - if(!strcmp(protocol, NGHTTP2_PROTO_VERSION_ID)) +#ifdef USE_HTTP2 + if(!strcmp(protocol, ALPN_H2)) conn->negnpn = CURL_HTTP_VERSION_2; else #endif diff --git a/libs/libcurl/src/vtls/gskit.c b/libs/libcurl/src/vtls/gskit.c index b0c73437bb..ca953769d1 100644 --- a/libs/libcurl/src/vtls/gskit.c +++ b/libs/libcurl/src/vtls/gskit.c @@ -101,8 +101,10 @@ struct ssl_backend_data { gsk_handle handle; int iocport; +#ifndef CURL_DISABLE_PROXY int localfd; int remotefd; +#endif }; #define BACKEND connssl->backend @@ -302,8 +304,9 @@ static CURLcode set_callback(struct Curl_easy *data, static CURLcode set_ciphers(struct Curl_easy *data, - gsk_handle h, unsigned int *protoflags) + gsk_handle h, unsigned int *protoflags) { + struct connectdata *conn = data->conn; const char *cipherlist = SSL_CONN_CONFIG(cipher_list); const char *clp; const struct gskit_cipher *ctp; @@ -515,6 +518,7 @@ static void close_async_handshake(struct ssl_connect_data *connssl) static int pipe_ssloverssl(struct connectdata *conn, int sockindex, int directions) { +#ifndef CURL_DISABLE_PROXY struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex]; fd_set fds_read; @@ -583,6 +587,9 @@ static int pipe_ssloverssl(struct connectdata *conn, int sockindex, } return ret; /* OK */ +#else + return 0; +#endif } @@ -596,6 +603,7 @@ static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data, while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0) ; BACKEND->handle = (gsk_handle) NULL; +#ifndef CURL_DISABLE_PROXY if(BACKEND->localfd >= 0) { close(BACKEND->localfd); BACKEND->localfd = -1; @@ -604,6 +612,7 @@ static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data, close(BACKEND->remotefd); BACKEND->remotefd = -1; } +#endif } if(BACKEND->iocport >= 0) close_async_handshake(connssl); @@ -665,6 +674,7 @@ static ssize_t gskit_recv(struct Curl_easy *data, int num, char *buf, static CURLcode set_ssl_version_min_max(unsigned int *protoflags, struct Curl_easy *data) { + struct connectdata *conn = data->conn; long ssl_version = SSL_CONN_CONFIG(version); long ssl_version_max = SSL_CONN_CONFIG(version_max); long i = ssl_version; @@ -705,20 +715,23 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert); const long int ssl_version = SSL_CONN_CONFIG(version); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); - const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name: - conn->host.name; + const char * const hostname = SSL_HOST_NAME(); const char *sni; unsigned int protoflags = 0; Qso_OverlappedIO_t commarea; +#ifndef CURL_DISABLE_PROXY int sockpair[2]; static const int sobufsize = CURL_MAX_WRITE_SIZE; +#endif /* Create SSL environment, start (preferably asynchronous) handshake. */ BACKEND->handle = (gsk_handle) NULL; BACKEND->iocport = -1; +#ifndef CURL_DISABLE_PROXY BACKEND->localfd = -1; BACKEND->remotefd = -1; +#endif /* GSKit supports two ways of specifying an SSL context: either by * application identifier (that should have been defined at the system @@ -757,6 +770,7 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, if(result) return result; +#ifndef CURL_DISABLE_PROXY /* Establish a pipelining socket pair for SSL over SSL. */ if(conn->proxy_ssl[sockindex].use) { if(Curl_socketpair(0, 0, 0, sockpair)) @@ -774,6 +788,7 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, curlx_nonblock(BACKEND->localfd, TRUE); curlx_nonblock(BACKEND->remotefd, TRUE); } +#endif /* Determine which SSL/TLS version should be enabled. */ sni = hostname; @@ -826,8 +841,13 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, if(!result) result = set_numeric(data, BACKEND->handle, GSK_OS400_READ_TIMEOUT, 1); if(!result) +#ifndef CURL_DISABLE_PROXY result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0? BACKEND->localfd: conn->sock[sockindex]); +#else + result = set_numeric(data, BACKEND->handle, GSK_FD, + conn->sock[sockindex]); +#endif if(!result) result = set_ciphers(data, BACKEND->handle, &protoflags); if(!protoflags) { @@ -896,10 +916,12 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, else if(errno != ENOBUFS) result = gskit_status(data, GSK_ERROR_IO, "QsoCreateIOCompletionPort()", 0); +#ifndef CURL_DISABLE_PROXY else if(conn->proxy_ssl[sockindex].use) { /* Cannot pipeline while handshaking synchronously. */ result = CURLE_SSL_CONNECT_ERROR; } +#endif else { /* No more completion port available. Use synchronous IO. */ result = gskit_status(data, gsk_secure_soc_init(BACKEND->handle), @@ -1035,8 +1057,7 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data, } /* Check pinned public key. */ - ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + ptr = SSL_PINNED_PUB_KEY(); if(!result && ptr) { curl_X509certificate x509; curl_asn1Element *p; @@ -1158,7 +1179,9 @@ static void gskit_close(struct Curl_easy *data, struct connectdata *conn, int sockindex) { close_one(&conn->ssl[sockindex], data, conn, sockindex); +#ifndef CURL_DISABLE_PROXY close_one(&conn->proxy_ssl[sockindex], data, conn, sockindex); +#endif } @@ -1281,7 +1304,9 @@ const struct Curl_ssl Curl_ssl_gskit = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - NULL /* sha256sum */ + NULL, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_GSKIT */ diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c index e3fad7fe02..ecde5c44de 100644 --- a/libs/libcurl/src/vtls/gtls.c +++ b/libs/libcurl/src/vtls/gtls.c @@ -263,7 +263,7 @@ static CURLcode handshake(struct Curl_easy *data, strerr = gnutls_alert_get_name(alert); } - if(strerr == NULL) + if(!strerr) strerr = gnutls_strerror(rc); infof(data, "gnutls_handshake() warning: %s\n", strerr); @@ -277,7 +277,7 @@ static CURLcode handshake(struct Curl_easy *data, strerr = gnutls_alert_get_name(alert); } - if(strerr == NULL) + if(!strerr) strerr = gnutls_strerror(rc); failf(data, "gnutls_handshake() failed: %s", strerr); @@ -308,15 +308,29 @@ static gnutls_x509_crt_fmt_t do_file_type(const char *type) #define GNUTLS_SRP "+SRP" static CURLcode -set_ssl_version_min_max(const char **prioritylist, struct Curl_easy *data) +set_ssl_version_min_max(struct Curl_easy *data, + const char **prioritylist, + const char *tls13support) { struct connectdata *conn = data->conn; long ssl_version = SSL_CONN_CONFIG(version); long ssl_version_max = SSL_CONN_CONFIG(version_max); - if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) { + if((ssl_version == CURL_SSLVERSION_DEFAULT) || + (ssl_version == CURL_SSLVERSION_TLSv1)) + ssl_version = CURL_SSLVERSION_TLSv1_0; + if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) ssl_version_max = CURL_SSLVERSION_MAX_DEFAULT; + if(!tls13support) { + /* If the running GnuTLS doesn't support TLS 1.3, we must not specify a + prioritylist involving that since it will make GnuTLS return an en + error back at us */ + if((ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) || + (ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT)) { + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + } } + switch(ssl_version | ssl_version_max) { case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" @@ -395,6 +409,7 @@ gtls_connect_step1(struct Curl_easy *data, const char *err = NULL; const char * const hostname = SSL_HOST_NAME(); long * const certverifyresult = &SSL_SET_OPTION_LVALUE(certverifyresult); + const char *tls13support; if(connssl->state == ssl_connection_complete) /* to make us tolerant against being called more than once for the @@ -542,36 +557,34 @@ gtls_connect_step1(struct Curl_easy *data, if(rc != GNUTLS_E_SUCCESS) return CURLE_SSL_CONNECT_ERROR; + /* "In GnuTLS 3.6.5, TLS 1.3 is enabled by default" */ + tls13support = gnutls_check_version("3.6.5"); + /* Ensure +SRP comes at the *end* of all relevant strings so that it can be * removed if a run-time error indicates that SRP is not supported by this * GnuTLS version */ switch(SSL_CONN_CONFIG(version)) { - case CURL_SSLVERSION_SSLv3: - prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0"; - break; + case CURL_SSLVERSION_TLSv1_3: + if(!tls13support) { + failf(data, "This GnuTLS installation does not support TLS 1.3"); + return CURLE_SSL_CONNECT_ERROR; + } + /* FALLTHROUGH */ case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0" -#ifdef HAS_TLS13 - ":+VERS-TLS1.3" -#endif - ; - break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - { - CURLcode result = set_ssl_version_min_max(&prioritylist, data); - if(result != CURLE_OK) - return result; - break; - } + case CURL_SSLVERSION_TLSv1_2: { + CURLcode result = set_ssl_version_min_max(data, &prioritylist, + tls13support); + if(result) + return result; + break; + } case CURL_SSLVERSION_SSLv2: - failf(data, "GnuTLS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv3: default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + failf(data, "GnuTLS does not support SSLv2 or SSLv3"); return CURLE_SSL_CONNECT_ERROR; } @@ -586,7 +599,6 @@ gtls_connect_step1(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; strcpy(prioritysrp, prioritylist); strcpy(prioritysrp + len, ":" GNUTLS_SRP); - rc = gnutls_priority_set_direct(session, prioritysrp, &err); free(prioritysrp); @@ -611,16 +623,16 @@ gtls_connect_step1(struct Curl_easy *data, int cur = 0; gnutls_datum_t protocols[2]; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { - protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID; - protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN; + protocols[cur].data = (unsigned char *)ALPN_H2; + protocols[cur].size = ALPN_H2_LENGTH; cur++; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + infof(data, "ALPN, offering %.*s\n", ALPN_H2_LENGTH, ALPN_H2); } #endif @@ -1178,8 +1190,7 @@ gtls_connect_step3(struct Curl_easy *data, infof(data, "\t server certificate activation date OK\n"); } - ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + ptr = SSL_PINNED_PUB_KEY(); if(ptr) { result = pkp_pin_peer_pubkey(data, x509_cert, ptr); if(result != CURLE_OK) { @@ -1243,10 +1254,10 @@ gtls_connect_step3(struct Curl_easy *data, infof(data, "ALPN, server accepted to use %.*s\n", proto.size, proto.data); -#ifdef USE_NGHTTP2 - if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data, - NGHTTP2_PROTO_VERSION_ID_LEN)) { +#ifdef USE_HTTP2 + if(proto.size == ALPN_H2_LENGTH && + !memcmp(ALPN_H2, proto.data, + ALPN_H2_LENGTH)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -1645,7 +1656,9 @@ const struct Curl_ssl Curl_ssl_gnutls = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - gtls_sha256sum /* sha256sum */ + gtls_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_GNUTLS */ diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c index 4b36f2d20c..3a0be0f04b 100644 --- a/libs/libcurl/src/vtls/mbedtls.c +++ b/libs/libcurl/src/vtls/mbedtls.c @@ -251,22 +251,16 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, const char * const ssl_capath = SSL_CONN_CONFIG(CApath); char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const char * const hostname = conn->host.name; - const long int port = conn->remote_port; -#endif + const char * const hostname = SSL_HOST_NAME(); + const long int port = SSL_HOST_PORT(); int ret = -1; char errorbuf[128]; errorbuf[0] = 0; - /* mbedTLS only supports SSLv3 and TLSv1 */ - if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { - failf(data, "mbedTLS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; + if((SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) || + (SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)) { + failf(data, "Not supported SSL version"); + return CURLE_NOT_BUILT_IN; } #ifdef THREADING_SUPPORT @@ -414,13 +408,6 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, MBEDTLS_SSL_MINOR_VERSION_1); infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n"); break; - case CURL_SSLVERSION_SSLv3: - mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_0); - mbedtls_ssl_conf_max_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_0); - infof(data, "mbedTLS: Set SSL version to SSLv3\n"); - break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: case CURL_SSLVERSION_TLSv1_2: @@ -549,14 +536,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; const mbedtls_x509_crt *peercert; -#ifndef CURL_DISABLE_PROXY - const char * const pinnedpubkey = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#else - const char * const pinnedpubkey = - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#endif + const char * const pinnedpubkey = SSL_PINNED_PUB_KEY(); conn->recv[sockindex] = mbed_recv; conn->send[sockindex] = mbed_send; @@ -1113,7 +1093,9 @@ const struct Curl_ssl Curl_ssl_mbedtls = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - mbedtls_sha256sum /* sha256sum */ + mbedtls_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_MBEDTLS */ diff --git a/libs/libcurl/src/vtls/mesalink.c b/libs/libcurl/src/vtls/mesalink.c index 5d6a1495d7..bf8600d323 100644 --- a/libs/libcurl/src/vtls/mesalink.c +++ b/libs/libcurl/src/vtls/mesalink.c @@ -98,8 +98,7 @@ mesalink_connect_step1(struct Curl_easy *data, #ifdef ENABLE_IPV6 struct in6_addr addr6; #endif - const char *const hostname = - SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; + const char * const hostname = SSL_HOST_NAME(); size_t hostname_len = strlen(hostname); SSL_METHOD *req_method = NULL; @@ -667,7 +666,9 @@ const struct Curl_ssl Curl_ssl_mesalink = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - NULL /* sha256sum */ + NULL, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c index a9f6959e3b..1582b1e580 100644 --- a/libs/libcurl/src/vtls/nss.c +++ b/libs/libcurl/src/vtls/nss.c @@ -139,9 +139,15 @@ static const struct cipher_s cipherlist[] = { {"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA}, {"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA}, {"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA}, + {"dhe_rsa_3des_sha", SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA}, + {"dhe_dss_3des_sha", SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA}, + {"dhe_rsa_des_sha", SSL_DHE_RSA_WITH_DES_CBC_SHA}, + {"dhe_dss_des_sha", SSL_DHE_DSS_WITH_DES_CBC_SHA}, /* TLS 1.0: Exportable 56-bit Cipher Suites. */ {"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA}, {"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA}, + /* Ephemeral DH with RC4 bulk encryption */ + {"dhe_dss_rc4_128_sha", TLS_DHE_DSS_WITH_RC4_128_SHA}, /* AES ciphers. */ {"dhe_dss_aes_128_cbc_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA}, {"dhe_dss_aes_256_cbc_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA}, @@ -219,6 +225,25 @@ static const struct cipher_s cipherlist[] = { {"aes_256_gcm_sha_384", TLS_AES_256_GCM_SHA384}, {"chacha20_poly1305_sha_256", TLS_CHACHA20_POLY1305_SHA256}, #endif +#ifdef TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 + /* AES CBC cipher suites in RFC 5246. Introduced in NSS release 3.20 */ + {"dhe_dss_aes_128_sha_256", TLS_DHE_DSS_WITH_AES_128_CBC_SHA256}, + {"dhe_dss_aes_256_sha_256", TLS_DHE_DSS_WITH_AES_256_CBC_SHA256}, +#endif +#ifdef TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + /* Camellia cipher suites in RFC 4132/5932. + Introduced in NSS release 3.12 */ + {"dhe_rsa_camellia_128_sha", TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA}, + {"dhe_dss_camellia_128_sha", TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA}, + {"dhe_rsa_camellia_256_sha", TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA}, + {"dhe_dss_camellia_256_sha", TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA}, + {"rsa_camellia_128_sha", TLS_RSA_WITH_CAMELLIA_128_CBC_SHA}, + {"rsa_camellia_256_sha", TLS_RSA_WITH_CAMELLIA_256_CBC_SHA}, +#endif +#ifdef TLS_RSA_WITH_SEED_CBC_SHA + /* SEED cipher suite in RFC 4162. Introduced in NSS release 3.12.3 */ + {"rsa_seed_sha", TLS_RSA_WITH_SEED_CBC_SHA}, +#endif }; #if defined(WIN32) @@ -312,7 +337,7 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model, while((*cipher) && (ISSPACE(*cipher))) ++cipher; - cipher_list = strchr(cipher, ','); + cipher_list = strpbrk(cipher, ":, "); if(cipher_list) { *cipher_list++ = '\0'; } @@ -380,7 +405,7 @@ static int is_file(const char *filename) { struct_stat st; - if(filename == NULL) + if(!filename) return 0; if(stat(filename, &st) == 0) @@ -845,8 +870,8 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg) } #ifdef USE_NGHTTP2 - if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) { + if(buflen == ALPN_H2_LENGTH && + !memcmp(ALPN_H2, buf, ALPN_H2_LENGTH)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -1423,7 +1448,7 @@ static CURLcode nss_setup(struct Curl_easy *data) static int nss_init(void) { /* curl_global_init() is not thread-safe so this test is ok */ - if(nss_initlock == NULL) { + if(!nss_initlock) { PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); nss_initlock = PR_NewLock(); nss_crllock = PR_NewLock(); @@ -1699,8 +1724,7 @@ static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version) return CURLE_OK; case CURL_SSLVERSION_SSLv3: - *nssver = SSL_LIBRARY_VERSION_3_0; - return CURLE_OK; + return CURLE_NOT_BUILT_IN; case CURL_SSLVERSION_TLSv1_0: *nssver = SSL_LIBRARY_VERSION_TLS_1_0; @@ -1806,7 +1830,7 @@ static CURLcode nss_set_blocking(struct ssl_connect_data *connssl, struct Curl_easy *data, bool blocking) { - static PRSocketOptionData sock_opt; + PRSocketOptionData sock_opt; struct ssl_backend_data *backend = connssl->backend; sock_opt.option = PR_SockOpt_Nonblocking; sock_opt.value.non_blocking = !blocking; @@ -2079,16 +2103,15 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, int cur = 0; unsigned char protocols[128]; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { - protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; - memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN); - cur += NGHTTP2_PROTO_VERSION_ID_LEN; + protocols[cur++] = ALPN_H2_LENGTH; + memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH); + cur += ALPN_H2_LENGTH; } #endif protocols[cur++] = ALPN_HTTP_1_1_LENGTH; @@ -2442,7 +2465,9 @@ const struct Curl_ssl Curl_ssl_nss = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ nss_false_start, /* false_start */ - nss_sha256sum /* sha256sum */ + nss_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_NSS */ diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c index 6583300b3c..ebd7abc3b4 100644 --- a/libs/libcurl/src/vtls/openssl.c +++ b/libs/libcurl/src/vtls/openssl.c @@ -122,12 +122,6 @@ #define HAVE_ERR_REMOVE_THREAD_STATE 1 #endif -#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \ - OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */ -#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */ -#define OPENSSL_NO_SSL2 -#endif - #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \ !(defined(LIBRESSL_VERSION_NUMBER) && \ LIBRESSL_VERSION_NUMBER < 0x20700000L) @@ -246,6 +240,10 @@ struct ssl_backend_data { #endif }; +static void ossl_associate_connection(struct Curl_easy *data, + struct connectdata *conn, + int sockindex); + /* * Number of bytes to read from the random number seed file. This must be * a finite value (because some entropy "files" like /dev/urandom have @@ -625,7 +623,7 @@ SSL_CTX_use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob, goto end; } - if(x == NULL) { + if(!x) { ret = 0; goto end; } @@ -656,7 +654,7 @@ SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob, ret = 0; goto end; } - if(pkey == NULL) { + if(!pkey) { ret = 0; goto end; } @@ -669,7 +667,7 @@ SSL_CTX_use_PrivateKey_blob(SSL_CTX *ctx, const struct curl_blob *blob, static int SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob, - const char *key_passwd) + const char *key_passwd) { /* SSL_CTX_add1_chain_cert introduced in OpenSSL 1.0.2 */ #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* OpenSSL 1.0.2 or later */ \ @@ -687,7 +685,7 @@ SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob, x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback, (void *)key_passwd); - if(x == NULL) { + if(!x) { ret = 0; goto end; } @@ -731,7 +729,7 @@ SSL_CTX_use_certificate_chain_blob(SSL_CTX *ctx, const struct curl_blob *blob, return ret; #else (void)ctx; /* unused */ - (void)in; /* unused */ + (void)blob; /* unused */ (void)key_passwd; /* unused */ return 0; #endif @@ -875,7 +873,7 @@ int cert_stuff(struct Curl_easy *data, STACK_OF(X509) *ca = NULL; if(cert_blob) { cert_bio = BIO_new_mem_buf(cert_blob->data, (int)(cert_blob->len)); - if(cert_bio == NULL) { + if(!cert_bio) { failf(data, "BIO_new_mem_buf NULL, " OSSL_PACKAGE " error %s", @@ -886,7 +884,7 @@ int cert_stuff(struct Curl_easy *data, } else { cert_bio = BIO_new(BIO_s_file()); - if(cert_bio == NULL) { + if(!cert_bio) { failf(data, "BIO_new return NULL, " OSSL_PACKAGE " error %s", @@ -2262,12 +2260,10 @@ select_next_proto_cb(SSL *ssl, struct connectdata *conn = data->conn; (void)ssl; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 && - !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN)) { - infof(data, "NPN, negotiated HTTP2 (%s)\n", - NGHTTP2_PROTO_VERSION_ID); + !select_next_protocol(out, outlen, in, inlen, ALPN_H2, ALPN_H2_LENGTH)) { + infof(data, "NPN, negotiated HTTP2 (%s)\n", ALPN_H2); conn->negnpn = CURL_HTTP_VERSION_2; return SSL_TLSEXT_ERR_OK; } @@ -2518,6 +2514,67 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) return res; } +static CURLcode load_cacert_from_memory(SSL_CTX *ctx, + const struct curl_blob *ca_info_blob) +{ + /* these need freed at the end */ + BIO *cbio = NULL; + STACK_OF(X509_INFO) *inf = NULL; + + /* everything else is just a reference */ + int i, count = 0; + X509_STORE *cts = NULL; + X509_INFO *itmp = NULL; + + if(ca_info_blob->len > (size_t)INT_MAX) + return CURLE_SSL_CACERT_BADFILE; + + cts = SSL_CTX_get_cert_store(ctx); + if(!cts) + return CURLE_OUT_OF_MEMORY; + + cbio = BIO_new_mem_buf(ca_info_blob->data, (int)ca_info_blob->len); + if(!cbio) + return CURLE_OUT_OF_MEMORY; + + inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL); + if(!inf) { + BIO_free(cbio); + return CURLE_SSL_CACERT_BADFILE; + } + + /* add each entry from PEM file to x509_store */ + for(i = 0; i < (int)sk_X509_INFO_num(inf); ++i) { + itmp = sk_X509_INFO_value(inf, i); + if(itmp->x509) { + if(X509_STORE_add_cert(cts, itmp->x509)) { + ++count; + } + else { + /* set count to 0 to return an error */ + count = 0; + break; + } + } + if(itmp->crl) { + if(X509_STORE_add_crl(cts, itmp->crl)) { + ++count; + } + else { + /* set count to 0 to return an error */ + count = 0; + break; + } + } + } + + sk_X509_INFO_pop_free(inf, X509_INFO_free); + BIO_free(cbio); + + /* if we didn't end up importing anything, treat that as an error */ + return (count > 0 ? CURLE_OK : CURLE_SSL_CACERT_BADFILE); +} + static CURLcode ossl_connect_step1(struct Curl_easy *data, struct connectdata *conn, int sockindex) { @@ -2528,6 +2585,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; ctx_option_t ctx_options = 0; + void *ssl_sessionid = NULL; #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME bool sni; @@ -2545,8 +2603,11 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, #endif char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); + const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob); const char * const ssl_cert_type = SSL_SET_OPTION(cert_type); - const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const char * const ssl_cafile = + /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ + (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile)); const char * const ssl_capath = SSL_CONN_CONFIG(CApath); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); @@ -2581,31 +2642,11 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, use_sni(TRUE); break; case CURL_SSLVERSION_SSLv2: -#ifdef OPENSSL_NO_SSL2 - failf(data, OSSL_PACKAGE " was built without SSLv2 support"); + failf(data, "No SSLv2 support"); return CURLE_NOT_BUILT_IN; -#else -#ifdef USE_OPENSSL_SRP - if(ssl_authtype == CURL_TLSAUTH_SRP) - return CURLE_SSL_CONNECT_ERROR; -#endif - req_method = SSLv2_client_method(); - use_sni(FALSE); - break; -#endif case CURL_SSLVERSION_SSLv3: -#ifdef OPENSSL_NO_SSL3_METHOD - failf(data, OSSL_PACKAGE " was built without SSLv3 support"); + failf(data, "No SSLv3 support"); return CURLE_NOT_BUILT_IN; -#else -#ifdef USE_OPENSSL_SRP - if(ssl_authtype == CURL_TLSAUTH_SRP) - return CURLE_SSL_CONNECT_ERROR; -#endif - req_method = SSLv3_client_method(); - use_sni(FALSE); - break; -#endif default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -2693,41 +2734,9 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, #endif switch(ssl_version) { - /* "--sslv2" option means SSLv2 only, disable all others */ case CURL_SSLVERSION_SSLv2: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ - SSL_CTX_set_min_proto_version(backend->ctx, SSL2_VERSION); - SSL_CTX_set_max_proto_version(backend->ctx, SSL2_VERSION); -#else - ctx_options |= SSL_OP_NO_SSLv3; - ctx_options |= SSL_OP_NO_TLSv1; -# if OPENSSL_VERSION_NUMBER >= 0x1000100FL - ctx_options |= SSL_OP_NO_TLSv1_1; - ctx_options |= SSL_OP_NO_TLSv1_2; -# ifdef TLS1_3_VERSION - ctx_options |= SSL_OP_NO_TLSv1_3; -# endif -# endif -#endif - break; - - /* "--sslv3" option means SSLv3 only, disable all others */ case CURL_SSLVERSION_SSLv3: -#if OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0 */ - SSL_CTX_set_min_proto_version(backend->ctx, SSL3_VERSION); - SSL_CTX_set_max_proto_version(backend->ctx, SSL3_VERSION); -#else - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_TLSv1; -# if OPENSSL_VERSION_NUMBER >= 0x1000100FL - ctx_options |= SSL_OP_NO_TLSv1_1; - ctx_options |= SSL_OP_NO_TLSv1_2; -# ifdef TLS1_3_VERSION - ctx_options |= SSL_OP_NO_TLSv1_3; -# endif -# endif -#endif - break; + return CURLE_NOT_BUILT_IN; /* "--tlsv" options mean TLS >= version */ case CURL_SSLVERSION_DEFAULT: @@ -2768,18 +2777,17 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, int cur = 0; unsigned char protocols[128]; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { - protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; + protocols[cur++] = ALPN_H2_LENGTH; - memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN); - cur += NGHTTP2_PROTO_VERSION_ID_LEN; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH); + cur += ALPN_H2_LENGTH; + infof(data, "ALPN, offering %s\n", ALPN_H2); } #endif @@ -2885,8 +2893,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, if((SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost)) && (SSL_SET_OPTION(native_ca_store))) { X509_STORE *store = SSL_CTX_get_cert_store(backend->ctx); - HCERTSTORE hStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL, - TEXT("ROOT")); + HCERTSTORE hStore = CertOpenSystemStore(0, TEXT("ROOT")); if(hStore) { PCCERT_CONTEXT pContext = NULL; @@ -3023,6 +3030,19 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, } #endif + if(ca_info_blob) { + result = load_cacert_from_memory(backend->ctx, ca_info_blob); + if(result) { + if(result == CURLE_OUT_OF_MEMORY || + (verifypeer && !imported_native_ca)) { + failf(data, "error importing CA certificate blob"); + return result; + } + /* Only warning if no certificate verification is required. */ + infof(data, "error importing CA certificate blob, continuing anyway\n"); + } + } + #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */ { @@ -3079,7 +3099,8 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, #endif #ifdef CURL_CA_FALLBACK - if(verifypeer && !ssl_cafile && !ssl_capath && !imported_native_ca) { + if(verifypeer && + !ca_info_blob && !ssl_cafile && !ssl_capath && !imported_native_ca) { /* verifying the peer without any CA certificates won't work so use openssl's built in default as fallback */ SSL_CTX_set_default_verify_paths(backend->ctx); @@ -3209,46 +3230,23 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, } #endif - /* Check if there's a cached ID we can/should use here! */ - if(SSL_SET_OPTION(primary.sessionid)) { - void *ssl_sessionid = NULL; - int data_idx = ossl_get_ssl_data_index(); - int connectdata_idx = ossl_get_ssl_conn_index(); - int sockindex_idx = ossl_get_ssl_sockindex_index(); - int proxy_idx = ossl_get_proxy_index(); + ossl_associate_connection(data, conn, sockindex); - if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && - proxy_idx >= 0) { - /* Store the data needed for the "new session" callback. - * The sockindex is stored as a pointer to an array element. */ - SSL_set_ex_data(backend->handle, data_idx, data); - SSL_set_ex_data(backend->handle, connectdata_idx, conn); - SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); -#ifndef CURL_DISABLE_PROXY - SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: - NULL); -#else - SSL_set_ex_data(backend->handle, proxy_idx, NULL); -#endif - - } - - Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, - &ssl_sessionid, NULL, sockindex)) { - /* we got a session id, use it! */ - if(!SSL_set_session(backend->handle, ssl_sessionid)) { - Curl_ssl_sessionid_unlock(data); - failf(data, "SSL: SSL_set_session failed: %s", - ossl_strerror(ERR_get_error(), error_buffer, - sizeof(error_buffer))); - return CURLE_SSL_CONNECT_ERROR; - } - /* Informational message */ - infof(data, "SSL re-using session ID\n"); + Curl_ssl_sessionid_lock(data); + if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, + &ssl_sessionid, NULL, sockindex)) { + /* we got a session id, use it! */ + if(!SSL_set_session(backend->handle, ssl_sessionid)) { + Curl_ssl_sessionid_unlock(data); + failf(data, "SSL: SSL_set_session failed: %s", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); + return CURLE_SSL_CONNECT_ERROR; } - Curl_ssl_sessionid_unlock(data); + /* Informational message */ + infof(data, "SSL re-using session ID\n"); } + Curl_ssl_sessionid_unlock(data); #ifndef CURL_DISABLE_PROXY if(conn->proxy_ssl[sockindex].use) { @@ -3353,6 +3351,19 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, error_buffer */ strcpy(error_buffer, "SSL certificate verification failed"); } +#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \ + !defined(LIBRESSL_VERSION_NUMBER) && \ + !defined(OPENSSL_IS_BORINGSSL)) + /* SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED is only available on + OpenSSL version above v1.1.1, not Libre SSL nor BoringSSL */ + else if((lib == ERR_LIB_SSL) && + (reason == SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED)) { + /* If client certificate is required, communicate the + error to client */ + result = CURLE_SSL_CLIENTCERT; + ossl_strerror(errdetail, error_buffer, sizeof(error_buffer)); + } +#endif else { result = CURLE_SSL_CONNECT_ERROR; ossl_strerror(errdetail, error_buffer, sizeof(error_buffer)); @@ -3366,11 +3377,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, */ if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) { const char * const hostname = SSL_HOST_NAME(); -#ifndef CURL_DISABLE_PROXY - const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const long int port = conn->remote_port; -#endif + const long int port = SSL_HOST_PORT(); char extramsg[80]=""; int sockerr = SOCKERRNO; if(sockerr && detail == SSL_ERROR_SYSCALL) @@ -3404,12 +3411,12 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, const unsigned char *neg_protocol; unsigned int len; SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len); - if(len != 0) { + if(len) { infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol); -#ifdef USE_NGHTTP2 - if(len == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) { +#ifdef USE_HTTP2 + if(len == ALPN_H2_LENGTH && + !memcmp(ALPN_H2, neg_protocol, len)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -3896,7 +3903,7 @@ static CURLcode servercert(struct Curl_easy *data, (int)SSL_SET_OPTION(issuercert_blob)->len); else { fp = BIO_new(BIO_s_file()); - if(fp == NULL) { + if(!fp) { failf(data, "BIO_new return NULL, " OSSL_PACKAGE " error %s", @@ -3983,8 +3990,7 @@ static CURLcode servercert(struct Curl_easy *data, /* when not strict, we don't bother about the verify cert problems */ result = CURLE_OK; - ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + ptr = SSL_PINNED_PUB_KEY(); if(!result && ptr) { result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr); if(result) @@ -4474,10 +4480,95 @@ static void *ossl_get_internals(struct ssl_connect_data *connssl, (void *)backend->ctx : (void *)backend->handle; } +static void ossl_associate_connection(struct Curl_easy *data, + struct connectdata *conn, + int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + + /* If we don't have SSL context, do nothing. */ + if(!backend->handle) + return; + + if(SSL_SET_OPTION(primary.sessionid)) { + int data_idx = ossl_get_ssl_data_index(); + int connectdata_idx = ossl_get_ssl_conn_index(); + int sockindex_idx = ossl_get_ssl_sockindex_index(); + int proxy_idx = ossl_get_proxy_index(); + + if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && + proxy_idx >= 0) { + /* Store the data needed for the "new session" callback. + * The sockindex is stored as a pointer to an array element. */ + SSL_set_ex_data(backend->handle, data_idx, data); + SSL_set_ex_data(backend->handle, connectdata_idx, conn); + SSL_set_ex_data(backend->handle, sockindex_idx, conn->sock + sockindex); +#ifndef CURL_DISABLE_PROXY + SSL_set_ex_data(backend->handle, proxy_idx, SSL_IS_PROXY() ? (void *) 1: + NULL); +#else + SSL_set_ex_data(backend->handle, proxy_idx, NULL); +#endif + } + } +} + +/* + * Starting with TLS 1.3, the ossl_new_session_cb callback gets called after + * the handshake. If the transfer that sets up the callback gets killed before + * this callback arrives, we must make sure to properly clear the data to + * avoid UAF problems. A future optimization could be to instead store another + * transfer that might still be using the same connection. + */ + +static void ossl_disassociate_connection(struct Curl_easy *data, + int sockindex) +{ + struct connectdata *conn = data->conn; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + + /* If we don't have SSL context, do nothing. */ + if(!backend->handle) + return; + + if(SSL_SET_OPTION(primary.sessionid)) { + bool isproxy = FALSE; + bool incache; + void *old_ssl_sessionid = NULL; + int data_idx = ossl_get_ssl_data_index(); + int connectdata_idx = ossl_get_ssl_conn_index(); + int sockindex_idx = ossl_get_ssl_sockindex_index(); + int proxy_idx = ossl_get_proxy_index(); + + if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && + proxy_idx >= 0) { + /* Invalidate the session cache entry, if any */ + isproxy = SSL_get_ex_data(backend->handle, proxy_idx) ? TRUE : FALSE; + + /* Disable references to data in "new session" callback to avoid + * accessing a stale pointer. */ + SSL_set_ex_data(backend->handle, data_idx, NULL); + SSL_set_ex_data(backend->handle, connectdata_idx, NULL); + SSL_set_ex_data(backend->handle, sockindex_idx, NULL); + SSL_set_ex_data(backend->handle, proxy_idx, NULL); + } + + Curl_ssl_sessionid_lock(data); + incache = !(Curl_ssl_getsessionid(data, conn, isproxy, + &old_ssl_sessionid, NULL, sockindex)); + if(incache) + Curl_ssl_delsessionid(data, old_ssl_sessionid); + Curl_ssl_sessionid_unlock(data); + } +} + const struct Curl_ssl Curl_ssl_openssl = { { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */ SSLSUPP_CA_PATH | + SSLSUPP_CAINFO_BLOB | SSLSUPP_CERTINFO | SSLSUPP_PINNEDPUBKEY | SSLSUPP_SSL_CTX | @@ -4508,10 +4599,12 @@ const struct Curl_ssl Curl_ssl_openssl = { ossl_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ #if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) - ossl_sha256sum /* sha256sum */ + ossl_sha256sum, /* sha256sum */ #else - NULL /* sha256sum */ + NULL, /* sha256sum */ #endif + ossl_associate_connection, /* associate_connection */ + ossl_disassociate_connection /* disassociate_connection */ }; #endif /* USE_OPENSSL */ diff --git a/libs/libcurl/src/vtls/rustls.c b/libs/libcurl/src/vtls/rustls.c index e4f589de57..d5247f936a 100644 --- a/libs/libcurl/src/vtls/rustls.c +++ b/libs/libcurl/src/vtls/rustls.c @@ -37,16 +37,11 @@ #include "multiif.h" -/* Per https://www.bearssl.org/api1.html, max TLS record size plus max - per-record overhead. */ -#define TLSBUF_SIZE (16384 + 325) - struct ssl_backend_data { const struct rustls_client_config *config; - struct rustls_client_session *session; + struct rustls_connection *conn; bool data_pending; - uint8_t *tlsbuf; }; /* For a given rustls_result error code, return the best-matching CURLcode. */ @@ -82,6 +77,28 @@ cr_connect(struct Curl_easy *data UNUSED_PARAM, return CURLE_SSL_CONNECT_ERROR; } +static int +read_cb(void *userdata, uint8_t *buf, uintptr_t len, uintptr_t *out_n) +{ + ssize_t n = sread(*(int *)userdata, buf, len); + if(n < 0) { + return SOCKERRNO; + } + *out_n = n; + return 0; +} + +static int +write_cb(void *userdata, const uint8_t *buf, uintptr_t len, uintptr_t *out_n) +{ + ssize_t n = swrite(*(int *)userdata, buf, len); + if(n < 0) { + return SOCKERRNO; + } + *out_n = n; + return 0; +} + /* * On each run: * - Read a chunk of bytes from the socket into rustls' TLS input buffer. @@ -101,65 +118,44 @@ cr_recv(struct Curl_easy *data, int sockindex, struct connectdata *conn = data->conn; struct ssl_connect_data *const connssl = &conn->ssl[sockindex]; struct ssl_backend_data *const backend = connssl->backend; - struct rustls_client_session *const session = backend->session; - curl_socket_t sockfd = conn->sock[sockindex]; + struct rustls_connection *const rconn = backend->conn; size_t n = 0; - ssize_t tls_bytes_read = 0; - size_t tls_bytes_processed = 0; + size_t tls_bytes_read = 0; size_t plain_bytes_copied = 0; rustls_result rresult = 0; char errorbuf[255]; + rustls_io_result io_error; - tls_bytes_read = sread(sockfd, backend->tlsbuf, TLSBUF_SIZE); - if(tls_bytes_read == 0) { - failf(data, "connection closed without TLS close_notify alert"); + io_error = rustls_connection_read_tls(rconn, read_cb, + &conn->sock[sockindex], &tls_bytes_read); + if(io_error == EAGAIN || io_error == EWOULDBLOCK) { + infof(data, "sread: EAGAIN or EWOULDBLOCK\n"); + } + else if(io_error) { + failf(data, "reading from socket: %s", strerror(io_error)); *err = CURLE_READ_ERROR; return -1; } - else if(tls_bytes_read < 0) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { - infof(data, "sread: EAGAIN or EWOULDBLOCK\n"); - *err = CURLE_AGAIN; - return -1; - } - failf(data, "reading from socket: %s", strerror(SOCKERRNO)); + else if(tls_bytes_read == 0) { + failf(data, "connection closed without TLS close_notify alert"); *err = CURLE_READ_ERROR; return -1; } - /* - * Now pull those bytes from the buffer into ClientSession. - */ - DEBUGASSERT(tls_bytes_read > 0); - while(tls_bytes_processed < (size_t)tls_bytes_read) { - rresult = rustls_client_session_read_tls(session, - backend->tlsbuf + tls_bytes_processed, - tls_bytes_read - tls_bytes_processed, - &n); - if(rresult != RUSTLS_RESULT_OK) { - failf(data, "error in rustls_client_session_read_tls"); - *err = CURLE_READ_ERROR; - return -1; - } - else if(n == 0) { - infof(data, "EOF from rustls_client_session_read_tls\n"); - break; - } + infof(data, "cr_recv read %ld bytes from the network\n", tls_bytes_read); - rresult = rustls_client_session_process_new_packets(session); - if(rresult != RUSTLS_RESULT_OK) { - rustls_error(rresult, errorbuf, sizeof(errorbuf), &n); - failf(data, "%.*s", n, errorbuf); - *err = map_error(rresult); - return -1; - } - - tls_bytes_processed += n; - backend->data_pending = TRUE; + rresult = rustls_connection_process_new_packets(rconn); + if(rresult != RUSTLS_RESULT_OK) { + rustls_error(rresult, errorbuf, sizeof(errorbuf), &n); + failf(data, "%.*s", n, errorbuf); + *err = map_error(rresult); + return -1; } + backend->data_pending = TRUE; + while(plain_bytes_copied < plainlen) { - rresult = rustls_client_session_read(session, + rresult = rustls_connection_read(rconn, (uint8_t *)plainbuf + plain_bytes_copied, plainlen - plain_bytes_copied, &n); @@ -168,20 +164,21 @@ cr_recv(struct Curl_easy *data, int sockindex, return 0; } else if(rresult != RUSTLS_RESULT_OK) { - failf(data, "error in rustls_client_session_read"); + failf(data, "error in rustls_connection_read"); *err = CURLE_READ_ERROR; return -1; } else if(n == 0) { - /* rustls returns 0 from client_session_read to mean "all currently + /* rustls returns 0 from connection_read to mean "all currently available data has been read." If we bring in more ciphertext with read_tls, more plaintext will become available. So don't tell curl this is an EOF. Instead, say "come back later." */ - infof(data, "EOF from rustls_client_session_read\n"); + infof(data, "cr_recv got 0 bytes of plaintext\n"); backend->data_pending = FALSE; break; } else { + infof(data, "cr_recv copied out %ld bytes of plaintext\n", n); plain_bytes_copied += n; } } @@ -214,68 +211,50 @@ cr_send(struct Curl_easy *data, int sockindex, struct connectdata *conn = data->conn; struct ssl_connect_data *const connssl = &conn->ssl[sockindex]; struct ssl_backend_data *const backend = connssl->backend; - struct rustls_client_session *const session = backend->session; - curl_socket_t sockfd = conn->sock[sockindex]; - ssize_t n = 0; + struct rustls_connection *const rconn = backend->conn; size_t plainwritten = 0; - size_t tlslen = 0; size_t tlswritten = 0; + size_t tlswritten_total = 0; rustls_result rresult; + rustls_io_result io_error; + + infof(data, "cr_send %ld bytes of plaintext\n", plainlen); if(plainlen > 0) { - rresult = rustls_client_session_write(session, - plainbuf, plainlen, &plainwritten); + rresult = rustls_connection_write(rconn, plainbuf, plainlen, + &plainwritten); if(rresult != RUSTLS_RESULT_OK) { - failf(data, "error in rustls_client_session_write"); + failf(data, "error in rustls_connection_write"); *err = CURLE_WRITE_ERROR; return -1; } else if(plainwritten == 0) { - failf(data, "EOF in rustls_client_session_write"); + failf(data, "EOF in rustls_connection_write"); *err = CURLE_WRITE_ERROR; return -1; } } - while(rustls_client_session_wants_write(session)) { - rresult = rustls_client_session_write_tls( - session, backend->tlsbuf, TLSBUF_SIZE, &tlslen); - if(rresult != RUSTLS_RESULT_OK) { - failf(data, "error in rustls_client_session_write_tls"); - *err = CURLE_WRITE_ERROR; + while(rustls_connection_wants_write(rconn)) { + io_error = rustls_connection_write_tls(rconn, write_cb, + &conn->sock[sockindex], &tlswritten); + if(io_error == EAGAIN || io_error == EWOULDBLOCK) { + infof(data, "swrite: EAGAIN after %ld bytes\n", tlswritten_total); + *err = CURLE_AGAIN; return -1; } - else if(tlslen == 0) { - failf(data, "EOF in rustls_client_session_write_tls"); + else if(io_error) { + failf(data, "writing to socket: %s", strerror(io_error)); *err = CURLE_WRITE_ERROR; return -1; } - - tlswritten = 0; - - while(tlswritten < tlslen) { - n = swrite(sockfd, backend->tlsbuf + tlswritten, tlslen - tlswritten); - if(n < 0) { - if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { - /* Since recv is called from poll, there should be room to - write at least some bytes before hitting EAGAIN. */ - infof(data, "swrite: EAGAIN after %ld bytes\n", tlswritten); - DEBUGASSERT(tlswritten > 0); - break; - } - failf(data, "error in swrite"); - *err = CURLE_WRITE_ERROR; - return -1; - } - if(n == 0) { - failf(data, "EOF in swrite"); - *err = CURLE_WRITE_ERROR; - return -1; - } - tlswritten += n; + if(tlswritten == 0) { + failf(data, "EOF in swrite"); + *err = CURLE_WRITE_ERROR; + return -1; } - - DEBUGASSERT(tlswritten <= tlslen); + infof(data, "cr_send wrote %ld bytes to network\n", tlswritten); + tlswritten_total += tlswritten; } return plainwritten; @@ -310,7 +289,7 @@ static CURLcode cr_init_backend(struct Curl_easy *data, struct connectdata *conn, struct ssl_backend_data *const backend) { - struct rustls_client_session *session = backend->session; + struct rustls_connection *rconn = backend->conn; struct rustls_client_config_builder *config_builder = NULL; const char *const ssl_cafile = SSL_CONN_CONFIG(CAfile); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); @@ -318,19 +297,26 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, char errorbuf[256]; size_t errorlen; int result; - - backend->tlsbuf = calloc(TLSBUF_SIZE, 1); - if(backend->tlsbuf == NULL) { - return CURLE_OUT_OF_MEMORY; - } + rustls_slice_bytes alpn[2] = { + { (const uint8_t *)ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH }, + { (const uint8_t *)ALPN_H2, ALPN_H2_LENGTH }, + }; config_builder = rustls_client_config_builder_new(); +#ifdef USE_HTTP2 + infof(data, "offering ALPN for HTTP/1.1 and HTTP/2\n"); + rustls_client_config_builder_set_protocols(config_builder, alpn, 2); +#else + infof(data, "offering ALPN for HTTP/1.1 only\n"); + rustls_client_config_builder_set_protocols(config_builder, alpn, 1); +#endif if(!verifypeer) { rustls_client_config_builder_dangerous_set_certificate_verifier( - config_builder, cr_verify_none, NULL); + config_builder, cr_verify_none); /* rustls doesn't support IP addresses (as of 0.19.0), and will reject - * sessions created with an IP address, even when certificate verification - * is turned off. Set a placeholder hostname and disable SNI. */ + * connections created with an IP address, even when certificate + * verification is turned off. Set a placeholder hostname and disable + * SNI. */ if(cr_hostname_is_ip(hostname)) { rustls_client_config_builder_set_enable_sni(config_builder, false); hostname = "example.invalid"; @@ -357,18 +343,51 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, } backend->config = rustls_client_config_builder_build(config_builder); - DEBUGASSERT(session == NULL); - result = rustls_client_session_new( - backend->config, hostname, &session); + DEBUGASSERT(rconn == NULL); + result = rustls_client_connection_new(backend->config, hostname, &rconn); if(result != RUSTLS_RESULT_OK) { rustls_error(result, errorbuf, sizeof(errorbuf), &errorlen); - failf(data, "failed to create client session: %.*s", errorlen, errorbuf); + failf(data, "rustls_client_connection_new: %.*s", errorlen, errorbuf); return CURLE_COULDNT_CONNECT; } - backend->session = session; + rustls_connection_set_userdata(rconn, backend); + backend->conn = rconn; return CURLE_OK; } +static void +cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn, + const struct rustls_connection *rconn) +{ + const uint8_t *protocol = NULL; + size_t len = 0; + + rustls_connection_get_alpn_protocol(rconn, &protocol, &len); + if(NULL == protocol) { + infof(data, "ALPN, server did not agree to a protocol\n"); + return; + } + +#ifdef USE_HTTP2 + if(len == ALPN_H2_LENGTH && 0 == memcmp(ALPN_H2, protocol, len)) { + infof(data, "ALPN, negotiated h2\n"); + conn->negnpn = CURL_HTTP_VERSION_2; + } + else +#endif + if(len == ALPN_HTTP_1_1_LENGTH && + 0 == memcmp(ALPN_HTTP_1_1, protocol, len)) { + infof(data, "ALPN, negotiated http/1.1\n"); + conn->negnpn = CURL_HTTP_VERSION_1_1; + } + else { + infof(data, "ALPN, negotiated an unrecognized protocol\n"); + } + + Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); +} + static CURLcode cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, int sockindex, bool *done) @@ -376,7 +395,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, struct ssl_connect_data *const connssl = &conn->ssl[sockindex]; curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_backend_data *const backend = connssl->backend; - struct rustls_client_session *session = NULL; + struct rustls_connection *rconn = NULL; CURLcode tmperr = CURLE_OK; int result; int what; @@ -393,7 +412,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, connssl->state = ssl_connection_negotiating; } - session = backend->session; + rconn = backend->conn; /* Read/write data until the handshake is done or the socket would block. */ for(;;) { @@ -404,18 +423,21 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, * then becomes true when we first write data, then becomes false again * once the handshake is done. */ - if(!rustls_client_session_is_handshaking(session)) { + if(!rustls_connection_is_handshaking(rconn)) { infof(data, "Done handshaking\n"); /* Done with the handshake. Set up callbacks to send/receive data. */ connssl->state = ssl_connection_complete; + + cr_set_negotiated_alpn(data, conn, rconn); + conn->recv[sockindex] = cr_recv; conn->send[sockindex] = cr_send; *done = TRUE; return CURLE_OK; } - wants_read = rustls_client_session_wants_read(session); - wants_write = rustls_client_session_wants_write(session); + wants_read = rustls_connection_wants_read(rconn); + wants_write = rustls_connection_wants_write(rconn); DEBUGASSERT(wants_read || wants_write); writefd = wants_write?sockfd:CURL_SOCKET_BAD; readfd = wants_read?sockfd:CURL_SOCKET_BAD; @@ -439,7 +461,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, /* socket is readable or writable */ if(wants_write) { - infof(data, "ClientSession wants us to write_tls.\n"); + infof(data, "rustls_connection wants us to write_tls.\n"); cr_send(data, sockindex, NULL, 0, &tmperr); if(tmperr == CURLE_AGAIN) { infof(data, "writing would block\n"); @@ -451,7 +473,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, } if(wants_read) { - infof(data, "ClientSession wants us to read_tls.\n"); + infof(data, "rustls_connection wants us to read_tls.\n"); cr_recv(data, sockindex, NULL, 0, &tmperr); if(tmperr == CURLE_AGAIN) { @@ -482,13 +504,13 @@ cr_getsock(struct connectdata *conn, curl_socket_t *socks) struct ssl_connect_data *const connssl = &conn->ssl[FIRSTSOCKET]; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; struct ssl_backend_data *const backend = connssl->backend; - struct rustls_client_session *session = backend->session; + struct rustls_connection *rconn = backend->conn; - if(rustls_client_session_wants_write(session)) { + if(rustls_connection_wants_write(rconn)) { socks[0] = sockfd; return GETSOCK_WRITESOCK(0); } - if(rustls_client_session_wants_read(session)) { + if(rustls_connection_wants_read(rconn)) { socks[0] = sockfd; return GETSOCK_READSOCK(0); } @@ -501,7 +523,7 @@ cr_get_internals(struct ssl_connect_data *connssl, CURLINFO info UNUSED_PARAM) { struct ssl_backend_data *backend = connssl->backend; - return &backend->session; + return &backend->conn; } static void @@ -513,21 +535,20 @@ cr_close(struct Curl_easy *data, struct connectdata *conn, CURLcode tmperr = CURLE_OK; ssize_t n = 0; - if(backend->session) { - rustls_client_session_send_close_notify(backend->session); + if(backend->conn) { + rustls_connection_send_close_notify(backend->conn); n = cr_send(data, sockindex, NULL, 0, &tmperr); if(n < 0) { failf(data, "error sending close notify: %d", tmperr); } - rustls_client_session_free(backend->session); - backend->session = NULL; + rustls_connection_free(backend->conn); + backend->conn = NULL; } if(backend->config) { rustls_client_config_free(backend->config); backend->config = NULL; } - free(backend->tlsbuf); } const struct Curl_ssl Curl_ssl_rustls = { @@ -554,7 +575,9 @@ const struct Curl_ssl Curl_ssl_rustls = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - NULL /* sha256sum */ + NULL, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_RUSTLS */ diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index 961a71f6d5..2bcf11db25 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.c @@ -117,6 +117,10 @@ #define SP_PROT_TLS1_2_CLIENT 0x00000800 #endif +#ifndef SCH_USE_STRONG_CRYPTO +#define SCH_USE_STRONG_CRYPTO 0x00400000 +#endif + #ifndef SECBUFFER_ALERT #define SECBUFFER_ALERT 17 #endif @@ -324,17 +328,22 @@ get_alg_id_by_name(char *name) } static CURLcode -set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers) +set_ssl_ciphers(SCHANNEL_CRED *schannel_cred, char *ciphers, + ALG_ID *algIds) { char *startCur = ciphers; int algCount = 0; - static ALG_ID algIds[45]; /*There are 45 listed in the MS headers*/ - while(startCur && (0 != *startCur) && (algCount < 45)) { + while(startCur && (0 != *startCur) && (algCount < NUMOF_CIPHERS)) { long alg = strtol(startCur, 0, 0); if(!alg) alg = get_alg_id_by_name(startCur); if(alg) algIds[algCount++] = alg; + else if(!strncmp(startCur, "USE_STRONG_CRYPTO", + sizeof("USE_STRONG_CRYPTO") - 1) || + !strncmp(startCur, "SCH_USE_STRONG_CRYPTO", + sizeof("SCH_USE_STRONG_CRYPTO") - 1)) + schannel_cred->dwFlags |= SCH_USE_STRONG_CRYPTO; else return CURLE_SSL_CIPHER; startCur = strchr(startCur, ':'); @@ -358,7 +367,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, size_t store_name_len; sep = _tcschr(path, TEXT('\\')); - if(sep == NULL) + if(!sep) return CURLE_SSL_CERTPROBLEM; store_name_len = sep - path; @@ -388,7 +397,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, store_path_start = sep + 1; sep = _tcschr(store_path_start, TEXT('\\')); - if(sep == NULL) + if(!sep) return CURLE_SSL_CERTPROBLEM; *thumbprint = sep + 1; @@ -398,7 +407,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, *sep = TEXT('\0'); *store_path = _tcsdup(store_path_start); *sep = TEXT('\\'); - if(*store_path == NULL) + if(!*store_path) return CURLE_OUT_OF_MEMORY; return CURLE_OK; @@ -428,12 +437,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, #endif TCHAR *host_name; CURLcode result; -#ifndef CURL_DISABLE_PROXY - char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - char * const hostname = conn->host.name; -#endif + char * const hostname = SSL_HOST_NAME(); DEBUGF(infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", @@ -469,7 +473,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, #endif #else #ifdef HAS_MANUAL_VERIFY_API - if(SSL_CONN_CONFIG(CAfile)) { + if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) { if(curlx_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_GREATER_THAN_EQUAL)) { BACKEND->use_manual_cred_validation = true; @@ -483,7 +487,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, else BACKEND->use_manual_cred_validation = false; #else - if(SSL_CONN_CONFIG(CAfile)) { + if(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) { failf(data, "schannel: CA cert support not built in"); return CURLE_NOT_BUILT_IN; } @@ -558,6 +562,14 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, "names in server certificates.\n")); } + if(!SSL_SET_OPTION(auto_client_cert)) { + schannel_cred.dwFlags &= ~SCH_CRED_USE_DEFAULT_CREDS; + schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS; + infof(data, "schannel: disabled automatic use of client certificate\n"); + } + else + infof(data, "schannel: enabled automatic use of client certificate\n"); + switch(conn->ssl_config.version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: @@ -572,18 +584,17 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, break; } case CURL_SSLVERSION_SSLv3: - schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; - break; case CURL_SSLVERSION_SSLv2: - schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT; - break; + failf(data, "SSL versions not supported"); + return CURLE_NOT_BUILT_IN; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; } if(SSL_CONN_CONFIG(cipher_list)) { - result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list)); + result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list), + BACKEND->algIds); if(CURLE_OK != result) { failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG"); return result; @@ -700,7 +711,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, } if(!blob) free(certdata); - if(cert_store == NULL) { + if(!cert_store) { DWORD errorcode = GetLastError(); if(errorcode == ERROR_INVALID_PASSWORD) failf(data, "schannel: Failed to import cert file %s, " @@ -717,7 +728,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL); - if(client_certs[0] == NULL) { + if(!client_certs[0]) { failf(data, "schannel: Failed to get certificate from file %s" ", last error is 0x%x", cert_showfilename_error, GetLastError()); @@ -861,11 +872,11 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, list_start_index = cur; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2) { - memcpy(&alpn_buffer[cur], NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN); - cur += NGHTTP2_PROTO_ALPN_LEN; - infof(data, "schannel: ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + memcpy(&alpn_buffer[cur], ALPN_H2, ALPN_H2_LENGTH); + cur += ALPN_H2_LENGTH; + infof(data, "schannel: ALPN, offering %s\n", ALPN_H2); } #endif @@ -893,11 +904,15 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); InitSecBufferDesc(&outbuf_desc, &outbuf, 1); - /* setup request flags */ + /* security request flags */ BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM; + if(!SSL_SET_OPTION(auto_client_cert)) { + BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; + } + /* allocate memory for the security context handle */ BACKEND->ctxt = (struct Curl_schannel_ctxt *) calloc(1, sizeof(struct Curl_schannel_ctxt)); @@ -997,12 +1012,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, SECURITY_STATUS sspi_status = SEC_E_OK; CURLcode result; bool doread; -#ifndef CURL_DISABLE_PROXY - char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - char * const hostname = conn->host.name; -#endif + char * const hostname = SSL_HOST_NAME(); const char *pubkey_ptr; doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; @@ -1015,23 +1025,23 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; /* buffer to store previously received and decrypted data */ - if(BACKEND->decdata_buffer == NULL) { + if(!BACKEND->decdata_buffer) { BACKEND->decdata_offset = 0; BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; BACKEND->decdata_buffer = malloc(BACKEND->decdata_length); - if(BACKEND->decdata_buffer == NULL) { + if(!BACKEND->decdata_buffer) { failf(data, "schannel: unable to allocate memory"); return CURLE_OUT_OF_MEMORY; } } /* buffer to store previously received and encrypted data */ - if(BACKEND->encdata_buffer == NULL) { + if(!BACKEND->encdata_buffer) { BACKEND->encdata_is_incomplete = false; BACKEND->encdata_offset = 0; BACKEND->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; BACKEND->encdata_buffer = malloc(BACKEND->encdata_length); - if(BACKEND->encdata_buffer == NULL) { + if(!BACKEND->encdata_buffer) { failf(data, "schannel: unable to allocate memory"); return CURLE_OUT_OF_MEMORY; } @@ -1046,7 +1056,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, reallocated_buffer = realloc(BACKEND->encdata_buffer, reallocated_length); - if(reallocated_buffer == NULL) { + if(!reallocated_buffer) { failf(data, "schannel: unable to re-allocate memory"); return CURLE_OUT_OF_MEMORY; } @@ -1101,7 +1111,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0); InitSecBufferDesc(&outbuf_desc, outbuf, 3); - if(inbuf[0].pvBuffer == NULL) { + if(!inbuf[0].pvBuffer) { failf(data, "schannel: unable to allocate memory"); return CURLE_OUT_OF_MEMORY; } @@ -1251,9 +1261,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n")); } - pubkey_ptr = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + pubkey_ptr = SSL_PINNED_PUB_KEY(); if(pubkey_ptr) { result = pkp_pin_peer_pubkey(data, conn, sockindex, pubkey_ptr); if(result) { @@ -1340,8 +1348,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, CERT_CONTEXT *ccert_context = NULL; bool isproxy = SSL_IS_PROXY(); #ifdef DEBUGBUILD - const char * const hostname = isproxy ? conn->http_proxy.host.name : - conn->host.name; + const char * const hostname = SSL_HOST_NAME(); #endif #ifdef HAS_ALPN SecPkgContext_ApplicationProtocol alpn_result; @@ -1389,10 +1396,9 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, infof(data, "schannel: ALPN, server accepted to use %.*s\n", alpn_result.ProtocolIdSize, alpn_result.ProtocolId); -#ifdef USE_NGHTTP2 - if(alpn_result.ProtocolIdSize == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, alpn_result.ProtocolId, - NGHTTP2_PROTO_VERSION_ID_LEN)) { +#ifdef USE_HTTP2 + if(alpn_result.ProtocolIdSize == ALPN_H2_LENGTH && + !memcmp(ALPN_H2, alpn_result.ProtocolId, ALPN_H2_LENGTH)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -1453,7 +1459,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context); - if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) { + if((sspi_status != SEC_E_OK) || !ccert_context) { failf(data, "schannel: failed to retrieve remote cert context"); return CURLE_PEER_FAILED_VERIFICATION; } @@ -1805,7 +1811,7 @@ schannel_recv(struct Curl_easy *data, int sockindex, } reallocated_buffer = realloc(BACKEND->encdata_buffer, reallocated_length); - if(reallocated_buffer == NULL) { + if(!reallocated_buffer) { *err = CURLE_OUT_OF_MEMORY; failf(data, "schannel: unable to re-allocate memory"); goto cleanup; @@ -1894,7 +1900,7 @@ schannel_recv(struct Curl_easy *data, int sockindex, } reallocated_buffer = realloc(BACKEND->decdata_buffer, reallocated_length); - if(reallocated_buffer == NULL) { + if(!reallocated_buffer) { *err = CURLE_OUT_OF_MEMORY; failf(data, "schannel: unable to re-allocate memory"); goto cleanup; @@ -2128,12 +2134,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn, * Shutting Down an Schannel Connection */ struct ssl_connect_data *connssl = &conn->ssl[sockindex]; -#ifndef CURL_DISABLE_PROXY - char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - char * const hostname = conn->host.name; -#endif + char * const hostname = SSL_HOST_NAME(); DEBUGASSERT(data); @@ -2296,7 +2297,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &pCertContextServer); - if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + if((sspi_status != SEC_E_OK) || !pCertContextServer) { char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); @@ -2406,6 +2407,9 @@ const struct Curl_ssl Curl_ssl_schannel = { { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */ SSLSUPP_CERTINFO | +#ifdef HAS_MANUAL_VERIFY_API + SSLSUPP_CAINFO_BLOB | +#endif SSLSUPP_PINNEDPUBKEY, sizeof(struct ssl_backend_data), @@ -2429,7 +2433,9 @@ const struct Curl_ssl Curl_ssl_schannel = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - schannel_sha256sum /* sha256sum */ + schannel_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_SCHANNEL */ diff --git a/libs/libcurl/src/vtls/schannel.h b/libs/libcurl/src/vtls/schannel.h index 2952caa1a5..77853aa30f 100644 --- a/libs/libcurl/src/vtls/schannel.h +++ b/libs/libcurl/src/vtls/schannel.h @@ -71,6 +71,8 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data, #endif #endif +#define NUMOF_CIPHERS 45 /* There are 45 listed in the MS headers */ + struct Curl_schannel_cred { CredHandle cred_handle; TimeStamp time_stamp; @@ -102,6 +104,7 @@ struct ssl_backend_data { #ifdef HAS_MANUAL_VERIFY_API bool use_manual_cred_validation; /* true if manual cred validation is used */ #endif + ALG_ID algIds[NUMOF_CIPHERS]; }; #endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */ diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c index e0fdbd5b63..25d47b8087 100644 --- a/libs/libcurl/src/vtls/schannel_verify.c +++ b/libs/libcurl/src/vtls/schannel_verify.c @@ -77,21 +77,156 @@ static int is_cr_or_lf(char c) return c == '\r' || c == '\n'; } -static CURLcode add_certs_to_store(HCERTSTORE trust_store, - const char *ca_file, - struct Curl_easy *data) +/* Search the substring needle,needlelen into string haystack,haystacklen + * Strings don't need to be terminated by a '\0'. + * Similar of OSX/Linux memmem (not available on Visual Studio). + * Return position of beginning of first occurence or NULL if not found + */ +static const char *c_memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen) +{ + const char *p; + char first; + const char *str_limit = (const char *)haystack + haystacklen; + if(!needlelen || needlelen > haystacklen) + return NULL; + first = *(const char *)needle; + for(p = (const char *)haystack; p <= (str_limit - needlelen); p++) + if(((*p) == first) && (memcmp(p, needle, needlelen) == 0)) + return p; + + return NULL; +} + +static CURLcode add_certs_data_to_store(HCERTSTORE trust_store, + const char *ca_buffer, + size_t ca_buffer_size, + const char *ca_file_text, + struct Curl_easy *data) +{ + const size_t begin_cert_len = strlen(BEGIN_CERT); + const size_t end_cert_len = strlen(END_CERT); + CURLcode result = CURLE_OK; + int num_certs = 0; + bool more_certs = 1; + const char *current_ca_file_ptr = ca_buffer; + const char *ca_buffer_limit = ca_buffer + ca_buffer_size; + + while(more_certs && (current_ca_file_ptrdwAltNameChoice != CERT_ALT_NAME_DNS_NAME) { continue; } - if(entry->pwszDNSName == NULL) { + if(!entry->pwszDNSName) { infof(data, "schannel: Empty DNS name."); continue; } @@ -536,27 +575,22 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data, const CERT_CHAIN_CONTEXT *pChainContext = NULL; HCERTCHAINENGINE cert_chain_engine = NULL; HCERTSTORE trust_store = NULL; -#ifndef CURL_DISABLE_PROXY - const char * const conn_hostname = SSL_IS_PROXY() ? - conn->http_proxy.host.name : - conn->host.name; -#else - const char * const conn_hostname = conn->host.name; -#endif + const char * const conn_hostname = SSL_HOST_NAME(); sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &pCertContextServer); - if((sspi_status != SEC_E_OK) || (pCertContextServer == NULL)) { + if((sspi_status != SEC_E_OK) || !pCertContextServer) { char buffer[STRERROR_LEN]; failf(data, "schannel: Failed to read remote certificate context: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); result = CURLE_PEER_FAILED_VERIFICATION; } - if(result == CURLE_OK && SSL_CONN_CONFIG(CAfile) && + if(result == CURLE_OK && + (SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) && BACKEND->use_manual_cred_validation) { /* * Create a chain engine that uses the certificates in the CA file as @@ -582,8 +616,19 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data, result = CURLE_SSL_CACERT_BADFILE; } else { - result = add_certs_to_store(trust_store, SSL_CONN_CONFIG(CAfile), - data); + const struct curl_blob *ca_info_blob = SSL_CONN_CONFIG(ca_info_blob); + if(ca_info_blob) { + result = add_certs_data_to_store(trust_store, + (const char *)ca_info_blob->data, + ca_info_blob->len, + "(memory blob)", + data); + } + else { + result = add_certs_file_to_store(trust_store, + SSL_CONN_CONFIG(CAfile), + data); + } } } diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c index 9d637da2ec..edd375ea7d 100644 --- a/libs/libcurl/src/vtls/sectransp.c +++ b/libs/libcurl/src/vtls/sectransp.c @@ -67,6 +67,7 @@ #define CURL_BUILD_IOS_7 0 #define CURL_BUILD_IOS_9 0 #define CURL_BUILD_IOS_11 0 +#define CURL_BUILD_IOS_13 0 #define CURL_BUILD_MAC 1 /* This is the maximum API level we are allowed to use when building: */ #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 @@ -76,6 +77,7 @@ #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 #define CURL_BUILD_MAC_10_11 MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 #define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 +#define CURL_BUILD_MAC_10_15 MAC_OS_X_VERSION_MAX_ALLOWED >= 101500 /* These macros mean "the following code is present to allow runtime backward compatibility with at least this cat or earlier": (You set this at build-time using the compiler command line option @@ -91,6 +93,7 @@ #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 #define CURL_BUILD_IOS_9 __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 #define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 +#define CURL_BUILD_IOS_13 __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 #define CURL_BUILD_MAC 0 #define CURL_BUILD_MAC_10_5 0 #define CURL_BUILD_MAC_10_6 0 @@ -99,6 +102,7 @@ #define CURL_BUILD_MAC_10_9 0 #define CURL_BUILD_MAC_10_11 0 #define CURL_BUILD_MAC_10_13 0 +#define CURL_BUILD_MAC_10_15 0 #define CURL_SUPPORT_MAC_10_5 0 #define CURL_SUPPORT_MAC_10_6 0 #define CURL_SUPPORT_MAC_10_7 0 @@ -138,6 +142,636 @@ struct ssl_backend_data { size_t ssl_write_buffered_length; }; +struct st_cipher { + const char *name; /* Cipher suite IANA name. It starts with "TLS_" prefix */ + const char *alias_name; /* Alias name is the same as OpenSSL cipher name */ + SSLCipherSuite num; /* Cipher suite code/number defined in IANA registry */ + bool weak; /* Flag to mark cipher as weak based on previous implementation + of Secure Transport back-end by CURL */ +}; + +/* Macro to initialize st_cipher data structure: stringify id to name, cipher + number/id, 'weak' suite flag + */ +#define CIPHER_DEF(num, alias, weak) \ + { #num, alias, num, weak } + +/* + Macro to initialize st_cipher data structure with name, code (IANA cipher + number/id value), and 'weak' suite flag. The first 28 cipher suite numbers + have the same IANA code for both SSL and TLS standards: numbers 0x0000 to + 0x001B. They have different names though. The first 4 letters of the cipher + suite name are the protocol name: "SSL_" or "TLS_", rest of the IANA name is + the same for both SSL and TLS cipher suite name. + The second part of the problem is that macOS/iOS SDKs don't define all TLS + codes but only 12 of them. The SDK defines all SSL codes though, i.e. SSL_NUM + constant is always defined for those 28 ciphers while TLS_NUM is defined only + for 12 of the first 28 ciphers. Those 12 TLS cipher codes match to + corresponding SSL enum value and represent the same cipher suite. Therefore + we'll use the SSL enum value for those cipher suites because it is defined + for all 28 of them. + We make internal data consistent and based on TLS names, i.e. all st_cipher + item names start with the "TLS_" prefix. + Summarizing all the above, those 28 first ciphers are presented in our table + with both TLS and SSL names. Their cipher numbers are assigned based on the + SDK enum value for the SSL cipher, which matches to IANA TLS number. + */ +#define CIPHER_DEF_SSLTLS(num_wo_prefix, alias, weak) \ + { "TLS_" #num_wo_prefix, alias, SSL_##num_wo_prefix, weak } + +/* + Cipher suites were marked as weak based on the following: + RC4 encryption - rfc7465, the document contains a list of deprecated ciphers. + Marked in the code below as weak. + RC2 encryption - many mentions, was found vulnerable to a relatively easy + attack https://link.springer.com/chapter/10.1007%2F3-540-69710-1_14 + Marked in the code below as weak. + DES and IDEA encryption - rfc5469, has a list of deprecated ciphers. + Marked in the code below as weak. + Anonymous Diffie-Hellman authentication and anonymous elliptic curve + Diffie-Hellman - vulnerable to a man-in-the-middle attack. Deprecated by + RFC 4346 aka TLS 1.1 (section A.5, page 60) + Null bulk encryption suites - not encrypted communication + Export ciphers, i.e. ciphers with restrictions to be used outside the US for + software exported to some countries, they were excluded from TLS 1.1 + version. More precisely, they were noted as ciphers which MUST NOT be + negotiated in RFC 4346 aka TLS 1.1 (section A.5, pages 60 and 61). + All of those filters were considered weak because they contain a weak + algorithm like DES, RC2 or RC4, and already considered weak by other + criteria. + 3DES - NIST deprecated it and is going to retire it by 2023 + https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA + OpenSSL https://www.openssl.org/blog/blog/2016/08/24/sweet32/ also + deprecated those ciphers. Some other libraries also consider it + vulnerable or at least not strong enough. + + CBC ciphers are vulnerable with SSL3.0 and TLS1.0: + https://www.cisco.com/c/en/us/support/docs/security/email-security-appliance + /118518-technote-esa-00.html + We don't take care of this issue because it is resolved by later TLS + versions and for us, it requires more complicated checks, we need to + check a protocol version also. Vulnerability doesn't look very critical + and we do not filter out those cipher suites. + */ + +#define CIPHER_WEAK_NOT_ENCRYPTED TRUE +#define CIPHER_WEAK_RC_ENCRYPTION TRUE +#define CIPHER_WEAK_DES_ENCRYPTION TRUE +#define CIPHER_WEAK_IDEA_ENCRYPTION TRUE +#define CIPHER_WEAK_ANON_AUTH TRUE +#define CIPHER_WEAK_3DES_ENCRYPTION TRUE +#define CIPHER_STRONG_ENOUGH FALSE + +/* Please do not change the order of the first ciphers available for SSL. + Do not insert and do not delete any of them. Code below + depends on their order and continuity. + If you add a new cipher, please maintain order by number, i.e. + insert in between existing items to appropriate place based on + cipher suite IANA number +*/ +const static struct st_cipher ciphertable[] = { + /* SSL version 3.0 and initial TLS 1.0 cipher suites. + Defined since SDK 10.2.8 */ + CIPHER_DEF_SSLTLS(NULL_WITH_NULL_NULL, /* 0x0000 */ + NULL, + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF_SSLTLS(RSA_WITH_NULL_MD5, /* 0x0001 */ + "NULL-MD5", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF_SSLTLS(RSA_WITH_NULL_SHA, /* 0x0002 */ + "NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_RC4_40_MD5, /* 0x0003 */ + "EXP-RC4-MD5", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_RC4_128_MD5, /* 0x0004 */ + "RC4-MD5", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_RC4_128_SHA, /* 0x0005 */ + "RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* 0x0006 */ + "EXP-RC2-CBC-MD5", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_IDEA_CBC_SHA, /* 0x0007 */ + "IDEA-CBC-SHA", + CIPHER_WEAK_IDEA_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x0008 */ + "EXP-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_DES_CBC_SHA, /* 0x0009 */ + "DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(RSA_WITH_3DES_EDE_CBC_SHA, /* 0x000A */ + "DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_DSS_EXPORT_WITH_DES40_CBC_SHA, /* 0x000B */ + "EXP-DH-DSS-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_DSS_WITH_DES_CBC_SHA, /* 0x000C */ + "DH-DSS-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_DSS_WITH_3DES_EDE_CBC_SHA, /* 0x000D */ + "DH-DSS-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x000E */ + "EXP-DH-RSA-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_RSA_WITH_DES_CBC_SHA, /* 0x000F */ + "DH-RSA-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x0010 */ + "DH-RSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, /* 0x0011 */ + "EXP-EDH-DSS-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_DSS_WITH_DES_CBC_SHA, /* 0x0012 */ + "EDH-DSS-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* 0x0013 */ + "DHE-DSS-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x0014 */ + "EXP-EDH-RSA-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_RSA_WITH_DES_CBC_SHA, /* 0x0015 */ + "EDH-RSA-DES-CBC-SHA", + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x0016 */ + "DHE-RSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF_SSLTLS(DH_anon_EXPORT_WITH_RC4_40_MD5, /* 0x0017 */ + "EXP-ADH-RC4-MD5", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF_SSLTLS(DH_anon_WITH_RC4_128_MD5, /* 0x0018 */ + "ADH-RC4-MD5", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF_SSLTLS(DH_anon_EXPORT_WITH_DES40_CBC_SHA, /* 0x0019 */ + "EXP-ADH-DES-CBC-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF_SSLTLS(DH_anon_WITH_DES_CBC_SHA, /* 0x001A */ + "ADH-DES-CBC-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF_SSLTLS(DH_anon_WITH_3DES_EDE_CBC_SHA, /* 0x001B */ + "ADH-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* 0x001C */ + NULL, + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* 0x001D */ + NULL, + CIPHER_STRONG_ENOUGH), + +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption */ + CIPHER_DEF(TLS_PSK_WITH_NULL_SHA, /* 0x002C */ + "PSK-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA, /* 0x002D */ + "DHE-PSK-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA, /* 0x002E */ + "RSA-PSK-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + + /* TLS addenda using AES, per RFC 3268. Defined since SDK 10.4u */ + CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA, /* 0x002F */ + "AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_CBC_SHA, /* 0x0030 */ + "DH-DSS-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_CBC_SHA, /* 0x0031 */ + "DH-RSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* 0x0032 */ + "DHE-DSS-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* 0x0033 */ + "DHE-RSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_128_CBC_SHA, /* 0x0034 */ + "ADH-AES128-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA, /* 0x0035 */ + "AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_CBC_SHA, /* 0x0036 */ + "DH-DSS-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_CBC_SHA, /* 0x0037 */ + "DH-RSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* 0x0038 */ + "DHE-DSS-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* 0x0039 */ + "DHE-RSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_256_CBC_SHA, /* 0x003A */ + "ADH-AES256-SHA", + CIPHER_WEAK_ANON_AUTH), + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + /* TLS 1.2 addenda, RFC 5246 */ + /* Server provided RSA certificate for key exchange. */ + CIPHER_DEF(TLS_RSA_WITH_NULL_SHA256, /* 0x003B */ + "NULL-SHA256", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA256, /* 0x003C */ + "AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA256, /* 0x003D */ + "AES256-SHA256", + CIPHER_STRONG_ENOUGH), + /* Server-authenticated (and optionally client-authenticated) + Diffie-Hellman. */ + CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, /* 0x003E */ + "DH-DSS-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, /* 0x003F */ + "DH-RSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, /* 0x0040 */ + "DHE-DSS-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + + /* TLS 1.2 addenda, RFC 5246 */ + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, /* 0x0067 */ + "DHE-RSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, /* 0x0068 */ + "DH-DSS-AES256-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, /* 0x0069 */ + "DH-RSA-AES256-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, /* 0x006A */ + "DHE-DSS-AES256-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, /* 0x006B */ + "DHE-RSA-AES256-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_128_CBC_SHA256, /* 0x006C */ + "ADH-AES128-SHA256", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_256_CBC_SHA256, /* 0x006D */ + "ADH-AES256-SHA256", + CIPHER_WEAK_ANON_AUTH), +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* Addendum from RFC 4279, TLS PSK */ + CIPHER_DEF(TLS_PSK_WITH_RC4_128_SHA, /* 0x008A */ + "PSK-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x008B */ + "PSK-3DES-EDE-CBC-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_PSK_WITH_AES_128_CBC_SHA, /* 0x008C */ + "PSK-AES128-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_AES_256_CBC_SHA, /* 0x008D */ + "PSK-AES256-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_RC4_128_SHA, /* 0x008E */ + "DHE-PSK-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x008F */ + "DHE-PSK-3DES-EDE-CBC-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_CBC_SHA, /* 0x0090 */ + "DHE-PSK-AES128-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_CBC_SHA, /* 0x0091 */ + "DHE-PSK-AES256-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_RC4_128_SHA, /* 0x0092 */ + "RSA-PSK-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x0093 */ + "RSA-PSK-3DES-EDE-CBC-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_CBC_SHA, /* 0x0094 */ + "RSA-PSK-AES128-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_CBC_SHA, /* 0x0095 */ + "RSA-PSK-AES256-CBC-SHA", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + /* Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites + for TLS. */ + CIPHER_DEF(TLS_RSA_WITH_AES_128_GCM_SHA256, /* 0x009C */ + "AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_WITH_AES_256_GCM_SHA384, /* 0x009D */ + "AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, /* 0x009E */ + "DHE-RSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, /* 0x009F */ + "DHE-RSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, /* 0x00A0 */ + "DH-RSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, /* 0x00A1 */ + "DH-RSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, /* 0x00A2 */ + "DHE-DSS-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, /* 0x00A3 */ + "DHE-DSS-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, /* 0x00A4 */ + "DH-DSS-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, /* 0x00A5 */ + "DH-DSS-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_128_GCM_SHA256, /* 0x00A6 */ + "ADH-AES128-GCM-SHA256", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_DH_anon_WITH_AES_256_GCM_SHA384, /* 0x00A7 */ + "ADH-AES256-GCM-SHA384", + CIPHER_WEAK_ANON_AUTH), +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + +#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 + /* RFC 5487 - PSK with SHA-256/384 and AES GCM */ + CIPHER_DEF(TLS_PSK_WITH_AES_128_GCM_SHA256, /* 0x00A8 */ + "PSK-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_AES_256_GCM_SHA384, /* 0x00A9 */ + "PSK-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, /* 0x00AA */ + "DHE-PSK-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, /* 0x00AB */ + "DHE-PSK-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, /* 0x00AC */ + "RSA-PSK-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, /* 0x00AD */ + "RSA-PSK-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_AES_128_CBC_SHA256, /* 0x00AE */ + "PSK-AES128-CBC-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_AES_256_CBC_SHA384, /* 0x00AF */ + "PSK-AES256-CBC-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_PSK_WITH_NULL_SHA256, /* 0x00B0 */ + "PSK-NULL-SHA256", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_PSK_WITH_NULL_SHA384, /* 0x00B1 */ + "PSK-NULL-SHA384", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, /* 0x00B2 */ + "DHE-PSK-AES128-CBC-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, /* 0x00B3 */ + "DHE-PSK-AES256-CBC-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA256, /* 0x00B4 */ + "DHE-PSK-NULL-SHA256", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA384, /* 0x00B5 */ + "DHE-PSK-NULL-SHA384", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, /* 0x00B6 */ + "RSA-PSK-AES128-CBC-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, /* 0x00B7 */ + "RSA-PSK-AES256-CBC-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA256, /* 0x00B8 */ + "RSA-PSK-NULL-SHA256", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA384, /* 0x00B9 */ + "RSA-PSK-NULL-SHA384", + CIPHER_WEAK_NOT_ENCRYPTED), +#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ + + /* RFC 5746 - Secure Renegotiation. This is not a real suite, + it is a response to initiate negotiation again */ + CIPHER_DEF(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, /* 0x00FF */ + NULL, + CIPHER_STRONG_ENOUGH), + +#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 + /* TLS 1.3 standard cipher suites for ChaCha20+Poly1305. + Note: TLS 1.3 ciphersuites do not specify the key exchange + algorithm -- they only specify the symmetric ciphers. + Cipher alias name matches to OpenSSL cipher name, and for + TLS 1.3 ciphers */ + CIPHER_DEF(TLS_AES_128_GCM_SHA256, /* 0x1301 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_AES_256_GCM_SHA384, /* 0x1302 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_CHACHA20_POLY1305_SHA256, /* 0x1303 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_AES_128_CCM_SHA256, /* 0x1304 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_AES_128_CCM_8_SHA256, /* 0x1305 */ + NULL, /* The OpenSSL cipher name matches to the IANA name */ + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ + +#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS + /* ECDSA addenda, RFC 4492 */ + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_NULL_SHA, /* 0xC001 */ + "ECDH-ECDSA-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, /* 0xC002 */ + "ECDH-ECDSA-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC003 */ + "ECDH-ECDSA-DES-CBC3-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC004 */ + "ECDH-ECDSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC005 */ + "ECDH-ECDSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_NULL_SHA, /* 0xC006 */ + "ECDHE-ECDSA-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, /* 0xC007 */ + "ECDHE-ECDSA-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC008 */ + "ECDHE-ECDSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC009 */ + "ECDHE-ECDSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC00A */ + "ECDHE-ECDSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_NULL_SHA, /* 0xC00B */ + "ECDH-RSA-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_ECDH_RSA_WITH_RC4_128_SHA, /* 0xC00C */ + "ECDH-RSA-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC00D */ + "ECDH-RSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* 0xC00E */ + "ECDH-RSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* 0xC00F */ + "ECDH-RSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_NULL_SHA, /* 0xC010 */ + "ECDHE-RSA-NULL-SHA", + CIPHER_WEAK_NOT_ENCRYPTED), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_RC4_128_SHA, /* 0xC011 */ + "ECDHE-RSA-RC4-SHA", + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC012 */ + "ECDHE-RSA-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* 0xC013 */ + "ECDHE-RSA-AES128-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, /* 0xC014 */ + "ECDHE-RSA-AES256-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_anon_WITH_NULL_SHA, /* 0xC015 */ + "AECDH-NULL-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_ECDH_anon_WITH_RC4_128_SHA, /* 0xC016 */ + "AECDH-RC4-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, /* 0xC017 */ + "AECDH-DES-CBC3-SHA", + CIPHER_WEAK_3DES_ENCRYPTION), + CIPHER_DEF(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, /* 0xC018 */ + "AECDH-AES128-SHA", + CIPHER_WEAK_ANON_AUTH), + CIPHER_DEF(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, /* 0xC019 */ + "AECDH-AES256-SHA", + CIPHER_WEAK_ANON_AUTH), +#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ + +#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS + /* Addenda from rfc 5289 Elliptic Curve Cipher Suites with + HMAC SHA-256/384. */ + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC023 */ + "ECDHE-ECDSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC024 */ + "ECDHE-ECDSA-AES256-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC025 */ + "ECDH-ECDSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC026 */ + "ECDH-ECDSA-AES256-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, /* 0xC027 */ + "ECDHE-RSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, /* 0xC028 */ + "ECDHE-RSA-AES256-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, /* 0xC029 */ + "ECDH-RSA-AES128-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, /* 0xC02A */ + "ECDH-RSA-AES256-SHA384", + CIPHER_STRONG_ENOUGH), + /* Addenda from rfc 5289 Elliptic Curve Cipher Suites with + SHA-256/384 and AES Galois Counter Mode (GCM) */ + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02B */ + "ECDHE-ECDSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02C */ + "ECDHE-ECDSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02D */ + "ECDH-ECDSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02E */ + "ECDH-ECDSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, /* 0xC02F */ + "ECDHE-RSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, /* 0xC030 */ + "ECDHE-RSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, /* 0xC031 */ + "ECDH-RSA-AES128-GCM-SHA256", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, /* 0xC032 */ + "ECDH-RSA-AES256-GCM-SHA384", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + +#if CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 + /* ECDHE_PSK Cipher Suites for Transport Layer Security (TLS), RFC 5489 */ + CIPHER_DEF(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, /* 0xC035 */ + "ECDHE-PSK-AES128-CBC-SHA", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, /* 0xC036 */ + "ECDHE-PSK-AES256-CBC-SHA", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 */ + +#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 + /* Addenda from rfc 7905 ChaCha20-Poly1305 Cipher Suites for + Transport Layer Security (TLS). */ + CIPHER_DEF(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA8 */ + "ECDHE-RSA-CHACHA20-POLY1305", + CIPHER_STRONG_ENOUGH), + CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA9 */ + "ECDHE-ECDSA-CHACHA20-POLY1305", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ + +#if CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 + /* ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS), + RFC 7905 */ + CIPHER_DEF(TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCAB */ + "PSK-CHACHA20-POLY1305", + CIPHER_STRONG_ENOUGH), +#endif /* CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 */ + + /* Tags for SSL 2 cipher kinds which are not specified for SSL 3. + Defined since SDK 10.2.8 */ + CIPHER_DEF(SSL_RSA_WITH_RC2_CBC_MD5, /* 0xFF80 */ + NULL, + CIPHER_WEAK_RC_ENCRYPTION), + CIPHER_DEF(SSL_RSA_WITH_IDEA_CBC_MD5, /* 0xFF81 */ + NULL, + CIPHER_WEAK_IDEA_ENCRYPTION), + CIPHER_DEF(SSL_RSA_WITH_DES_CBC_MD5, /* 0xFF82 */ + NULL, + CIPHER_WEAK_DES_ENCRYPTION), + CIPHER_DEF(SSL_RSA_WITH_3DES_EDE_CBC_MD5, /* 0xFF83 */ + NULL, + CIPHER_WEAK_3DES_ENCRYPTION), +}; + +#define NUM_OF_CIPHERS sizeof(ciphertable)/sizeof(ciphertable[0]) + + /* pinned public key support tests */ /* version 1 supports macOS 10.12+ and iOS 10+ */ @@ -295,586 +929,23 @@ static OSStatus SocketWrite(SSLConnectionRef connection, } #ifndef CURL_DISABLE_VERBOSE_STRINGS -CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) -{ - switch(cipher) { - /* SSL version 3.0 */ - case SSL_RSA_WITH_NULL_MD5: - return "SSL_RSA_WITH_NULL_MD5"; - break; - case SSL_RSA_WITH_NULL_SHA: - return "SSL_RSA_WITH_NULL_SHA"; - break; - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: - return "SSL_RSA_EXPORT_WITH_RC4_40_MD5"; - break; - case SSL_RSA_WITH_RC4_128_MD5: - return "SSL_RSA_WITH_RC4_128_MD5"; - break; - case SSL_RSA_WITH_RC4_128_SHA: - return "SSL_RSA_WITH_RC4_128_SHA"; - break; - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: - return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"; - break; - case SSL_RSA_WITH_IDEA_CBC_SHA: - return "SSL_RSA_WITH_IDEA_CBC_SHA"; - break; - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_RSA_WITH_DES_CBC_SHA: - return "SSL_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_DSS_WITH_DES_CBC_SHA: - return "SSL_DH_DSS_WITH_DES_CBC_SHA"; - break; - case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_RSA_WITH_DES_CBC_SHA: - return "SSL_DH_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - return "SSL_DHE_DSS_WITH_DES_CBC_SHA"; - break; - case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - return "SSL_DHE_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: - return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"; - break; - case SSL_DH_anon_WITH_RC4_128_MD5: - return "SSL_DH_anon_WITH_RC4_128_MD5"; - break; - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_anon_WITH_DES_CBC_SHA: - return "SSL_DH_anon_WITH_DES_CBC_SHA"; - break; - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: - return "SSL_FORTEZZA_DMS_WITH_NULL_SHA"; - break; - case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: - return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; - break; - /* TLS 1.0 with AES (RFC 3268) - (Apparently these are used in SSLv3 implementations as well.) */ - case TLS_RSA_WITH_AES_128_CBC_SHA: - return "TLS_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA: - return "TLS_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; - break; - /* SSL version 2.0 */ - case SSL_RSA_WITH_RC2_CBC_MD5: - return "SSL_RSA_WITH_RC2_CBC_MD5"; - break; - case SSL_RSA_WITH_IDEA_CBC_MD5: - return "SSL_RSA_WITH_IDEA_CBC_MD5"; - break; - case SSL_RSA_WITH_DES_CBC_MD5: - return "SSL_RSA_WITH_DES_CBC_MD5"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_MD5: - return "SSL_RSA_WITH_3DES_EDE_CBC_MD5"; - break; - } - return "SSL_NULL_WITH_NULL_NULL"; -} - CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) { - switch(cipher) { - /* TLS 1.0 with AES (RFC 3268) */ - case TLS_RSA_WITH_AES_128_CBC_SHA: - return "TLS_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA: - return "TLS_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; - break; -#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS - /* TLS 1.0 with ECDSA (RFC 4492) */ - case TLS_ECDH_ECDSA_WITH_NULL_SHA: - return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: - return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_NULL_SHA: - return "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_NULL_SHA: - return "TLS_ECDH_RSA_WITH_NULL_SHA"; - break; - case TLS_ECDH_RSA_WITH_RC4_128_SHA: - return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_NULL_SHA: - return "TLS_ECDHE_RSA_WITH_NULL_SHA"; - break; - case TLS_ECDHE_RSA_WITH_RC4_128_SHA: - return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_NULL_SHA: - return "TLS_ECDH_anon_WITH_NULL_SHA"; - break; - case TLS_ECDH_anon_WITH_RC4_128_SHA: - return "TLS_ECDH_anon_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; - break; -#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - /* TLS 1.2 (RFC 5246) */ - case TLS_RSA_WITH_NULL_MD5: - return "TLS_RSA_WITH_NULL_MD5"; - break; - case TLS_RSA_WITH_NULL_SHA: - return "TLS_RSA_WITH_NULL_SHA"; - break; - case TLS_RSA_WITH_RC4_128_MD5: - return "TLS_RSA_WITH_RC4_128_MD5"; - break; - case TLS_RSA_WITH_RC4_128_SHA: - return "TLS_RSA_WITH_RC4_128_SHA"; - break; - case TLS_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_RSA_WITH_NULL_SHA256: - return "TLS_RSA_WITH_NULL_SHA256"; - break; - case TLS_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_anon_WITH_RC4_128_MD5: - return "TLS_DH_anon_WITH_RC4_128_MD5"; - break; - case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA256: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA256: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; - break; - /* TLS 1.2 with AES GCM (RFC 5288) */ - case TLS_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_anon_WITH_AES_128_GCM_SHA256: - return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_anon_WITH_AES_256_GCM_SHA384: - return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; - break; - /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */ - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: - return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; - break; -#else - case SSL_RSA_WITH_NULL_MD5: - return "TLS_RSA_WITH_NULL_MD5"; - break; - case SSL_RSA_WITH_NULL_SHA: - return "TLS_RSA_WITH_NULL_SHA"; - break; - case SSL_RSA_WITH_RC4_128_MD5: - return "TLS_RSA_WITH_RC4_128_MD5"; - break; - case SSL_RSA_WITH_RC4_128_SHA: - return "TLS_RSA_WITH_RC4_128_SHA"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_anon_WITH_RC4_128_MD5: - return "TLS_DH_anon_WITH_RC4_128_MD5"; - break; - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ -#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 - /* TLS PSK (RFC 4279): */ - case TLS_PSK_WITH_RC4_128_SHA: - return "TLS_PSK_WITH_RC4_128_SHA"; - break; - case TLS_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_PSK_WITH_AES_128_CBC_SHA: - return "TLS_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_PSK_WITH_AES_256_CBC_SHA: - return "TLS_PSK_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_RC4_128_SHA: - return "TLS_DHE_PSK_WITH_RC4_128_SHA"; - break; - case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: - return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: - return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_RC4_128_SHA: - return "TLS_RSA_PSK_WITH_RC4_128_SHA"; - break; - case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: - return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: - return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"; - break; - /* More TLS PSK (RFC 4785): */ - case TLS_PSK_WITH_NULL_SHA: - return "TLS_PSK_WITH_NULL_SHA"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA: - return "TLS_DHE_PSK_WITH_NULL_SHA"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA: - return "TLS_RSA_PSK_WITH_NULL_SHA"; - break; - /* Even more TLS PSK (RFC 5487): */ - case TLS_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_PSK_WITH_NULL_SHA256: - return "TLS_PSK_WITH_NULL_SHA256"; - break; - case TLS_PSK_WITH_NULL_SHA384: - return "TLS_PSK_WITH_NULL_SHA384"; - break; - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA256: - return "TLS_DHE_PSK_WITH_NULL_SHA256"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA384: - return "TLS_RSA_PSK_WITH_NULL_SHA384"; - break; - case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA256: - return "TLS_RSA_PSK_WITH_NULL_SHA256"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA384: - return "TLS_RSA_PSK_WITH_NULL_SHA384"; - break; -#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ -#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 - /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */ - case TLS_AES_128_GCM_SHA256: - return "TLS_AES_128_GCM_SHA256"; - break; - case TLS_AES_256_GCM_SHA384: - return "TLS_AES_256_GCM_SHA384"; - break; - case TLS_CHACHA20_POLY1305_SHA256: - return "TLS_CHACHA20_POLY1305_SHA256"; - break; - case TLS_AES_128_CCM_SHA256: - return "TLS_AES_128_CCM_SHA256"; - break; - case TLS_AES_128_CCM_8_SHA256: - return "TLS_AES_128_CCM_8_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"; - break; -#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ + /* The first ciphers in the ciphertable are continuos. Here we do small + optimization and instead of loop directly get SSL name by cipher number. + */ + if(cipher <= SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA) { + return ciphertable[cipher].name; + } + /* Iterate through the rest of the ciphers */ + for(size_t i = SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA + 1; + i < NUM_OF_CIPHERS; + ++i) { + if(ciphertable[i].num == cipher) { + return ciphertable[i].name; + } } - return "TLS_NULL_WITH_NULL_NULL"; + return ciphertable[SSL_NULL_WITH_NULL_NULL].name; } #endif /* !CURL_DISABLE_VERBOSE_STRINGS */ @@ -1087,12 +1158,14 @@ static OSStatus CopyIdentityWithLabel(char *label, (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i); err = SecIdentityCopyCertificate(identity, &cert); if(err == noErr) { + OSStatus copy_status = noErr; #if CURL_BUILD_IOS common_name = SecCertificateCopySubjectSummary(cert); #elif CURL_BUILD_MAC_10_7 - SecCertificateCopyCommonName(cert, &common_name); + copy_status = SecCertificateCopyCommonName(cert, &common_name); #endif - if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) { + if(copy_status == noErr && + CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) { CFRelease(cert); CFRelease(common_name); CFRetain(identity); @@ -1253,7 +1326,7 @@ CF_INLINE bool is_file(const char *filename) { struct_stat st; - if(filename == NULL) + if(!filename) return false; if(stat(filename, &st) == 0) @@ -1386,6 +1459,200 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } +static bool is_cipher_suite_strong(SSLCipherSuite suite_num) +{ + for(size_t i = 0; i < NUM_OF_CIPHERS; ++i) { + if(ciphertable[i].num == suite_num) { + return !ciphertable[i].weak; + } + } + /* If the cipher is not in our list, assume it is a new one + and therefore strong. Previous implementation was the same, + if cipher suite is not in the list, it was considered strong enough */ + return true; +} + +static bool is_separator(char c) +{ + /* Return whether character is a cipher list separator. */ + switch(c) { + case ' ': + case '\t': + case ':': + case ',': + case ';': + return true; + } + return false; +} + +static CURLcode sectransp_set_default_ciphers(struct Curl_easy *data, + SSLContextRef ssl_ctx) +{ + size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i; + SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL; + OSStatus err = noErr; + +#if CURL_BUILD_MAC + int darwinver_maj = 0, darwinver_min = 0; + + GetDarwinVersionNumber(&darwinver_maj, &darwinver_min); +#endif /* CURL_BUILD_MAC */ + + /* Disable cipher suites that ST supports but are not safe. These ciphers + are unlikely to be used in any case since ST gives other ciphers a much + higher priority, but it's probably better that we not connect at all than + to give the user a false sense of security if the server only supports + insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */ + err = SSLGetNumberSupportedCiphers(ssl_ctx, &all_ciphers_count); + if(err != noErr) { + failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d", + err); + return CURLE_SSL_CIPHER; + } + all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(!all_ciphers) { + failf(data, "SSL: Failed to allocate memory for all ciphers"); + return CURLE_OUT_OF_MEMORY; + } + allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); + if(!allowed_ciphers) { + Curl_safefree(all_ciphers); + failf(data, "SSL: Failed to allocate memory for allowed ciphers"); + return CURLE_OUT_OF_MEMORY; + } + err = SSLGetSupportedCiphers(ssl_ctx, all_ciphers, + &all_ciphers_count); + if(err != noErr) { + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + return CURLE_SSL_CIPHER; + } + for(i = 0UL ; i < all_ciphers_count ; i++) { +#if CURL_BUILD_MAC + /* There's a known bug in early versions of Mountain Lion where ST's ECC + ciphers (cipher suite 0xC001 through 0xC032) simply do not work. + Work around the problem here by disabling those ciphers if we are + running in an affected version of OS X. */ + if(darwinver_maj == 12 && darwinver_min <= 3 && + all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { + continue; + } +#endif /* CURL_BUILD_MAC */ + if(is_cipher_suite_strong(all_ciphers[i])) { + allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; + } + } + err = SSLSetEnabledCiphers(ssl_ctx, allowed_ciphers, + allowed_ciphers_count); + Curl_safefree(all_ciphers); + Curl_safefree(allowed_ciphers); + if(err != noErr) { + failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + return CURLE_SSL_CIPHER; + } + return CURLE_OK; +} + +static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data, + SSLContextRef ssl_ctx, + const char *ciphers) +{ + size_t ciphers_count = 0; + const char *cipher_start = ciphers; + OSStatus err = noErr; + SSLCipherSuite selected_ciphers[NUM_OF_CIPHERS]; + + if(!ciphers) + return CURLE_OK; + + while(is_separator(*ciphers)) /* Skip initial separators. */ + ciphers++; + if(!*ciphers) + return CURLE_OK; + + cipher_start = ciphers; + while(*cipher_start && ciphers_count < NUM_OF_CIPHERS) { + bool cipher_found = FALSE; + size_t cipher_len = 0; + const char *cipher_end = NULL; + bool tls_name = FALSE; + + /* Skip separators */ + while(is_separator(*cipher_start)) + cipher_start++; + if(*cipher_start == '\0') { + break; + } + /* Find last position of a cipher in the ciphers string */ + cipher_end = cipher_start; + while (*cipher_end != '\0' && !is_separator(*cipher_end)) { + ++cipher_end; + } + + /* IANA cipher names start with the TLS_ or SSL_ prefix. + If the 4th symbol of the cipher is '_' we look for a cipher in the + table by its (TLS) name. + Otherwise, we try to match cipher by an alias. */ + if(cipher_start[3] == '_') { + tls_name = TRUE; + } + /* Iterate through the cipher table and look for the cipher, starting + the cipher number 0x01 because the 0x00 is not the real cipher */ + cipher_len = cipher_end - cipher_start; + for(size_t i = 1; i < NUM_OF_CIPHERS; ++i) { + const char *table_cipher_name = NULL; + if(tls_name) { + table_cipher_name = ciphertable[i].name; + } + else if(ciphertable[i].alias_name != NULL) { + table_cipher_name = ciphertable[i].alias_name; + } + else { + continue; + } + /* Compare a part of the string between separators with a cipher name + in the table and make sure we matched the whole cipher name */ + if(strncmp(cipher_start, table_cipher_name, cipher_len) == 0 + && table_cipher_name[cipher_len] == '\0') { + selected_ciphers[ciphers_count] = ciphertable[i].num; + ++ciphers_count; + cipher_found = TRUE; + break; + } + } + if(!cipher_found) { + /* It would be more human-readable if we print the wrong cipher name + but we don't want to allocate any additional memory and copy the name + into it, then add it into logs. + Also, we do not modify an original cipher list string. We just point + to positions where cipher starts and ends in the cipher list string. + The message is a bit cryptic and longer than necessary but can be + understood by humans. */ + failf(data, "SSL: cipher string \"%s\" contains unsupported cipher name" + " starting position %d and ending position %d", + ciphers, + cipher_start - ciphers, + cipher_end - ciphers); + return CURLE_SSL_CIPHER; + } + if(*cipher_end) { + cipher_start = cipher_end + 1; + } + else { + break; + } + } + /* All cipher suites in the list are found. Report to logs as-is */ + infof(data, "SSL: Setting cipher suites list \"%s\"\n", ciphers); + + err = SSLSetEnabledCiphers(ssl_ctx, selected_ciphers, ciphers_count); + if(err != noErr) { + failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + return CURLE_SSL_CIPHER; + } + return CURLE_OK; +} static CURLcode sectransp_connect_step1(struct Curl_easy *data, struct connectdata *conn, @@ -1394,28 +1661,22 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, curl_socket_t sockfd = conn->sock[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); - const struct curl_blob *ssl_cablob = NULL; + const struct curl_blob *ssl_cablob = SSL_CONN_CONFIG(ca_info_blob); + const char * const ssl_cafile = + /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */ + (ssl_cablob ? NULL : SSL_CONN_CONFIG(CAfile)); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); -#ifndef CURL_DISABLE_PROXY bool isproxy = SSL_IS_PROXY(); - const char * const hostname = isproxy ? conn->http_proxy.host.name : - conn->host.name; - const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; -#else - const isproxy = FALSE; - const char * const hostname = conn->host.name; - const long int port = conn->remote_port; -#endif + const char * const hostname = SSL_HOST_NAME(); + const long int port = SSL_HOST_PORT(); #ifdef ENABLE_IPV6 struct in6_addr addr; #else struct in_addr addr; #endif /* ENABLE_IPV6 */ - size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i; - SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL; + char *ciphers; OSStatus err = noErr; #if CURL_BUILD_MAC int darwinver_maj = 0, darwinver_min = 0; @@ -1486,21 +1747,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, break; } case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol3); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol3); - break; case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionMin(backend->ssl_ctx, kSSLProtocol2); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kSSLProtocol2); - break; + failf(data, "SSL versions not supported"); + return CURLE_NOT_BUILT_IN; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -1535,23 +1784,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, break; } case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol3, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - break; case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol2, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - break; + failf(data, "SSL versions not supported"); + return CURLE_NOT_BUILT_IN; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -1583,23 +1818,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, failf(data, "Your version of the OS does not support TLSv1.3"); return CURLE_SSL_CONNECT_ERROR; case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol2, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - break; case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocol3, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - break; + failf(data, "SSL versions not supported"); + return CURLE_NOT_BUILT_IN; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -1612,14 +1833,14 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!isproxy || !conn->bits.tunnel_proxy) #endif ) { - CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID)); - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2)); + infof(data, "ALPN, offering %s\n", ALPN_H2); } #endif @@ -1790,7 +2011,8 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile); if(!(is_cert_file || is_cert_data)) { - failf(data, "SSL: can't load CA certificate file %s", ssl_cafile); + failf(data, "SSL: can't load CA certificate file %s", + ssl_cafile ? ssl_cafile : "(blob memory)"); return CURLE_SSL_CACERT_BADFILE; } } @@ -1820,121 +2042,16 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, infof(data, "WARNING: disabling hostname validation also disables SNI.\n"); } - /* Disable cipher suites that ST supports but are not safe. These ciphers - are unlikely to be used in any case since ST gives other ciphers a much - higher priority, but it's probably better that we not connect at all than - to give the user a false sense of security if the server only supports - insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */ - err = SSLGetNumberSupportedCiphers(backend->ssl_ctx, &all_ciphers_count); - if(err != noErr) { - failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d", - err); - return CURLE_SSL_CIPHER; - } - all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - if(!all_ciphers) { - failf(data, "SSL: Failed to allocate memory for all ciphers"); - return CURLE_OUT_OF_MEMORY; - } - allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - if(!allowed_ciphers) { - Curl_safefree(all_ciphers); - failf(data, "SSL: Failed to allocate memory for allowed ciphers"); - return CURLE_OUT_OF_MEMORY; - } - err = SSLGetSupportedCiphers(backend->ssl_ctx, all_ciphers, - &all_ciphers_count); - if(err != noErr) { - Curl_safefree(all_ciphers); - Curl_safefree(allowed_ciphers); - return CURLE_SSL_CIPHER; + ciphers = SSL_CONN_CONFIG(cipher_list); + if(ciphers) { + err = sectransp_set_selected_ciphers(data, backend->ssl_ctx, ciphers); } - for(i = 0UL ; i < all_ciphers_count ; i++) { -#if CURL_BUILD_MAC - /* There's a known bug in early versions of Mountain Lion where ST's ECC - ciphers (cipher suite 0xC001 through 0xC032) simply do not work. - Work around the problem here by disabling those ciphers if we are - running in an affected version of OS X. */ - if(darwinver_maj == 12 && darwinver_min <= 3 && - all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { - continue; - } -#endif /* CURL_BUILD_MAC */ - switch(all_ciphers[i]) { - /* Disable NULL ciphersuites: */ - case SSL_NULL_WITH_NULL_NULL: - case SSL_RSA_WITH_NULL_MD5: - case SSL_RSA_WITH_NULL_SHA: - case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */ - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: - case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */ - case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ - case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */ - case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */ - case 0x002C: /* TLS_PSK_WITH_NULL_SHA */ - case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */ - case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */ - case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */ - case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */ - case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */ - case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */ - case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */ - case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */ - /* Disable anonymous ciphersuites: */ - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: - case SSL_DH_anon_WITH_RC4_128_MD5: - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_anon_WITH_DES_CBC_SHA: - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */ - case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */ - case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */ - case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */ - case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */ - case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ - case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ - case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ - case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ - /* Disable weak key ciphersuites: */ - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_RSA_WITH_DES_CBC_SHA: - case SSL_DH_DSS_WITH_DES_CBC_SHA: - case SSL_DH_RSA_WITH_DES_CBC_SHA: - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - /* Disable IDEA: */ - case SSL_RSA_WITH_IDEA_CBC_SHA: - case SSL_RSA_WITH_IDEA_CBC_MD5: - /* Disable RC4: */ - case SSL_RSA_WITH_RC4_128_MD5: - case SSL_RSA_WITH_RC4_128_SHA: - case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */ - case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/ - case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */ - case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */ - case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */ - case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */ - case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */ - break; - default: /* enable everything else */ - allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; - break; - } + else { + err = sectransp_set_default_ciphers(data, backend->ssl_ctx); } - err = SSLSetEnabledCiphers(backend->ssl_ctx, allowed_ciphers, - allowed_ciphers_count); - Curl_safefree(all_ciphers); - Curl_safefree(allowed_ciphers); if(err != noErr) { - failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); + failf(data, "SSL: Unable to set ciphers for SSL/TLS handshake. " + "Error code: %d", err); return CURLE_SSL_CIPHER; } @@ -1972,7 +2089,8 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, else { CURLcode result; ssl_sessionid = - aprintf("%s:%d:%d:%s:%ld", ssl_cafile, + aprintf("%s:%d:%d:%s:%ld", + ssl_cafile ? ssl_cafile : "(blob memory)", verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port); ssl_sessionid_len = strlen(ssl_sessionid); @@ -2023,21 +2141,21 @@ static long pem_to_der(const char *in, unsigned char **out, size_t *outlen) /* Jump through the separators at the beginning of the certificate. */ sep_start = strstr(in, "-----"); - if(sep_start == NULL) + if(!sep_start) return 0; cert_start = strstr(sep_start + 1, "-----"); - if(cert_start == NULL) + if(!cert_start) return -1; cert_start += 5; /* Find separator after the end of the certificate. */ cert_end = strstr(cert_start, "-----"); - if(cert_end == NULL) + if(!cert_end) return -1; sep_end = strstr(cert_end + 1, "-----"); - if(sep_end == NULL) + if(!sep_end) return -1; sep_end += 5; @@ -2112,7 +2230,7 @@ static int read_cert(const char *file, unsigned char **out, size_t *outlen) } static int append_cert_to_array(struct Curl_easy *data, - unsigned char *buf, size_t buflen, + const unsigned char *buf, size_t buflen, CFMutableArrayRef array) { CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen); @@ -2150,18 +2268,14 @@ static int append_cert_to_array(struct Curl_easy *data, return CURLE_OK; } -static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, - SSLContextRef ctx) +static CURLcode verify_cert_buf(struct Curl_easy *data, + const unsigned char *certbuf, size_t buflen, + SSLContextRef ctx) { int n = 0, rc; long res; - unsigned char *certbuf, *der; - size_t buflen, derlen, offset = 0; - - if(read_cert(cafile, &certbuf, &buflen) < 0) { - failf(data, "SSL: failed to read or invalid CA certificate"); - return CURLE_SSL_CACERT_BADFILE; - } + unsigned char *der; + size_t derlen, offset = 0; /* * Certbuf now contains the contents of the certificate file, which can be @@ -2174,8 +2288,7 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, */ CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - if(array == NULL) { - free(certbuf); + if(!array) { failf(data, "SSL: out of memory creating CA certificate array"); return CURLE_OUT_OF_MEMORY; } @@ -2189,7 +2302,6 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, */ res = pem_to_der((const char *)certbuf + offset, &der, &derlen); if(res < 0) { - free(certbuf); CFRelease(array); failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle", n, offset); @@ -2200,7 +2312,6 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, if(res == 0 && offset == 0) { /* This is not a PEM file, probably a certificate in DER format. */ rc = append_cert_to_array(data, certbuf, buflen, array); - free(certbuf); if(rc != CURLE_OK) { CFRelease(array); return rc; @@ -2209,14 +2320,12 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, } else if(res == 0) { /* No more certificates in the bundle. */ - free(certbuf); break; } rc = append_cert_to_array(data, der, derlen, array); free(der); if(rc != CURLE_OK) { - free(certbuf); CFRelease(array); return rc; } @@ -2224,7 +2333,7 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, SecTrustRef trust; OSStatus ret = SSLCopyPeerTrust(ctx, &trust); - if(trust == NULL) { + if(!trust) { failf(data, "SSL: error getting certificate chain"); CFRelease(array); return CURLE_PEER_FAILED_VERIFICATION; @@ -2273,6 +2382,38 @@ static CURLcode verify_cert(const char *cafile, struct Curl_easy *data, } } +static CURLcode verify_cert(struct Curl_easy *data, const char *cafile, + const struct curl_blob *ca_info_blob, + SSLContextRef ctx) +{ + int result; + unsigned char *certbuf; + size_t buflen; + + if(ca_info_blob) { + certbuf = (unsigned char *)malloc(ca_info_blob->len + 1); + if(!certbuf) { + return CURLE_OUT_OF_MEMORY; + } + buflen = ca_info_blob->len; + memcpy(certbuf, ca_info_blob->data, ca_info_blob->len); + certbuf[ca_info_blob->len]='\0'; + } + else if(cafile) { + if(read_cert(cafile, &certbuf, &buflen) < 0) { + failf(data, "SSL: failed to read or invalid CA certificate"); + return CURLE_SSL_CACERT_BADFILE; + } + } + else + return CURLE_SSL_CACERT_BADFILE; + + result = verify_cert_buf(data, certbuf, buflen, ctx); + free(certbuf); + return result; +} + + #ifdef SECTRANSP_PINNEDPUBKEY static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, SSLContextRef ctx, @@ -2297,19 +2438,19 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, do { SecTrustRef trust; OSStatus ret = SSLCopyPeerTrust(ctx, &trust); - if(ret != noErr || trust == NULL) + if(ret != noErr || !trust) break; SecKeyRef keyRef = SecTrustCopyPublicKey(trust); CFRelease(trust); - if(keyRef == NULL) + if(!keyRef) break; #ifdef SECTRANSP_PINNEDPUBKEY_V1 publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL); CFRelease(keyRef); - if(publicKeyBits == NULL) + if(!publicKeyBits) break; #elif SECTRANSP_PINNEDPUBKEY_V2 @@ -2317,7 +2458,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL, &publicKeyBits); CFRelease(keyRef); - if(success != errSecSuccess || publicKeyBits == NULL) + if(success != errSecSuccess || !publicKeyBits) break; #endif /* SECTRANSP_PINNEDPUBKEY_V2 */ @@ -2389,12 +2530,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, OSStatus err; SSLCipherSuite cipher; SSLProtocol protocol = 0; -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - const char * const hostname = conn->host.name; -#endif + const char * const hostname = SSL_HOST_NAME(); DEBUGASSERT(ssl_connect_2 == connssl->connecting_state || ssl_connect_2_reading == connssl->connecting_state @@ -2413,8 +2549,10 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, /* The below is errSSLServerAuthCompleted; it's not defined in Leopard's headers */ case -9841: - if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { - CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data, + if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) && + SSL_CONN_CONFIG(verifypeer)) { + CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile), + SSL_CONN_CONFIG(ca_info_blob), backend->ssl_ctx); if(result) return result; @@ -2601,8 +2739,9 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, #if CURL_BUILD_MAC_10_6 /* Only returned when kSSLSessionOptionBreakOnCertRequested is set */ case errSSLClientCertRequested: - failf(data, "The server has requested a client certificate"); - break; + failf(data, "Server requested a client certificate during the " + "handshake"); + return CURLE_SSL_CLIENTCERT; #endif #if CURL_BUILD_MAC_10_9 /* Alias for errSSLLast, end of error range */ @@ -2640,11 +2779,11 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, switch(protocol) { case kSSLProtocol2: infof(data, "SSL 2.0 connection using %s\n", - SSLCipherNameForNumber(cipher)); + TLSCipherNameForNumber(cipher)); break; case kSSLProtocol3: infof(data, "SSL 3.0 connection using %s\n", - SSLCipherNameForNumber(cipher)); + TLSCipherNameForNumber(cipher)); break; case kTLSProtocol1: infof(data, "TLS 1.0 connection using %s\n", @@ -2681,10 +2820,9 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1) chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0); -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(chosenProtocol && - !CFStringCompare(chosenProtocol, CFSTR(NGHTTP2_PROTO_VERSION_ID), - 0)) { + !CFStringCompare(chosenProtocol, CFSTR(ALPN_H2), 0)) { conn->negnpn = CURL_HTTP_VERSION_2; } else @@ -3258,8 +3396,10 @@ static ssize_t sectransp_recv(struct Curl_easy *data, /* The below is errSSLPeerAuthCompleted; it's not defined in Leopard's headers */ case -9841: - if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) { - CURLcode result = verify_cert(SSL_CONN_CONFIG(CAfile), data, + if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) && + SSL_CONN_CONFIG(verifypeer)) { + CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile), + SSL_CONN_CONFIG(ca_info_blob), backend->ssl_ctx); if(result) return result; @@ -3286,6 +3426,7 @@ static void *sectransp_get_internals(struct ssl_connect_data *connssl, const struct Curl_ssl Curl_ssl_sectransp = { { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */ + SSLSUPP_CAINFO_BLOB | #ifdef SECTRANSP_PINNEDPUBKEY SSLSUPP_PINNEDPUBKEY, #else @@ -3313,7 +3454,9 @@ const struct Curl_ssl Curl_ssl_sectransp = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ sectransp_false_start, /* false_start */ - sectransp_sha256sum /* sha256sum */ + sectransp_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #ifdef __clang__ diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c index 2e07df0a04..65f4f773dd 100644 --- a/libs/libcurl/src/vtls/vtls.c +++ b/libs/libcurl/src/vtls/vtls.c @@ -135,6 +135,7 @@ Curl_ssl_config_matches(struct ssl_primary_config *data, (data->verifyhost == needle->verifyhost) && (data->verifystatus == needle->verifystatus) && blobcmp(data->cert_blob, needle->cert_blob) && + blobcmp(data->ca_info_blob, needle->ca_info_blob) && Curl_safe_strcasecompare(data->CApath, needle->CApath) && Curl_safe_strcasecompare(data->CAfile, needle->CAfile) && Curl_safe_strcasecompare(data->clientcert, needle->clientcert) && @@ -161,6 +162,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, dest->sessionid = source->sessionid; CLONE_BLOB(cert_blob); + CLONE_BLOB(ca_info_blob); CLONE_STRING(CApath); CLONE_STRING(CAfile); CLONE_STRING(clientcert); @@ -185,6 +187,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) Curl_safefree(sslc->cipher_list13); Curl_safefree(sslc->pinned_key); Curl_safefree(sslc->cert_blob); + Curl_safefree(sslc->ca_info_blob); Curl_safefree(sslc->curves); } @@ -315,6 +318,8 @@ Curl_ssl_connect(struct Curl_easy *data, struct connectdata *conn, if(!result) Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */ + else + conn->ssl[sockindex].use = FALSE; return result; } @@ -338,7 +343,9 @@ Curl_ssl_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, /* mark this is being ssl requested from here on. */ conn->ssl[sockindex].use = TRUE; result = Curl_ssl->connect_nonblocking(data, conn, sockindex, done); - if(!result && *done) + if(result) + conn->ssl[sockindex].use = FALSE; + else if(*done) Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */ return result; } @@ -579,6 +586,25 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, return CURLE_OK; } +void Curl_ssl_associate_conn(struct Curl_easy *data, + struct connectdata *conn) +{ + if(Curl_ssl->associate_connection) { + Curl_ssl->associate_connection(data, conn, FIRSTSOCKET); + if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted) + Curl_ssl->associate_connection(data, conn, SECONDARYSOCKET); + } +} + +void Curl_ssl_detach_conn(struct Curl_easy *data, + struct connectdata *conn) +{ + if(Curl_ssl->disassociate_connection) { + Curl_ssl->disassociate_connection(data, FIRSTSOCKET); + if(conn->sock[SECONDARYSOCKET] && conn->bits.sock_accepted) + Curl_ssl->disassociate_connection(data, SECONDARYSOCKET); + } +} void Curl_ssl_close_all(struct Curl_easy *data) { @@ -1207,7 +1233,9 @@ static const struct Curl_ssl Curl_ssl_multi = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - NULL /* sha256sum */ + NULL, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; const struct Curl_ssl *Curl_ssl = diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index 2b43e7744b..7f93e7aedb 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -32,6 +32,7 @@ struct ssl_connect_data; #define SSLSUPP_SSL_CTX (1<<3) /* supports CURLOPT_SSL_CTX */ #define SSLSUPP_HTTPS_PROXY (1<<4) /* supports access via HTTPS proxies */ #define SSLSUPP_TLS13_CIPHERSUITES (1<<5) /* supports TLS 1.3 ciphersuites */ +#define SSLSUPP_CAINFO_BLOB (1<<6) struct Curl_ssl { /* @@ -83,6 +84,11 @@ struct Curl_ssl { bool (*false_start)(void); CURLcode (*sha256sum)(const unsigned char *input, size_t inputlen, unsigned char *sha256sum, size_t sha256sumlen); + + void (*associate_connection)(struct Curl_easy *data, + struct connectdata *conn, + int sockindex); + void (*disassociate_connection)(struct Curl_easy *data, int sockindex); }; #ifdef USE_SSL @@ -126,9 +132,11 @@ bool Curl_ssl_tls13_ciphersuites(void); #define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */ #endif -/* see https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */ +/* see https://www.iana.org/assignments/tls-extensiontype-values/ */ #define ALPN_HTTP_1_1_LENGTH 8 #define ALPN_HTTP_1_1 "http/1.1" +#define ALPN_H2_LENGTH 2 +#define ALPN_H2 "h2" /* set of helper macros for the backends to access the correct fields. For the proxy or for the remote host - to properly support HTTPS proxy */ @@ -148,6 +156,8 @@ bool Curl_ssl_tls13_ciphersuites(void); (SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name) #define SSL_HOST_DISPNAME() \ (SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname) +#define SSL_HOST_PORT() \ + (SSL_IS_PROXY() ? conn->port : conn->remote_port) #define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \ ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \ : data->set.str[STRING_SSL_PINNEDPUBLICKEY]) @@ -158,6 +168,7 @@ bool Curl_ssl_tls13_ciphersuites(void); #define SSL_CONN_CONFIG(var) conn->ssl_config.var #define SSL_HOST_NAME() conn->host.name #define SSL_HOST_DISPNAME() conn->host.dispname +#define SSL_HOST_PORT() conn->remote_port #define SSL_PINNED_PUB_KEY() \ data->set.str[STRING_SSL_PINNEDPUBLICKEY] #endif @@ -277,6 +288,11 @@ bool Curl_ssl_cert_status_request(void); bool Curl_ssl_false_start(void); +void Curl_ssl_associate_conn(struct Curl_easy *data, + struct connectdata *conn); +void Curl_ssl_detach_conn(struct Curl_easy *data, + struct connectdata *conn); + #define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ #else /* if not USE_SSL */ @@ -303,6 +319,8 @@ bool Curl_ssl_false_start(void); #define Curl_ssl_cert_status_request() FALSE #define Curl_ssl_false_start() FALSE #define Curl_ssl_tls13_ciphersuites() FALSE +#define Curl_ssl_associate_conn(a,b) Curl_nop_stmt +#define Curl_ssl_detach_conn(a,b) Curl_nop_stmt #endif #endif /* HEADER_CURL_VTLS_H */ diff --git a/libs/libcurl/src/vtls/wolfssl.c b/libs/libcurl/src/vtls/wolfssl.c index c6f428034f..60e27e3662 100644 --- a/libs/libcurl/src/vtls/wolfssl.c +++ b/libs/libcurl/src/vtls/wolfssl.c @@ -47,16 +47,6 @@ #endif #endif -/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in - options.h, but is only seen in >= 3.6.6 since that's when they started - disabling SSLv3 by default. */ -#ifndef WOLFSSL_ALLOW_SSLV3 -#if (LIBWOLFSSL_VERSION_HEX < 0x03006006) || \ - defined(HAVE_WOLFSSLV3_CLIENT_METHOD) -#define WOLFSSL_ALLOW_SSLV3 -#endif -#endif - #include #include "urldata.h" @@ -285,18 +275,6 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, failf(data, "wolfSSL: TLS 1.3 is not yet supported"); return CURLE_SSL_CONNECT_ERROR; #endif - case CURL_SSLVERSION_SSLv3: -#ifdef WOLFSSL_ALLOW_SSLV3 - req_method = SSLv3_client_method(); - use_sni(FALSE); -#else - failf(data, "wolfSSL does not support SSLv3"); - return CURLE_NOT_BUILT_IN; -#endif - break; - case CURL_SSLVERSION_SSLv2: - failf(data, "wolfSSL does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; default: failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); return CURLE_SSL_CONNECT_ERROR; @@ -418,12 +396,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, #ifdef ENABLE_IPV6 struct in6_addr addr6; #endif -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; -#else - const char * const hostname = conn->host.name; -#endif + const char * const hostname = SSL_HOST_NAME(); size_t hostname_len = strlen(hostname); if((hostname_len < USHRT_MAX) && (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) && @@ -474,10 +447,10 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, /* wolfSSL's ALPN protocol name list format is a comma separated string of protocols in descending order of preference, eg: "h2,http/1.1" */ -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2) { - strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ","); - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + strcpy(protocols + strlen(protocols), ALPN_H2 ","); + infof(data, "ALPN, offering %s\n", ALPN_H2); } #endif @@ -552,20 +525,9 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, int ret = -1; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; -#ifndef CURL_DISABLE_PROXY - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : - conn->host.name; - const char * const dispname = SSL_IS_PROXY() ? - conn->http_proxy.host.dispname : conn->host.dispname; - const char * const pinnedpubkey = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#else - const char * const hostname = conn->host.name; - const char * const dispname = conn->host.dispname; - const char * const pinnedpubkey = - data->set.str[STRING_SSL_PINNEDPUBLICKEY]; -#endif + const char * const hostname = SSL_HOST_NAME(); + const char * const dispname = SSL_HOST_DISPNAME(); + const char * const pinnedpubkey = SSL_PINNED_PUB_KEY(); conn->recv[sockindex] = wolfssl_recv; conn->send[sockindex] = wolfssl_send; @@ -725,11 +687,10 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, if(protocol_len == ALPN_HTTP_1_1_LENGTH && !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) conn->negnpn = CURL_HTTP_VERSION_1_1; -#ifdef USE_NGHTTP2 +#ifdef USE_HTTP2 else if(data->state.httpwant >= CURL_HTTP_VERSION_2 && - protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN)) + protocol_len == ALPN_H2_LENGTH && + !memcmp(protocol, ALPN_H2, ALPN_H2_LENGTH)) conn->negnpn = CURL_HTTP_VERSION_2; #endif else @@ -820,7 +781,7 @@ static ssize_t wolfssl_send(struct Curl_easy *data, int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; int rc = SSL_write(backend->handle, mem, memlen); - if(rc < 0) { + if(rc <= 0) { int err = SSL_get_error(backend->handle, rc); switch(err) { @@ -1164,7 +1125,9 @@ const struct Curl_ssl Curl_ssl_wolfssl = { Curl_none_set_engine_default, /* set_engine_default */ Curl_none_engines_list, /* engines_list */ Curl_none_false_start, /* false_start */ - wolfssl_sha256sum /* sha256sum */ + wolfssl_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif diff --git a/libs/libcurl/src/x509asn1.c b/libs/libcurl/src/x509asn1.c index f29aa05b87..281c97248b 100644 --- a/libs/libcurl/src/x509asn1.c +++ b/libs/libcurl/src/x509asn1.c @@ -1145,10 +1145,8 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn, int matched = -1; size_t addrlen = (size_t) -1; ssize_t len; - const char *const hostname = SSL_IS_PROXY()? - conn->http_proxy.host.name : conn->host.name; - const char *const dispname = SSL_IS_PROXY()? - conn->http_proxy.host.dispname : conn->host.dispname; + const char * const hostname = SSL_HOST_NAME(); + const char * const dispname = SSL_HOST_DISPNAME(); #ifdef ENABLE_IPV6 struct in6_addr addr; #else -- cgit v1.2.3