diff options
author | dartraiden <wowemuh@gmail.com> | 2021-04-03 16:14:19 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2021-04-03 16:14:19 +0300 |
commit | f223275b6ca65c29f8f098818241150338e00123 (patch) | |
tree | 7cc89050956d82aab5ee33cf98f211f1840c28e6 /libs | |
parent | 9a749bc628747c148394314a97fdeae6e032dc0b (diff) |
libcurl: update to 7.76.0
Diffstat (limited to 'libs')
103 files changed, 4572 insertions, 3346 deletions
diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES index f3439fd046..762a865fe1 100644 --- a/libs/libcurl/docs/CHANGES +++ b/libs/libcurl/docs/CHANGES @@ -6,6 +6,1999 @@ Changelog +Version 7.76.0 (31 Mar 2021) + +Daniel Stenberg (31 Mar 2021) +- RELEASE-NOTES: synced + + curl 7.76.0 release + +- THANKS: added names from 7.76.0 + +- CURLOPT_AUTOREFERER.3: clarify that it sets the full URL + + ... some users may not want that! + +- define: remove CURL_DISABLE_NTLM ifdefs + + It was never defined anywhere. Fixed disable-scan (test 1165) to also + scan headers, which found this issue. + + Closes #6809 + +- vtls: fix addsessionid for non-proxy builds + + 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 <jpmenil@gmail.com> + + 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 + +- TODO: Custom progress meter update interval + + Ref: https://stackoverflow.com/q/66789977/93747 + +- docs/ABI: tighten up the language + + Make the promises more firm + + Closes #6786 + +- openldap: disconnect better + + 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. + + Follow-up to e467ea3bd937f38 + Assisted-by: Patrick Monnerat + Closes #6787 + +- libssh2: kdb_callback: get the right struct pointer + + 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) + + Reported-by: Christian Schmitz + Fixes #6691 + Closes #6782 + +- tftp: remove unused struct fields + + Follow-up to d3d90ad9c00530d + + Closes #6781 + +- 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: Michael Brown + Fixes #6769 + Closes #6778 + +- azure: disable test 433 on azure-ubuntu + + Something in that environment sets XDG_CONFIG_HOME for us in a way that + breaks the test. + + Reported-by: Marc Hörsken + Fixes #6739 + Closes #6777 + +- tftp: remove the 3600 second default timeout + + ... it was never meant to be there. + + Reported-by: Tomas Berger + Fixes #6774 + Closes #6776 + +- docs: make gen.pl support *italic* and **bold** + + Remove some nroffisms from the cmdline doc files to simplify editing, + and instead support this markdown style. + + Closes #6771 + +- ngtcp2: sync with recent API updates + + Closes #6770 + +- RELEASE-NOTES: synced + +- libssh2:ssh_connect: clear session pointer after free + + 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 + +- [Jacob Hoffman-Andrews brought this change] + + docs: document version of crustls dependency + + This also pins a specific release in the Travis test so future + API-breaking changins in crustls won't break curl builds. + + Add RUSTLS documentation to release tarball. + + Enable running tests for rustls, minus FTP tests (require + connect_blocking, which rustls doesn't implement) and 313 (requires CRL + handling). + + Closes #6763 + +- [Jacob Hoffman-Andrews brought this change] + + rustls: Handle close_notify. + + 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). + + Closes #6763 + +- docs: clarify timeouts for queued transfers in multi API + + Closes #6758 + +- ftpserver: only load the preprocessed test file + + We always preprocess and tests are no longer sensible to load "raw" + + Closes #6738 + +- tests: use %TESTNUMBER instead of fixed number + + This makes the tests easier to copy and relocate to other test numbers + without having to update content. + + Closes #6738 + +- KNOWN_BUGS: CURLOPT_OPENSOCKETPAIRFUNCTION is missing + + Closes #5747 + +- TODO: provide timing info for each redirect + + Closes #6743 + +Jay Satiro (17 Mar 2021) +- docs: Add SSL backend names to CURL_SSL_BACKEND + + - Document the names that can be used with CURL_SSL_BACKEND: + bearssl, gnutls, gskit, mbedtls, mesalink, nss, openssl, rustls, + schannel, secure-transport, wolfssl + + Ref: https://github.com/curl/curl/issues/2209#issuecomment-360623286 + Ref: https://github.com/curl/curl/issues/6717#issuecomment-800745201 + + Closes https://github.com/curl/curl/pull/6755 + +- docs: Explain DOH transfers inherit some SSL settings + + - 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 + +Daniel Stenberg (17 Mar 2021) +- http: make 416 not fail with resume + CURLOPT_FAILONERRROR + + 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. + + Updated test 1156, added test 1273 + + Reported-by: Jonathan Watt + Fixes #6740 + Closes #6753 + +- Curl_timeleft: check both timeouts during connect + + 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. + + 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. + + The CONNECTTIMEOUT is per connect attempt. The TIMEOUT is for the entire + operation. + + Fixes #6744 + Closes #6745 + Reported-by: Andrei Bica + Assisted-by: Jay Satiro + +- configure: remove use of deprecated macros + + AC_HEADER_TIME, AC_HEADER_STDC and AC_TYPE_SIGNAL + +- configure: make AC_TRY_* into AC_*_IFELSE + + ... as the former versions are deprecated. + +- 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. + + Reported-by: Emil Engler + Fixes #6647 + Closes #6748 + +- RELEASE-NOTES: synced + +- travis: use ubuntu nghttp2 package instead of build our own + + Closes #6751 + +- travis: bump wolfssl to 4.7.0 + +- travis: only build wolfssl when needed + + Closes #6751 + +- [Jacob Hoffman-Andrews brought this change] + + rustls: allocate a buffer for TLS data. + + 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 #6742 + +- travis: add a rustls build + + ... that doesn't run any tests (yet) + + Closes #6750 + +- 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 + + 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 #6747 + +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. + + Reviewed-by: Marcel Raad + + Closes #6277 + +- config: fix detection of restricted Windows App environment + + 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. + + Reviewed-by: Marcel Raad + + Part of #6277 + +Daniel Stenberg (15 Mar 2021) +- HISTORY: curl 7.7.2 was the first version used in Mac OS X 10.1 + +- gen.pl: quote "bare" minuses in the nroff curl.1 + + Reported-by: Alejandro Colomar + Fixes #6698 + Closes #6722 + +Daniel Gustafsson (14 Mar 2021) +- hsts: remove unused defines + + 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 #6741 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +Daniel Stenberg (12 Mar 2021) +- github: add torture-ftp for FTP-only torture testing + + and at 20% to try to keep the run-time reasonable + + Closes #6728 + +- travis: split "torture" into a separate "events" build as well + + Run torture without FTP and reducing coverage to 20% + + For some reason the torture tests now run a lot slower on travis and run + into the 50 minute limit all the time. + + Closes #6728 + +- ftp: fix memory leak in ftp_done + + If after a transfer is complete Curl_GetFTPResponse() returns an error, + curl would not free the ftp->pathalloc block. + + Found by torture-testing test 576 + + 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] + + rustls: support CURLOPT_SSL_VERIFYPEER + + 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. + + 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). + + Closes #6719 + +Daniel Gustafsson (12 Mar 2021) +- cookies: Fix potential NULL pointer deref with PSL + + 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. + + 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 <daniel@haxx.se> + +Daniel Stenberg (12 Mar 2021) +- [Michael Hordijk brought this change] + + configure: only add OpenSSL paths if they are defined + + 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 (12 Mar 2021) +- retry.d: Clarify transient 5xx HTTP response codes + + - Clarify the only 5xx response codes that are treated as transient are + 500, 502, 503 and 504. + + Prior to this change it said it treated all 5xx as transient, but the + code says otherwise. + + Ref: https://github.com/curl/curl/blob/curl-7_75_0/src/tool_operate.c#L462-L495 + + Closes https://github.com/curl/curl/pull/6724 + +- retry-all-errors.d: Explain curl errors versus HTTP response errors + + - 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. + + The --retry-all-errors doc says "Retry on any error" which some users + may find misleading without the added explanation. + + 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 + + Reported-by: Lawrence Gripper + + Fixes https://github.com/curl/curl/issues/6712 + Closes https://github.com/curl/curl/pull/6720 + +Daniel Stenberg (11 Mar 2021) +- travis: switch ngtcp2 build over to quictls + + The ngtcp2 project switched over to using the quictls OpenSSL fork + instead of their own patched OpenSSL. We follow suit. + + Closes #6729 + +- test220/314: adjust to run with Hyper + +- c-hyper: support automatic content-encoding + + Closes #6727 + +- http: remove superfluous NULL assign + + Closes #6727 + +- tool_operate: bail if set CURLOPT_HTTP09_ALLOWED returns error + + Closes #6727 + +- setopt: error on CURLOPT_HTTP09_ALLOWED set true with Hyper + + Not supported. + + Closes #6727 + +- test306: make it not run with Hyper + + ... as it tests HTTP/0.9 which Hyper doesn't support. + +- test304: header CRLF cleanup to work with Hyper + +- FTP: allow SIZE to fail when doing (resumed) upload + + Added test 362 to verify. + + Reported-by: Jordan Brown + Regression since 7ea2e1d0c5a7f (7.73.0) + Fixes #6715 + Closes #6725 + +- configure: provide Largefile feature for curl-config + + ... as cmake now does it correctly, and make test1014 check for it + + Closes #6702 + +- config: remove CURL_SIZEOF_CURL_OFF_T use only SIZEOF_CURL_OFF_T + + Make the code consistently use a single name for the size of the + "curl_off_t" type. + + Closes #6702 + +Jay Satiro (10 Mar 2021) +- [Jun-ya Kato brought this change] + + 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 + +Daniel Stenberg (10 Mar 2021) +- [ejanchivdorj brought this change] + + multi: update pending list when removing handle + + when removing a handle, most of the lists are updated but pending list + is not updated. Updating now. + + Closes #6713 + +- [kokke brought this change] + + lib1536: check ptr against NULL before dereferencing it + + Closes #6710 + +- [kokke brought this change] + + lib1537: check ptr against NULL before dereferencing it + + Fixes #6707 + Closes #6708 + +- travis: make torture tests skip TLS-SRP tests + + ... as it seems to often hang. + + Also: skip the "normal" tests as they're already run by many other + builds. + + Closes #6705 + +- openssl: adapt to v3's new const for a few API calls + + Closes #6703 + +- quiche: fix crash when failing to connect + + Reported-by: ウさん + Fixes #6664 + Closes #6701 + +- RELEASE-NOTES: synced + + Fixed the release counter and added a missing contributor + +- RELEASE-NOTES: synced + +- dynbuf: bump the max HTTP request to 1MB + + Raised from 128KB to allow longer request headers. + + Reported-by: Carl Zogheib + Fixes #6681 + Closes #6685 + +Jay Satiro (6 Mar 2021) +- schannel: Evaluate CURLOPT_SSL_OPTIONS via SSL_SET_OPTION macro + + - 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. + + Example: + + Evaluate SSL_SET_OPTION(no_revoke) instead of data->set.ssl.no_revoke. + + 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. + + Since neither Schannel nor Secure Transport backends currently support + HTTPS proxy in libcurl, this change is for posterity and has no other + effect. + + Closes https://github.com/curl/curl/pull/6690 + +- [kokke brought this change] + + c-hyper: Remove superfluous pointer check + + `n` pointer is never NULL once set. Found by static analysis. + + Ref: https://github.com/curl/curl/issues/6696 + + Closes https://github.com/curl/curl/pull/6697 + +- version.d: Add missing features to the features list + + - Add missing entries for gsasl, Kerberos, NTLM_WB, TrackMemory, + Unicode and zstd. + + - Remove krb4 since it's no longer a feature. + + Reported-by: Ádler Jonas Gross + + Fixes https://github.com/curl/curl/issues/6677 + Closes https://github.com/curl/curl/pull/6687 + +- [Vladimir Varlamov brought this change] + + docs: add missing Arg tag to --stderr + + Prior to this change the required argument was not shown. + + curl.1 before: --stderr + curl.1 after: --stderr <file> + + curl --help before: + --stderr Where to redirect stderr + + curl --help after: + --stderr <file> Where to redirect stderr + + Closes https://github.com/curl/curl/pull/6692 + +- projects: Update VS projects for OpenSSL 1.1.x + + - Update VS project templates to use the OpenSSL lib names and include + directories for OpenSSL 1.1.x. + + 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. + + The template changes in this commit were made by script: + + libeay32.lib => libcrypto.lib + ssleay32.lib => libssl.lib + ..\..\..\..\..\openssl\inc32 => ..\..\..\..\..\openssl\include + + 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 + + - Change build-openssl.bat to copy the build's include directory to the + output directory (as seen above). + + Each build has its own opensslconf.h which is different so we can't just + include the source include directory any longer. + + 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. + + - Change build-openssl.bat to use a temporary install directory that is + different from the temporary build directory. + + 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. + + 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 + + Fixes https://github.com/curl/curl/issues/984 + Closes https://github.com/curl/curl/pull/6675 + +- doh: Inherit CURLOPT_STDERR from user's easy handle + + 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. + + Bug: https://github.com/curl/curl/issues/6605 + Reported-by: arvids-kokins-bidstack@users.noreply.github.com + + Closes https://github.com/curl/curl/pull/6661 + +Marc Hoersken (1 Mar 2021) +- CI/azure: replace python-impacket with python3-impacket + + As of this month Azure DevOps uses Ubuntu 20.04 LTS which + no longer supports Python 2 and instead ships Python 3. + + Closes #6678 + +- runtests.pl: kill processes locking test log files + + Introduce a new runtests.pl command option: -rm + + For now only required and implemented for Windows. + Ignore stunnel logs due to long running processes. + + Requires Sysinternals handle[64].exe to be on PATH. + + Reviewed-by: Jay Satiro + + Ref: #6058 + Closes #6179 + +- pathhelp.pm: fix use of pwd -L in Msys environment + + While Msys2 has a pwd binary which supports -L, + Msys1 only has a shell built-in with that feature. + + Reviewed-by: Jay Satiro + + Part of #6179 + +Daniel Gustafsson (1 Mar 2021) +- ldap: use correct memory free function + + 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. + + Closes #6671 + Reviewed-by: Jay Satiro <raysatiro@yahoo.com> + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +- url: fix typo in comment + + Correct a small typo which snuck in with a304051620. + +Jay Satiro (28 Feb 2021) +- tool_help: Increase space between option and description + + - Increase the minimum number of spaces between the option and the + description from 1 to 2. + + Before: + ~~~ + -u, --user <user:password> Server user and password + -A, --user-agent <name> Send User-Agent <name> to server + -v, --verbose Make the operation more talkative + -V, --version Show version number and quit + -w, --write-out <format> Use output FORMAT after completion + --xattr Store metadata in extended file attributes + ~~~ + + After: + ~~~ + -u, --user <user:password> Server user and password + -A, --user-agent <name> Send User-Agent <name> to server + -v, --verbose Make the operation more talkative + -V, --version Show version number and quit + -w, --write-out <format> Use output FORMAT after completion + --xattr Store metadata in extended file attributes + ~~~ + + Closes https://github.com/curl/curl/pull/6674 + +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 + +- tool_operate: check argc before accessing argv[1] + + Follow-up to 09363500b + Reported-by: Emil Engler + Reviewed-by: Daniel Gustafsson + Closes #6668 + +Daniel Gustafsson (26 Feb 2021) +- [Jean-Philippe Menil brought this change] + + openssl: remove get_ssl_version_txt in favor of SSL_get_version + + 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 <daniel@yesql.se> + Signed-off-by: Jean-Philippe Menil <jpmenil@gmail.com> + +- gnutls: Fix nettle discovery + + 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: + + https://curl.se/dev/log.cgi?id=20210225123226-30704#prob1 + + This removes all uses of USE_GNUTLS_NETTLE and also removes the + gcrypt support from the metalink code while at it. + + Closes #6656 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +- cookies: Support multiple -b parameters + + 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. + + Closes #6649 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +Daniel Stenberg (25 Feb 2021) +- build: remove all traces of USE_BLOCKING_SOCKETS + + libcurl doesn't behave properly with the define set + + Closes #6655 + +- RELEASE-NOTES: synced + +Daniel Gustafsson (25 Feb 2021) +- docs: Fix typos + + Random typos spotted when skimming docs. + +- 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 <daniel@haxx.se> + +Daniel Stenberg (24 Feb 2021) +- urldata: make 'actions[]' use unsigned char instead of int + + ... as it only needs a few bits per index anyway. + + Reviewed-by: Daniel Gustafsson + Closes #6648 + +- configure: fail if --with-quiche is used and quiche isn't found + + Closes #6652 + +- [Gregor Jasny brought this change] + + cmake: use CMAKE_INSTALL_INCLUDEDIR indirection + + Reviewed-by: Sergei Nikulov + Closes #6440 + +Viktor Szakats (23 Feb 2021) +- mingw: enable using strcasecmp() + + This makes the 'Features:' list sorted case-insensitively, + bringing output in-line with *nix builds. + + Reviewed-by: Jay Satiro + Closes #6644 + +- build: delete unused feature guards + + - `HAVE_STRNCASECMP` + - `HAVE_TCGETATTR` + - `HAVE_TCSETATTR` + + Reviewed-by: Jay Satiro + Reviewed-by: Daniel Stenberg + Closes #6645 + +Jay Satiro (23 Feb 2021) +- docs: add CURLOPT_CURLU to 'See also' in curl_url_ functions + + Closes https://github.com/curl/curl/pull/6639 + +Daniel Stenberg (23 Feb 2021) +- [Jacob Hoffman-Andrews brought this change] + + configure: make hyper opt-in, and fail if missing + + Previously, configure would look for hyper by default, and use it if + found; otherwise it would not use hyper, and not error. + + Now, configure will not look for hyper unless --with-hyper is passed. If + configure looks for hyper and fails, it will error. + + Also, add -ld -lpthread -lm to Hyper's libs. I think they are required. + + Closes #6598 + +- 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... + + Regression from b68dc34af341805aeb7b3715 (shipped in 7.75.0) + + Reported-by: Amaury Denoyelle + Fixes #6640 + Closes #6641 + +- 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 + +- curl_url_set.3: mention CURLU_PATH_AS_IS + + ... it has been supported since the URL API was added. + + Bug: https://curl.se/mail/lib-2021-02/0046.html + + Closes #6638 + +Viktor Szakats (21 Feb 2021) +- time: enable 64-bit time_t in supported mingw environments + + (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. + + Assisted-by: Jay Satiro + Closes #6636 + +Jay Satiro (20 Feb 2021) +- test1188: Check for --fail HTTP status + + - Change the test to check for curl error on HTTP 404 Not Found. + + 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. + + 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 + + Closes https://github.com/curl/curl/pull/6637 + +- memdebug: close debug logfile explicitly on exit + + - Use atexit to register a dbg cleanup function that closes the logfile. + + 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. + + 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). + + Ref: https://github.com/google/sanitizers/issues/1374 + + Bug: https://github.com/curl/curl/pull/6591#issuecomment-780396541 + + Closes https://github.com/curl/curl/pull/6620 + +- curl_multibyte: always return a heap-allocated copy of string + + - Change the Windows char <-> UTF-8 conversion functions to return an + allocated copy of the passed in string instead of the original. + + 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. + + 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 https://github.com/curl/curl/pull/6602 + +Viktor Szakats (19 Feb 2021) +- http: add new files missed from referrer commit + + Ref: 44872aefc2d54f297caf2b0cc887df321bc9d791 + Ref: #6591 + +- 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) + + Closes #6591 + +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 + +- url: fix memory leak if OOM in the HSTS handling + + Reported-by: Viktor Szakats + Bug: https://github.com/curl/curl/pull/6627#issuecomment-781626205 + + Closes #6628 + +- 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. + + Closes #6625 + +- 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. + + Follow-up to 35ca04ce1b77636 + + Makes test 1188 work for c-ares builds + + Closes #6626 + +Viktor Szakats (18 Feb 2021) +- ci: stop building on freebsd-12-1 + + 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 + ``` + + FreeBSD thread suggests that 12.1 is EOL, and best to avoid. + + Ref: https://forums.freebsd.org/threads/78856/ + + Reviewed-by: Daniel Stenberg + Closes #6622 + +Daniel Stenberg (18 Feb 2021) +- test1188: change error from connect to resolve error + + 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 + +- url.c: use consistent error message for failed resolve + +- BUGS: language polish + +- wolfssl: don't store a NULL sessionid + + 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 + +- parse_proxy: fix a memory leak in the OOM path + + Reported-by: Jay Satiro + Reviewed-by: Jay Satiro + Reviewed-by: Emil Engler + + Closes #6614 + Bug: https://github.com/curl/curl/pull/6591#issuecomment-780396541 + +Jay Satiro (17 Feb 2021) +- url: fix possible use-after-free in default protocol + + 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. + + Bug: https://github.com/curl/curl/issues/6604#issuecomment-780138219 + Reported-by: arvids-kokins-bidstack@users.noreply.github.com + + Closes https://github.com/curl/curl/pull/6613 + +Daniel Stenberg (16 Feb 2021) +- multi: rename the multi transfer states + + 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. + + State names NOT ending with *ing are transitional ones. + + Closes #6612 + +Viktor Szakats (16 Feb 2021) +- http: do not add a referrer header with empty value + + 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 + +Daniel Stenberg (16 Feb 2021) +- lib: remove 'conn->data' completely + + 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 #6608 + +- openldap: pass 'data' to the callbacks instead of 'conn' + +Jay Satiro (15 Feb 2021) +- doh: Fix sharing user's resolve list with DOH handles + + - Share the shared object from the user's easy handle with the DOH + handles. + + 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. + + 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. + + Reported-by: Manuj Bhatia + + Fixes https://github.com/curl/curl/issues/6589 + Closes https://github.com/curl/curl/pull/6607 + +Daniel Stenberg (15 Feb 2021) +- http2: remove conn->data use + + ... 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 #6520 + +- openssl: remove conn->data use + + We still make the trace callback function get the connectdata struct + passed to it, since the callback is anchored on the connection. + + 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 code therefore makes sure to set the "logger" handle before using + OpenSSL calls so that the right easy handle gets used for tracing. + + Closes #6522 + +- RELEASE-NOTES: synced + +Jay Satiro (14 Feb 2021) +- doh: add options to disable ssl verification + + - New libcurl options CURLOPT_DOH_SSL_VERIFYHOST, + CURLOPT_DOH_SSL_VERIFYPEER and CURLOPT_DOH_SSL_VERIFYSTATUS do the + same as their respective counterparts. + + - New curl tool options --doh-insecure and --doh-cert-status do the same + as their respective counterparts. + + 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. + + Ref: https://github.com/curl/curl/pull/4579#issuecomment-554723676 + + Fixes https://github.com/curl/curl/issues/4578 + Closes https://github.com/curl/curl/pull/6597 + +- hostip: fix crash in sync resolver builds that use DOH + + - Guard some Curl_async accesses with USE_CURL_ASYNC instead of + !CURLRES_SYNCH. + + 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. + + Closes https://github.com/curl/curl/pull/6603 + +Daniel Stenberg (13 Feb 2021) +- KNOWN_BUGS: cannot enable LDAPS on Windows with cmake + + Reported-by: Jack Boos Yu + Closes #6284 + +- KNOWN_BUGS: Excessive HTTP/2 packets with TCP_NODELAY + + Reported-by: Alex Xu + Closes #6363 + +- http: use credentials from transfer, not connection + + 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. + + 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.* + + Added test 675 to verify different credentials used in two requests done + over a reused HTTP connection, which previously behaved wrongly. + + Fixes #6542 + Closes #6545 + +- test433: clear some home dir env variables + + Follow-up to bd6b54ba1f55b5 + + ... so that XDG_CONFIG_HOME is the only home dir variable set and thus + used correctly in the test! + + Fixes #6599 + Closes #6600 + +- RELEASE-NOTES: synced + + bumped the version to 7.76.0 + +- travis: install libgsasl-dev to add that to the builds + + Closes #6588 + +- urldata: don't touch data->set.httpversion at run-time + + Rename it to 'httpwant' and make a cloned field in the state struct as + well for run-time updates. + + Also: refuse non-supported HTTP versions. Verified with test 129. + + Closes #6585 + +Viktor Szakats (11 Feb 2021) +- tests: disable .curlrc in more environments + + by also setting CURL_HOME and XDG_CONFIG_HOME envvars to the local + directory. + + Reviewed-by: Daniel Stenberg + Fixes #6595 + Closes #6596 + +- docs/Makefile.inc: format to be update-friendly + + - one source file per line + - convert tabs to spaces + - do not align line-continuation backslashes + - sort source files alphabetically + + Reviewed-by: Daniel Stenberg + Closes #6593 + +Daniel Stenberg (11 Feb 2021) +- curl: provide libgsasl version and feature info in -V output + + Closes #6592 + +- gsasl: provide CURL_VERSION_GSASL if built-in + + To let applications know the feature is available. + + Closes #6592 + +- curl: add --fail-with-body + + Prevent both --fail and --fail-with-body on the same command line. + + Verify with test 349, 360 and 361. + + Closes #6449 + +- TODO: remove HSTS + + Provided now since commit 7385610d0c74 + +Jay Satiro (10 Feb 2021) +- tests: Fix tests failing due to change in curl --help + + Follow-up to parent 3183217 which added add missing <mode> argument to + --create-file-mode <mode>. + + Ref: https://github.com/curl/curl/issues/6590 + +- tool_help: add missing argument for --create-file-mode + + Prior to this change the required argument was not shown in curl --help. + + before: + --create-file-mode File mode for created files + + after: + --create-file-mode <mode> File mode (octal) for created files + + Reported-by: ZimCodes@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/6590 + +- create-file-mode.d: add missing Arg tag + + Prior to this change the required argument was not shown. + + curl.1 before: --create-file-mode + curl.1 after: --create-file-mode <mode> + + Reported-by: ZimCodes@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/6590 + +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 + +- Makefile.m32: add support for libgsasl dependency + + Reviewed-by: Marcel Raad + Closes #6586 + +Marcel Raad (10 Feb 2021) +- ngtcp2: clarify calculation precedence + + As suggested by Codacy/cppcheck. + + Closes https://github.com/curl/curl/pull/6576 + +- server: remove redundant condition + + `end` is always non-null here. + + Closes https://github.com/curl/curl/pull/6576 + +- lib: remove redundant code + + Closes https://github.com/curl/curl/pull/6576 + +- mqttd: remove unused variable + + Closes https://github.com/curl/curl/pull/6576 + +- tool_paramhlp: reduce variable scope + + Closes https://github.com/curl/curl/pull/6576 + +- tests: reduce variable scopes + + Closes https://github.com/curl/curl/pull/6576 + +- lib: reduce variable scopes + + Closes https://github.com/curl/curl/pull/6576 + +- ftp: fix Codacy/cppcheck warning about null pointer arithmetic + + Increment `bytes` only if it is non-null. + + 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 + + Follow-up to cb2dc1ba8 + +- ftp: add 'list_only' to the transfer state struct + + 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. + + Added test case 1570 to verify. + + Closes #6578 + +- ftp: add 'prefer_ascii' to the transfer state struct + + ... 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. + + 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 + +- RELEASE-NOTES: synced + +- [Jacob Hoffman-Andrews brought this change] + + vtls: initial implementation of rustls backend + + This adds a new TLS backend, rustls. It uses the C-to-rustls bindings + from https://github.com/abetterinternet/crustls. + + Rustls is at https://github.com/ctz/rustls/. + + 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. + + Blog post for context: + https://www.abetterinternet.org/post/memory-safe-curl/ + + Closes #6350 + +- [Simon Josefsson brought this change] + + sasl: support SCRAM-SHA-1 and SCRAM-SHA-256 via libgsasl + + Closes #6372 + +Jay Satiro (9 Feb 2021) +- lib: use int type for more port variables + + This is a follow-up to 764c6bd. Prior to that change port variables + were usually type long. + + Closes https://github.com/curl/curl/pull/6553 + +- tool_writeout: refactor write-out and write-out json + + - Deduplicate the logic used by write-out and write-out json. + + 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. + + 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. + + - Support write-out %{errormsg} and %{exitcode} in json. + + - Clarify in the doc that %{exitcode} is the exit code of the transfer. + + 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 https://github.com/curl/curl/pull/6544 + +- lib: drop USE_SOCKETPAIR in favor of CURL_DISABLE_SOCKETPAIR + + .. since the former is undocumented and they both do the same thing. + + Closes https://github.com/curl/curl/pull/6517 + +- curl_multibyte: fall back to local code page stat/access on Windows + + 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). + + 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/6514 + +- [Stephan Szabo brought this change] + + file: Support unicode urls on windows + + Closes https://github.com/curl/curl/pull/6501 + +- [Vincent Torri brought this change] + + cmake: fix import library name for non-MS compiler on Windows + + - Use _imp.lib suffix only for Microsoft's compiler (MSVC). + + Prior to this change library suffix _imp.lib was used for the import + library on Windows regardless of compiler. + + With this change the other compilers should now use their default + suffix which should be .dll.a. + + 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 : + + https://sourceware.org/binutils/docs/ld/WIN32.html + + 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/6225 + +Daniel Stenberg (9 Feb 2021) +- urldata: move 'followlocation' to UrlState + + As this is a state variable it does not belong in UserDefined which is + used to store values set by the user. + + Closes #6582 + +- [Ikko Ashimine brought this change] + + http_proxy: fix typo in http_proxy.c + + settting -> setting + + Closes #6583 + +- [Fabian Keil brought this change] + + tests/server: Bump MAX_TAG_LEN to 200 + + This is useful for tests containing HTML inside of <data> sections. + For <img> tags it's not uncommon to be longer than the previous + limit of 79 bytes. + + An example of a previously problem-causing tag is: + <img src="http://config.privoxy.org/send-banner?type=auto" border="0" title="Killed-http://www.privoxy.org/images/privoxy.png-by-size" width="88" height="31"> + 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 <data> + 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] + + runtests.1: document -o, -P, -L, and -E + +- [Fabian Keil brought this change] + + runtests.pl: add %TESTNUMBER variable to make copying tests more convenient + +- [Fabian Keil brought this change] + + runtests.pl: add an -o option to change internal variables + + 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. + + Usage: + ./runtests.pl -o TESTDIR=$privoxy_curl_test_dir -o HOSTIP=10.0.0.1 ... + +- [Fabian Keil brought this change] + + runtests.pl: cleanups + + - 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 + + It can contain additional restraints for test numbers, + keywords and tools. + + 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. + + 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: + + 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 + + To specify multiple $TESTNUMBERs, $KEYWORDs and $TOOLs + on a single line, split them with commas. + +- [Fabian Keil brought this change] + + runtests.pl: add -L parameter to require additional perl libraries + + 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. + + Such differences are proxy-specific and thus the modifications + should be maintained together with the proxy. + +- [Fabian Keil brought this change] + + runtests.pl: add a -P option to specify an external proxy + + ... that should be used when executing the tests. + + The assumption is that the proxy is an HTTP proxy. + + This option should be used together with -L to provide + a customized compareparts() version that knows which + proxy-specific header differences should be ignored. + + This option doesn't work for all test types yet. + +- [Fabian Keil brought this change] + + tests: fixup several tests + + missing CRs and modified %hostip + + lib556/test556: use a real HTTP version to make test reuse more convenient + + make sure the weekday in Date headers matches the date + + test61: replace stray "^M" (5e 4d) at the end of a cookie with a '^M' (0d) + + Gets the test working with external proxies like Privoxy again. + + Closes #6463 + +- ftp: never set data->set.ftp_append outside setopt + + Since the set value then risks getting used like that when the easy + handle is reused by the application. + + Also: renamed the struct field from 'ftp_append' to 'remote_append' + since it is also used for SSH protocols. + + Closes #6579 + +- urldata: remove the 'rtspversion' field + + from struct connectdata and the corresponding code in http.c that set + it. It was never used for anything! + + Closes #6581 + +- CURLOPT_QUOTE.3: clarify that libcurl doesn't parse what's sent + + ... so passed in commands may confuse libcurl's knowledge of state. + + 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 + + Closes #6558 + +- RELEASE-PROCEDURE: remove old release dates, add new + +- docs/SSL-PROBLEMS: enhanced + + Elaborate on the intermediate cert issue, and mention that anything + below TLS 1.2 is generally considered insecure these days. + + 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 + + In a url after <scheme>:// follows the possibly empty authority part + till the next /, so that url missed a /. + + Closes #6573 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + Reviewed-by: Daniel Gustafsson <daniel@yesql.se> + +Daniel Stenberg (5 Feb 2021) +- hostip: fix build with sync resolver + + 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 + + gskit_send() first paramater is a pointer to Curl_easy not connectdata + struct. + + Closes #6570 + Fixes #6569 + +- urldata: fix build without HTTP and MQTT + + Reported-by: Joseph Chen + Fixes #6562 + Closes #6563 + +- ftp: avoid SIZE when asking for a TYPE A file + + ... as we ignore it anyway because servers don't report the correct size + and proftpd even blatantly returns a 550. + + Updates a set of tests accordingly. + + Reported-by: awesomenode on github + Fixes #6564 + Closes #6565 + +- pingpong: rename the curl_pp_transfer enum to use PP prefix + + Using an FTP prefix for PP provided functionality was misleading. + +- RELEASE-NOTES: synced + + ... and bump pending version to 7.75.1 (for now) + +Jay Satiro (4 Feb 2021) +- build: fix --disable-http-auth + + Broken since 215db08 (precedes 7.75.0). + + Reported-by: Benbuck Nason + + Fixes https://github.com/curl/curl/issues/6567 + +- build: fix --disable-dateparse + + Broken since 215db08 (precedes 7.75.0). + + Bug: https://curl.se/mail/lib-2021-02/0008.html + Reported-by: Firefox OS + +Daniel Stenberg (4 Feb 2021) +- [Jon Rumsey brought this change] + + OS400: update for CURLOPT_AWS_SIGV4 + + chkstrings fails because a new string option that could require codepage + conversion has been added. + + Closes #6561 + Fixes #6560 + +- BUG-BOUNTY: removed the cooperation mention + Version 7.75.0 (3 Feb 2021) Daniel Stenberg (3 Feb 2021) @@ -5667,1781 +7660,3 @@ Daniel Stenberg (16 Jul 2020) - ngtcp2: adjust to recent sockaddr updates Closes #5690 - -- page-header: provide protocol details in the curl.1 man page - - Add protocol and version specific information about all protocols curl - supports. - - Fixes #5679 - Reported-by: tbugfinder on github - Closes #5686 - -Daniel Gustafsson (16 Jul 2020) -- docs: Update a few leftover mentions of DarwinSSL - - Commit 76a9c3c4be10b3d4d379d5b23ca76806bbae536a renamed DarwinSSL to the - more correct/common name Secure Transport, but a few mentions in the docs - remained. - - Closes #5688 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - -Daniel Stenberg (16 Jul 2020) -- file2memory: use a define instead of -1 unsigned value - - ... to use the maximum value for 'size_t' when detecting integer overflow. - Changed the limit to max/4 as already that seems unreasonably large. - - Codacy didn't like the previous approach. - - Closes #5683 - -- CURL_PUSH_ERROROUT: allow the push callback to fail the parent stream - - ... by adding support for a new dedicated return code. - - Suggested-by: Jonathan Cardoso - Assisted-by: Erik Johansson - URL: https://curl.haxx.se/mail/lib-2020-06/0099.html - Closes #5636 - -- [Baruch Siach brought this change] - - nss: fix build with disabled proxy support - - Avoid reference to fields that do not exist when CURL_DISABLE_PROXY is - defined. - - Closes #5667 - -- test1139: make it display the difference on test failures - -- test1119: verify stdout in the test - - So that failures will be displayed in the terminal, as it makes test failures - visually displayed easier and faster. - - Closes #5644 - -- curl: add %{method} to the -w variables - - Gets the CURLINFO_EFFECTIVE_METHOD from libcurl. - - Added test 1197 to verify. - -- CURLINFO_EFFECTIVE_METHOD: added - - Provide the HTTP method that was used on the latest request, which might - be relevant for users when there was one or more redirects involved. - - Closes #5511 - -Viktor Szakats (14 Jul 2020) -- windows: add unicode to feature list - - Reviewed-by: Marcel Raad - Reviewed-by: Marc Hörsken - - Closes #5491 - -Daniel Stenberg (14 Jul 2020) -- multi: remove two checks always true - - Detected by Codacy - Closes #5676 - -Marc Hoersken (13 Jul 2020) -- workflows: limit what branches to run CodeQL on - - Align CodeQL action with existing CI actions: - - Update branch filter to avoid duplicate CI runs. - - Shorten workflow name due to informative job name. - - Reviewed-by: Daniel Stenberg - - Closes #5660 - -- appveyor: collect libcurl.dll variants with prefix or suffix - - On some platforms libcurl is build with a platform-specific - prefix and/or a version number suffix. - - Assisted-by: Jay Satiro - - Closes #5659 - -Daniel Stenberg (12 Jul 2020) -- [ihsinme brought this change] - - socks: use size_t for size variable - - Use the unsigned type (size_t) in the arithmetic of pointers. In this - context, the signed type (ssize_t) is used unnecessarily. - - Authored-by: ihsinme on github - Closes #5654 - -- RELEASE-NOTES: synced - - ... and bumped to 7.72.0 as the next release version number - -- [Gilles Vollant brought this change] - - content_encoding: add zstd decoding support - - include zstd curl patch for Makefile.m32 from vszakats - and include Add CMake support for zstd from Peter Wu - - Helped-by: Viktor Szakats - Helped-by: Peter Wu - Closes #5453 - -- asyn.h: remove the Curl_resolver_getsock define - - - not used - - used the wrong number of arguments - - confused the Codeacy code analyzer - - Closes #5647 - -- [Nicolas Sterchele brought this change] - - configure.ac: Sort features name in summary - - - Same as protocols - - Closes #5656 - -- [Matthias Naegler brought this change] - - cmake: fix windows xp build - - Reviewed-by: Marcel Raad - Closes #5662 - -- ngtcp2: update to modified qlog callback prototype - - Closes #5675 - -- transfer: fix memory-leak with CURLOPT_CURLU in a duped handle - - Added test case 674 to reproduce and verify the bug report. - - Fixes #5665 - Reported-by: NobodyXu on github - Closes #5673 - -- [Baruch Siach brought this change] - - bearssl: fix build with disabled proxy support - - Avoid reference to fields that do not exist when CURL_DISABLE_PROXY is - defined. - - Reviewed-by: Nicolas Sterchele - Closes #5666 - -- RELEASE-NOTES: synced - -Jay Satiro (11 Jul 2020) -- [Carlo Marcelo Arenas Belón brought this change] - - cirrus-ci: upgrade 11-STABLE to 11.4 - - Meant to be the last of the 11 series and so make sure that all - other references reflect all 11 versions so they can be retired - together later. - - Closes https://github.com/curl/curl/pull/5668 - -- [Filip Salomonsson brought this change] - - CURLINFO_CERTINFO.3: fix typo - - Closes https://github.com/curl/curl/pull/5655 - -Daniel Stenberg (4 Jul 2020) -- http2: only do the *done() cleanups for HTTP - - Follow-up to ef86daf4d3 - - Closes #5650 - Fixes #5646 - -- [Alex Kiernan brought this change] - - gnutls: repair the build with `CURL_DISABLE_PROXY` - - `http_proxy`/`proxy_ssl`/`tunnel_proxy` will not be available in `conn` - if `CURL_DISABLE_PROXY` is enabled. Repair the build with that - configuration. - - Signed-off-by: Alex Kiernan <alex.kiernan@gmail.com> - Closes #5645 - -Alex Kiernan (3 Jul 2020) -- gnutls: Fetch backend when using proxy - - Fixes: 89865c149 ("gnutls: remove the BACKEND define kludge") - Signed-off-by: Alex Kiernan <alex.kiernan@gmail.com> - -Daniel Stenberg (3 Jul 2020) -- [Laramie Leavitt brought this change] - - http2: close the http2 connection when no more requests may be sent - - Well-behaving HTTP2 servers send two GOAWAY messages. The first - message is a warning that indicates that the server is going to - stop accepting streams. The second one actually closes the stream. - - nghttp2 reports this state (and the other state of no more stream - identifiers) via the call nghttp2_session_check_request_allowed(). - In this state the client should not create more streams on the - session (tcp connection), and in curl this means that the server - has requested that the connection is closed. - - It would be also be possible to put the connclose() call into the - on_http2_frame_recv() function that triggers on the GOAWAY message. - - This fixes a bug seen when the client sees the following sequence of - frames: - - // advisory GOAWAY - HTTP2 GOAWAY [stream-id = 0, promised-stream-id = -1] - ... some additional frames - - // final GOAWAY - HTTP2 GOAWAY [stream-id = 0, promised-stream-id = N ] - - Before this change, curl will attempt to reuse the connection even - after the last stream, will encounter this error: - - * Found bundle for host localhost: 0x5595f0a694e0 [can multiplex] - * Re-using existing connection! (#0) with host localhost - * Connected to localhost (::1) port 10443 (#0) - * Using Stream ID: 9 (easy handle 0x5595f0a72e30) - > GET /index.html?5 HTTP/2 - > Host: localhost:10443 - > user-agent: curl/7.68.0 - > accept: */* - > - * stopped the pause stream! - * Connection #0 to host localhost left intact - curl: (16) Error in the HTTP2 framing layer - - This error may posion the connection cache, causing future requests - which resolve to the same curl connection to go through the same error - path. - - Closes #5643 - -- ftpserver: don't verify SMTP MAIL FROM names - - Rely on tests asking the names to get refused instead - test servers - should be as dumb as possible. Edited test 914, 955 and 959 accordingly. - - Closes #5639 - -- curl_version_info.3: CURL_VERSION_KERBEROS4 is deprecated - - This came up in #5640. It make sense to clarify this in the docs! - - Reminded-by: Kamil Dudka - Closes #5642 - -Kamil Dudka (3 Jul 2020) -- tool_getparam: make --krb option work again - - It was disabled by mistake in commit curl-7_37_1-23-ge38ba4301. - - Bug: https://bugzilla.redhat.com/1833193 - Closes #5640 - -Daniel Stenberg (2 Jul 2020) -- [Jeremy Maitin-Shepard brought this change] - - http2: fix nghttp2_strerror -> nghttp2_http2_strerror in debug messages - - Confusingly, nghttp2 has two different error code enums: - - - nghttp2_error, to be used with nghttp2_strerror - - nghttp2_error_code, to be used with nghttp2_http2_strerror - - Closes #5641 - -Marcel Raad (2 Jul 2020) -- url: silence MSVC warning - - Since commit f3d501dc678, if proxy support is disabled, MSVC warns: - url.c : warning C4701: potentially uninitialized local variable - 'hostaddr' used - url.c : error C4703: potentially uninitialized local pointer variable - 'hostaddr' used - - That could actually only happen if both `conn->bits.proxy` and - `CURL_DISABLE_PROXY` were enabled. - Initialize it to NULL to silence the warning. - - Closes https://github.com/curl/curl/pull/5638 - -Daniel Stenberg (1 Jul 2020) -- RELEASE-NOTES: synced - -Version 7.71.1 (30 Jun 2020) - -Daniel Stenberg (30 Jun 2020) -- RELEASE-NOTES: curl 7.71.1 - -- THANKS: add contributors to 7.71.1 - -- scripts/copyright.pl: skip .dcignore - -- Revert "multi: implement wait using winsock events" - - This reverts commit 8bc25c590e530de87595d1bb3577f699eb1309b9. - - That commit (from #5397) introduced a regression in 7.71.0. - - Reported-by: tmkk on github - Fixes #5631 - Closes #5632 - -- TODO: Add flag to specify download directory - -- TODO: return code to CURLMOPT_PUSHFUNCTION to fail connection - -- cirrus-ci: disable FreeBSD 13 (again) - - It has been failing for a good while again. This time we better leave it - disabled until we have more reason to believe it behaves. - - Closes #5628 - -- ngtcp2: sync with current master - - ngtcp2 added two new callbacks - - Reported-by: Lucien Zürcher - Fixes #5624 - Closes #5627 - -- examples/multithread.c: call curl_global_cleanup() - - Reported-by: qiandu2006 on github - Fixes #5622 - Closes #5623 - -- vtls: compare cert blob when finding a connection to reuse - - Reported-by: Gergely Nagy - Fixes #5617 - Closes #5619 - -- RELEASE-NOTES: synced - -- terminology: call them null-terminated strings - - Updated terminology in docs, comments and phrases to refer to C strings - as "null-terminated". Done to unify with how most other C oriented docs - refer of them and what users in general seem to prefer (based on a - single highly unscientific poll on twitter). - - Reported-by: coinhubs on github - Fixes #5598 - Closes #5608 - -- http: fix proxy auth with blank password - - Regression in 7.71.0 - - Added test case 346 to verify. - - Reported-by: Kristoffer Gleditsch - Fixes #5613 - Closes #5616 - -- .dcignore: ignore tests and docs directories - - This is a config file for deepcode.ai, a static code analyzer. - -Jay Satiro (26 Jun 2020) -- tool_cb_hdr: Fix etag warning output and return code - - - Return 'failure' on failure, to follow the existing style. - - - Put Warning: and the warning message on the same line. - - Ref: https://github.com/curl/curl/issues/5610 - - Closes https://github.com/curl/curl/pull/5612 - -Daniel Stenberg (26 Jun 2020) -- CURLOPT_READFUNCTION.3: provide the upload data size up front - - Assisted-by: Jay Satiro - Closes #5607 - -- test1539: do a HTTP 1.0 POST without a set size (fails) - - Attempt to reproduce #5593. Test case 1514 is very similar but uses - HTTP/1.1 and thus switches to chunked. - - Closes #5595 - -- [Baruch Siach brought this change] - - mbedtls: fix build with disabled proxy support - - Don't reference fields that do not exist. Fixes build failure: - - vtls/mbedtls.c: In function 'mbed_connect_step1': - vtls/mbedtls.c:249:54: error: 'struct connectdata' has no member named 'http_proxy' - - Closes #5615 - -- codeql-analysis.yml: fix the 'languages' setting - - It needs a 'with:' in front of it. - -GitHub (26 Jun 2020) -- [Daniel Stenberg brought this change] - - gtihub: codeql-analysis.yml - - enables code security scanning with github actions - -Daniel Stenberg (25 Jun 2020) -- tests: verify newline in username and password for HTTP - - test 1296 is a simply command line test - - test 1910 is a libcurl test including a redirect - -- url: allow user + password to contain "control codes" for HTTP(S) - - Reported-by: Jon Johnson Jr - Fixes #5582 - Closes #5592 - -- escape: make the URL decode able to reject only %00 bytes - - ... or all "control codes" or nothing. - - Assisted-by: Nicolas Sterchele - -- http2: set the correct URL in pushed transfers - - ...previously CURLINFO_EFFECTIVE_URL would report the URL of the - original "mother transfer", not the actually pushed resource. - - Reported-by: Jonathan Cardoso Machado - Fixes #5589 - Closes #5591 - -Jay Satiro (25 Jun 2020) -- [Javier Blazquez brought this change] - - openssl: Fix compilation on Windows when ngtcp2 is enabled - - - Include wincrypt before OpenSSL includes so that the latter can - properly handle any conflicts between the two. - - Closes https://github.com/curl/curl/pull/5606 - -Daniel Stenberg (25 Jun 2020) -- test543: extended to verify zero length input - - As was reported in #5601 - -- escape: zero length input should return a zero length output - - Regression added in 7.71.0. - - Fixes #5601 - Reported-by: Kristoffer Gleditsch - Closes #5602 - -- Curl_inet_ntop: always check the return code - - Reported-by: Siva Sivaraman - Fixes #5412 - Closes #5597 - -- sendf: improve the message on client write errors - - Replace "Failed writing body (X != Y)" with - "Failure writing output to destination". Possibly slightly less cryptic. - - Reported-by: coinhubs on github - Fixes #5594 - Closes #5596 - -- RELEASE-NOTES: synced - -- curlver: start working on 7.71.1 - -- [Denis Baručić brought this change] - - DYNBUF.md: fix a typo: trail => tail - - Closes #5599 - -Version 7.71.0 (23 Jun 2020) - -Daniel Stenberg (23 Jun 2020) -- RELEASE-NOTES: curl 7.71.0 release - -- THANKS: curl 7.71.0 additions - -- url: make sure pushed streams get an allocated download buffer - - Follow-up to c4e6968127e876b0 - - When a new transfer is created, as a resuly of an acknowledged push, - that transfer needs a download buffer allocated. - - Closes #5590 - -Jay Satiro (22 Jun 2020) -- openssl: Don't ignore CA paths when using Windows CA store - - This commit changes the behavior of CURLSSLOPT_NATIVE_CA so that it does - not override CURLOPT_CAINFO / CURLOPT_CAPATH, or the hardcoded default - locations. Instead the CA store can now be used at the same time. - - The change is due to the impending release. The issue is still being - discussed. The behavior of CURLSSLOPT_NATIVE_CA is subject to change and - is now documented as experimental. - - Ref: bc052cc (parent commit) - Ref: https://github.com/curl/curl/issues/5585 - -- tool_operate: Don't use Windows CA store as a fallback - - Background: - - 148534d added CURLSSLOPT_NATIVE_CA to use the Windows OS certificate - store in libcurl w/ OpenSSL on Windows. CURLSSLOPT_NATIVE_CA overrides - CURLOPT_CAINFO if both are set. The curl tool will fall back to - CURLSSLOPT_NATIVE_CA if it could not find a certificate bundle to set - via CURLOPT_CAINFO. - - Problem: - - libcurl may be built with hardcoded paths to a certificate bundle or - directory, and if CURLSSLOPT_NATIVE_CA is used then those paths are - ignored. - - Solution: - - A solution is still being discussed but since there's an impending - release this commit removes using CURLSSLOPT_NATIVE_CA in the curl tool. - - Ref: https://github.com/curl/curl/issues/5585 - -- openssl: Fix CA fallback logic for OpenSSL 3.0 build - - Prior to this change I assume a build error would occur when - CURL_CA_FALLBACK was used. - - Closes https://github.com/curl/curl/pull/5587 - -Daniel Stenberg (22 Jun 2020) -- copyright: update mismatched copyright years - -- test1460: verify that -Ji is not ok - -- tool_getparam: -i is not OK if -J is used - - Reported-by: sn on hackerone - Bug: https://curl.haxx.se/docs/CVE-2020-8177.html - -- [Peter Wu brought this change] - - CMake: ignore INTERFACE_LIBRARY targets for pkg-config file - - Reviewed-by: Marcel Raad - Fixes #5512 - Closes #5517 - -- [Valentyn Korniienko brought this change] - - multibyte: Fixed access-> waccess to file for Windows Plarform - - Reviewed-by: Marcel Raad - Closes #5580 - -- altsvc: bump to h3-29 - - Closes #5584 - -- urlglob: treat literal IPv6 addresses with zone IDs as a host name - - ... and not as a "glob". Now done by passing the supposed host to the - URL parser which supposedly will do a better job at identifying "real" - numerical IPv6 addresses. - - Reported-by: puckipedia on github - Fixes #5576 - Closes #5579 - -- test1179: verify error message for non-existing cmdline option - -- tool_getparam: repair the error message for unknown flag - - Follow-up to 9e5669f3880674 - Detected by Coverity CID 1464582 ("Logically dead code") - - Closes #5577 - -- FILEFORMAT: describe verify/stderr - -- connect: improve happy eyeballs handling - - For QUIC but also for regular TCP when the second family runs out of IPs - with a failure while the first family is still trying to connect. - - Separated the timeout handling for IPv4 and IPv6 connections when they - both have a number of addresses to iterate over. - -- ngtcp2: never call fprintf() in lib code in release version - -- ngtcp2: fix happy eyeballs quic connect crash - - Reported-by: Peter Wu - Fixes #5565 - Closes #5568 - -- select: remove the unused ELAPSED_MS() macro - - Closes #5573 - -Marc Hoersken (17 Jun 2020) -- [rcombs brought this change] - - 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. - - Reviewed-by: Gergely Nagy - Reviewed-by: Marc Hörsken - - Closes #5397 - -Daniel Stenberg (17 Jun 2020) -- manpage: add three missing environment variables - - CURL_SSL_BACKEND, QLOGDIR and SSLKEYLOGFILE - - Closes #5571 - -- RELEASE-NOTES: synced - -- configure: for wolfSSL, check for the DES func needed for NTLM - - Also adds pkg-config support for the wolfSSL detection. - -- [Ruurd Beerstra brought this change] - - ntlm: enable NTLM support with wolfSSL - - When wolfSSL is built with its OpenSSL API layer, it fetures the same DES* - functions that OpenSSL has. This change take advantage of that. - - Co-authored-by: Daniel Stenberg - Closes #5556 - Fixes #5548 - -- http: move header storage to Curl_easy from connectdata - - Since the connection can be used by many independent requests (using - HTTP/2 or HTTP/3), things like user-agent and other transfer-specific - data MUST NOT be kept connection oriented as it could lead to requests - getting the wrong string for their requests. This struct data was - lingering like this due to old HTTP1 legacy thinking where it didn't - mattered.. - - Fixes #5566 - Closes #5567 - -- CODE_REVIEW.md: how to do code reviews in curl - - Assisted-by: Daniel Gustafsson - Assisted-by: Rich Salz - Assisted-by: Hugo van Kemenade - Assisted-by: James Fuller - Assisted-by: Marc Hörsken - Assisted-by: Jay Satiro - - Closes #5555 - -- altsvc: remove the num field from the altsvc struct - - It was superfluous since we have the list.size alredy - - Reported-by: Jay Satiro - Fixes #5553 - Closes #5563 - -- version.d: expanded and alpha-sorted - - Added a few missing features not previously mentioned. Ordered them - alphabetically. - - Closes #5558 - -- ABI.md: rename to .md and polish the markdown - - Closes #5562 - -- HELP-US: add a section for "smaller tasks" - - The point of this section is to meet the CII Best Practices gold level - critera: - - "The project MUST clearly identify small tasks that can be performed by - new or casual contributors" - - Closes #5560 - -- TODO: retry on the redirected-to URL - - Closes #5462 - -- mailmap: Nicolas Sterchele - -- [Nicolas Sterchele brought this change] - - TODO: remove 19.3 section title - - Follow-up to ad6416986755e417c66e2c6, which caused wrong formatting on - curl documentation website - - Closes #5561 - -- [Martin V brought this change] - - test1560: avoid possibly negative association in wording - - Closes #5549 - -- share: don't set the share flag it something fails - - When asking for a specific feature to be shared in the share object, - that bit was previously set unconditionally even if the shared feature - failed or otherwise wouldn't work. - - Closes #5554 - -- buildconf: remove -print from the find command that removes files - - It's just too annoying and unnecessary to get a long list of files shown - -- RELEASE-NOTES: synced - -- wording: avoid blacklist/whitelist stereotypes - - Instead of discussing if there's value or meaning (implied or not) in - the colors, let's use words without the same possibly negative - associations. - - Closes #5546 - -Jay Satiro (9 Jun 2020) -- tool_getparam: fix memory leak in parse_args - - Prior to this change in Windows Unicode builds most parsed options would - not be freed. - - Found using _CrtDumpMemoryLeaks(). - - Ref: https://github.com/curl/curl/issues/5545 - -Daniel Stenberg (8 Jun 2020) -- socks: detect connection close during handshake - - The SOCKS4/5 state machines weren't properly terminated when the proxy - connection got closed, leading to a busy-loop. - - Reported-By: zloi-user on github - Fixes #5532 - Closes #5542 - -- [James Fuller brought this change] - - multi: add defensive check on data->multi->num_alive - - Closes #5540 - -- Curl_addrinfo: use one malloc instead of three - - To reduce the amount of allocations needed for creating a Curl_addrinfo - struct, make a single larger malloc instead of three separate smaller - ones. - - Closes #5533 - -- [Alessandro Ghedini brought this change] - - quiche: update SSLKEYLOGFILE support - - quiche now requires the application to explicitly set the keylog path - for each connection, rather than reading the environment variable - itself. - - Closes #5541 - -- tests: add two simple tests for --login-options - - Test 895 and 896 - as a follow-up to a3e972313b - - Closes #5539 - -- ngtcp2: update with recent API changes - - Syncs with ngtcp2 commit 7e9a917d386d98 merged June 7 2020. - - Assisted-by: Tatsuhiro Tsujikawa - Closes #5538 - -- [James Fuller brought this change] - - socks: remove unreachable breaks in socks.c and mime.c - - Closes #5537 - -- tool_cfgable: free login_options at exit - - Memory leak - Reported-by: Geeknik Labs - Fixes #5535 - Closes #5536 - -- libssh2: keep sftp errors as 'unsigned long' - - Remove weird work-around for storing the SFTP errors as int instead of - the "unsigned long" that libssh2 actually returns for SFTP errors. - - Closes #5534 - -Marc Hoersken (6 Jun 2020) -- timeouts: move ms timeouts to timediff_t from int and long - - Now that all functions in select.[ch] take timediff_t instead - of the limited int or long, we can remove type conversions - and related preprocessor checks to silence compiler warnings. - - Avoiding conversions from time_t was already done in 842f73de. - - Based upon #5262 - Supersedes #5214, #5220 and #5221 - Follow up to #5343 and #5479 - Closes #5490 - -Daniel Stenberg (6 Jun 2020) -- [François Rigault brought this change] - - openssl: set FLAG_TRUSTED_FIRST unconditionally - - On some systems, openssl 1.0.x is still the default, but it has been - patched to contain all the recent security fixes. As a result of this - patching, it is possible for macro X509_V_FLAG_NO_ALT_CHAINS to be - defined, while the previous behavior of openssl to not look at trusted - chains first, remains. - - Fix it: ensure X509_V_FLAG_TRUSTED_FIRST is always set, do not try to - probe for the behavior of openssl based on the existence ofmacros. - - Closes #5530 - -- server/util: fix logmsg format using curl_off_t argument - - ... this caused segfaults on armv7. - - Regression added in dd0365d560aea5a (7.70.0) - - Reviewed-by: Jay Satiro - Closes #5529 - -- RELEASE-NOTES: synced - -- [Cherish98 brought this change] - - socks: fix expected length of SOCKS5 reply - - Commit 4a4b63d forgot to set the expected SOCKS5 reply length when the - reply ATYP is X'01'. This resulted in erroneously expecting more bytes - when the request length is greater than the reply length (e.g., when - remotely resolving the hostname). - - Closes #5527 - -Marc Hoersken (5 Jun 2020) -- .gitignore: add directory containing the stats repo - - Since the new curl/stats repository is designed to be - checked out into the curl repository working tree as stats/ - it should be on the ignore list to aid in commit staging. - -Daniel Stenberg (5 Jun 2020) -- [Adnan Khan brought this change] - - HTTP3.md: clarify cargo build directory - - Cargo needs to be called from within the 'quiche' directory. - - Closes #5522 - -- user-agent.d: spell out what happens given a blank argument - - Closes #5525 - -- trailers: switch h1-trailer logic to use dynbuf - - In the continued effort to remove "manual" realloc schemes. - - Closes #5524 - -- CURLINFO_ACTIVESOCKET.3: clarify the description - - Reported-by: Jay Satiro - Fixes #5299 - Closes #5520 - -- mailmap: Don J Olmstead - -- configure: only strip first -L from LDFLAGS - - In the logic that works out if a given OpenSSL path works, it stripped - off a possibly leading -L flag using an incorrect sed pattern which - would remove all instances of -L in the string, including if the path - itself contained that two-letter sequence! - - The same pattern was used and is now updated in multiple places. Now it - only removes -L if it starts the strings. - - Reported-by: Mohamed Osama - Fixes #5519 - Closes #5521 - -Peter Wu (4 Jun 2020) -- quiche: advertise draft 28 support - - Fix the verbose message while at it, quiche currently supports draft - 27 and draft 28 simultaneously. - - Closes #5518 - -Daniel Stenberg (4 Jun 2020) -- KNOWN_BUGS: RTSP authentication breaks without redirect support - - Closes #4750 - -Jay Satiro (4 Jun 2020) -- projects: Add crypt32.lib to dependencies for all OpenSSL configs - - Windows project configurations that use OpenSSL with USE_WIN32_CRYPTO - need crypt32. - - Follow-up to 148534d which added CURLSSLOPT_NATIVE_CA for 7.71.0. - - The changes that are in this commit were made by script. - - Ref: https://gist.github.com/jay/a1861b50ecce2b32931237180f856e28 - - Closes https://github.com/curl/curl/pull/5516 - -Marc Hoersken (3 Jun 2020) -- CI/macos: fix 'is already installed' errors by using bundle - - Avoid failing CI builds due to nghttp2 being already installed. - - Closes #5513 - -Daniel Stenberg (3 Jun 2020) -- altsvc: fix 'dsthost' may be used uninitialized in this function - -- RELEASE-NOTES: synced - -- urldata: let the HTTP method be in the set.* struct - - When the method is updated inside libcurl we must still not change the - method as set by the user as then repeated transfers with that same - handle might not execute the same operation anymore! - - This fixes the libcurl part of #5462 - - Test 1633 added to verify. - - Closes #5499 - -- hostip: fix the memory-leak introduced in 67d2802 - - Fixes #5503 - Closes #5504 - -- test970: make it require proxy support - - This test verifies the -w %json output and the test case includes a full - generated "blob". If there's no proxy support built into libcurl, it - will return an error for proxy related info variables and they will not - be included in the json, thus causing a mismatch and this test fails. - - Reported-by: Marc Hörsken - Fixes #5501 - Closes #5502 - -- [Radoslav Georgiev brought this change] - - examples/http2-down/upload: add error checks - - If `index.html` does not exist in the directory from which the example - is invoked, the fopen(upload, "rb") invocation in `setup` would fail, - returning NULL. This value is subsequently passed as the FILE* argument - of the `fread` invocation in the `read_callback` function, which is the - actual cause of the crash (apparently `fread` assumes that argument to - be non-null). - - In addition, mitigate some possible crashes of similar origin. - - Closes #5463 - -- [kotoriのねこ brought this change] - - examples/ephiperfifo: turn off interval when setting timerfd - - Reported-by: therealhirudo on github - Fixes #5485 - Closes #5497 - -- [Saleem Abdulrasool brought this change] - - vtls: repair the build with `CURL_DISABLE_PROXY` - - `http_proxy` will not be available in `conndata` if `CURL_DISABLE_PROXY` - is enabled. Repair the build with that configuration. - - Follow-up to f3d501dc67 - - Closes #5498 - -- transfer: remove k->str NULL check - - "Null-checking k->str suggests that it may be null, but it has already - been dereferenced on all paths leading to the check" - and it can't - legally be NULL at this point. Remove check. - - Detected by Coverity CID 1463884 - - Closes #5495 - -Marc Hoersken (1 Jun 2020) -- select: always use Sleep in Curl_wait_ms on Win32 - - Since Win32 almost always will also have USE_WINSOCK, - we can reduce complexity and always use Sleep there. - - Assisted-by: Jay Satiro - Reviewed-by: Daniel Stenberg - - Follow up to #5343 - Closes #5489 - -Daniel Stenberg (31 May 2020) -- conncache: download buffer needs +1 size for trailing zero - - Follow-up to c4e6968127e - Detected by OSS-Fuzz: https://oss-fuzz.com/testcase-detail/5727799779524608 - -Marc Hoersken (31 May 2020) -- azure: use matrix strategy to avoid configuration redundancy - - This also includes the following changes: - - - Use the same timeout for all jobs on Linux (60 minutes) - and Windows (90 minutes) - - Use CLI stable apt-get install -y instead of apt install - which warns about that and run apt-get update first - - Enable MQTT for Windows msys2 builds instead of - legacy msys1 builds - - Add ./configure --prefix parameter to the msys2 builds - - The MSYSTEM environment variable is now preset inside - the container images for the msys2 builds - - Note: on Azure Pipelines the matrix strategy is basically - just a simple list of job copies and not really a matrix. - - Closes #5468 - -Daniel Stenberg (30 May 2020) -- build: disable more code/data when built without proxy support - - Added build to travis to verify - - Closes #5466 - -- url: alloc the download buffer at transfer start - - ... and free it as soon as the transfer is done. It removes the extra - alloc when a new size is set with setopt() and reduces memory for unused - easy handles. - - In addition: the closure_handle now doesn't use an allocated buffer at - all but the smallest supported size as a stack based one. - - Closes #5472 - -- timeouts: change millisecond timeouts to timediff_t from time_t - - For millisecond timers we like timediff_t better. Also, time_t can be - unsigned so returning a negative value doesn't work then. - - Closes #5479 - -Marc Hoersken (30 May 2020) -- select: add overflow checks for timeval conversions - - Using time_t and suseconds_t if suseconds_t is available, - long on Windows (maybe others in the future) and int elsewhere. - - Also handle case of ULONG_MAX being greater or equal to INFINITE. - - Assisted-by: Jay Satiro - Reviewed-by: Daniel Stenberg - - Part of #5343 - -- select: use timediff_t instead of time_t and int for timeout_ms - - Make all functions in select.[ch] take timeout_ms as timediff_t - which should always be large enough and signed on all platforms - to take all possible timeout values and avoid type conversions. - - Reviewed-by: Jay Satiro - Reviewed-by: Daniel Stenberg - - Replaces #5107 and partially #5262 - Related to #5240 and #5286 - Closes #5343 - -- unit1604.c: fix implicit conv from 'SANITIZEcode' to 'CURLcode' - - GCC 10 warns about this with warning: implicit conversion - from 'SANITIZEcode' to 'CURLcode' [-Wenum-conversion] - - Since 'expected_result' is not really of type 'CURLcode' and - it is not exposed in any way, we can just use 'SANITIZEcode'. - - Reviewed-by: Daniel Stenberg - Reviewed-by: Marcel Raad - - Closes #5476 - -- tests/libtest: fix undefined reference to 'curlx_win32_fopen' - - Since curl_setup.h now makes use of curlx_win32_fopen for Win32 - builds with USE_WIN32_LARGE_FILES or USE_WIN32_SMALL_FILES defined, - we need to include the relevant files for tests using fopen, - because the libtest sources are also including curl_setup.h - - Reviewed-by: Marcel Raad - Reviewed-by: Daniel Stenberg - - Follow up to #3784 (ffdddb45d9) - Closes #5475 - -- appveyor: add non-debug plain autotools-based build - - This should enable us to catch linking issues with the - testsuite early, like the one described/fixed in #5475. - - Reviewed-by: Daniel Stenberg - Reviewed-by: Marcel Raad - - Closes #5477 - -Daniel Stenberg (29 May 2020) -- RELEASE-NOTES: synced - -- Revert "buildconf: use find -execdir" - - This partially reverts commit c712009838f44211958854de431315586995bc61. - - Keep the ares_ files removed but bring back the older way to run find, - to make it work with busybox's find, as apparently that's being used. - - Reported-by: Max Peal - Fixes #5483 - Closes #5484 - -- server/sws: fix asan warning on use of uninitialized variable - -- libssh2: improved error output for wrong quote syntax - - Reported-by: Werner Stolz - - Closes #5474 - -- mk-lib1521: generate code for testing BLOB options as well - - Follow-up to cac5374298b3 - - Closes #5478 - -- configure: repair the check if argv can be written to - - Due to bad escaping of the test code, the test wouldn't build and thus - result in a negative test result, which would lead to the unconditional - assumption that overwriting the arguments doesn't work and thus curl - would never hide credentials given in the command line, even when it - would otherwise be possible. - - Regression from commit 2d4c2152c (7.60.0) - - Reported-by: huzunhao on github - Fixes #5470 - Closes #5471 - -Peter Wu (28 May 2020) -- CMake: rebuild Makefile.inc.cmake when Makefile.inc changes - - Otherwise the build might fail due to missing source files, as - demonstrated by the recent keylog.c addition on an existing build dir. - - Closes #5469 - -Daniel Stenberg (28 May 2020) -- urldata: fix comments: Curl_done() is called multi_done() now - - ... since 575e885db - -Peter Wu (27 May 2020) -- ngtcp2: use common key log routine for better thread-safety - - Tested with ngtcp2 built against the OpenSSL library. Additionally - tested with MultiSSL (NSS for TLS and ngtcp2+OpenSSL for QUIC). - - The TLS backend (independent of QUIC) may or may not already have opened - the keylog file before. Therefore Curl_tls_keylog_open is always called - to ensure the file is open. - -- wolfssl: add SSLKEYLOGFILE support - - Tested following the same curl and tshark commands as in commit - "vtls: Extract and simplify key log file handling from OpenSSL" using - WolfSSL v4.4.0-stable-128-g5179503e8 from git master built with - `./configure --enable-all --enable-debug CFLAGS=-DHAVE_SECRET_CALLBACK`. - - Full support for this feature requires certain wolfSSL build options, - see "Availability note" in lib/vtls/wolfssl.c for details. - - Closes #5327 - -- vtls: Extract and simplify key log file handling from OpenSSL - - Create a set of routines for TLS key log file handling to enable reuse - with other TLS backends. Simplify the OpenSSL backend as follows: - - - Drop the ENABLE_SSLKEYLOGFILE macro as it is unconditionally enabled. - - Do not perform dynamic memory allocation when preparing a log entry. - Unless the TLS specifications change we can suffice with a reasonable - fixed-size buffer. - - Simplify state tracking when SSL_CTX_set_keylog_callback is - unavailable. My original sslkeylog.c code included this tracking in - order to handle multiple calls to SSL_connect and detect new keys - after renegotiation (via SSL_read/SSL_write). For curl however we can - be sure that a single master secret eventually becomes available - after SSL_connect, so a simple flag is sufficient. An alternative to - the flag is examining SSL_state(), but this seems more complex and is - not pursued. Capturing keys after server renegotiation was already - unsupported in curl and remains unsupported. - - Tested with curl built against OpenSSL 0.9.8zh, 1.0.2u, and 1.1.1f - (`SSLKEYLOGFILE=keys.txt curl -vkso /dev/null https://localhost:4433`) - against an OpenSSL 1.1.1f server configured with: - - # Force non-TLSv1.3, use TLSv1.0 since 0.9.8 fails with 1.1 or 1.2 - openssl s_server -www -tls1 - # Likewise, but fail the server handshake. - openssl s_server -www -tls1 -Verify 2 - # TLS 1.3 test. No need to test the failing server handshake. - openssl s_server -www -tls1_3 - - Verify that all secrets (1 for TLS 1.0, 4 for TLS 1.3) are correctly - written using Wireshark. For the first and third case, expect four - matches per connection (decrypted Server Finished, Client Finished, HTTP - Request, HTTP Response). For the second case where the handshake fails, - expect a decrypted Server Finished only. - - tshark -i lo -pf tcp -otls.keylog_file:keys.txt -Tfields \ - -eframe.number -eframe.time -etcp.stream -e_ws.col.Info \ - -dtls.port==4433,http -ohttp.desegment_body:FALSE \ - -Y 'tls.handshake.verify_data or http' - - A single connection can easily be identified via the `tcp.stream` field. - -Daniel Stenberg (27 May 2020) -- FILEFORMAT: add more features that tests can depend on - -- [Michael Kaufmann brought this change] - - transfer: close connection after excess data has been read - - For HTTP 1.x, it's a protocol error when the server sends more bytes - than announced. If this happens, don't reuse the connection, because the - start position of the next response is undefined. - - Closes #5440 - -- [Estanislau Augé-Pujadas brought this change] - - Revert "ssh: ignore timeouts during disconnect" - - This reverts commit f31760e63b4e9ef1eb25f8f211390f8239388515. Shipped in - curl 7.54.1. - - Bug: https://curl.haxx.se/mail/lib-2020-05/0068.html - Closes #5465 - -- urldata: connect related booleans live in struct ConnectBits - - And remove a few unused booleans! - - Closes #5461 - -- hostip: on macOS avoid DoH when given a numerical IP address - - When USE_RESOLVE_ON_IPS is set (defined on macOS), it means that - numerical IP addresses still need to get "resolved" - but not with DoH. - - Reported-by: Viktor Szakats - Fixes #5454 - Closes #5459 - -- ngtcp2: cleanup memory when failing to connect - - Reported-by: Peter Wu - Fixes #5447 (the ngtcp2 side of it) - Closes #5451 - -- quiche: clean up memory properly when failing to connect - - Addresses the quiche side of #5447 - Reported-by: Peter Wu - Closes #5450 - -- cleanup: use a single space after equals sign in assignments - -- url: accept "any length" credentials for proxy auth - - They're only limited to the maximum string input restrictions, not to - 256 bytes. - - Added test 1178 to verify - - Reported-by: Will Roberts - Fixes #5448 - Closes #5449 - -- [Maksim Stsepanenka brought this change] - - test1167: fixes in badsymbols.pl - - Closes #5442 - -- altsvc: fix parser for lines ending with CRLF - - Fixed the alt-svc parser to treat a newline as end of line. - - The unit tests in test 1654 were done without CRLF and thus didn't quite - match the real world. Now they use CRLF as well. - - Reported-by: Peter Wu - Assisted-by: Peter Wu - Assisted-by: Jay Satiro - Fixes #5445 - Closes #5446 - -Viktor Szakats (25 May 2020) -- all: fix codespell errors - - Reviewed-by: Jay Satiro - Reviewed-by: Daniel Stenberg - Closes https://github.com/curl/curl/pull/5452 - -Peter Wu (25 May 2020) -- ngtcp2: fix build with current ngtcp2 master implementing draft 28 - - Based on client.cc changes from ngtcp2. Tested with current git master, - ngtcp2 commit c77d5731ce92, nghttp3 commit 65ff479d4380. - - Fixes #5444 - Closes #5443 - -Daniel Stenberg (25 May 2020) -- RELEASE-NOTES: synced - - moved the new setopts up to a "change" - -- RELEASE-NOTES: synced - -- copyright: updated year ranges out of sync - - ... and whitelisted a few more files in the the copyright.pl script. - -- [Gilles Vollant brought this change] - - setopt: add CURLOPT_PROXY_ISSUERCERT(_BLOB) for coherency - - Closes #5431 - -- curl: remove -J "informational" written on stdout - - curl would previously show "curl: Saved to filename 'name from header'" - if -J was used and a name was picked from the Content-Disposition - header. That output could interfer with other stdout output, such as -w. - - This commit removes that output line. - Bug: https://curl.haxx.se/mail/archive-2020-05/0044.html - Reported-by: Коваленко Анатолий Викторович - Closes #5435 - -Peter Wu (22 May 2020) -- travis: simplify quiche build instructions wrt boringssl - - quiche builds boringssl as static library, reuse that instead of - building another shared library. - - Closes #5438 - -- configure: fix pthread check with static boringssl - - A shared boringssl/OpenSSL library requires -lcrypto only for linking. - A static build additionally requires `-ldl -lpthread`. In the latter - case `-lpthread` is added to LIBS which prevented `-pthread` from being - added to CFLAGS. Clear LIBS to fix linking failures for libtest tests. - -Daniel Stenberg (22 May 2020) -- Revert "sendf: make failf() use the mvsnprintf() return code" - - This reverts commit 74623551f306990e70c7c5515b88972005604a74. - - Instead mark the function call with (void). Getting the return code and - using it instead triggered Coverity warning CID 1463596 because - snprintf() can return a negative value... - - Closes #5441 - -- typecheck-gcc.h: CURLINFO_PRIVATE does not need a 'char *' - - Reported-by: Billyzou0741326 on github - Fixes #5432 - Closes #5436 - -- tests/server/util.h: add extern to silence compiler warning - - Follow-up from a3b0699d5c1 - -- typecheck-gcc.h: fix the OFF_T check - - The option number also needs to be less than CURLOPTTYPE_BLOB. - - Follow-up to cac5374298 - Reported-by: Jeroen Ooms - Bug: https://github.com/curl/curl/pull/5365#issuecomment-631084114 - -- TODO: --dry-run - - Closes #5426 - -- TODO: Ratelimit or wait between serial requests - - Closes #5406 - -- tool_paramhlp: fixup C89 mistake - - Follow-up to c5f0a9db22. - -- [Siva Sivaraman brought this change] - - tool_paramhlp: fixed potentially uninitialized strtol() variable - - Seems highly unlikely to actually be possible, but better safe than - sorry. - - Closes #5417 - -- [Siva Sivaraman brought this change] - - tool_operate: fixed potentially uninitialized variables - - ... in curl_easy_getinfo() calls. They're harmless but clearing the - variables makes the code safer and comforts the reader. - - Closes #5416 - -- sha256: move assign to the declaration line - - Follow-up to fae30656. Should've been squashed with that commit... - -- [Siva Sivaraman brought this change] - - sha256: fixed potentially uninitialized variable - - Closes #5414 - -- sendf: make failf() use the mvsnprintf() return code - - ... and avoid a strlen() call. Fixes a MonocleAI warning. - - Reported-by: MonocleAI - Fixes #5413 - Closes #5420 - -- hostip: make Curl_printable_address not return anything - - It was not used much anyway and instead we let it store a blank buffer - in case of failure. - - Reported-by: MonocleAI - Fixes #5411 - Closes #5418 - -- ftp: mark return-ignoring calls to Curl_GetFTPResponse with (void) - - They're done on purpose, make that visible in the code. - Reported-by: MonocleAI - Fixes #5412 - Closes #549 - -- TODO: forbid TLS post-handshake auth and do TLS record padding - - Closes #5396 - Closes #5398 - -- RELEASE-NOTES: synced - -- dynbuf: return NULL when there's no buffer length - - ... as returning a "" is not a good idea as the string is supposed to be - allocated and returning a const string will cause issues. - - Reported-by: Brian Carpenter - Follow-up to ed35d6590e72c - Closes #5405 - -Peter Wu (16 May 2020) -- travis: upgrade to bionic, clang-9, improve readability - - Changes, partially to reduce build failures from external dependencies: - - Upgrade Ubuntu and drop unnecessary third-party repos. - - Properly clone apt config to ensure retries. - - Upgrade to clang-9 from the standard repos. - - Use Ubuntu 20.04 focal for the libssh build, use of ssh_get_publickey - fails on -Werror=deprecated-declarations in Ubuntu 18.04. Do not use - focal everywhere yet since Travis CI has not documented this option. - In focal, python-impacket (Py2.7) has been removed, leaving only - python3-impacket. Since it is only needed for SMB tests and not SSH, - skip it for the libssh job since it might need more work. - - apt: Remove gcc-8 and libstdc++-8-dev, already installed via g++-8. - - Non-functional cleanups: - - Simplify test matrix, drop redundant os and compiler keys. - - Deprecation fixes: remove sudo, rename matrix -> jobs. - - Every job has an 'env' key, put this key first in a list item. - - Closes #5370 - -- travis: whitespace-only changes for consistency - - Automatically apply a consistent indentation with: - - python3 -c 'from ruamel.yaml import YAML;y=YAML();d=y.load(open(".travis.yml"));y.width=500;y.dump(d,open(".travis.yml.new","w"))' - - followed by manually re-indenting three comments. - - Closes #5370 - -- CMake: add libssh build support - - Closes #5372 - -Daniel Stenberg (15 May 2020) -- KNOWN_BUGS: wolfssh: publickey auth doesn't work - - Closes #4820 - -- KNOWN_BUGS: OS400 port requires deprecated IBM library - - Closes #5176 - -- [Vyron Tsingaras brought this change] - - http2: keep trying to send pending frames after req.upload_done - - Fixes #1410 - Closes #5401 - -- [Gilles Vollant brought this change] - - setopt: support certificate options in memory with struct curl_blob - - This change introduces a generic way to provide binary data in setopt - options, called BLOBs. - - This change introduces these new setopts: - - CURLOPT_ISSUERCERT_BLOB, CURLOPT_PROXY_SSLCERT_BLOB, - CURLOPT_PROXY_SSLKEY_BLOB, CURLOPT_SSLCERT_BLOB and CURLOPT_SSLKEY_BLOB. - - Reviewed-by: Daniel Stenberg - Closes #5357 - -- source cleanup: remove all custom typedef structs - - - Stick to a single unified way to use structs - - Make checksrc complain on 'typedef struct {' - - Allow them in tests, public headers and examples - - - Let MD4_CTX, MD5_CTX, and SHA256_CTX typedefs remain as they actually - typedef different types/structs depending on build conditions. - - Closes #5338 - -- travis: remove the .checksrc fiddling - -- ftp: make domore_getsock() return the secondary socket properly - - Previously, after PASV and immediately after the data connection has - connected, the function would only return the control socket to wait for - which then made the data connection simply timeout and not get polled - correctly. This become obvious when running test 1631 and 1632 event- - based. - -- test1632: verify FTP through HTTPS-proxy with connection re-use - -- test1631: verify FTP download through HTTPS-proxy - -- sws: as last resort, get test number from server cmd file - - If it can't be found in the request. Also support --cmdfile to set it to - a custom file name. - - runtests.pl always writes this file with the test number in it since a - while back. - -- ftp: shut down the secondary connection properly when SSL is used - - Reported-by: Neal Poole - Fixes #5340 - Closes #5385 - -Marcel Raad (14 May 2020) -- KNOWN_BUGS: adapt 5.5 to recent changes - - It only applies to non-Unicode builds now. - Also merge 5.10 into it as it's effectively a duplicate. - - Closes https://github.com/curl/curl/pull/3784 - -- curl_setup: support Unicode functions to open files on Windows - - Use them only if `_UNICODE` is defined, in which case command-line - arguments have been converted to UTF-8. - - Closes https://github.com/curl/curl/pull/3784 - -- tool: support UTF-16 command line on Windows - - - use `wmain` instead of `main` when `_UNICODE` is defined [0] - - define `argv_item_t` as `wchar_t *` in this case - - use the curl_multibyte gear to convert the command-line arguments to - UTF-8 - - This makes it possible to pass parameters with characters outside of - the current locale on Windows, which is required for some tests, e.g. - the IDN tests. Out of the box, this currently only works with the - Visual Studio project files, which default to Unicode, and winbuild - with the `ENABLE_UNICODE` option. - - [0] https://devblogs.microsoft.com/oldnewthing/?p=40643 - - Ref: https://github.com/curl/curl/issues/3747 - Closes https://github.com/curl/curl/pull/3784 - -- curl_multibyte: add to curlx - - This will also be needed in the tool and tests. - - Ref: https://github.com/curl/curl/pull/3758#issuecomment-482197512 - Closes https://github.com/curl/curl/pull/3784 - -Daniel Stenberg (14 May 2020) -- url: make the updated credentials URL-encoded in the URL - - Found-by: Gregory Jefferis - Reported-by: Jeroen Ooms - Added test 1168 to verify. Bug spotted when doing a redirect. - Bug: https://github.com/jeroen/curl/issues/224 - Closes #5400 - -- tests: add https-proxy support to the test suite - - Initial test 1630 added with basic HTTPS-proxy use. HTTPS-proxy is like - HTTP proxy but with a full TLS connection to the proxy. - - Closes #5399 - -- mailmap: James Fuller - -- [Major_Tom brought this change] - - vauth/cleartext: fix theoretical integer overflow - - Fix theoretical integer overflow in Curl_auth_create_plain_message. - - The security impact of the overflow was discussed on hackerone. We - agreed this is more of a theoretical vulnerability, as the integer - overflow would only be triggerable on systems using 32-bits size_t with - over 4GB of available memory space for the process. - - Closes #5391 - -Jay Satiro (13 May 2020) -- curl.1: Quote globbed URLs - - - Quote the globbing example URLs that contain characters [] {} since - otherwise they may be interpreted as shell metacharacters. - - Bug: https://github.com/curl/curl/issues/5388 - Reported-by: John Simpson - - Closes https://github.com/curl/curl/pull/5394 - -Daniel Stenberg (14 May 2020) -- checksrc: enhance the ASTERISKSPACE and update code accordingly - - Fine: "struct hello *world" - - Not fine: "struct hello* world" (and variations) - - Closes #5386 - -- docs/options-in-versions: which version added each cmdline option - - Added test 971 to verify that the list is in sync with the files in - cmdline-opts. The check also verifies that .d-files that uses Added: - specify the same version number as the options-in-versions file does. - - Closes #5381 - -- docs: unify protocol lists - - We boast support for 25 transfer protocols. Make sure the lists are - consistent - - Closes #5384 diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS index 69c3c11dca..91a9f3c396 100644 --- a/libs/libcurl/docs/THANKS +++ b/libs/libcurl/docs/THANKS @@ -45,6 +45,7 @@ Alan Pinstein Albert Chin-A-Young Albert Choy Alejandro Alvarez Ayllon +Alejandro Colomar Alejandro R. Sedeño Aleksandar Milivojevic Aleksey Tulinov @@ -72,6 +73,7 @@ Alex Rousskov Alex Samorukov Alex Suykov Alex Vinnik +Alex Xu Alexander Beedie Alexander Dyagilev Alexander Elgert @@ -98,6 +100,7 @@ Alfonso Martone Alfred Gebert Allen Pulsifer Alona Rossen +Amaury Denoyelle amishmm on github Amit Katyal Amol Pattekar @@ -129,6 +132,7 @@ Andreas Schuldei Andreas Streichardt Andreas Wurf Andrei Benea +Andrei Bica Andrei Cipu Andrei Karas Andrei Kurushin @@ -169,6 +173,7 @@ Anthon Pang Anthony Avina Anthony Bryan Anthony G. Basile +Anthony Ramine Antoine Aubert Antoine Calando Anton Bychkov @@ -193,6 +198,7 @@ Artak Galoyan Arthur Murray Arve Knudsen Arvid Norberg +arvids-kokins-bidstack on github asavah on github Ashish Shukla Ashwin Metpalli @@ -202,6 +208,7 @@ Ates Goral Augustus Saunders Austin Green Avery Fay +awesomenode on github Axel Tillequin Ayoub Boudhar b9a1 on github @@ -269,6 +276,7 @@ Bob Relyea Bob Richmond Bob Schader bobmitchell1956 on github +Bodo Bergmann Bogdan Nicula Brad Burdick Brad Fitzpatrick @@ -321,6 +329,7 @@ Camille Moncelier Caolan McNamara Captain Basil Carie Pointer +Carl Zogheib Carlo Cannas Carlo Marcelo Arenas Belón Carlo Teubner @@ -491,11 +500,14 @@ David Binderman David Blaikie David Byron David Cohen +David Demelier David E. Narváez David Earl David Eriksson David Garske +David Goerger David Houlder +David Hu David Hull David J Meyer David James @@ -610,6 +622,7 @@ Dániel Bakai Early Ehlinger Earnestly on github Eason-Yu on github +ebejan on github Ebenezer Ikonne Ed Morley Edgaras Janušauskas @@ -706,6 +719,7 @@ Felix Yan Feng Tu Fernando Muñoz Filip Salomonsson +Firefox OS Flameborn on github Flavio Medeiros Florian Pritz @@ -791,6 +805,7 @@ Greg Onufer Greg Pratt Greg Rowe Greg Zavertnik +Gregor Jasny Gregory Jefferis Gregory Nicholls Gregory Szorc @@ -901,6 +916,7 @@ Ivan Avdeev IvanoG on github Ivo Bellin Salarin iz8mbw on github +Jack Boos Yu Jack Zhang Jackarain on github Jacky Lam @@ -972,6 +988,7 @@ Jean-Louis Lemaire Jean-Marc Ranger Jean-Noël Rouvignac Jean-Philippe Barrette-LaPierre +Jean-Philippe Menil Jeff Connelly Jeff Hodges Jeff Johnson @@ -1026,6 +1043,7 @@ Joe Malicki Joe Mason Joel Chen Joel Depooter +Joel Teichroeb joey-l-us on github Jofell Gallardo Johan Anderson @@ -1035,6 +1053,7 @@ Johan van Selst Johannes Bauer Johannes Ernst Johannes G. Kristinsson +Johannes Lesr Johannes Schindelin John A. Bristor John Bradshaw @@ -1092,13 +1111,15 @@ Jonathan Cardoso Machado Jonathan Hseu Jonathan Moerman Jonathan Nieder +Jonathan Watt Jongki Suwandi -jonrumsey on github Joombalaya on github Joonas Kuorilehto +Jordan Brown Jose Alf Jose Kahan Josef Wolf +Joseph Chen Josh Bialkowski Josh Kapell joshhe on github @@ -1127,6 +1148,7 @@ Julien Chaffraix Julien Nabet Julien Royer Jun-ichiro itojun Hagino +Jun-ya Kato jungle-boogie on github Junho Choi Jurij Smakov @@ -1194,6 +1216,7 @@ Klaus Stein Klevtsov Vadim Kobi Gurkan Koen Dergent +kokke on github Konstantin Isakov Konstantin Kushnir kotoriのねこ @@ -1239,6 +1262,7 @@ Laurent Bonnans Laurent Rabret Lauri Kasanen Laurie Clark-Michalek +Lawrence Gripper Lawrence Matthews Lawrence Wagerfield Legoff Vincent @@ -1255,6 +1279,7 @@ Leon Breedt Leon Winter Leonardo Rosati Leonardo Taccari +Li Xinwei Liam Healy lijian996 on github Lijo Antony @@ -1312,6 +1337,7 @@ Mandy Wu Manfred Schwarb MAntoniak on github Manuel Massing +Manuj Bhatia Marc Aldorasi Marc Boucher Marc Deslauriers @@ -1441,6 +1467,7 @@ Michael Anti Michael Baentsch Michael Benedict Michael Brehm +Michael Brown Michael Calmer Michael Cronenworth Michael Curtis @@ -1449,6 +1476,7 @@ Michael Felt Michael Forney Michael Gmelin Michael Goffioul +Michael Hordijk Michael Jahn Michael Jerris Michael Kalinin @@ -1685,6 +1713,7 @@ Pedro Monreal Pedro Neves pendrek at hackerone Peng Li +Per Jensen Per Lundberg Per Malmberg Per Nilsson @@ -1860,6 +1889,7 @@ Robert Kolcun Robert Linden Robert Olson Robert Prag +Robert Ronto Robert Schumann Robert Weaver Robert Wruck @@ -2239,6 +2269,7 @@ Vlad Ureche Vladimir Grishchenko Vladimir Kotal Vladimir Lazarenko +Vladimir Varlamov Vlastimil Ovčáčík Vojtech Janota Vojtech Minarik @@ -2315,14 +2346,17 @@ Zhao Yisha Zhaoyang Wu Zhibiao Wu Zhouyihai Ding +ZimCodes on github zloi-user on github Zmey Petroff Zvi Har'El zzq1015 on github +Ádler Jonas Gross İsmail Dönmez Łukasz Domeradzki Štefan Kremeň Коваленко Анатолий Викторович Никита Дорохин +ウさん 不确定 加藤郁之 diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h index 71204ee327..bed8068b0b 100644 --- a/libs/libcurl/include/curl/curl.h +++ b/libs/libcurl/include/curl/curl.h @@ -155,7 +155,8 @@ typedef enum { CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */ CURLSSLBACKEND_MBEDTLS = 11, CURLSSLBACKEND_MESALINK = 12, - CURLSSLBACKEND_BEARSSL = 13 + CURLSSLBACKEND_BEARSSL = 13, + CURLSSLBACKEND_RUSTLS = 14 } curl_sslbackend; /* aliases for library clones and renames */ @@ -2078,6 +2079,15 @@ typedef enum { /* Parameters for V4 signature */ CURLOPT(CURLOPT_AWS_SIGV4, CURLOPTTYPE_STRINGPOINT, 305), + /* Same as CURLOPT_SSL_VERIFYPEER but for DOH (DNS-over-HTTPS) servers. */ + CURLOPT(CURLOPT_DOH_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 306), + + /* Same as CURLOPT_SSL_VERIFYHOST but for DOH (DNS-over-HTTPS) servers. */ + CURLOPT(CURLOPT_DOH_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 307), + + /* Same as CURLOPT_SSL_VERIFYSTATUS but for DOH (DNS-over-HTTPS) servers. */ + CURLOPT(CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 308), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -2751,8 +2761,9 @@ typedef enum { CURLINFO_RETRY_AFTER = CURLINFO_OFF_T + 57, CURLINFO_EFFECTIVE_METHOD = CURLINFO_STRING + 58, CURLINFO_PROXY_ERROR = CURLINFO_LONG + 59, + CURLINFO_REFERER = CURLINFO_STRING + 60, - CURLINFO_LASTONE = 59 + CURLINFO_LASTONE = 60 } CURLINFO; /* CURLINFO_RESPONSE_CODE is the new name for the option previously known as @@ -2953,6 +2964,7 @@ typedef struct curl_version_info_data curl_version_info_data; #define CURL_VERSION_ZSTD (1<<26) /* zstd features are present */ #define CURL_VERSION_UNICODE (1<<27) /* Unicode support on Windows */ #define CURL_VERSION_HSTS (1<<28) /* HSTS is supported */ +#define CURL_VERSION_GSASL (1<<29) /* libgsasl is supported */ /* * NAME curl_version_info() diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h index 81e9aa3429..ea137ef7ab 100644 --- a/libs/libcurl/include/curl/curlver.h +++ b/libs/libcurl/include/curl/curlver.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -26,16 +26,16 @@ a script at release-time. This was made its own header file in 7.11.2 */ /* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "1996 - 2020 Daniel Stenberg, <daniel@haxx.se>." +#define LIBCURL_COPYRIGHT "1996 - 2021 Daniel Stenberg, <daniel@haxx.se>." /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.75.0" +#define LIBCURL_VERSION "7.76.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 75 +#define LIBCURL_VERSION_MINOR 76 #define LIBCURL_VERSION_PATCH 0 /* This is the numeric version of the libcurl version number, meant for easier @@ -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 0x074b00 +#define LIBCURL_VERSION_NUM 0x074c00 /* * 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-02-03" +#define LIBCURL_TIMESTAMP "2021-03-31" #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 7677636521..d601dbdd21 100644 --- a/libs/libcurl/libcurl.vcxproj +++ b/libs/libcurl/libcurl.vcxproj @@ -353,6 +353,9 @@ <ClCompile Include="src\vauth\digest_sspi.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="src\vauth\gsasl.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="src\vauth\krb5_gssapi.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt index 9736e39e52..a58b47b865 100644 --- a/libs/libcurl/src/CMakeLists.txt +++ b/libs/libcurl/src/CMakeLists.txt @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -117,13 +117,16 @@ endif() if(WIN32) if(BUILD_SHARED_LIBS) - # Add "_imp" as a suffix before the extension to avoid conflicting with the statically linked "libcurl.lib" - set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib") + if(MSVC) + # Add "_imp" as a suffix before the extension to avoid conflicting with + # the statically linked "libcurl.lib" + set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib") + endif() endif() endif() target_include_directories(${LIB_NAME} INTERFACE - $<INSTALL_INTERFACE:include> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>) install(TARGETS ${LIB_NAME} diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in index 2960c281cf..c17ae17a51 100644 --- a/libs/libcurl/src/Makefile.in +++ b/libs/libcurl/src/Makefile.in @@ -234,17 +234,18 @@ am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \ am__dirstamp = $(am__leading_dot)dirstamp am__objects_2 = vauth/libcurl_la-cleartext.lo vauth/libcurl_la-cram.lo \ vauth/libcurl_la-digest.lo vauth/libcurl_la-digest_sspi.lo \ - vauth/libcurl_la-krb5_gssapi.lo vauth/libcurl_la-krb5_sspi.lo \ - vauth/libcurl_la-ntlm.lo vauth/libcurl_la-ntlm_sspi.lo \ - vauth/libcurl_la-oauth2.lo vauth/libcurl_la-spnego_gssapi.lo \ + vauth/libcurl_la-gsasl.lo vauth/libcurl_la-krb5_gssapi.lo \ + vauth/libcurl_la-krb5_sspi.lo vauth/libcurl_la-ntlm.lo \ + vauth/libcurl_la-ntlm_sspi.lo vauth/libcurl_la-oauth2.lo \ + vauth/libcurl_la-spnego_gssapi.lo \ vauth/libcurl_la-spnego_sspi.lo vauth/libcurl_la-vauth.lo am__objects_3 = vtls/libcurl_la-bearssl.lo vtls/libcurl_la-gskit.lo \ vtls/libcurl_la-gtls.lo vtls/libcurl_la-keylog.lo \ vtls/libcurl_la-mbedtls.lo \ vtls/libcurl_la-mbedtls_threadlock.lo \ vtls/libcurl_la-mesalink.lo vtls/libcurl_la-nss.lo \ - vtls/libcurl_la-openssl.lo vtls/libcurl_la-schannel.lo \ - vtls/libcurl_la-schannel_verify.lo \ + vtls/libcurl_la-openssl.lo vtls/libcurl_la-rustls.lo \ + vtls/libcurl_la-schannel.lo vtls/libcurl_la-schannel_verify.lo \ vtls/libcurl_la-sectransp.lo vtls/libcurl_la-vtls.lo \ vtls/libcurl_la-wolfssl.lo am__objects_4 = vquic/libcurl_la-ngtcp2.lo vquic/libcurl_la-quiche.lo \ @@ -324,7 +325,7 @@ am__objects_9 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \ libcurlu_la-wildcard.lo libcurlu_la-x509asn1.lo am__objects_10 = vauth/libcurlu_la-cleartext.lo \ vauth/libcurlu_la-cram.lo vauth/libcurlu_la-digest.lo \ - vauth/libcurlu_la-digest_sspi.lo \ + vauth/libcurlu_la-digest_sspi.lo vauth/libcurlu_la-gsasl.lo \ vauth/libcurlu_la-krb5_gssapi.lo \ vauth/libcurlu_la-krb5_sspi.lo vauth/libcurlu_la-ntlm.lo \ vauth/libcurlu_la-ntlm_sspi.lo vauth/libcurlu_la-oauth2.lo \ @@ -335,7 +336,8 @@ am__objects_11 = vtls/libcurlu_la-bearssl.lo vtls/libcurlu_la-gskit.lo \ vtls/libcurlu_la-mbedtls.lo \ vtls/libcurlu_la-mbedtls_threadlock.lo \ vtls/libcurlu_la-mesalink.lo vtls/libcurlu_la-nss.lo \ - vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-schannel.lo \ + vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-rustls.lo \ + vtls/libcurlu_la-schannel.lo \ vtls/libcurlu_la-schannel_verify.lo \ vtls/libcurlu_la-sectransp.lo vtls/libcurlu_la-vtls.lo \ vtls/libcurlu_la-wolfssl.lo @@ -604,6 +606,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ vauth/$(DEPDIR)/libcurl_la-cram.Plo \ vauth/$(DEPDIR)/libcurl_la-digest.Plo \ vauth/$(DEPDIR)/libcurl_la-digest_sspi.Plo \ + vauth/$(DEPDIR)/libcurl_la-gsasl.Plo \ vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo \ vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Plo \ vauth/$(DEPDIR)/libcurl_la-ntlm.Plo \ @@ -616,6 +619,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ vauth/$(DEPDIR)/libcurlu_la-cram.Plo \ vauth/$(DEPDIR)/libcurlu_la-digest.Plo \ vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Plo \ + vauth/$(DEPDIR)/libcurlu_la-gsasl.Plo \ vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo \ vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Plo \ vauth/$(DEPDIR)/libcurlu_la-ntlm.Plo \ @@ -645,6 +649,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ vtls/$(DEPDIR)/libcurl_la-mesalink.Plo \ vtls/$(DEPDIR)/libcurl_la-nss.Plo \ vtls/$(DEPDIR)/libcurl_la-openssl.Plo \ + vtls/$(DEPDIR)/libcurl_la-rustls.Plo \ vtls/$(DEPDIR)/libcurl_la-schannel.Plo \ vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo \ vtls/$(DEPDIR)/libcurl_la-sectransp.Plo \ @@ -659,6 +664,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo \ vtls/$(DEPDIR)/libcurlu_la-nss.Plo \ vtls/$(DEPDIR)/libcurlu_la-openssl.Plo \ + vtls/$(DEPDIR)/libcurlu_la-rustls.Plo \ vtls/$(DEPDIR)/libcurlu_la-schannel.Plo \ vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo \ vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo \ @@ -848,7 +854,6 @@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ USE_ARES = @USE_ARES@ USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ -USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@ USE_HYPER = @USE_HYPER@ USE_LIBRTMP = @USE_LIBRTMP@ USE_LIBSSH = @USE_LIBSSH@ @@ -863,9 +868,13 @@ USE_NGTCP2_CRYPTO_OPENSSL = @USE_NGTCP2_CRYPTO_OPENSSL@ USE_NSS = @USE_NSS@ USE_OPENLDAP = @USE_OPENLDAP@ USE_QUICHE = @USE_QUICHE@ +USE_RUSTLS = @USE_RUSTLS@ USE_SCHANNEL = @USE_SCHANNEL@ USE_SECTRANSP = @USE_SECTRANSP@ USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@ +USE_WIN32_CRYPTO = @USE_WIN32_CRYPTO@ +USE_WIN32_LARGE_FILES = @USE_WIN32_LARGE_FILES@ +USE_WIN32_SMALL_FILES = @USE_WIN32_SMALL_FILES@ USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@ USE_WOLFSSH = @USE_WOLFSSH@ USE_WOLFSSL = @USE_WOLFSSL@ @@ -1007,6 +1016,7 @@ LIB_VAUTH_CFILES = \ vauth/cram.c \ vauth/digest.c \ vauth/digest_sspi.c \ + vauth/gsasl.c \ vauth/krb5_gssapi.c \ vauth/krb5_sspi.c \ vauth/ntlm.c \ @@ -1031,6 +1041,7 @@ LIB_VTLS_CFILES = \ vtls/mesalink.c \ vtls/nss.c \ vtls/openssl.c \ + vtls/rustls.c \ vtls/schannel.c \ vtls/schannel_verify.c \ vtls/sectransp.c \ @@ -1047,6 +1058,7 @@ LIB_VTLS_HFILES = \ vtls/mesalink.h \ vtls/nssg.h \ vtls/openssl.h \ + vtls/rustls.h \ vtls/schannel.h \ vtls/sectransp.h \ vtls/vtls.h \ @@ -1442,6 +1454,8 @@ vauth/libcurl_la-digest.lo: vauth/$(am__dirstamp) \ vauth/$(DEPDIR)/$(am__dirstamp) vauth/libcurl_la-digest_sspi.lo: vauth/$(am__dirstamp) \ vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurl_la-gsasl.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) vauth/libcurl_la-krb5_gssapi.lo: vauth/$(am__dirstamp) \ vauth/$(DEPDIR)/$(am__dirstamp) vauth/libcurl_la-krb5_sspi.lo: vauth/$(am__dirstamp) \ @@ -1482,6 +1496,8 @@ vtls/libcurl_la-nss.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-openssl.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-rustls.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-schannel.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-schannel_verify.lo: vtls/$(am__dirstamp) \ @@ -1527,6 +1543,8 @@ vauth/libcurlu_la-digest.lo: vauth/$(am__dirstamp) \ vauth/$(DEPDIR)/$(am__dirstamp) vauth/libcurlu_la-digest_sspi.lo: vauth/$(am__dirstamp) \ vauth/$(DEPDIR)/$(am__dirstamp) +vauth/libcurlu_la-gsasl.lo: vauth/$(am__dirstamp) \ + vauth/$(DEPDIR)/$(am__dirstamp) vauth/libcurlu_la-krb5_gssapi.lo: vauth/$(am__dirstamp) \ vauth/$(DEPDIR)/$(am__dirstamp) vauth/libcurlu_la-krb5_sspi.lo: vauth/$(am__dirstamp) \ @@ -1561,6 +1579,8 @@ vtls/libcurlu_la-nss.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-openssl.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-rustls.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-schannel.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-schannel_verify.lo: vtls/$(am__dirstamp) \ @@ -1843,6 +1863,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-cram.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-digest.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-digest_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-gsasl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-ntlm.Plo@am__quote@ # am--include-marker @@ -1855,6 +1876,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-cram.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-digest.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-gsasl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurlu_la-ntlm.Plo@am__quote@ # am--include-marker @@ -1884,6 +1906,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mesalink.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-nss.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-openssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-rustls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-sectransp.Plo@am__quote@ # am--include-marker @@ -1898,6 +1921,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-nss.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-openssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-rustls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo@am__quote@ # am--include-marker @@ -2795,6 +2819,13 @@ vauth/libcurl_la-digest_sspi.lo: vauth/digest_sspi.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 vauth/libcurl_la-digest_sspi.lo `test -f 'vauth/digest_sspi.c' || echo '$(srcdir)/'`vauth/digest_sspi.c +vauth/libcurl_la-gsasl.lo: vauth/gsasl.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 vauth/libcurl_la-gsasl.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-gsasl.Tpo -c -o vauth/libcurl_la-gsasl.lo `test -f 'vauth/gsasl.c' || echo '$(srcdir)/'`vauth/gsasl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-gsasl.Tpo vauth/$(DEPDIR)/libcurl_la-gsasl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/gsasl.c' object='vauth/libcurl_la-gsasl.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 vauth/libcurl_la-gsasl.lo `test -f 'vauth/gsasl.c' || echo '$(srcdir)/'`vauth/gsasl.c + vauth/libcurl_la-krb5_gssapi.lo: vauth/krb5_gssapi.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 vauth/libcurl_la-krb5_gssapi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Tpo -c -o vauth/libcurl_la-krb5_gssapi.lo `test -f 'vauth/krb5_gssapi.c' || echo '$(srcdir)/'`vauth/krb5_gssapi.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Tpo vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo @@ -2914,6 +2945,13 @@ vtls/libcurl_la-openssl.lo: vtls/openssl.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 vtls/libcurl_la-openssl.lo `test -f 'vtls/openssl.c' || echo '$(srcdir)/'`vtls/openssl.c +vtls/libcurl_la-rustls.lo: vtls/rustls.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 vtls/libcurl_la-rustls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-rustls.Tpo -c -o vtls/libcurl_la-rustls.lo `test -f 'vtls/rustls.c' || echo '$(srcdir)/'`vtls/rustls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-rustls.Tpo vtls/$(DEPDIR)/libcurl_la-rustls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/rustls.c' object='vtls/libcurl_la-rustls.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 vtls/libcurl_la-rustls.lo `test -f 'vtls/rustls.c' || echo '$(srcdir)/'`vtls/rustls.c + vtls/libcurl_la-schannel.lo: vtls/schannel.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 vtls/libcurl_la-schannel.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-schannel.Tpo -c -o vtls/libcurl_la-schannel.lo `test -f 'vtls/schannel.c' || echo '$(srcdir)/'`vtls/schannel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-schannel.Tpo vtls/$(DEPDIR)/libcurl_la-schannel.Plo @@ -3852,6 +3890,13 @@ vauth/libcurlu_la-digest_sspi.lo: vauth/digest_sspi.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 vauth/libcurlu_la-digest_sspi.lo `test -f 'vauth/digest_sspi.c' || echo '$(srcdir)/'`vauth/digest_sspi.c +vauth/libcurlu_la-gsasl.lo: vauth/gsasl.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 vauth/libcurlu_la-gsasl.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-gsasl.Tpo -c -o vauth/libcurlu_la-gsasl.lo `test -f 'vauth/gsasl.c' || echo '$(srcdir)/'`vauth/gsasl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-gsasl.Tpo vauth/$(DEPDIR)/libcurlu_la-gsasl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vauth/gsasl.c' object='vauth/libcurlu_la-gsasl.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 vauth/libcurlu_la-gsasl.lo `test -f 'vauth/gsasl.c' || echo '$(srcdir)/'`vauth/gsasl.c + vauth/libcurlu_la-krb5_gssapi.lo: vauth/krb5_gssapi.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 vauth/libcurlu_la-krb5_gssapi.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Tpo -c -o vauth/libcurlu_la-krb5_gssapi.lo `test -f 'vauth/krb5_gssapi.c' || echo '$(srcdir)/'`vauth/krb5_gssapi.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Tpo vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo @@ -3971,6 +4016,13 @@ vtls/libcurlu_la-openssl.lo: vtls/openssl.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 vtls/libcurlu_la-openssl.lo `test -f 'vtls/openssl.c' || echo '$(srcdir)/'`vtls/openssl.c +vtls/libcurlu_la-rustls.lo: vtls/rustls.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 vtls/libcurlu_la-rustls.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-rustls.Tpo -c -o vtls/libcurlu_la-rustls.lo `test -f 'vtls/rustls.c' || echo '$(srcdir)/'`vtls/rustls.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-rustls.Tpo vtls/$(DEPDIR)/libcurlu_la-rustls.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/rustls.c' object='vtls/libcurlu_la-rustls.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 vtls/libcurlu_la-rustls.lo `test -f 'vtls/rustls.c' || echo '$(srcdir)/'`vtls/rustls.c + vtls/libcurlu_la-schannel.lo: vtls/schannel.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 vtls/libcurlu_la-schannel.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-schannel.Tpo -c -o vtls/libcurlu_la-schannel.lo `test -f 'vtls/schannel.c' || echo '$(srcdir)/'`vtls/schannel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-schannel.Tpo vtls/$(DEPDIR)/libcurlu_la-schannel.Plo @@ -4437,6 +4489,7 @@ distclean: distclean-am -rm -f vauth/$(DEPDIR)/libcurl_la-cram.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-digest.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-digest_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-gsasl.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-ntlm.Plo @@ -4449,6 +4502,7 @@ distclean: distclean-am -rm -f vauth/$(DEPDIR)/libcurlu_la-cram.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-digest.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-gsasl.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-ntlm.Plo @@ -4478,6 +4532,7 @@ distclean: distclean-am -rm -f vtls/$(DEPDIR)/libcurl_la-mesalink.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-nss.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-openssl.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-rustls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-schannel.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo @@ -4492,6 +4547,7 @@ distclean: distclean-am -rm -f vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-nss.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-openssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-rustls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo @@ -4784,6 +4840,7 @@ maintainer-clean: maintainer-clean-am -rm -f vauth/$(DEPDIR)/libcurl_la-cram.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-digest.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-digest_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurl_la-gsasl.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-krb5_gssapi.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-krb5_sspi.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-ntlm.Plo @@ -4796,6 +4853,7 @@ maintainer-clean: maintainer-clean-am -rm -f vauth/$(DEPDIR)/libcurlu_la-cram.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-digest.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-digest_sspi.Plo + -rm -f vauth/$(DEPDIR)/libcurlu_la-gsasl.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-krb5_gssapi.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-krb5_sspi.Plo -rm -f vauth/$(DEPDIR)/libcurlu_la-ntlm.Plo @@ -4825,6 +4883,7 @@ maintainer-clean: maintainer-clean-am -rm -f vtls/$(DEPDIR)/libcurl_la-mesalink.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-nss.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-openssl.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-rustls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-schannel.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-schannel_verify.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo @@ -4839,6 +4898,7 @@ maintainer-clean: maintainer-clean-am -rm -f vtls/$(DEPDIR)/libcurlu_la-mesalink.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-nss.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-openssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-rustls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-schannel_verify.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-sectransp.Plo diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc index e8d2259f2f..90ec6aa05c 100644 --- a/libs/libcurl/src/Makefile.inc +++ b/libs/libcurl/src/Makefile.inc @@ -25,6 +25,7 @@ LIB_VAUTH_CFILES = \ vauth/cram.c \ vauth/digest.c \ vauth/digest_sspi.c \ + vauth/gsasl.c \ vauth/krb5_gssapi.c \ vauth/krb5_sspi.c \ vauth/ntlm.c \ @@ -49,6 +50,7 @@ LIB_VTLS_CFILES = \ vtls/mesalink.c \ vtls/nss.c \ vtls/openssl.c \ + vtls/rustls.c \ vtls/schannel.c \ vtls/schannel_verify.c \ vtls/sectransp.c \ @@ -65,6 +67,7 @@ LIB_VTLS_HFILES = \ vtls/mesalink.h \ vtls/nssg.h \ vtls/openssl.h \ + vtls/rustls.h \ vtls/schannel.h \ vtls/sectransp.h \ vtls/vtls.h \ diff --git a/libs/libcurl/src/Makefile.m32 b/libs/libcurl/src/Makefile.m32 index d23eeead3b..9f1f5963d5 100644 --- a/libs/libcurl/src/Makefile.m32 +++ b/libs/libcurl/src/Makefile.m32 @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1999 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 1999 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -59,6 +59,10 @@ endif ifndef LIBRTMP_PATH LIBRTMP_PATH = ../../librtmp-2.4 endif +# Edit the path below to point to the base of your libgsasl package. +ifndef LIBGSASL_PATH +LIBGSASL_PATH = ../../libgsasl-1.10.0 +endif # Edit the path below to point to the base of your libidn2 package. ifndef LIBIDN2_PATH LIBIDN2_PATH = ../../libidn2-2.0.3 @@ -198,6 +202,9 @@ endif ifeq ($(findstring -brotli,$(CFG)),-brotli) BROTLI = 1 endif +ifeq ($(findstring -gsasl,$(CFG)),-gsasl) +GSASL = 1 +endif ifeq ($(findstring -idn2,$(CFG)),-idn2) IDN2 = 1 endif @@ -346,6 +353,11 @@ ifdef BROTLI DLL_LIBS += -lbrotlidec endif endif +ifdef GSASL + INCLUDES += -I"$(LIBGSASL_PATH)/include" + CFLAGS += -DUSE_GSASL + DLL_LIBS += -L"$(LIBGSASL_PATH)/lib" -lgsasl +endif ifdef IDN2 INCLUDES += -I"$(LIBIDN2_PATH)/include" CFLAGS += -DUSE_LIBIDN2 diff --git a/libs/libcurl/src/asyn-ares.c b/libs/libcurl/src/asyn-ares.c index 2484a7b498..c9bd9d16a5 100644 --- a/libs/libcurl/src/asyn-ares.c +++ b/libs/libcurl/src/asyn-ares.c @@ -384,13 +384,8 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, them */ res->temp_ai = NULL; - if(!data->state.async.dns) { - failf(data, "Could not resolve: %s (%s)", - data->state.async.hostname, - ares_strerror(data->state.async.status)); - result = data->conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY: - CURLE_COULDNT_RESOLVE_HOST; - } + if(!data->state.async.dns) + result = Curl_resolver_error(data); else *dns = data->state.async.dns; diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c index 9fcbc3c1fd..c453203f75 100644 --- a/libs/libcurl/src/asyn-thread.c +++ b/libs/libcurl/src/asyn-thread.c @@ -163,7 +163,7 @@ struct thread_sync_data { int port; char *hostname; /* hostname to resolve, Curl_async.hostname duplicate */ -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR struct Curl_easy *data; curl_socket_t sock_pair[2]; /* socket pair */ #endif @@ -201,7 +201,7 @@ void destroy_thread_sync_data(struct thread_sync_data *tsd) if(tsd->res) Curl_freeaddrinfo(tsd->res); -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR /* * close one end of the socket pair (may be done in resolver thread); * the other end (for reading) is always closed in the parent thread. @@ -243,7 +243,7 @@ int init_thread_sync_data(struct thread_data *td, Curl_mutex_init(tsd->mtx); -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */ if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { tsd->sock_pair[0] = CURL_SOCKET_BAD; @@ -297,7 +297,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) struct thread_data *td = tsd->td; char service[12]; int rc; -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR char buf[1]; #endif @@ -322,7 +322,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) free(td); } else { -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { /* DNS has been resolved, signal client task */ buf[0] = 1; @@ -382,7 +382,7 @@ static void destroy_async_data(struct Curl_async *async) if(async->tdata) { struct thread_data *td = async->tdata; int done; -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR curl_socket_t sock_rd = td->tsd.sock_pair[0]; struct Curl_easy *data = td->tsd.data; #endif @@ -407,7 +407,7 @@ static void destroy_async_data(struct Curl_async *async) free(async->tdata); } -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR /* * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL @@ -484,35 +484,6 @@ static bool init_resolve_thread(struct Curl_easy *data, } /* - * resolver_error() calls failf() with the appropriate message after a resolve - * error - */ - -static CURLcode resolver_error(struct Curl_easy *data) -{ - const char *host_or_proxy; - CURLcode result; - -#ifndef CURL_DISABLE_PROXY - struct connectdata *conn = data->conn; - if(conn->bits.httpproxy) { - host_or_proxy = "proxy"; - result = CURLE_COULDNT_RESOLVE_PROXY; - } - else -#endif - { - host_or_proxy = "host"; - result = CURLE_COULDNT_RESOLVE_HOST; - } - - failf(data, "Could not resolve %s: %s", host_or_proxy, - data->state.async.hostname); - - return result; -} - -/* * 'entry' may be NULL and then no data is returned */ static CURLcode thread_wait_resolv(struct Curl_easy *data, @@ -542,7 +513,7 @@ static CURLcode thread_wait_resolv(struct Curl_easy *data, if(!data->state.async.dns && report) /* a name was not resolved, report error */ - result = resolver_error(data); + result = Curl_resolver_error(data); destroy_async_data(&data->state.async); @@ -616,7 +587,7 @@ CURLcode Curl_resolver_is_resolved(struct Curl_easy *data, getaddrinfo_complete(data); if(!data->state.async.dns) { - CURLcode result = resolver_error(data); + CURLcode result = Curl_resolver_error(data); destroy_async_data(&data->state.async); return result; } @@ -654,13 +625,13 @@ int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks) timediff_t milli; timediff_t ms; struct resdata *reslv = (struct resdata *)data->state.async.resolver; -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR struct thread_data *td = data->state.async.tdata; #else (void)socks; #endif -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR if(td) { /* return read fd to client for polling the DNS resolution status */ socks[0] = td->tsd.sock_pair[0]; @@ -679,7 +650,7 @@ int Curl_resolver_getsock(struct Curl_easy *data, curl_socket_t *socks) else milli = 200; Curl_expire(data, milli, EXPIRE_ASYNC_NAME); -#ifdef USE_SOCKETPAIR +#ifndef CURL_DISABLE_SOCKETPAIR } #endif diff --git a/libs/libcurl/src/c-hyper.c b/libs/libcurl/src/c-hyper.c index 10bd7ef9bf..5d370d7bda 100644 --- a/libs/libcurl/src/c-hyper.c +++ b/libs/libcurl/src/c-hyper.c @@ -51,6 +51,7 @@ #include "transfer.h" #include "multiif.h" #include "progress.h" +#include "content_encoding.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -175,7 +176,11 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk) if(k->ignorebody) return HYPER_ITER_CONTINUE; Curl_debug(data, CURLINFO_DATA_IN, buf, len); - result = Curl_client_write(data, CLIENTWRITE_BODY, buf, len); + if(!data->set.http_ce_skip && k->writer_stack) + /* content-encoded data */ + result = Curl_unencode_write(data, k->writer_stack, buf, len); + else + result = Curl_client_write(data, CLIENTWRITE_BODY, buf, len); if(result) { data->state.hresult = result; @@ -464,8 +469,6 @@ CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers, else linelen = 2; /* CRLF ending */ linelen += (p - n); - if(!n) - return CURLE_BAD_FUNCTION_ARGUMENT; vlen = p - v; if(HYPERE_OK != hyper_headers_add(headers, (uint8_t *)n, nlen, @@ -741,7 +744,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) goto error; } - if(data->set.httpversion == CURL_HTTP_VERSION_1_0) { + if(data->state.httpwant == CURL_HTTP_VERSION_1_0) { if(HYPERE_OK != hyper_request_set_version(req, HYPER_HTTP_VERSION_1_0)) { failf(data, "error setting HTTP version"); @@ -807,14 +810,27 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) #endif Curl_safefree(data->state.aptr.ref); - if(data->change.referer && !Curl_checkheaders(data, "Referer")) { - data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer); + if(data->state.referer && !Curl_checkheaders(data, "Referer")) { + data->state.aptr.ref = aprintf("Referer: %s\r\n", data->state.referer); if(!data->state.aptr.ref) return CURLE_OUT_OF_MEMORY; if(Curl_hyper_header(data, headers, data->state.aptr.ref)) goto error; } + if(!Curl_checkheaders(data, "Accept-Encoding") && + data->set.str[STRING_ENCODING]) { + Curl_safefree(data->state.aptr.accept_encoding); + data->state.aptr.accept_encoding = + aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]); + if(!data->state.aptr.accept_encoding) + return CURLE_OUT_OF_MEMORY; + if(Curl_hyper_header(data, headers, data->state.aptr.accept_encoding)) + goto error; + } + else + Curl_safefree(data->state.aptr.accept_encoding); + result = cookies(data, conn, headers); if(result) return result; diff --git a/libs/libcurl/src/config-os400.h b/libs/libcurl/src/config-os400.h index b8676113d7..67fbc41d8b 100644 --- a/libs/libcurl/src/config-os400.h +++ b/libs/libcurl/src/config-os400.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -352,12 +352,6 @@ /* Define if you have the <sys/ioctl.h> header file. */ #define HAVE_SYS_IOCTL_H -/* Define if you have the `tcgetattr' function. */ -#undef HAVE_TCGETATTR - -/* Define if you have the `tcsetattr' function. */ -#undef HAVE_TCSETATTR - /* Define if you have the <termios.h> header file. */ #undef HAVE_TERMIOS_H diff --git a/libs/libcurl/src/config-plan9.h b/libs/libcurl/src/config-plan9.h index cc8adde725..fc19c5f036 100644 --- a/libs/libcurl/src/config-plan9.h +++ b/libs/libcurl/src/config-plan9.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -173,7 +173,6 @@ #define HAVE_STRCASECMP 1 #define HAVE_STRDUP 1 #define HAVE_STRING_H 1 -#define HAVE_STRNCASECMP 1 #define HAVE_STRSTR 1 #define HAVE_STRTOK_R 1 #define HAVE_STRTOLL 1 @@ -202,7 +201,6 @@ #define STRERROR_R_TYPE_ARG3 int #define TIME_WITH_SYS_TIME 1 -#define USE_BLOCKING_SOCKETS 1 #define USE_MANUAL 1 #define __attribute__(x) diff --git a/libs/libcurl/src/config-riscos.h b/libs/libcurl/src/config-riscos.h index 9b5f8da921..43b1deb6d2 100644 --- a/libs/libcurl/src/config-riscos.h +++ b/libs/libcurl/src/config-riscos.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -329,12 +329,6 @@ /* Define if you have the <sys/types.h> header file. */ #define HAVE_SYS_TYPES_H -/* Define if you have the `tcgetattr' function. */ -#define HAVE_TCGETATTR - -/* Define if you have the `tcsetattr' function. */ -#define HAVE_TCSETATTR - /* Define if you have the <termios.h> header file. */ #define HAVE_TERMIOS_H diff --git a/libs/libcurl/src/config-tpf.h b/libs/libcurl/src/config-tpf.h index bf69179fd5..4f8a07e9bc 100644 --- a/libs/libcurl/src/config-tpf.h +++ b/libs/libcurl/src/config-tpf.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -617,9 +617,6 @@ /* Define if you want to enable ares support */ /* #undef USE_ARES */ -/* Define to disable non-blocking sockets */ -/* #undef USE_BLOCKING_SOCKETS */ - /* if GnuTLS is enabled */ /* #undef USE_GNUTLS */ diff --git a/libs/libcurl/src/config-vxworks.h b/libs/libcurl/src/config-vxworks.h index 73edd530b4..f811952853 100644 --- a/libs/libcurl/src/config-vxworks.h +++ b/libs/libcurl/src/config-vxworks.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -56,9 +56,6 @@ /* to disable LDAPS */ #define CURL_DISABLE_LDAPS 1 -/* to disable NTLM authentication */ -#define CURL_DISABLE_NTLM 1 - /* to disable proxies */ /* #undef CURL_DISABLE_PROXY */ @@ -568,9 +565,6 @@ /* Define to 1 if you have the `strlcpy' function. */ /* #undef HAVE_STRLCPY */ -/* Define to 1 if you have the strncasecmp function. */ -#define HAVE_STRNCASECMP 1 - /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ @@ -841,9 +835,6 @@ /* Define if you want to enable c-ares support */ /* #undef USE_ARES */ -/* Define to disable non-blocking sockets. */ -/* #undef USE_BLOCKING_SOCKETS */ - /* if GnuTLS is enabled */ /* #undef USE_GNUTLS */ diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index 4b98a6ad37..0817ec5b12 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -246,12 +246,10 @@ /* 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. */ -/* #define HAVE_STRCASECMP 1 */ +#ifdef __MINGW32__ +#define HAVE_STRCASECMP 1 +#endif /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 @@ -262,9 +260,6 @@ /* Define if you have the stricmp function. */ #define HAVE_STRICMP 1 -/* Define if you have the strncasecmp function. */ -/* #define HAVE_STRNCASECMP 1 */ - /* Define if you have the strnicmp function. */ #define HAVE_STRNICMP 1 @@ -277,12 +272,6 @@ #define HAVE_STRTOLL 1 #endif -/* Define if you have the tcgetattr function. */ -/* #define HAVE_TCGETATTR 1 */ - -/* Define if you have the tcsetattr function. */ -/* #define HAVE_TCSETATTR 1 */ - /* Define if you have the utime function. */ #ifndef __BORLANDC__ #define HAVE_UTIME 1 @@ -506,9 +495,14 @@ #define _CRT_NONSTDC_NO_DEPRECATE 1 #endif -/* VS2005 and later default size for time_t is 64-bit, unless - _USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) +/* mingw-w64, mingw using >= MSVCR80, and visual studio >= 2005 (MSVCR80) + all default to 64-bit time_t unless _USE_32BIT_TIME_T is defined */ +#ifdef __MINGW32__ +# include <_mingw.h> +#endif +#if defined(__MINGW64_VERSION_MAJOR) || \ + (defined(__MINGW32__) && (__MSVCRT_VERSION__ >= 0x0800)) || \ + (defined(_MSC_VER) && (_MSC_VER >= 1400)) # ifndef _USE_32BIT_TIME_T # define SIZEOF_TIME_T 8 # else @@ -717,9 +711,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 9060836944..7f59fd562b 100644 --- a/libs/libcurl/src/config-win32ce.h +++ b/libs/libcurl/src/config-win32ce.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -205,9 +205,6 @@ /* Define if you have the stricmp function. */ /* #define HAVE_STRICMP 1 */ -/* Define if you have the strncasecmp function. */ -/* #define HAVE_STRNCASECMP 1 */ - /* Define if you have the strnicmp function. */ /* #define HAVE_STRNICMP 1 */ @@ -219,12 +216,6 @@ #define HAVE_STRTOLL 1 #endif -/* Define if you have the tcgetattr function. */ -/* #define HAVE_TCGETATTR 1 */ - -/* Define if you have the tcsetattr function. */ -/* #define HAVE_TCSETATTR 1 */ - /* Define if you have the utime function */ #define HAVE_UTIME 1 diff --git a/libs/libcurl/src/conncache.c b/libs/libcurl/src/conncache.c index 8dfdc0ac81..5453c00f33 100644 --- a/libs/libcurl/src/conncache.c +++ b/libs/libcurl/src/conncache.c @@ -466,7 +466,6 @@ Curl_conncache_extract_bundle(struct Curl_easy *data, data->state.conn_cache->num_conn--; DEBUGF(infof(data, "The cache now contains %zu members\n", data->state.conn_cache->num_conn)); - conn_candidate->data = data; /* associate! */ } return conn_candidate; @@ -529,7 +528,6 @@ Curl_conncache_extract_oldest(struct Curl_easy *data) connc->num_conn--; DEBUGF(infof(data, "The cache now contains %zu members\n", connc->num_conn)); - conn_candidate->data = data; /* associate! */ } CONNCACHE_UNLOCK(data); diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index baab1840e1..296fb62503 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -171,65 +171,63 @@ singleipconnect(struct Curl_easy *data, * infinite time left). If the value is negative, the timeout time has already * elapsed. * - * The start time is stored in progress.t_startsingle - as set with - * Curl_pgrsTime(..., TIMER_STARTSINGLE); - * * If 'nowp' is non-NULL, it points to the current time. * 'duringconnect' is FALSE if not during a connect, as then of course the * connect timeout is not taken into account! * * @unittest: 1303 */ + +#define TIMEOUT_CONNECT 1 +#define TIMEOUT_MAXTIME 2 + timediff_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect) { - int timeout_set = 0; - timediff_t timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0; + unsigned int timeout_set = 0; + timediff_t connect_timeout_ms = 0; + timediff_t maxtime_timeout_ms = 0; + timediff_t timeout_ms = 0; struct curltime now; - /* if a timeout is set, use the most restrictive one */ - - if(data->set.timeout > 0) - timeout_set |= 1; - if(duringconnect && (data->set.connecttimeout > 0)) - timeout_set |= 2; - - switch(timeout_set) { - case 1: - timeout_ms = data->set.timeout; - break; - case 2: - timeout_ms = data->set.connecttimeout; - break; - case 3: - if(data->set.timeout < data->set.connecttimeout) - timeout_ms = data->set.timeout; - else - timeout_ms = data->set.connecttimeout; - break; - default: - /* use the default */ - if(!duringconnect) - /* if we're not during connect, there's no default timeout so if we're - at zero we better just return zero and not make it a negative number - by the math below */ - return 0; - break; + /* The duration of a connect and the total transfer are calculated from two + different time-stamps. It can end up with the total timeout being reached + before the connect timeout expires and we must acknowledge whichever + timeout that is reached first. The total timeout is set per entire + operation, while the connect timeout is set per connect. */ + + if(data->set.timeout > 0) { + timeout_set = TIMEOUT_MAXTIME; + maxtime_timeout_ms = data->set.timeout; + } + if(duringconnect) { + timeout_set |= TIMEOUT_CONNECT; + connect_timeout_ms = (data->set.connecttimeout > 0) ? + data->set.connecttimeout : DEFAULT_CONNECT_TIMEOUT; } + if(!timeout_set) + /* no timeout */ + return 0; if(!nowp) { now = Curl_now(); nowp = &now; } - /* subtract elapsed time */ - if(duringconnect) - /* since this most recent connect started */ - timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle); - else - /* since the entire operation started */ - timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop); + if(timeout_set & TIMEOUT_MAXTIME) { + maxtime_timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop); + timeout_ms = maxtime_timeout_ms; + } + + if(timeout_set & TIMEOUT_CONNECT) { + connect_timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle); + + if(!(timeout_set & TIMEOUT_MAXTIME) || + (connect_timeout_ms < maxtime_timeout_ms)) + timeout_ms = connect_timeout_ms; + } + if(!timeout_ms) /* avoid returning 0 as that means no timeout! */ return -1; @@ -611,7 +609,7 @@ static CURLcode trynextip(struct Curl_easy *data, /* Copies connection info into the transfer handle to make it available when the transfer handle is no longer associated with the connection. */ void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn, - char *local_ip, long local_port) + char *local_ip, int local_port) { memcpy(data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN); if(local_ip && local_ip[0]) @@ -627,7 +625,7 @@ void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn, /* retrieves ip address and port from a sockaddr structure. note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, - char *addr, long *port) + char *addr, int *port) { struct sockaddr_in *si = NULL; #ifdef ENABLE_IPV6 @@ -690,7 +688,7 @@ void Curl_conninfo_remote(struct Curl_easy *data, char buffer[STRERROR_LEN]; struct Curl_sockaddr_storage ssrem; curl_socklen_t plen; - long port; + int port; plen = sizeof(struct Curl_sockaddr_storage); memset(&ssrem, 0, sizeof(ssrem)); if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) { @@ -715,7 +713,7 @@ void Curl_conninfo_remote(struct Curl_easy *data, /* retrieves the start/end point information of a socket of an established connection */ void Curl_conninfo_local(struct Curl_easy *data, curl_socket_t sockfd, - char *local_ip, long *local_port) + char *local_ip, int *local_port) { #ifdef HAVE_GETSOCKNAME char buffer[STRERROR_LEN]; @@ -752,7 +750,7 @@ void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn, ip address and port number whenever an outgoing connection is **established** from the primary socket to a remote address. */ char local_ip[MAX_IPADR_LEN] = ""; - long local_port = -1; + int local_port = -1; if(conn->transport == TRNSPRT_TCP) { if(!conn->bits.reuse && !conn->bits.tcp_fastopen) { @@ -908,8 +906,10 @@ CURLcode Curl_is_connected(struct Curl_easy *data, connkeep(conn, "HTTP/3 default"); return CURLE_OK; } - if(result) + if(result) { + conn->tempsock[i] = CURL_SOCKET_BAD; error = SOCKERRNO; + } } else #endif @@ -1158,7 +1158,7 @@ static CURLcode singleipconnect(struct Curl_easy *data, curl_socket_t sockfd; CURLcode result; char ipaddress[MAX_IPADR_LEN]; - long port; + int port; bool is_tcp; #ifdef TCP_FASTOPEN_CONNECT int optval = 1; @@ -1180,7 +1180,7 @@ static CURLcode singleipconnect(struct Curl_easy *data, Curl_closesocket(data, conn, sockfd); return CURLE_OK; } - infof(data, " Trying %s:%ld...\n", ipaddress, port); + infof(data, " Trying %s:%d...\n", ipaddress, port); #ifdef ENABLE_IPV6 is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) && @@ -1448,11 +1448,9 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, } c = find.found; - if(connp) { + if(connp) /* only store this if the caller cares for it */ *connp = c; - c->data = data; - } return c->sock[FIRSTSOCKET]; } return CURL_SOCKET_BAD; diff --git a/libs/libcurl/src/connect.h b/libs/libcurl/src/connect.h index 566b3531d7..1a055f58de 100644 --- a/libs/libcurl/src/connect.h +++ b/libs/libcurl/src/connect.h @@ -54,7 +54,7 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, struct connectdata **connp); bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, - char *addr, long *port); + char *addr, int *port); /* * Check if a connection seems to be alive. @@ -81,9 +81,9 @@ void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn, void Curl_conninfo_remote(struct Curl_easy *data, struct connectdata *conn, curl_socket_t sockfd); void Curl_conninfo_local(struct Curl_easy *data, curl_socket_t sockfd, - char *local_ip, long *local_port); + char *local_ip, int *local_port); void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn, - char *local_ip, long local_port); + char *local_ip, int local_port); int Curl_closesocket(struct Curl_easy *data, struct connectdata *conn, curl_socket_t sock); diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c index 09fd092ac3..b85e5e921c 100644 --- a/libs/libcurl/src/cookie.c +++ b/libs/libcurl/src/cookie.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -348,7 +348,7 @@ static char *sanitize_cookie_path(const char *cookie_path) */ void Curl_cookie_loadfiles(struct Curl_easy *data) { - struct curl_slist *list = data->change.cookielist; + struct curl_slist *list = data->state.cookielist; if(list) { Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); while(list) { @@ -365,8 +365,8 @@ void Curl_cookie_loadfiles(struct Curl_easy *data) data->cookies = newcookies; list = list->next; } - curl_slist_free_all(data->change.cookielist); /* clean up list */ - data->change.cookielist = NULL; /* don't do this again! */ + curl_slist_free_all(data->state.cookielist); /* clean up list */ + data->state.cookielist = NULL; /* don't do this again! */ Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); } } @@ -951,8 +951,12 @@ Curl_cookie_add(struct Curl_easy *data, remove_expired(c); #ifdef USE_LIBPSL - /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */ - if(domain && co->domain && !isip(co->domain)) { + /* + * Check if the domain is a Public Suffix and if yes, ignore the cookie. We + * must also check that the data handle isn't NULL since the psl code will + * dereference it. + */ + if(data && (domain && co->domain && !isip(co->domain))) { const psl_ctx_t *psl = Curl_psl_use(data); int acceptable; @@ -1652,7 +1656,7 @@ struct curl_slist *Curl_cookie_list(struct Curl_easy *data) void Curl_flush_cookies(struct Curl_easy *data, bool cleanup) { if(data->set.str[STRING_COOKIEJAR]) { - if(data->change.cookielist) { + if(data->state.cookielist) { /* If there is a list of cookie files to read, do it first so that we have all the told files read before we write the new jar. Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */ @@ -1667,11 +1671,11 @@ void Curl_flush_cookies(struct Curl_easy *data, bool cleanup) data->set.str[STRING_COOKIEJAR]); } else { - if(cleanup && data->change.cookielist) { + if(cleanup && data->state.cookielist) { /* since nothing is written, we can just free the list of cookie file names */ - curl_slist_free_all(data->change.cookielist); /* clean up list */ - data->change.cookielist = NULL; + curl_slist_free_all(data->state.cookielist); /* clean up list */ + data->state.cookielist = NULL; } Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); } diff --git a/libs/libcurl/src/cookie.h b/libs/libcurl/src/cookie.h index e0aa383bec..460bbb1040 100644 --- a/libs/libcurl/src/cookie.h +++ b/libs/libcurl/src/cookie.h @@ -91,13 +91,13 @@ struct Curl_easy; */ struct Cookie *Curl_cookie_add(struct Curl_easy *data, - struct CookieInfo *, bool header, bool noexpiry, - char *lineptr, + struct CookieInfo *c, bool header, + bool noexpiry, char *lineptr, const char *domain, const char *path, bool secure); -struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *, - const char *, bool); +struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, const char *host, + const char *path, bool secure); void Curl_cookie_freelist(struct Cookie *cookies); void Curl_cookie_clearall(struct CookieInfo *cookies); void Curl_cookie_clearsess(struct CookieInfo *cookies); @@ -110,9 +110,10 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies); #define Curl_flush_cookies(x,y) Curl_nop_stmt #else void Curl_flush_cookies(struct Curl_easy *data, bool cleanup); -void Curl_cookie_cleanup(struct CookieInfo *); +void Curl_cookie_cleanup(struct CookieInfo *c); struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, - const char *, struct CookieInfo *, bool); + const char *file, struct CookieInfo *inc, + bool newsession); struct curl_slist *Curl_cookie_list(struct Curl_easy *data); void Curl_cookie_loadfiles(struct Curl_easy *data); #endif diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake index 4c61a02c6e..fc1857ebb1 100644 --- a/libs/libcurl/src/curl_config.h.cmake +++ b/libs/libcurl/src/curl_config.h.cmake @@ -98,7 +98,7 @@ #endif /* Allow SMB to work on Windows */ -#cmakedefine USE_WIN32_CRYPTO +#cmakedefine USE_WIN32_CRYPTO 1 /* Use Windows LDAP implementation */ #cmakedefine USE_WIN32_LDAP 1 @@ -659,9 +659,6 @@ /* Define to 1 if you have the `strlcpy' function. */ #cmakedefine HAVE_STRLCPY 1 -/* Define to 1 if you have the strncasecmp function. */ -#cmakedefine HAVE_STRNCASECMP 1 - /* Define to 1 if you have the strncmpi function. */ #cmakedefine HAVE_STRNCMPI 1 @@ -963,9 +960,6 @@ ${SIZEOF_TIME_T_CODE} /* Define if you want to enable WIN32 threaded DNS lookup */ #cmakedefine USE_THREADS_WIN32 1 -/* Define to disable non-blocking sockets. */ -#cmakedefine USE_BLOCKING_SOCKETS 1 - /* if GnuTLS is enabled */ #cmakedefine USE_GNUTLS 1 @@ -1079,3 +1073,9 @@ ${SIZEOF_TIME_T_CODE} /* Define to 1 if you have the mach_absolute_time function. */ #cmakedefine HAVE_MACH_ABSOLUTE_TIME 1 + +/* to enable Windows IDN */ +#cmakedefine USE_WIN32_IDN 1 + +/* to make the compiler know the prototypes of Windows IDN APIs */ +#cmakedefine WANT_IDN_PROTOTYPES 1 diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in index fa5cf8de78..89a1d195a6 100644 --- a/libs/libcurl/src/curl_config.h.in +++ b/libs/libcurl/src/curl_config.h.in @@ -681,9 +681,6 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H -/* Define to 1 if you have the strncasecmp function. */ -#undef HAVE_STRNCASECMP - /* Define to 1 if you have the strncmpi function. */ #undef HAVE_STRNCMPI @@ -795,6 +792,9 @@ /* Define to 1 if you have the winber.h header file. */ #undef HAVE_WINBER_H +/* Define to 1 if you have the wincrypt.h header file. */ +#undef HAVE_WINCRYPT_H + /* Define to 1 if you have the windows.h header file. */ #undef HAVE_WINDOWS_H @@ -909,9 +909,6 @@ /* Define to the function return type for recv. */ #undef RECV_TYPE_RETV -/* Define as the return type of signal handlers (`int' or `void'). */ -#undef RETSIGTYPE - /* Define to the type qualifier of arg 5 for select. */ #undef SELECT_QUAL_ARG5 @@ -975,9 +972,6 @@ /* Define to the type of arg 3 for strerror_r. */ #undef STRERROR_R_TYPE_ARG3 -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -#undef TIME_WITH_SYS_TIME - /* if AmiSSL is in use */ #undef USE_AMISSL @@ -993,8 +987,8 @@ /* if GnuTLS is enabled */ #undef USE_GNUTLS -/* if GnuTLS uses nettle as crypto backend */ -#undef USE_GNUTLS_NETTLE +/* GSASL support enabled */ +#undef USE_GSASL /* to enable HSTS */ #undef USE_HSTS @@ -1053,6 +1047,9 @@ /* if quiche is in use */ #undef USE_QUICHE +/* if rustls is enabled */ +#undef USE_RUSTLS + /* to enable Windows native SSL/TLS support */ #undef USE_SCHANNEL @@ -1071,6 +1068,10 @@ /* Use Unix domain sockets */ #undef USE_UNIX_SOCKETS +/* Define to 1 if you are building a Windows target with crypto API support. + */ +#undef USE_WIN32_CRYPTO + /* Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz). */ #undef USE_WIN32_IDN diff --git a/libs/libcurl/src/curl_endian.c b/libs/libcurl/src/curl_endian.c index 2fc25bc173..b6f107e10a 100644 --- a/libs/libcurl/src/curl_endian.c +++ b/libs/libcurl/src/curl_endian.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -81,7 +81,7 @@ unsigned short Curl_read16_be(const unsigned char *buf) ((unsigned short)buf[1])); } -#if (CURL_SIZEOF_CURL_OFF_T > 4) +#if (SIZEOF_CURL_OFF_T > 4) /* * write32_le() * @@ -121,4 +121,4 @@ void Curl_write64_le(const __int64 value, unsigned char *buffer) write32_le((int)value, buffer); write32_le((int)(value >> 32), buffer + 4); } -#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */ +#endif /* SIZEOF_CURL_OFF_T > 4 */ diff --git a/libs/libcurl/src/curl_endian.h b/libs/libcurl/src/curl_endian.h index 341dfaf3cc..4e12d7da4d 100644 --- a/libs/libcurl/src/curl_endian.h +++ b/libs/libcurl/src/curl_endian.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -31,7 +31,7 @@ unsigned int Curl_read32_le(const unsigned char *buf); /* Converts a 16-bit integer from big endian */ unsigned short Curl_read16_be(const unsigned char *buf); -#if (CURL_SIZEOF_CURL_OFF_T > 4) +#if (SIZEOF_CURL_OFF_T > 4) /* Converts a 64-bit integer to little endian */ #if defined(HAVE_LONGLONG) void Curl_write64_le(const long long value, unsigned char *buffer); diff --git a/libs/libcurl/src/curl_multibyte.c b/libs/libcurl/src/curl_multibyte.c index d327c8ba77..16418bee4c 100644 --- a/libs/libcurl/src/curl_multibyte.c +++ b/libs/libcurl/src/curl_multibyte.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -21,7 +21,11 @@ ***************************************************************************/ /* - * This file is 'mem-include-scan' clean. See test 1132. + * This file is 'mem-include-scan' clean, which means memdebug.h and + * curl_memory.h are purposely not included in this file. See test 1132. + * + * The functions in this file are curlx functions which are not tracked by the + * curl memory tracker memdebug. */ #include "curl_setup.h" @@ -82,6 +86,32 @@ char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w) #if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES) +int curlx_win32_open(const char *filename, int oflag, ...) +{ + int pmode = 0; + +#ifdef _UNICODE + int result = -1; + wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename); +#endif + + va_list param; + va_start(param, oflag); + if(oflag & O_CREAT) + pmode = va_arg(param, int); + va_end(param); + +#ifdef _UNICODE + if(filename_w) + result = _wopen(filename_w, oflag, pmode); + free(filename_w); + if(result != -1) + return result; +#endif + + return (_open)(filename, oflag, pmode); +} + FILE *curlx_win32_fopen(const char *filename, const char *mode) { #ifdef _UNICODE @@ -104,50 +134,38 @@ int curlx_win32_stat(const char *path, struct_stat *buffer) int result = -1; #ifdef _UNICODE wchar_t *path_w = curlx_convert_UTF8_to_wchar(path); -#endif /* _UNICODE */ - + if(path_w) { #if defined(USE_WIN32_SMALL_FILES) -#if defined(_UNICODE) - if(path_w) result = _wstat(path_w, buffer); - else -#endif /* _UNICODE */ - result = _stat(path, buffer); -#else /* USE_WIN32_SMALL_FILES */ -#if defined(_UNICODE) - if(path_w) +#else result = _wstati64(path_w, buffer); - else +#endif + free(path_w); + if(result != -1) + return result; + } #endif /* _UNICODE */ - result = _stati64(path, buffer); -#endif /* USE_WIN32_SMALL_FILES */ -#ifdef _UNICODE - free(path_w); +#if defined(USE_WIN32_SMALL_FILES) + result = _stat(path, buffer); +#else + result = _stati64(path, buffer); #endif - return result; } int curlx_win32_access(const char *path, int mode) { - int result = -1; -#ifdef _UNICODE - wchar_t *path_w = curlx_convert_UTF8_to_wchar(path); -#endif /* _UNICODE */ - #if defined(_UNICODE) - if(path_w) - result = _waccess(path_w, mode); - else -#endif /* _UNICODE */ - result = _access(path, mode); - -#ifdef _UNICODE + wchar_t *path_w = curlx_convert_UTF8_to_wchar(path); + if(path_w) { + int result = _waccess(path_w, mode); free(path_w); -#endif - - return result; + if(result != -1) + return result; + } +#endif /* _UNICODE */ + return _access(path, mode); } #endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */ diff --git a/libs/libcurl/src/curl_multibyte.h b/libs/libcurl/src/curl_multibyte.h index 8adaf49784..491155e6a7 100644 --- a/libs/libcurl/src/curl_multibyte.h +++ b/libs/libcurl/src/curl_multibyte.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -31,7 +31,6 @@ wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8); char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w); - #endif /* WIN32 */ /* @@ -40,29 +39,23 @@ char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w); * preprocessor conditional directives needed by code using these * to differentiate UNICODE from non-UNICODE builds. * - * When building with UNICODE defined, these two macros - * curlx_convert_UTF8_to_tchar() and curlx_convert_tchar_to_UTF8() - * return a pointer to a newly allocated memory area holding result. - * When the result is no longer needed, allocated memory is intended - * to be free'ed with curlx_unicodefree(). + * In the case of a non-UNICODE build the tchar strings are char strings that + * are duplicated via strdup and remain in whatever the passed in encoding is, + * which is assumed to be UTF-8 but may be other encoding. Therefore the + * significance of the conversion functions is primarily for UNICODE builds. + * + * Allocated memory should be free'd with curlx_unicodefree(). * - * When building without UNICODE defined, this macros - * curlx_convert_UTF8_to_tchar() and curlx_convert_tchar_to_UTF8() - * return the pointer received as argument. curlx_unicodefree() does - * no actual free'ing of this pointer it is simply set to NULL. + * Note: Because these are curlx functions their memory usage is not tracked + * by the curl memory tracker memdebug. You'll notice that curlx function-like + * macros call free and strdup in parentheses, eg (strdup)(ptr), and that's to + * ensure that the curl memdebug override macros do not replace them. */ #if defined(UNICODE) && defined(WIN32) #define curlx_convert_UTF8_to_tchar(ptr) curlx_convert_UTF8_to_wchar((ptr)) #define curlx_convert_tchar_to_UTF8(ptr) curlx_convert_wchar_to_UTF8((ptr)) -#define curlx_unicodefree(ptr) \ - do { \ - if(ptr) { \ - (free)(ptr); \ - (ptr) = NULL; \ - } \ - } while(0) typedef union { unsigned short *tchar_ptr; @@ -73,10 +66,8 @@ typedef union { #else -#define curlx_convert_UTF8_to_tchar(ptr) (ptr) -#define curlx_convert_tchar_to_UTF8(ptr) (ptr) -#define curlx_unicodefree(ptr) \ - do {(ptr) = NULL;} while(0) +#define curlx_convert_UTF8_to_tchar(ptr) (strdup)(ptr) +#define curlx_convert_tchar_to_UTF8(ptr) (strdup)(ptr) typedef union { char *tchar_ptr; @@ -87,4 +78,12 @@ typedef union { #endif /* UNICODE && WIN32 */ +#define curlx_unicodefree(ptr) \ + do { \ + if(ptr) { \ + (free)(ptr); \ + (ptr) = NULL; \ + } \ + } while(0) + #endif /* HEADER_CURL_MULTIBYTE_H */ diff --git a/libs/libcurl/src/curl_ntlm_core.c b/libs/libcurl/src/curl_ntlm_core.c index 9a075ac90f..66146a881c 100644 --- a/libs/libcurl/src/curl_ntlm_core.c +++ b/libs/libcurl/src/curl_ntlm_core.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -34,13 +34,12 @@ /* Please keep the SSL backend-specific #if branches in this order: 1. USE_OPENSSL - 2. USE_GNUTLS_NETTLE - 3. USE_GNUTLS - 4. USE_NSS - 5. USE_MBEDTLS - 6. USE_SECTRANSP - 7. USE_OS400CRYPTO - 8. USE_WIN32_CRYPTO + 2. USE_GNUTLS + 3. USE_NSS + 4. USE_MBEDTLS + 5. USE_SECTRANSP + 6. USE_OS400CRYPTO + 7. USE_WIN32_CRYPTO This ensures that: - the same SSL branch gets activated throughout this source @@ -74,13 +73,9 @@ # define DESKEY(x) &x # endif -#elif defined(USE_GNUTLS_NETTLE) - -# include <nettle/des.h> - #elif defined(USE_GNUTLS) -# include <gcrypt.h> +# include <nettle/des.h> #elif defined(USE_NSS) @@ -159,7 +154,7 @@ static void setup_des_key(const unsigned char *key_56, DES_set_key(&key, ks); } -#elif defined(USE_GNUTLS_NETTLE) +#elif defined(USE_GNUTLS) static void setup_des_key(const unsigned char *key_56, struct des_ctx *des) @@ -176,26 +171,6 @@ static void setup_des_key(const unsigned char *key_56, des_set_key(des, (const uint8_t *) key); } -#elif defined(USE_GNUTLS) - -/* - * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. - */ -static void setup_des_key(const unsigned char *key_56, - gcry_cipher_hd_t *des) -{ - char key[8]; - - /* Expand the 56-bit key to 64-bits */ - extend_key_56_to_64(key_56, key); - - /* Set the key parity to odd */ - Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); - - /* Set the key */ - gcry_cipher_setkey(*des, key, sizeof(key)); -} - #elif defined(USE_NSS) /* @@ -402,7 +377,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys, setup_des_key(keys + 14, DESKEY(ks)); DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16), DESKEY(ks), DES_ENCRYPT); -#elif defined(USE_GNUTLS_NETTLE) +#elif defined(USE_GNUTLS) struct des_ctx des; setup_des_key(keys, &des); des_encrypt(&des, 8, results, plaintext); @@ -410,23 +385,6 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys, des_encrypt(&des, 8, results + 8, plaintext); setup_des_key(keys + 14, &des); des_encrypt(&des, 8, results + 16, plaintext); -#elif defined(USE_GNUTLS) - gcry_cipher_hd_t des; - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(keys, &des); - gcry_cipher_encrypt(des, results, 8, plaintext, 8); - gcry_cipher_close(des); - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(keys + 7, &des); - gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8); - gcry_cipher_close(des); - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(keys + 14, &des); - gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8); - gcry_cipher_close(des); #elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) encrypt_des(plaintext, results, keys); @@ -473,24 +431,12 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data, setup_des_key(pw + 7, DESKEY(ks)); DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8), DESKEY(ks), DES_ENCRYPT); -#elif defined(USE_GNUTLS_NETTLE) +#elif defined(USE_GNUTLS) struct des_ctx des; setup_des_key(pw, &des); des_encrypt(&des, 8, lmbuffer, magic); setup_des_key(pw + 7, &des); des_encrypt(&des, 8, lmbuffer + 8, magic); -#elif defined(USE_GNUTLS) - gcry_cipher_hd_t des; - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(pw, &des); - gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8); - gcry_cipher_close(des); - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(pw + 7, &des); - gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8); - gcry_cipher_close(des); #elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) encrypt_des(magic, lmbuffer, pw); @@ -644,7 +590,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, CURLcode result = CURLE_OK; -#if CURL_SIZEOF_CURL_OFF_T < 8 +#if SIZEOF_CURL_OFF_T < 8 #error "this section needs 64bit support to work" #endif diff --git a/libs/libcurl/src/curl_ntlm_core.h b/libs/libcurl/src/curl_ntlm_core.h index fab628c590..75fcdeb16e 100644 --- a/libs/libcurl/src/curl_ntlm_core.h +++ b/libs/libcurl/src/curl_ntlm_core.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,7 +30,6 @@ then it must be initialized to be used by NTLM. */ #if !defined(USE_OPENSSL) && \ !defined(USE_WOLFSSL) && \ - !defined(USE_GNUTLS_NETTLE) && \ !defined(USE_GNUTLS) && \ defined(USE_NSS) #define NTLM_NEEDS_NSS_INIT @@ -57,7 +56,7 @@ /* Define USE_NTLM_V2 in order to allow the type-3 message to include the LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1 and support for 64-bit integers. */ -#if defined(USE_NTRESPONSES) && (CURL_SIZEOF_CURL_OFF_T > 4) +#if defined(USE_NTRESPONSES) && (SIZEOF_CURL_OFF_T > 4) #define USE_NTLM_V2 #endif diff --git a/libs/libcurl/src/curl_rtmp.c b/libs/libcurl/src/curl_rtmp.c index fabdc88484..1360f335fc 100644 --- a/libs/libcurl/src/curl_rtmp.c +++ b/libs/libcurl/src/curl_rtmp.c @@ -204,7 +204,7 @@ static CURLcode rtmp_setup_connection(struct Curl_easy *data, RTMP_Init(r); RTMP_SetBufferMS(r, DEF_BUFTIME); - if(!RTMP_SetupURL(r, data->change.url)) { + if(!RTMP_SetupURL(r, data->state.url)) { RTMP_Free(r); return CURLE_URL_MALFORMAT; } diff --git a/libs/libcurl/src/curl_sasl.c b/libs/libcurl/src/curl_sasl.c index ffeb75164d..2cba185470 100644 --- a/libs/libcurl/src/curl_sasl.c +++ b/libs/libcurl/src/curl_sasl.c @@ -23,6 +23,8 @@ * RFC2831 DIGEST-MD5 authentication * RFC4422 Simple Authentication and Security Layer (SASL) * RFC4616 PLAIN authentication + * RFC5802 SCRAM-SHA-1 authentication + * RFC7677 SCRAM-SHA-256 authentication * RFC6749 OAuth 2.0 Authorization Framework * RFC7628 A Set of SASL Mechanisms for OAuth * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt> @@ -67,6 +69,8 @@ static const struct { { "NTLM", 4, SASL_MECH_NTLM }, { "XOAUTH2", 7, SASL_MECH_XOAUTH2 }, { "OAUTHBEARER", 11, SASL_MECH_OAUTHBEARER }, + { "SCRAM-SHA-1", 11, SASL_MECH_SCRAM_SHA_1 }, + { "SCRAM-SHA-256",13, SASL_MECH_SCRAM_SHA_256 }, { ZERO_NULL, 0, 0 } }; @@ -90,6 +94,13 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) } #endif +#if defined(USE_GSASL) + /* Cleanup the GSASL structure */ + if(authused & (SASL_MECH_SCRAM_SHA_1 | SASL_MECH_SCRAM_SHA_256)) { + Curl_auth_gsasl_cleanup(&conn->gsasl); + } +#endif + #if defined(USE_NTLM) /* Cleanup the NTLM structure */ if(authused == SASL_MECH_NTLM) { @@ -215,6 +226,7 @@ static void state(struct SASL *sasl, struct Curl_easy *data, "GSSAPI_NO_DATA", "OAUTH2", "OAUTH2_RESP", + "GSASL", "CANCEL", "FINAL", /* LAST */ @@ -316,6 +328,37 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, } else #endif +#ifdef USE_GSASL + if((enabledmechs & SASL_MECH_SCRAM_SHA_256) && + Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_256, + &conn->gsasl)) { + mech = SASL_MECH_STRING_SCRAM_SHA_256; + sasl->authused = SASL_MECH_SCRAM_SHA_256; + state1 = SASL_GSASL; + state2 = SASL_GSASL; + + 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); + } + else if((enabledmechs & SASL_MECH_SCRAM_SHA_1) && + Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1, + &conn->gsasl)) { + mech = SASL_MECH_STRING_SCRAM_SHA_1; + sasl->authused = SASL_MECH_SCRAM_SHA_1; + state1 = SASL_GSASL; + state2 = SASL_GSASL; + + 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); + } + else +#endif #ifndef CURL_DISABLE_CRYPTO_AUTH if((enabledmechs & SASL_MECH_DIGEST_MD5) && Curl_auth_is_digest_supported()) { @@ -480,8 +523,16 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, case SASL_EXTERNAL: result = Curl_auth_create_external_message(data, conn->user, &resp, &len); 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) + 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); diff --git a/libs/libcurl/src/curl_sasl.h b/libs/libcurl/src/curl_sasl.h index 75a957583a..8648c632b6 100644 --- a/libs/libcurl/src/curl_sasl.h +++ b/libs/libcurl/src/curl_sasl.h @@ -37,6 +37,8 @@ struct connectdata; #define SASL_MECH_NTLM (1 << 6) #define SASL_MECH_XOAUTH2 (1 << 7) #define SASL_MECH_OAUTHBEARER (1 << 8) +#define SASL_MECH_SCRAM_SHA_1 (1 << 9) +#define SASL_MECH_SCRAM_SHA_256 (1 << 10) /* Authentication mechanism values */ #define SASL_AUTH_NONE 0 @@ -53,6 +55,8 @@ struct connectdata; #define SASL_MECH_STRING_NTLM "NTLM" #define SASL_MECH_STRING_XOAUTH2 "XOAUTH2" #define SASL_MECH_STRING_OAUTHBEARER "OAUTHBEARER" +#define SASL_MECH_STRING_SCRAM_SHA_1 "SCRAM-SHA-1" +#define SASL_MECH_STRING_SCRAM_SHA_256 "SCRAM-SHA-256" /* SASL machine states */ typedef enum { @@ -71,6 +75,7 @@ typedef enum { SASL_GSSAPI_NO_DATA, SASL_OAUTH2, SASL_OAUTH2_RESP, + SASL_GSASL, SASL_CANCEL, SASL_FINAL } saslstate; diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index 22def2defa..cf1c26a14e 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -54,6 +54,16 @@ # ifndef NOGDI # define NOGDI # endif +/* Detect Windows App environment which has a restricted access + * to the Win32 APIs. */ +# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \ + defined(WINAPI_FAMILY) +# include <winapifamily.h> +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define CURL_WINDOWS_APP +# endif +# endif #endif /* @@ -151,8 +161,6 @@ #include <curl/curl.h> -#define CURL_SIZEOF_CURL_OFF_T SIZEOF_CURL_OFF_T - /* * Disable other protocols when http is the only one desired. */ @@ -335,8 +343,10 @@ # define stat(fname,stp) curlx_win32_stat(fname, stp) # define struct_stat struct _stati64 # define LSEEK_ERROR (__int64)-1 +# define open curlx_win32_open # define fopen(fname,mode) curlx_win32_fopen(fname, mode) # define access(fname,mode) curlx_win32_access(fname, mode) + int curlx_win32_open(const char *filename, int oflag, ...); int curlx_win32_stat(const char *path, struct_stat *buffer); FILE *curlx_win32_fopen(const char *filename, const char *mode); int curlx_win32_access(const char *path, int mode); @@ -356,9 +366,11 @@ # define fstat(fdes,stp) _fstat(fdes, stp) # define stat(fname,stp) curlx_win32_stat(fname, stp) # define struct_stat struct _stat +# define open curlx_win32_open # define fopen(fname,mode) curlx_win32_fopen(fname, mode) # define access(fname,mode) curlx_win32_access(fname, mode) int curlx_win32_stat(const char *path, struct_stat *buffer); + int curlx_win32_open(const char *filename, int oflag, ...); FILE *curlx_win32_fopen(const char *filename, const char *mode); int curlx_win32_access(const char *path, int mode); # endif @@ -408,7 +420,7 @@ #if (SIZEOF_CURL_OFF_T == 4) # define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF) #else - /* assume CURL_SIZEOF_CURL_OFF_T == 8 */ + /* assume SIZEOF_CURL_OFF_T == 8 */ # define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) #endif #define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1)) @@ -612,7 +624,7 @@ int netware_init(void); defined(USE_MBEDTLS) || \ defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) || \ - defined(USE_BEARSSL) + defined(USE_BEARSSL) || defined(USE_RUSTLS) #define USE_SSL /* SSL support has been enabled */ #endif @@ -629,7 +641,7 @@ int netware_init(void); #endif /* Single point where USE_NTLM definition might be defined */ -#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH) +#ifndef CURL_DISABLE_CRYPTO_AUTH #if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \ defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \ defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \ @@ -760,17 +772,6 @@ endings either CRLF or LF so 't' is appropriate. # endif #endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUND */ -/* Detect Windows App environment which has a restricted access - * to the Win32 APIs. */ -# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \ - defined(WINAPI_FAMILY) -# include <winapifamily.h> -# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ - !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -# define CURL_WINDOWS_APP -# endif -# endif - /* for systems that don't detect this in configure, use a sensible default */ #ifndef CURL_SA_FAMILY_T #define CURL_SA_FAMILY_T unsigned short diff --git a/libs/libcurl/src/doh.c b/libs/libcurl/src/doh.c index 004244c8d2..52388cba3e 100644 --- a/libs/libcurl/src/doh.c +++ b/libs/libcurl/src/doh.c @@ -207,10 +207,12 @@ static int doh_done(struct Curl_easy *doh, CURLcode result) } #define ERROR_CHECK_SETOPT(x,y) \ -do { \ - result = curl_easy_setopt(doh, x, y); \ - if(result) \ - goto error; \ +do { \ + result = curl_easy_setopt(doh, x, y); \ + if(result && \ + result != CURLE_NOT_BUILT_IN && \ + result != CURLE_UNKNOWN_OPTION) \ + goto error; \ } while(0) static CURLcode dohprobe(struct Curl_easy *data, @@ -282,84 +284,86 @@ static CURLcode dohprobe(struct Curl_easy *data, ERROR_CHECK_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); #endif ERROR_CHECK_SETOPT(CURLOPT_TIMEOUT_MS, (long)timeout_ms); + ERROR_CHECK_SETOPT(CURLOPT_SHARE, data->share); + if(data->set.err && data->set.err != stderr) + ERROR_CHECK_SETOPT(CURLOPT_STDERR, data->set.err); if(data->set.verbose) ERROR_CHECK_SETOPT(CURLOPT_VERBOSE, 1L); if(data->set.no_signal) ERROR_CHECK_SETOPT(CURLOPT_NOSIGNAL, 1L); + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, + data->set.doh_verifyhost ? 2L : 0L); + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, + data->set.doh_verifypeer ? 1L : 0L); + ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, + data->set.doh_verifystatus ? 1L : 0L); + /* Inherit *some* SSL options from the user's transfer. This is a - best-guess as to which options are needed for compatibility. #3661 */ + best-guess as to which options are needed for compatibility. #3661 + + Note DOH does not inherit the user's proxy server so proxy SSL settings + have no effect and are not inherited. If that changes then two new + options should be added to check doh proxy insecure separately, + CURLOPT_DOH_PROXY_SSL_VERIFYHOST and CURLOPT_DOH_PROXY_SSL_VERIFYPEER. + */ if(data->set.ssl.falsestart) ERROR_CHECK_SETOPT(CURLOPT_SSL_FALSESTART, 1L); - if(data->set.ssl.primary.verifyhost) - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYHOST, 2L); -#ifndef CURL_DISABLE_PROXY - if(data->set.proxy_ssl.primary.verifyhost) - ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYHOST, 2L); - if(data->set.proxy_ssl.primary.verifypeer) - ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_VERIFYPEER, 1L); - if(data->set.str[STRING_SSL_CAFILE_PROXY]) { - ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAINFO, - data->set.str[STRING_SSL_CAFILE_PROXY]); - } - if(data->set.str[STRING_SSL_CRLFILE_PROXY]) { - ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE, - data->set.str[STRING_SSL_CRLFILE_PROXY]); - } - if(data->set.proxy_ssl.no_revoke) - ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); - else if(data->set.proxy_ssl.revoke_best_effort) - ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, - CURLSSLOPT_REVOKE_BEST_EFFORT); - if(data->set.str[STRING_SSL_CAPATH_PROXY]) { - ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH, - data->set.str[STRING_SSL_CAPATH_PROXY]); - } -#endif - if(data->set.ssl.primary.verifypeer) - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L); - if(data->set.ssl.primary.verifystatus) - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYSTATUS, 1L); - if(data->set.str[STRING_SSL_CAFILE_ORIG]) { + if(data->set.str[STRING_SSL_CAFILE]) { ERROR_CHECK_SETOPT(CURLOPT_CAINFO, - data->set.str[STRING_SSL_CAFILE_ORIG]); + data->set.str[STRING_SSL_CAFILE]); } - if(data->set.str[STRING_SSL_CAPATH_ORIG]) { + if(data->set.str[STRING_SSL_CAPATH]) { ERROR_CHECK_SETOPT(CURLOPT_CAPATH, - data->set.str[STRING_SSL_CAPATH_ORIG]); + data->set.str[STRING_SSL_CAPATH]); } - if(data->set.str[STRING_SSL_CRLFILE_ORIG]) { + if(data->set.str[STRING_SSL_CRLFILE]) { ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, - data->set.str[STRING_SSL_CRLFILE_ORIG]); + data->set.str[STRING_SSL_CRLFILE]); } if(data->set.ssl.certinfo) ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); if(data->set.str[STRING_SSL_RANDOM_FILE]) { ERROR_CHECK_SETOPT(CURLOPT_RANDOM_FILE, - data->set.str[STRING_SSL_RANDOM_FILE]); + data->set.str[STRING_SSL_RANDOM_FILE]); } if(data->set.str[STRING_SSL_EGDSOCKET]) { ERROR_CHECK_SETOPT(CURLOPT_EGDSOCKET, - data->set.str[STRING_SSL_EGDSOCKET]); + data->set.str[STRING_SSL_EGDSOCKET]); } - if(data->set.ssl.no_revoke) - ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); - else if(data->set.ssl.revoke_best_effort) - ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_REVOKE_BEST_EFFORT); if(data->set.ssl.fsslctx) ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); if(data->set.ssl.fsslctxp) ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_DATA, data->set.ssl.fsslctxp); if(data->set.str[STRING_SSL_EC_CURVES]) { ERROR_CHECK_SETOPT(CURLOPT_SSL_EC_CURVES, - data->set.str[STRING_SSL_EC_CURVES]); + data->set.str[STRING_SSL_EC_CURVES]); + } + + { + long mask = + (data->set.ssl.enable_beast ? + CURLSSLOPT_ALLOW_BEAST : 0) | + (data->set.ssl.no_revoke ? + CURLSSLOPT_NO_REVOKE : 0) | + (data->set.ssl.no_partialchain ? + CURLSSLOPT_NO_PARTIALCHAIN : 0) | + (data->set.ssl.revoke_best_effort ? + CURLSSLOPT_REVOKE_BEST_EFFORT : 0) | + (data->set.ssl.native_ca_store ? + CURLSSLOPT_NATIVE_CA : 0); + curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask); } doh->set.fmultidone = doh_done; doh->set.dohfor = data; /* identify for which transfer this is done */ p->easy = doh; - /* add this transfer to the multi handle */ + /* DOH private_data must be null because the user must have a way to + distinguish their transfer's handle from DOH handles in user + callbacks (ie SSL CTX callback). */ + DEBUGASSERT(!data->set.private_data); + if(curl_multi_add_handle(multi, doh)) goto error; } diff --git a/libs/libcurl/src/dynbuf.h b/libs/libcurl/src/dynbuf.h index 484e40c645..252411f842 100644 --- a/libs/libcurl/src/dynbuf.h +++ b/libs/libcurl/src/dynbuf.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2020, 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -74,7 +74,7 @@ int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save); #define DYN_DOH_CNAME 256 #define DYN_PAUSE_BUFFER (64 * 1024 * 1024) #define DYN_HAXPROXY 2048 -#define DYN_HTTP_REQUEST (128*1024) +#define DYN_HTTP_REQUEST (1024*1024) #define DYN_H2_HEADERS (128*1024) #define DYN_H2_TRAILERS (128*1024) #define DYN_APRINTF 8000000 diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c index 0fb255af49..4ce1bbf63b 100644 --- a/libs/libcurl/src/easy.c +++ b/libs/libcurl/src/easy.c @@ -810,7 +810,7 @@ static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src) result = Curl_mime_duppart(&dst->set.mimepost, &src->set.mimepost); if(src->set.resolve) - dst->change.resolve = dst->set.resolve; + dst->state.resolve = dst->set.resolve; return result; } @@ -858,25 +858,25 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) } /* duplicate all values in 'change' */ - if(data->change.cookielist) { - outcurl->change.cookielist = - Curl_slist_duplicate(data->change.cookielist); - if(!outcurl->change.cookielist) + if(data->state.cookielist) { + outcurl->state.cookielist = + Curl_slist_duplicate(data->state.cookielist); + if(!outcurl->state.cookielist) goto fail; } - if(data->change.url) { - outcurl->change.url = strdup(data->change.url); - if(!outcurl->change.url) + if(data->state.url) { + outcurl->state.url = strdup(data->state.url); + if(!outcurl->state.url) goto fail; - outcurl->change.url_alloc = TRUE; + outcurl->state.url_alloc = TRUE; } - if(data->change.referer) { - outcurl->change.referer = strdup(data->change.referer); - if(!outcurl->change.referer) + if(data->state.referer) { + outcurl->state.referer = strdup(data->state.referer); + if(!outcurl->state.referer) goto fail; - outcurl->change.referer_alloc = TRUE; + outcurl->state.referer_alloc = TRUE; } /* Reinitialize an SSL engine for the new handle @@ -947,12 +947,12 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) fail: if(outcurl) { - curl_slist_free_all(outcurl->change.cookielist); - outcurl->change.cookielist = NULL; + curl_slist_free_all(outcurl->state.cookielist); + outcurl->state.cookielist = NULL; Curl_safefree(outcurl->state.buffer); Curl_dyn_free(&outcurl->state.headerb); - Curl_safefree(outcurl->change.url); - Curl_safefree(outcurl->change.referer); + Curl_safefree(outcurl->state.url); + Curl_safefree(outcurl->state.referer); Curl_altsvc_cleanup(&outcurl->asi); Curl_hsts_cleanup(&outcurl->hsts); Curl_freeset(outcurl); @@ -1034,8 +1034,8 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) /* Unpause parts in active mime tree. */ if((k->keepon & ~newstate & KEEP_SEND_PAUSE) && - (data->mstate == CURLM_STATE_PERFORM || - data->mstate == CURLM_STATE_TOOFAST) && + (data->mstate == MSTATE_PERFORMING || + data->mstate == MSTATE_RATELIMITING) && data->state.fread_func == (curl_read_callback) Curl_mime_read) { Curl_mime_unpause(data->state.in); } @@ -1052,8 +1052,6 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) unsigned int i; unsigned int count = data->state.tempcount; struct tempbuf writebuf[3]; /* there can only be three */ - struct connectdata *conn = data->conn; - struct Curl_easy *saved_data = NULL; /* copy the structs to allow for immediate re-pausing */ for(i = 0; i < data->state.tempcount; i++) { @@ -1062,12 +1060,6 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) } data->state.tempcount = 0; - /* set the connection's current owner */ - if(conn->data != data) { - saved_data = conn->data; - conn->data = data; - } - for(i = 0; i < count; i++) { /* even if one function returns error, this loops through and frees all buffers */ @@ -1078,10 +1070,6 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) Curl_dyn_free(&writebuf[i].b); } - /* recover previous owner of the connection */ - if(saved_data) - conn->data = saved_data; - if(result) return result; } diff --git a/libs/libcurl/src/easyoptions.c b/libs/libcurl/src/easyoptions.c index b54829ba38..db8337b044 100644 --- a/libs/libcurl/src/easyoptions.c +++ b/libs/libcurl/src/easyoptions.c @@ -78,6 +78,9 @@ struct curl_easyoption Curl_easyopts[] = { {"DNS_SERVERS", CURLOPT_DNS_SERVERS, CURLOT_STRING, 0}, {"DNS_SHUFFLE_ADDRESSES", CURLOPT_DNS_SHUFFLE_ADDRESSES, CURLOT_LONG, 0}, {"DNS_USE_GLOBAL_CACHE", CURLOPT_DNS_USE_GLOBAL_CACHE, CURLOT_LONG, 0}, + {"DOH_SSL_VERIFYHOST", CURLOPT_DOH_SSL_VERIFYHOST, CURLOT_LONG, 0}, + {"DOH_SSL_VERIFYPEER", CURLOPT_DOH_SSL_VERIFYPEER, CURLOT_LONG, 0}, + {"DOH_SSL_VERIFYSTATUS", CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOT_LONG, 0}, {"DOH_URL", CURLOPT_DOH_URL, CURLOT_STRING, 0}, {"EGDSOCKET", CURLOPT_EGDSOCKET, CURLOT_STRING, 0}, {"ENCODING", CURLOPT_ACCEPT_ENCODING, CURLOT_STRING, CURLOT_FLAG_ALIAS}, @@ -349,6 +352,6 @@ struct curl_easyoption Curl_easyopts[] = { */ int Curl_easyopts_check(void) { - return ((CURLOPT_LASTENTRY%10000) != (305 + 1)); + return ((CURLOPT_LASTENTRY%10000) != (308 + 1)); } #endif diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c index 3818a9ea46..5bf44f1180 100644 --- a/libs/libcurl/src/ftp.c +++ b/libs/libcurl/src/ftp.c @@ -1357,7 +1357,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data) struct FTP *ftp = data->req.p.ftp; struct connectdata *conn = data->conn; - if(ftp->transfer != FTPTRANSFER_BODY) { + if(ftp->transfer != PPTRANSFER_BODY) { /* doesn't transfer any data */ /* still possibly do PRE QUOTE jobs */ @@ -1378,7 +1378,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data) result = Curl_pp_sendf(data, &ftpc->pp, "PRET %s", data->set.str[STRING_CUSTOMREQUEST]? data->set.str[STRING_CUSTOMREQUEST]: - (data->set.ftp_list_only?"NLST":"LIST")); + (data->state.list_only?"NLST":"LIST")); else if(data->set.upload) result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s", conn->proto.ftpc.file); @@ -1401,7 +1401,7 @@ static CURLcode ftp_state_rest(struct Curl_easy *data, struct FTP *ftp = data->req.p.ftp; struct ftp_conn *ftpc = &conn->proto.ftpc; - if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) { + if((ftp->transfer != PPTRANSFER_BODY) && ftpc->file) { /* if a "head"-like request is being made (on a file) */ /* Determine if server can respond to REST command and therefore @@ -1423,7 +1423,7 @@ static CURLcode ftp_state_size(struct Curl_easy *data, struct FTP *ftp = data->req.p.ftp; struct ftp_conn *ftpc = &conn->proto.ftpc; - if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) { + if((ftp->transfer == PPTRANSFER_INFO) && ftpc->file) { /* if a "head"-like request is being made (on a file) */ /* we know ftpc->file is a valid pointer to a file name */ @@ -1485,7 +1485,7 @@ static CURLcode ftp_state_list(struct Curl_easy *data) cmd = aprintf("%s%s%s", data->set.str[STRING_CUSTOMREQUEST]? data->set.str[STRING_CUSTOMREQUEST]: - (data->set.ftp_list_only?"NLST":"LIST"), + (data->state.list_only?"NLST":"LIST"), lstArg? " ": "", lstArg? lstArg: ""); free(lstArg); @@ -1525,17 +1525,17 @@ static CURLcode ftp_state_type(struct Curl_easy *data) information. Which in FTP can't be much more than the file size and date. */ if(data->set.opt_no_body && ftpc->file && - ftp_need_type(conn, data->set.prefer_ascii)) { + ftp_need_type(conn, data->state.prefer_ascii)) { /* The SIZE command is _not_ RFC 959 specified, and therefore many servers may not support it! It is however the only way we have to get a file's size! */ - ftp->transfer = FTPTRANSFER_INFO; + ftp->transfer = PPTRANSFER_INFO; /* this means no actual transfer will be made */ /* Some servers return different sizes for different modes, and thus we must set the proper type before we check the size */ - result = ftp_nb_type(data, conn, data->set.prefer_ascii, FTP_TYPE); + result = ftp_nb_type(data, conn, data->state.prefer_ascii, FTP_TYPE); if(result) return result; } @@ -1578,6 +1578,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data, struct connectdata *conn = data->conn; struct FTP *ftp = data->req.p.ftp; struct ftp_conn *ftpc = &conn->proto.ftpc; + bool append = data->set.remote_append; if((data->state.resume_from && !sizechecked) || ((data->state.resume_from > 0) && sizechecked)) { @@ -1604,7 +1605,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data, } /* enable append */ - data->set.ftp_append = TRUE; + append = TRUE; /* Let's read off the proper amount of bytes from the input. */ if(conn->seek_func) { @@ -1652,7 +1653,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data, /* Set ->transfer so that we won't get any error in * ftp_done() because we didn't transfer anything! */ - ftp->transfer = FTPTRANSFER_NONE; + ftp->transfer = PPTRANSFER_NONE; state(data, FTP_STOP); return CURLE_OK; @@ -1661,8 +1662,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data, /* we've passed, proceed as normal */ } /* resume_from */ - result = Curl_pp_sendf(data, &ftpc->pp, - data->set.ftp_append?"APPE %s":"STOR %s", + result = Curl_pp_sendf(data, &ftpc->pp, append?"APPE %s":"STOR %s", ftpc->file); if(!result) state(data, FTP_STOR); @@ -1739,7 +1739,7 @@ static CURLcode ftp_state_quote(struct Curl_easy *data, result = ftp_state_cwd(data, conn); break; case FTP_RETR_PREQUOTE: - if(ftp->transfer != FTPTRANSFER_BODY) + if(ftp->transfer != PPTRANSFER_BODY) state(data, FTP_STOP); else { if(ftpc->known_filesize != -1) { @@ -1747,13 +1747,19 @@ static CURLcode ftp_state_quote(struct Curl_easy *data, result = ftp_state_retr(data, ftpc->known_filesize); } else { - if(data->set.ignorecl) { - /* This code is to support download of growing files. It prevents - the state machine from requesting the file size from the - server. With an unknown file size the download continues until - the server terminates it, otherwise the client stops if the - received byte count exceeds the reported file size. Set option - CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/ + if(data->set.ignorecl || data->state.prefer_ascii) { + /* 'ignorecl' is used to support download of growing files. It + prevents the state machine from requesting the file size from + the server. With an unknown file size the download continues + until the server terminates it, otherwise the client stops if + the received byte count exceeds the reported file size. Set + option CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this + behavior. + + In addition: asking for the size for 'TYPE A' transfers is not + constructive since servers don't report the converted size. So + skip it. + */ result = Curl_pp_sendf(data, &ftpc->pp, "RETR %s", ftpc->file); if(!result) state(data, FTP_RETR); @@ -2133,7 +2139,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, default: if(data->info.filetime <= data->set.timevalue) { infof(data, "The requested document is not new enough\n"); - ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */ + ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */ data->info.timecond = TRUE; state(data, FTP_STOP); return CURLE_OK; @@ -2142,7 +2148,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, case CURL_TIMECOND_IFUNMODSINCE: if(data->info.filetime > data->set.timevalue) { infof(data, "The requested document is not old enough\n"); - ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */ + ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */ data->info.timecond = TRUE; state(data, FTP_STOP); return CURLE_OK; @@ -2250,7 +2256,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data, /* Set ->transfer so that we won't get any error in ftp_done() * because we didn't transfer the any file */ - ftp->transfer = FTPTRANSFER_NONE; + ftp->transfer = PPTRANSFER_NONE; state(data, FTP_STOP); return CURLE_OK; } @@ -2303,8 +2309,12 @@ static CURLcode ftp_state_size_resp(struct Curl_easy *data, } else if(ftpcode == 550) { /* "No such file or directory" */ - failf(data, "The file does not exist"); - return CURLE_REMOTE_FILE_NOT_FOUND; + /* allow a SIZE failure for (resumed) uploads, when probing what command + to use */ + if(instate != FTP_STOR_SIZE) { + failf(data, "The file does not exist"); + return CURLE_REMOTE_FILE_NOT_FOUND; + } } if(instate == FTP_SIZE) { @@ -2448,7 +2458,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data, */ if((instate != FTP_LIST) && - !data->set.prefer_ascii && + !data->state.prefer_ascii && (ftp->downloadsize < 1)) { /* * It seems directory listings either don't show the size or very @@ -2476,7 +2486,8 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data, bytes--; } /* if we have nothing but digits: */ - if(bytes++) { + if(bytes) { + ++bytes; /* get the number! */ (void)curlx_strtoofft(bytes, NULL, 0, &size); } @@ -2487,7 +2498,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data, if(size > data->req.maxdownload && data->req.maxdownload > 0) size = data->req.size = data->req.maxdownload; - else if((instate != FTP_LIST) && (data->set.prefer_ascii)) + else if((instate != FTP_LIST) && (data->state.prefer_ascii)) size = -1; /* kludge for servers that understate ASCII mode file size */ infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n", @@ -2521,7 +2532,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data, else { if((instate == FTP_LIST) && (ftpcode == 450)) { /* simply no matching files in the dir listing */ - ftp->transfer = FTPTRANSFER_NONE; /* don't download anything */ + ftp->transfer = PPTRANSFER_NONE; /* don't download anything */ state(data, FTP_STOP); /* this phase is over */ } else { @@ -3291,7 +3302,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, close_secondarysocket(data, conn); } - if(!result && (ftp->transfer == FTPTRANSFER_BODY) && ftpc->ctl_valid && + if(!result && (ftp->transfer == PPTRANSFER_BODY) && ftpc->ctl_valid && pp->pending_resp && !premature) { /* * Let's see what the server says about the transfer we just performed, @@ -3314,8 +3325,10 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */ } - if(result) + if(result) { + Curl_safefree(ftp->pathalloc); return result; + } if(ftpc->dont_check && data->req.maxdownload > 0) { /* we have just sent ABOR and there is no reliable way to check if it was @@ -3351,7 +3364,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, if((-1 != data->state.infilesize) && (data->state.infilesize != data->req.writebytecount) && !data->set.crlf && - (ftp->transfer == FTPTRANSFER_BODY)) { + (ftp->transfer == PPTRANSFER_BODY)) { failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T " out of %" CURL_FORMAT_CURL_OFF_T " bytes)", data->req.bytecount, data->state.infilesize); @@ -3383,7 +3396,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, } /* clear these for next connection */ - ftp->transfer = FTPTRANSFER_BODY; + ftp->transfer = PPTRANSFER_BODY; ftpc->dont_check = FALSE; /* Send any post-transfer QUOTE strings? */ @@ -3594,7 +3607,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) *completep = 0; } - if(ftp->transfer <= FTPTRANSFER_INFO) { + if(ftp->transfer <= PPTRANSFER_INFO) { /* a transfer is about to take place, or if not a file name was given so we'll do a SIZE on it later and then we need the right TYPE first */ @@ -3620,7 +3633,8 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) } } else if(data->set.upload) { - result = ftp_nb_type(data, conn, data->set.prefer_ascii, FTP_STOR_TYPE); + result = ftp_nb_type(data, conn, data->state.prefer_ascii, + FTP_STOR_TYPE); if(result) return result; @@ -3641,13 +3655,13 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) if(result) ; - else if(data->set.ftp_list_only || !ftpc->file) { + else if(data->state.list_only || !ftpc->file) { /* The specified path ends with a slash, and therefore we think this is a directory that is requested, use LIST. But before that we need to set ASCII transfer mode. */ /* But only if a body transfer was requested. */ - if(ftp->transfer == FTPTRANSFER_BODY) { + if(ftp->transfer == PPTRANSFER_BODY) { result = ftp_nb_type(data, conn, TRUE, FTP_LIST_TYPE); if(result) return result; @@ -3655,7 +3669,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) /* otherwise just fall through */ } else { - result = ftp_nb_type(data, conn, data->set.prefer_ascii, + result = ftp_nb_type(data, conn, data->state.prefer_ascii, FTP_RETR_TYPE); if(result) return result; @@ -3703,7 +3717,7 @@ CURLcode ftp_perform(struct Curl_easy *data, if(data->set.opt_no_body) { /* requested no body means no transfer... */ struct FTP *ftp = data->req.p.ftp; - ftp->transfer = FTPTRANSFER_INFO; + ftp->transfer = PPTRANSFER_INFO; } *dophase_done = FALSE; /* not done yet */ @@ -4193,7 +4207,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data) ftpc->file = NULL; /* instead of point to a zero byte, we make it a NULL pointer */ - if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) { + if(data->set.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) { /* We need a file name when uploading. Return error! */ failf(data, "Uploading to a URL without a file name!"); free(rawPath); @@ -4241,7 +4255,7 @@ static CURLcode ftp_dophase_done(struct Curl_easy *data, bool connected) } } - if(ftp->transfer != FTPTRANSFER_BODY) + if(ftp->transfer != PPTRANSFER_BODY) /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); else if(!connected) @@ -4345,23 +4359,23 @@ static CURLcode ftp_setup_connection(struct Curl_easy *data, switch(command) { case 'A': /* ASCII mode */ - data->set.prefer_ascii = TRUE; + data->state.prefer_ascii = TRUE; break; case 'D': /* directory mode */ - data->set.ftp_list_only = TRUE; + data->state.list_only = TRUE; break; case 'I': /* binary mode */ default: /* switch off ASCII */ - data->set.prefer_ascii = FALSE; + data->state.prefer_ascii = FALSE; break; } } /* get some initial data into the ftp struct */ - ftp->transfer = FTPTRANSFER_BODY; + ftp->transfer = PPTRANSFER_BODY; ftp->downloadsize = 0; conn->proto.ftpc.known_filesize = -1; /* unknown size for now */ diff --git a/libs/libcurl/src/ftplistparser.c b/libs/libcurl/src/ftplistparser.c index d3720b1f10..81825e6ff6 100644 --- a/libs/libcurl/src/ftplistparser.c +++ b/libs/libcurl/src/ftplistparser.c @@ -966,7 +966,6 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, else if(c == '\n') { parser->offsets.filename = parser->item_offset; finfo->b_data[finfo->b_used - 1] = 0; - parser->offsets.filename = parser->item_offset; result = ftp_pl_insert_finfo(data, infop); if(result) { parser->error = result; diff --git a/libs/libcurl/src/getinfo.c b/libs/libcurl/src/getinfo.c index 67ea07d2ee..9091e6139d 100644 --- a/libs/libcurl/src/getinfo.c +++ b/libs/libcurl/src/getinfo.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -94,7 +94,7 @@ static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info, { switch(info) { case CURLINFO_EFFECTIVE_URL: - *param_charp = data->change.url?data->change.url:(char *)""; + *param_charp = data->state.url?data->state.url:(char *)""; break; case CURLINFO_EFFECTIVE_METHOD: { const char *m = data->set.str[STRING_CUSTOMREQUEST]; @@ -145,6 +145,10 @@ static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info, option had been enabled! */ *param_charp = data->info.wouldredirect; break; + case CURLINFO_REFERER: + /* Return the referrer header for this request, or NULL if unset */ + *param_charp = data->state.referer; + break; case CURLINFO_PRIMARY_IP: /* Return the ip address of the most recent (primary) connection */ *param_charp = data->info.conn_primary_ip; @@ -235,7 +239,7 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, break; #endif case CURLINFO_REDIRECT_COUNT: - *param_longp = data->set.followlocation; + *param_longp = data->state.followlocation; break; case CURLINFO_HTTPAUTH_AVAIL: lptr.to_long = param_longp; diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c index 8ba3fe81ce..750afe8a97 100644 --- a/libs/libcurl/src/hostip.c +++ b/libs/libcurl/src/hostip.c @@ -269,7 +269,7 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data, dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1); /* No entry found in cache, check if we might have a wildcard entry */ - if(!dns && data->change.wildcard_resolve) { + if(!dns && data->state.wildcard_resolve) { create_hostcache_id("*", port, entry_id, sizeof(entry_id)); entry_len = strlen(entry_id); @@ -520,8 +520,14 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, if(data->set.resolver_start) { int st; Curl_set_in_callback(data, true); - st = data->set.resolver_start(data->state.async.resolver, NULL, - data->set.resolver_start_client); + st = data->set.resolver_start( +#ifdef USE_CURL_ASYNC + data->state.async.resolver, +#else + NULL, +#endif + NULL, + data->set.resolver_start_client); Curl_set_in_callback(data, false); if(st) return CURLRESOLV_ERROR; @@ -872,9 +878,9 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) int port = 0; /* Default is no wildcard found */ - data->change.wildcard_resolve = false; + data->state.wildcard_resolve = false; - for(hostp = data->change.resolve; hostp; hostp = hostp->next) { + for(hostp = data->state.resolve; hostp; hostp = hostp->next) { char entry_id[MAX_HOSTCACHE_LEN]; if(!hostp->data) continue; @@ -1055,11 +1061,11 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) if(hostname[0] == '*' && hostname[1] == '\0') { infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks\n", hostname, port); - data->change.wildcard_resolve = true; + data->state.wildcard_resolve = true; } } } - data->change.resolve = NULL; /* dealt with now */ + data->state.resolve = NULL; /* dealt with now */ return CURLE_OK; } @@ -1102,10 +1108,12 @@ CURLcode Curl_once_resolved(struct Curl_easy *data, bool *protocol_done) CURLcode result; struct connectdata *conn = data->conn; +#ifdef USE_CURL_ASYNC if(data->state.async.dns) { conn->dns_entry = data->state.async.dns; data->state.async.dns = NULL; } +#endif result = Curl_setup_conn(data, protocol_done); @@ -1116,3 +1124,32 @@ CURLcode Curl_once_resolved(struct Curl_easy *data, bool *protocol_done) } return result; } + +/* + * Curl_resolver_error() calls failf() with the appropriate message after a + * resolve error + */ + +CURLcode Curl_resolver_error(struct Curl_easy *data) +{ + const char *host_or_proxy; + CURLcode result; + +#ifndef CURL_DISABLE_PROXY + struct connectdata *conn = data->conn; + if(conn->bits.httpproxy) { + host_or_proxy = "proxy"; + result = CURLE_COULDNT_RESOLVE_PROXY; + } + else +#endif + { + host_or_proxy = "host"; + result = CURLE_COULDNT_RESOLVE_HOST; + } + + failf(data, "Could not resolve %s: %s", host_or_proxy, + data->state.async.hostname); + + return result; +} diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h index c495c21e02..c0fd3c8c46 100644 --- a/libs/libcurl/src/hostip.h +++ b/libs/libcurl/src/hostip.h @@ -245,4 +245,5 @@ CURLcode Curl_resolv_check(struct Curl_easy *data, int Curl_resolv_getsock(struct Curl_easy *data, curl_socket_t *socks); +CURLcode Curl_resolver_error(struct Curl_easy *data); #endif /* HEADER_CURL_HOSTIP_H */ diff --git a/libs/libcurl/src/hsts.c b/libs/libcurl/src/hsts.c index 0e7c19cfbd..fd4926f36b 100644 --- a/libs/libcurl/src/hsts.c +++ b/libs/libcurl/src/hsts.c @@ -46,8 +46,6 @@ #define MAX_HSTS_LINE 4095 #define MAX_HSTS_HOSTLEN 256 #define MAX_HSTS_HOSTLENSTR "256" -#define MAX_HSTS_SUBLEN 4 -#define MAX_HSTS_SUBLENSTR "4" #define MAX_HSTS_DATELEN 64 #define MAX_HSTS_DATELENSTR "64" diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c index 6f7f55d078..02c81c419b 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.c @@ -183,7 +183,7 @@ static CURLcode http_setup_conn(struct Curl_easy *data, Curl_mime_initpart(&http->form, data); data->req.p.http = http; - if(data->set.httpversion == CURL_HTTP_VERSION_3) { + if(data->state.httpwant == CURL_HTTP_VERSION_3) { if(conn->handler->flags & PROTOPT_SSL) /* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does the QUIC dance. */ @@ -298,26 +298,27 @@ static CURLcode http_output_basic(struct Curl_easy *data, bool proxy) { size_t size = 0; char *authorization = NULL; - struct connectdata *conn = data->conn; char **userp; const char *user; const char *pwd; CURLcode result; char *out; + /* credentials are unique per transfer for HTTP, do not use the ones for the + connection */ if(proxy) { #ifndef CURL_DISABLE_PROXY userp = &data->state.aptr.proxyuserpwd; - user = conn->http_proxy.user; - pwd = conn->http_proxy.passwd; + user = data->state.aptr.proxyuser; + pwd = data->state.aptr.proxypasswd; #else return CURLE_NOT_BUILT_IN; #endif } else { userp = &data->state.aptr.userpwd; - user = conn->user; - pwd = conn->passwd; + user = data->state.aptr.user; + pwd = data->state.aptr.passwd; } out = aprintf("%s:%s", user, pwd ? pwd : ""); @@ -595,7 +596,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data) conn->httpversion > 11) { infof(data, "Forcing HTTP/1.1 for NTLM"); connclose(conn, "Force HTTP/1.1 connection"); - data->set.httpversion = CURL_HTTP_VERSION_1_1; + data->state.httpwant = CURL_HTTP_VERSION_1_1; } } #ifndef CURL_DISABLE_PROXY @@ -621,7 +622,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data) we must make sure to free it before allocating a new one. As figured out in bug #2284386 */ Curl_safefree(data->req.newurl); - data->req.newurl = strdup(data->change.url); /* clone URL */ + data->req.newurl = strdup(data->state.url); /* clone URL */ if(!data->req.newurl) return CURLE_OUT_OF_MEMORY; } @@ -634,7 +635,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data) we didn't try HEAD or GET */ if((data->state.httpreq != HTTPREQ_GET) && (data->state.httpreq != HTTPREQ_HEAD)) { - data->req.newurl = strdup(data->change.url); /* clone URL */ + data->req.newurl = strdup(data->state.url); /* clone URL */ if(!data->req.newurl) return CURLE_OUT_OF_MEMORY; data->state.authhost.done = TRUE; @@ -709,7 +710,6 @@ output_auth_headers(struct Curl_easy *data, if(authstatus->picked == CURLAUTH_DIGEST) { auth = "Digest"; result = Curl_output_digest(data, - conn, proxy, (const unsigned char *)request, (const unsigned char *)path); @@ -756,11 +756,14 @@ output_auth_headers(struct Curl_easy *data, #ifndef CURL_DISABLE_PROXY infof(data, "%s auth using %s with user '%s'\n", proxy ? "Proxy" : "Server", auth, - proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") : - (conn->user ? conn->user : "")); + proxy ? (data->state.aptr.proxyuser ? + data->state.aptr.proxyuser : "") : + (data->state.aptr.user ? + data->state.aptr.user : "")); #else infof(data, "Server auth using %s with user '%s'\n", - auth, conn->user ? conn->user : ""); + auth, data->state.aptr.user ? + data->state.aptr.user : ""); #endif authstatus->multipass = (!authstatus->done) ? TRUE : FALSE; } @@ -871,13 +874,17 @@ Curl_http_output_auth(struct Curl_easy *data, #else /* when disabled */ CURLcode -Curl_http_output_auth(struct connectdata *conn, +Curl_http_output_auth(struct Curl_easy *data, + struct connectdata *conn, const char *request, + Curl_HttpReq httpreq, const char *path, bool proxytunnel) { + (void)data; (void)conn; (void)request; + (void)httpreq; (void)path; (void)proxytunnel; return CURLE_OK; @@ -943,7 +950,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, CURLcode result = Curl_input_negotiate(data, conn, proxy, auth); if(!result) { DEBUGASSERT(!data->req.newurl); - data->req.newurl = strdup(data->change.url); + data->req.newurl = strdup(data->state.url); if(!data->req.newurl) return CURLE_OUT_OF_MEMORY; data->state.authproblem = FALSE; @@ -1088,6 +1095,14 @@ static bool http_should_fail(struct Curl_easy *data) return FALSE; /* + ** A 416 response to a resume request is presumably because the file is + ** already completely downloaded and thus not actually a fail. + */ + if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET && + httpcode == 416) + return FALSE; + + /* ** Any code >= 400 that's not 401 or 407 is always ** a terminal error */ @@ -1152,7 +1167,12 @@ static size_t readmoredata(char *buffer, /* make sure that a HTTP request is never sent away chunked! */ data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE; - if(http->postsize <= (curl_off_t)fullsize) { + if(data->set.max_send_speed && + (data->set.max_send_speed < http->postsize)) + /* speed limit */ + fullsize = (size_t)data->set.max_send_speed; + + else if(http->postsize <= (curl_off_t)fullsize) { memcpy(buffer, http->postdata, (size_t)http->postsize); fullsize = (size_t)http->postsize; @@ -1192,7 +1212,7 @@ CURLcode Curl_buffer_send(struct dynbuf *in, counter */ curl_off_t *bytes_written, /* how much of the buffer contains body data */ - size_t included_body_bytes, + curl_off_t included_body_bytes, int socketindex) { ssize_t amount; @@ -1215,10 +1235,10 @@ CURLcode Curl_buffer_send(struct dynbuf *in, ptr = Curl_dyn_ptr(in); size = Curl_dyn_len(in); - headersize = size - included_body_bytes; /* the initial part that isn't body - is header */ + headersize = size - (size_t)included_body_bytes; /* the initial part that + isn't body is header */ - DEBUGASSERT(size > included_body_bytes); + DEBUGASSERT(size > (size_t)included_body_bytes); result = Curl_convert_to_network(data, ptr, headersize); /* Curl_convert_to_network calls failf if unsuccessful */ @@ -1234,13 +1254,25 @@ CURLcode Curl_buffer_send(struct dynbuf *in, #endif ) && conn->httpversion != 20) { + /* Make sure this doesn't send more body bytes than what the max send + speed says. The request bytes do not count to the max speed. + */ + if(data->set.max_send_speed && + (included_body_bytes > data->set.max_send_speed)) { + curl_off_t overflow = included_body_bytes - data->set.max_send_speed; + DEBUGASSERT((size_t)overflow < size); + sendsize = size - (size_t)overflow; + } + 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. */ - - sendsize = CURLMIN(size, CURL_MAX_WRITE_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 @@ -1272,7 +1304,19 @@ CURLcode Curl_buffer_send(struct dynbuf *in, } else #endif - sendsize = size; + { + /* Make sure this doesn't send more body bytes than what the max send + speed says. The request bytes do not count to the max speed. + */ + if(data->set.max_send_speed && + (included_body_bytes > data->set.max_send_speed)) { + curl_off_t overflow = included_body_bytes - data->set.max_send_speed; + DEBUGASSERT((size_t)overflow < size); + sendsize = size - (size_t)overflow; + } + else + sendsize = size; + } } result = Curl_write(data, sockfd, ptr, sendsize, &amount); @@ -1500,7 +1544,7 @@ static CURLcode add_haproxy_protocol_header(struct Curl_easy *data) msnprintf(proxy_header, sizeof(proxy_header), - "PROXY %s %s %s %li %li\r\n", + "PROXY %s %s %s %i %i\r\n", tcp_version, data->info.conn_local_ip, data->info.conn_primary_ip, @@ -1548,7 +1592,7 @@ static int https_getsock(struct Curl_easy *data, { (void)data; if(conn->handler->flags & PROTOPT_SSL) - return Curl_ssl_getsock(conn, socks); + return Curl_ssl->getsock(conn, socks); return GETSOCK_BLANK; } #endif /* USE_SSL */ @@ -1621,11 +1665,11 @@ static bool use_http_1_1plus(const struct Curl_easy *data, { if((data->state.httpversion == 10) || (conn->httpversion == 10)) return FALSE; - if((data->set.httpversion == CURL_HTTP_VERSION_1_0) && + if((data->state.httpwant == CURL_HTTP_VERSION_1_0) && (conn->httpversion <= 10)) return FALSE; - return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) || - (data->set.httpversion >= CURL_HTTP_VERSION_1_1)); + return ((data->state.httpwant == CURL_HTTP_VERSION_NONE) || + (data->state.httpwant >= CURL_HTTP_VERSION_1_1)); } #ifndef USE_HYPER @@ -1633,7 +1677,7 @@ static const char *get_http_string(const struct Curl_easy *data, const struct connectdata *conn) { #ifdef ENABLE_QUIC - if((data->set.httpversion == CURL_HTTP_VERSION_3) || + if((data->state.httpwant == CURL_HTTP_VERSION_3) || (conn->httpversion == 30)) return "3"; #endif @@ -1698,7 +1742,7 @@ CURLcode Curl_http_compile_trailers(struct curl_slist *trailers, if( #ifdef CURL_DO_LINEEND_CONV - (handle->set.prefer_ascii) || + (handle->state.prefer_ascii) || #endif (handle->set.crlf)) { /* \n will become \r\n later on */ @@ -1960,10 +2004,10 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data, } #else /* disabled */ -CURLcode Curl_add_timecondition(const struct connectdata *conn, +CURLcode Curl_add_timecondition(struct Curl_easy *data, struct dynbuf *req) { - (void)conn; + (void)data; (void)req; return CURLE_OK; } @@ -2174,7 +2218,7 @@ CURLcode Curl_http_target(struct Curl_easy *data, /* Extract the URL to use in the request. Store in STRING_TEMP_URL for clean-up reasons if the function returns before the free() further down. */ - uc = curl_url_get(h, CURLUPART_URL, &url, 0); + uc = curl_url_get(h, CURLUPART_URL, &url, CURLU_NO_DEFAULT_PORT); if(uc) { curl_url_cleanup(h); return CURLE_OUT_OF_MEMORY; @@ -2205,7 +2249,7 @@ CURLcode Curl_http_target(struct Curl_easy *data, } if(!type) { result = Curl_dyn_addf(r, ";type=%c", - data->set.prefer_ascii ? 'a' : 'i'); + data->state.prefer_ascii ? 'a' : 'i'); if(result) return result; } @@ -2614,8 +2658,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, } } /* issue the request */ - result = Curl_buffer_send(r, data, &data->info.request_size, - (size_t)included_body, FIRSTSOCKET); + result = Curl_buffer_send(r, data, &data->info.request_size, included_body, + FIRSTSOCKET); if(result) failf(data, "Failed sending HTTP POST request"); @@ -2946,7 +2990,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) default: /* Check if user wants to use HTTP/2 with clear TCP*/ #ifdef USE_NGHTTP2 - if(data->set.httpversion == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) { + if(data->state.httpwant == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) { #ifndef CURL_DISABLE_PROXY if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { /* We don't support HTTP/2 proxies yet. Also it's debatable @@ -3002,8 +3046,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) } Curl_safefree(data->state.aptr.ref); - if(data->change.referer && !Curl_checkheaders(data, "Referer")) { - data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer); + if(data->state.referer && !Curl_checkheaders(data, "Referer")) { + data->state.aptr.ref = aprintf("Referer: %s\r\n", data->state.referer); if(!data->state.aptr.ref) return CURLE_OUT_OF_MEMORY; } @@ -3016,10 +3060,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(!data->state.aptr.accept_encoding) return CURLE_OUT_OF_MEMORY; } - else { + else Curl_safefree(data->state.aptr.accept_encoding); - data->state.aptr.accept_encoding = NULL; - } #ifdef HAVE_LIBZ /* we only consider transfer-encoding magic if libz support is built-in */ @@ -3124,7 +3166,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) *data->set.str[STRING_ENCODING] && data->state.aptr.accept_encoding)? data->state.aptr.accept_encoding:"", - (data->change.referer && data->state.aptr.ref)? + (data->state.referer && data->state.aptr.ref)? data->state.aptr.ref:"" /* Referer: <data> */, #ifndef CURL_DISABLE_PROXY (conn->bits.httpproxy && @@ -3152,10 +3194,10 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(!(conn->handler->flags&PROTOPT_SSL) && conn->httpversion != 20 && - (data->set.httpversion == CURL_HTTP_VERSION_2)) { + (data->state.httpwant == CURL_HTTP_VERSION_2)) { /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done over SSL */ - result = Curl_http2_request_upgrade(&req, conn); + result = Curl_http2_request_upgrade(&req, data); if(result) { Curl_dyn_free(&req); return result; @@ -3995,7 +4037,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, infof(data, "Got 417 while waiting for a 100\n"); data->state.disableexpect = TRUE; DEBUGASSERT(!data->req.newurl); - data->req.newurl = strdup(data->change.url); + data->req.newurl = strdup(data->state.url); Curl_done_sending(data, k); } else if(data->set.http_keep_sending_on_error) { @@ -4144,10 +4186,11 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, */ char separator; char twoorthree[2]; + int httpversion = 0; nc = sscanf(HEADER1, " HTTP/%1d.%1d%c%3d", &httpversion_major, - &conn->httpversion, + &httpversion, &separator, &k->httpcode); @@ -4159,7 +4202,23 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, } if((nc == 4) && (' ' == separator)) { - conn->httpversion += 10 * httpversion_major; + httpversion += 10 * httpversion_major; + switch(httpversion) { + case 10: + case 11: +#if defined(USE_NGHTTP2) || defined(USE_HYPER) + case 20: +#endif +#if defined(ENABLE_QUIC) + case 30: +#endif + conn->httpversion = (unsigned char)httpversion; + break; + default: + failf(data, "Unsupported HTTP version (%u.%d) in response", + httpversion/10, httpversion%10); + return CURLE_UNSUPPORTED_PROTOCOL; + } if(k->upgr101 == UPGR101_RECEIVED) { /* supposedly upgraded to http2 now */ @@ -4200,14 +4259,14 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, } else if(conn->handler->protocol & CURLPROTO_RTSP) { char separator; + int rtspversion; nc = sscanf(HEADER1, " RTSP/%1d.%1d%c%3d", &rtspversion_major, - &conn->rtspversion, + &rtspversion, &separator, &k->httpcode); if((nc == 4) && (' ' == separator)) { - conn->rtspversion += 10 * rtspversion_major; conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */ } else { diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h index 28f9341f67..36e2152fe3 100644 --- a/libs/libcurl/src/http.h +++ b/libs/libcurl/src/http.h @@ -58,7 +58,7 @@ char *Curl_checkProxyheaders(struct Curl_easy *data, CURLcode Curl_buffer_send(struct dynbuf *in, struct Curl_easy *data, curl_off_t *bytes_written, - size_t included_body_bytes, + curl_off_t included_body_bytes, int socketindex); #else #define Curl_buffer_send(a,b,c,d,e) CURLE_OK @@ -251,9 +251,16 @@ struct h2settings { struct http_conn { #ifdef USE_NGHTTP2 #define H2_BINSETTINGS_LEN 80 - nghttp2_session *h2; uint8_t binsettings[H2_BINSETTINGS_LEN]; size_t binlen; /* length of the binsettings data */ + + /* We associate the connnectdata struct with the connection, but we need to + make sure we can identify the current "driving" transfer. This is a + work-around for the lack of nghttp2_session_set_user_data() in older + nghttp2 versions that we want to support. (Added in 1.31.0) */ + struct Curl_easy *trnsfr; + + nghttp2_session *h2; Curl_send *send_underlying; /* underlying send Curl_send callback */ Curl_recv *recv_underlying; /* underlying recv Curl_recv callback */ char *inbuf; /* buffer to receive data from underlying socket */ diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index be4c712420..ce9a0d393c 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -211,6 +211,24 @@ static bool http2_connisdead(struct Curl_easy *data, struct connectdata *conn) return dead; } +/* + * Set the transfer that is currently using this HTTP/2 connection. + */ +static void set_transfer(struct http_conn *c, + struct Curl_easy *data) +{ + c->trnsfr = data; +} + +/* + * Get the transfer that is currently using this HTTP/2 connection. + */ +static struct Curl_easy *get_transfer(struct http_conn *c) +{ + DEBUGASSERT(c && c->trnsfr); + return c->trnsfr; +} + static unsigned int http2_conncheck(struct Curl_easy *data, struct connectdata *conn, unsigned int checks_to_perform) @@ -247,6 +265,7 @@ static unsigned int http2_conncheck(struct Curl_easy *data, } if(send_frames) { + set_transfer(c, data); /* set the transfer */ rc = nghttp2_session_send(c->h2); if(rc) failf(data, "nghttp2_session_send() failed: %s(%d)", @@ -349,6 +368,7 @@ static ssize_t send_callback(nghttp2_session *h2, { struct connectdata *conn = (struct connectdata *)userp; struct http_conn *c = &conn->proto.httpc; + struct Curl_easy *data = get_transfer(c); ssize_t written; CURLcode result = CURLE_OK; @@ -359,7 +379,7 @@ static ssize_t send_callback(nghttp2_session *h2, /* called before setup properly! */ return NGHTTP2_ERR_CALLBACK_FAILURE; - written = ((Curl_send*)c->send_underlying)(conn->data, FIRSTSOCKET, + written = ((Curl_send*)c->send_underlying)(data, FIRSTSOCKET, mem, length, &result); if(result == CURLE_AGAIN) { @@ -367,7 +387,7 @@ static ssize_t send_callback(nghttp2_session *h2, } if(written == -1) { - failf(conn->data, "Failed sending HTTP2 data"); + failf(data, "Failed sending HTTP2 data"); return NGHTTP2_ERR_CALLBACK_FAILURE; } @@ -507,10 +527,10 @@ static int set_transfer_url(struct Curl_easy *data, return 4; curl_url_cleanup(u); - if(data->change.url_alloc) - free(data->change.url); - data->change.url_alloc = TRUE; - data->change.url = url; + if(data->state.url_alloc) + free(data->state.url); + data->state.url_alloc = TRUE; + data->state.url = url; return 0; } @@ -633,6 +653,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, struct http_conn *httpc = &conn->proto.httpc; struct Curl_easy *data_s = NULL; struct HTTP *stream = NULL; + struct Curl_easy *data = get_transfer(httpc); int rv; size_t left, ncopy; int32_t stream_id = frame->hd.stream_id; @@ -642,30 +663,30 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, /* stream ID zero is for connection-oriented stuff */ if(frame->hd.type == NGHTTP2_SETTINGS) { uint32_t max_conn = httpc->settings.max_concurrent_streams; - H2BUGF(infof(conn->data, "Got SETTINGS\n")); + H2BUGF(infof(data, "Got SETTINGS\n")); httpc->settings.max_concurrent_streams = nghttp2_session_get_remote_settings( session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); httpc->settings.enable_push = nghttp2_session_get_remote_settings( session, NGHTTP2_SETTINGS_ENABLE_PUSH); - H2BUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n", + H2BUGF(infof(data, "MAX_CONCURRENT_STREAMS == %d\n", httpc->settings.max_concurrent_streams)); - H2BUGF(infof(conn->data, "ENABLE_PUSH == %s\n", + H2BUGF(infof(data, "ENABLE_PUSH == %s\n", httpc->settings.enable_push?"TRUE":"false")); if(max_conn != httpc->settings.max_concurrent_streams) { /* only signal change if the value actually changed */ - infof(conn->data, + infof(data, "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n", httpc->settings.max_concurrent_streams); - multi_connchanged(conn->data->multi); + multi_connchanged(data->multi); } } return 0; } data_s = nghttp2_session_get_stream_user_data(session, stream_id); if(!data_s) { - H2BUGF(infof(conn->data, + H2BUGF(infof(data, "No Curl_easy associated with stream: %x\n", stream_id)); return 0; @@ -733,14 +754,9 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, stream->memlen += ncopy; drain_this(data_s, httpc); - { - /* get the pointer from userp again since it was re-assigned above */ - struct connectdata *conn_s = (struct connectdata *)userp; - - /* if we receive data for another handle, wake that up */ - if(conn_s->data != data_s) - Curl_expire(data_s, 0, EXPIRE_RUN_NOW); - } + /* if we receive data for another handle, wake that up */ + if(get_transfer(httpc) != data_s) + Curl_expire(data_s, 0, EXPIRE_RUN_NOW); break; case NGHTTP2_PUSH_PROMISE: rv = push_promise(data_s, conn, &frame->push_promise); @@ -768,15 +784,15 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, int32_t stream_id, - const uint8_t *data, size_t len, void *userp) + const uint8_t *mem, size_t len, void *userp) { struct HTTP *stream; struct Curl_easy *data_s; size_t nread; struct connectdata *conn = (struct connectdata *)userp; + struct http_conn *httpc = &conn->proto.httpc; (void)session; (void)flags; - (void)data; DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ @@ -792,7 +808,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, return NGHTTP2_ERR_CALLBACK_FAILURE; nread = CURLMIN(stream->len, len); - memcpy(&stream->mem[stream->memlen], data, nread); + memcpy(&stream->mem[stream->memlen], mem, nread); stream->len -= nread; stream->memlen += nread; @@ -800,7 +816,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, drain_this(data_s, &conn->proto.httpc); /* if we receive data for another handle, wake that up */ - if(conn->data != data_s) + if(get_transfer(httpc) != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); H2BUGF(infof(data_s, "%zu data received for stream %u " @@ -810,7 +826,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, stream->memlen)); if(nread < len) { - stream->pausedata = data + nread; + stream->pausedata = mem + nread; stream->pauselen = len - nread; H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer" ", stream %u\n", @@ -822,7 +838,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, /* pause execution of nghttp2 if we received data for another handle in order to process them first. */ - if(conn->data != data_s) { + if(get_transfer(httpc) != data_s) { data_s->conn->proto.httpc.pause_stream_id = stream_id; return NGHTTP2_ERR_PAUSE; @@ -944,6 +960,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, struct Curl_easy *data_s; int32_t stream_id = frame->hd.stream_id; struct connectdata *conn = (struct connectdata *)userp; + struct http_conn *httpc = &conn->proto.httpc; CURLcode result; (void)flags; @@ -1049,7 +1066,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(result) return NGHTTP2_ERR_CALLBACK_FAILURE; /* if we receive data for another handle, wake that up */ - if(conn->data != data_s) + if(get_transfer(httpc) != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n", @@ -1073,7 +1090,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(result) return NGHTTP2_ERR_CALLBACK_FAILURE; /* if we receive data for another handle, wake that up */ - if(conn->data != data_s) + if(get_transfer(httpc) != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); H2BUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen, @@ -1138,27 +1155,27 @@ static int error_callback(nghttp2_session *session, size_t len, void *userp) { - struct connectdata *conn = (struct connectdata *)userp; (void)session; - infof(conn->data, "http2 error: %.*s\n", len, msg); + (void)msg; + (void)len; + (void)userp; return 0; } #endif -static void populate_settings(struct connectdata *conn, +static void populate_settings(struct Curl_easy *data, struct http_conn *httpc) { nghttp2_settings_entry *iv = httpc->local_settings; - DEBUGASSERT(conn->data); iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; - iv[0].value = Curl_multi_max_concurrent_streams(conn->data->multi); + iv[0].value = Curl_multi_max_concurrent_streams(data->multi); iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE; iv[1].value = HTTP2_HUGE_WINDOW_SIZE; iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; - iv[2].value = conn->data->multi->push_cb != NULL; + iv[2].value = data->multi->push_cb != NULL; httpc->local_settings_num = 3; } @@ -1187,6 +1204,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature) if(premature) { /* RST_STREAM */ + set_transfer(httpc, data); /* set the transfer */ if(!nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, http->stream_id, NGHTTP2_STREAM_CLOSED)) (void)nghttp2_session_send(httpc->h2); @@ -1209,6 +1227,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature) http->stream_id); DEBUGASSERT(0); } + set_transfer(httpc, NULL); http->stream_id = 0; } } @@ -1269,18 +1288,18 @@ static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn) * Append headers to ask for a HTTP1.1 to HTTP2 upgrade. */ CURLcode Curl_http2_request_upgrade(struct dynbuf *req, - struct connectdata *conn) + struct Curl_easy *data) { CURLcode result; ssize_t binlen; char *base64; size_t blen; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; struct SingleRequest *k = &data->req; uint8_t *binsettings = conn->proto.httpc.binsettings; struct http_conn *httpc = &conn->proto.httpc; - populate_settings(conn, httpc); + populate_settings(data, httpc); /* this returns number of bytes it wrote */ binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN, @@ -1338,6 +1357,7 @@ static int h2_process_pending_input(struct Curl_easy *data, nread = httpc->inbuflen - httpc->nread_inbuf; inbuf = httpc->inbuf + httpc->nread_inbuf; + set_transfer(httpc, data); /* set the transfer */ rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread); if(rv < 0) { failf(data, @@ -1426,13 +1446,15 @@ CURLcode Curl_http2_done_sending(struct Curl_easy *data, H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)\n", data)); - /* re-set KEEP_SEND to make sure we are called again */ - k->keepon |= KEEP_SEND; - /* and attempt to send the pending frames */ rv = h2_session_send(data, h2); if(rv != 0) result = CURLE_SEND_ERROR; + + if(nghttp2_session_want_write(h2)) { + /* re-set KEEP_SEND to make sure we are called again */ + k->keepon |= KEEP_SEND; + } } } return result; @@ -1542,6 +1564,8 @@ static int h2_session_send(struct Curl_easy *data, nghttp2_session *h2) { struct HTTP *stream = data->req.p.http; + struct http_conn *httpc = &data->conn->proto.httpc; + set_transfer(httpc, data); if((data->set.stream_weight != data->state.stream_weight) || (data->set.stream_depends_e != data->state.stream_depends_e) || (data->set.stream_depends_on != data->state.stream_depends_on) ) { @@ -1707,6 +1731,17 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, } if(nread == 0) { + if(!stream->closed) { + /* This will happen when the server or proxy server is SIGKILLed + during data transfer. We should emit an error since our data + received may be incomplete. */ + failf(data, "HTTP/2 stream %d was not closed cleanly before" + " end of the underlying stream", + stream->stream_id); + *err = CURLE_HTTP2_STREAM; + return -1; + } + H2BUGF(infof(data, "end of stream\n")); *err = CURLE_OK; return 0; @@ -2117,9 +2152,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, stream_id, (void *)data); stream->stream_id = stream_id; - /* this does not call h2_session_send() since there can not have been any - * priority update since the nghttp2_submit_request() call above */ - rv = nghttp2_session_send(h2); + rv = h2_session_send(data, h2); if(rv != 0) { H2BUGF(infof(data, "http2_send() nghttp2_session_send error (%s)%d\n", @@ -2244,7 +2277,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data, } } else { - populate_settings(conn, httpc); + populate_settings(data, httpc); /* stream ID is unknown at this point */ stream->stream_id = -1; diff --git a/libs/libcurl/src/http2.h b/libs/libcurl/src/http2.h index 119e584a8b..150f7219f0 100644 --- a/libs/libcurl/src/http2.h +++ b/libs/libcurl/src/http2.h @@ -43,7 +43,7 @@ CURLcode Curl_http2_init(struct connectdata *conn); void Curl_http2_init_state(struct UrlState *state); void Curl_http2_init_userset(struct UserDefined *set); CURLcode Curl_http2_request_upgrade(struct dynbuf *req, - struct connectdata *conn); + struct Curl_easy *data); CURLcode Curl_http2_setup(struct Curl_easy *data, struct connectdata *conn); CURLcode Curl_http2_switched(struct Curl_easy *data, const char *ptr, size_t nread); diff --git a/libs/libcurl/src/http_aws_sigv4.c b/libs/libcurl/src/http_aws_sigv4.c index 8fd1c77e60..a04b46a351 100644 --- a/libs/libcurl/src/http_aws_sigv4.c +++ b/libs/libcurl/src/http_aws_sigv4.c @@ -99,8 +99,8 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) char *request_type = NULL; char *credential_scope = NULL; char *str_to_sign = NULL; - const char *user = conn->user ? conn->user : ""; - const char *passwd = conn->passwd ? conn->passwd : ""; + const char *user = data->state.aptr.user ? data->state.aptr.user : ""; + const char *passwd = data->state.aptr.passwd ? data->state.aptr.passwd : ""; char *secret = NULL; unsigned char tmp_sign0[32] = {0}; unsigned char tmp_sign1[32] = {0}; diff --git a/libs/libcurl/src/http_digest.c b/libs/libcurl/src/http_digest.c index 596b215db6..132f3930c8 100644 --- a/libs/libcurl/src/http_digest.c +++ b/libs/libcurl/src/http_digest.c @@ -67,7 +67,6 @@ CURLcode Curl_input_digest(struct Curl_easy *data, } CURLcode Curl_output_digest(struct Curl_easy *data, - struct connectdata *conn, bool proxy, const unsigned char *request, const unsigned char *uripath) @@ -97,16 +96,16 @@ CURLcode Curl_output_digest(struct Curl_easy *data, #else digest = &data->state.proxydigest; allocuserpwd = &data->state.aptr.proxyuserpwd; - userp = conn->http_proxy.user; - passwdp = conn->http_proxy.passwd; + userp = data->state.aptr.proxyuser; + passwdp = data->state.aptr.proxypasswd; authp = &data->state.authproxy; #endif } else { digest = &data->state.digest; allocuserpwd = &data->state.aptr.userpwd; - userp = conn->user; - passwdp = conn->passwd; + userp = data->state.aptr.user; + passwdp = data->state.aptr.passwd; authp = &data->state.authhost; } diff --git a/libs/libcurl/src/http_digest.h b/libs/libcurl/src/http_digest.h index 106caa7c4f..89438d1a1f 100644 --- a/libs/libcurl/src/http_digest.h +++ b/libs/libcurl/src/http_digest.h @@ -31,7 +31,6 @@ CURLcode Curl_input_digest(struct Curl_easy *data, /* this is for creating digest header output */ CURLcode Curl_output_digest(struct Curl_easy *data, - struct connectdata *conn, bool proxy, const unsigned char *request, const unsigned char *uripath); diff --git a/libs/libcurl/src/http_ntlm.c b/libs/libcurl/src/http_ntlm.c index 6cb829edfa..4fa38f0b09 100644 --- a/libs/libcurl/src/http_ntlm.c +++ b/libs/libcurl/src/http_ntlm.c @@ -140,10 +140,10 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) if(proxy) { #ifndef CURL_DISABLE_PROXY allocuserpwd = &data->state.aptr.proxyuserpwd; - userp = conn->http_proxy.user; - passwdp = conn->http_proxy.passwd; + userp = data->state.aptr.proxyuser; + passwdp = data->state.aptr.proxypasswd; service = data->set.str[STRING_PROXY_SERVICE_NAME] ? - data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; + data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; hostname = conn->http_proxy.host.name; ntlm = &conn->proxyntlm; state = &conn->proxy_ntlm_state; @@ -154,10 +154,10 @@ CURLcode Curl_output_ntlm(struct Curl_easy *data, bool proxy) } else { allocuserpwd = &data->state.aptr.userpwd; - userp = conn->user; - passwdp = conn->passwd; + userp = data->state.aptr.user; + passwdp = data->state.aptr.passwd; service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : "HTTP"; + data->set.str[STRING_SERVICE_NAME] : "HTTP"; hostname = conn->host.name; ntlm = &conn->ntlm; state = &conn->http_ntlm_state; diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c index a03a27fdc4..732fea7e34 100644 --- a/libs/libcurl/src/http_proxy.c +++ b/libs/libcurl/src/http_proxy.c @@ -759,7 +759,7 @@ static CURLcode CONNECT(struct Curl_easy *data, if((conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) && (HYPERE_OK != hyper_request_set_version(req, HYPER_HTTP_VERSION_1_0))) { - failf(data, "error settting HTTP version"); + failf(data, "error setting HTTP version"); goto error; } diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c index 2d8069921c..e887357e1c 100644 --- a/libs/libcurl/src/imap.c +++ b/libs/libcurl/src/imap.c @@ -1519,7 +1519,7 @@ static CURLcode imap_done(struct Curl_easy *data, CURLcode status, Curl_safefree(imap->custom_params); /* Clear the transfer mode for the next request */ - imap->transfer = FTPTRANSFER_BODY; + imap->transfer = PPTRANSFER_BODY; return result; } @@ -1545,7 +1545,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected, if(data->set.opt_no_body) { /* Requested no body means no transfer */ - imap->transfer = FTPTRANSFER_INFO; + imap->transfer = PPTRANSFER_INFO; } *dophase_done = FALSE; /* not done yet */ @@ -1667,7 +1667,7 @@ static CURLcode imap_dophase_done(struct Curl_easy *data, bool connected) (void)connected; - if(imap->transfer != FTPTRANSFER_BODY) + if(imap->transfer != PPTRANSFER_BODY) /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c index 307ebebafd..860a4a851a 100644 --- a/libs/libcurl/src/ldap.c +++ b/libs/libcurl/src/ldap.c @@ -296,10 +296,10 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) *done = TRUE; /* unconditionally */ infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n", LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION); - infof(data, "LDAP local: %s\n", data->change.url); + infof(data, "LDAP local: %s\n", data->state.url); #ifdef HAVE_LDAP_URL_PARSE - rc = ldap_url_parse(data->change.url, &ludp); + rc = ldap_url_parse(data->state.url, &ludp); #else rc = _ldap_url_parse(data, conn, &ludp); #endif @@ -875,7 +875,7 @@ static int _ldap_url_parse2(struct Curl_easy *data, ludp->lud_dn = curlx_convert_UTF8_to_tchar(unescaped); /* Free the unescaped string as we are done with it */ - curlx_unicodefree(unescaped); + free(unescaped); if(!ludp->lud_dn) { rc = LDAP_NO_MEMORY; @@ -943,7 +943,7 @@ static int _ldap_url_parse2(struct Curl_easy *data, ludp->lud_attrs[i] = curlx_convert_UTF8_to_tchar(unescaped); /* Free the unescaped string as we are done with it */ - curlx_unicodefree(unescaped); + free(unescaped); if(!ludp->lud_attrs[i]) { free(attributes); @@ -1010,7 +1010,7 @@ static int _ldap_url_parse2(struct Curl_easy *data, ludp->lud_filter = curlx_convert_UTF8_to_tchar(unescaped); /* Free the unescaped string as we are done with it */ - curlx_unicodefree(unescaped); + free(unescaped); if(!ludp->lud_filter) { rc = LDAP_NO_MEMORY; diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index bc332ad5d3..0b9abed3c0 100644 --- a/libs/libcurl/src/libcurl.plist +++ b/libs/libcurl/src/libcurl.plist @@ -15,7 +15,7 @@ <string>se.curl.libcurl</string> <key>CFBundleVersion</key> - <string>7.75.0</string> + <string>7.76.0</string> <key>CFBundleName</key> <string>libcurl</string> @@ -27,9 +27,9 @@ <string>????</string> <key>CFBundleShortVersionString</key> - <string>libcurl 7.75.0</string> + <string>libcurl 7.76.0</string> <key>CFBundleGetInfoString</key> - <string>libcurl.plist 7.75.0</string> + <string>libcurl.plist 7.76.0</string> </dict> </plist> diff --git a/libs/libcurl/src/md4.c b/libs/libcurl/src/md4.c index 8ae6ac3fab..e731e123d3 100644 --- a/libs/libcurl/src/md4.c +++ b/libs/libcurl/src/md4.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -44,7 +44,7 @@ #endif #endif /* USE_MBEDTLS */ -#if defined(USE_GNUTLS_NETTLE) +#if defined(USE_GNUTLS) #include <nettle/md4.h> @@ -70,33 +70,6 @@ static void MD4_Final(unsigned char *result, MD4_CTX *ctx) md4_digest(ctx, MD4_DIGEST_SIZE, result); } -#elif defined(USE_GNUTLS) - -#include <gcrypt.h> - -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -typedef gcry_md_hd_t MD4_CTX; - -static void MD4_Init(MD4_CTX *ctx) -{ - gcry_md_open(ctx, GCRY_MD_MD4, 0); -} - -static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) -{ - gcry_md_write(*ctx, data, size); -} - -static void MD4_Final(unsigned char *result, MD4_CTX *ctx) -{ - memcpy(result, gcry_md_read(*ctx, 0), MD4_DIGEST_LENGTH); - gcry_md_close(*ctx); -} - #elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4) /* When OpenSSL is available we use the MD4-functions from OpenSSL */ #include <openssl/md4.h> diff --git a/libs/libcurl/src/md5.c b/libs/libcurl/src/md5.c index 513ffb2fb7..7a24fd8cf4 100644 --- a/libs/libcurl/src/md5.c +++ b/libs/libcurl/src/md5.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -38,7 +38,7 @@ #endif #endif /* USE_MBEDTLS */ -#if defined(USE_GNUTLS_NETTLE) +#if defined(USE_GNUTLS) #include <nettle/md5.h> #include "curl_memory.h" @@ -64,33 +64,6 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx) md5_digest(ctx, 16, digest); } -#elif defined(USE_GNUTLS) - -#include <gcrypt.h> -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -typedef gcry_md_hd_t MD5_CTX; - -static void MD5_Init(MD5_CTX *ctx) -{ - gcry_md_open(ctx, GCRY_MD_MD5, 0); -} - -static void MD5_Update(MD5_CTX *ctx, - const unsigned char *input, - unsigned int inputLen) -{ - gcry_md_write(*ctx, input, inputLen); -} - -static void MD5_Final(unsigned char *digest, MD5_CTX *ctx) -{ - memcpy(digest, gcry_md_read(*ctx, 0), 16); - gcry_md_close(*ctx); -} - #elif defined(USE_OPENSSL) && !defined(USE_AMISSL) /* When OpenSSL is available we use the MD5-function from OpenSSL */ #include <openssl/md5.h> diff --git a/libs/libcurl/src/memdebug.c b/libs/libcurl/src/memdebug.c index 881ee85c32..050c5d4b2f 100644 --- a/libs/libcurl/src/memdebug.c +++ b/libs/libcurl/src/memdebug.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -55,9 +55,24 @@ struct memdebug { */ FILE *curl_dbg_logfile = NULL; +static bool registered_cleanup = FALSE; /* atexit registered cleanup */ static bool memlimit = FALSE; /* enable memory limit */ static long memsize = 0; /* set number of mallocs allowed */ +/* 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. curl/curl#6620 */ +static void curl_dbg_cleanup(void) +{ + if(curl_dbg_logfile && + curl_dbg_logfile != stderr && + curl_dbg_logfile != stdout) { + fclose(curl_dbg_logfile); + } + curl_dbg_logfile = NULL; +} + /* this sets the log file name */ void curl_dbg_memdebug(const char *logname) { @@ -72,6 +87,8 @@ void curl_dbg_memdebug(const char *logname) setbuf(curl_dbg_logfile, (char *)NULL); #endif } + if(!registered_cleanup) + registered_cleanup = !atexit(curl_dbg_cleanup); } /* This function sets the number of malloc() calls that should return @@ -91,15 +108,13 @@ static bool countcheck(const char *func, int line, const char *source) should not be made */ if(memlimit && source) { if(!memsize) { - if(source) { - /* log to file */ - curl_dbg_log("LIMIT %s:%d %s reached memlimit\n", - source, line, func); - /* log to stderr also */ - fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", - source, line, func); - fflush(curl_dbg_logfile); /* because it might crash now */ - } + /* log to file */ + curl_dbg_log("LIMIT %s:%d %s reached memlimit\n", + source, line, func); + /* log to stderr also */ + fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", + source, line, func); + fflush(curl_dbg_logfile); /* because it might crash now */ errno = ENOMEM; return TRUE; /* RETURN ERROR! */ } diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index 85707a1af9..be3e41f8bb 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -83,19 +83,19 @@ static void process_pending_handles(struct Curl_multi *multi); #ifdef DEBUGBUILD static const char * const statename[]={ "INIT", - "CONNECT_PEND", + "PENDING", "CONNECT", - "WAITRESOLVE", - "WAITCONNECT", - "WAITPROXYCONNECT", - "SENDPROTOCONNECT", + "RESOLVING", + "CONNECTING", + "TUNNELING", "PROTOCONNECT", + "PROTOCONNECTING", "DO", "DOING", - "DO_MORE", - "DO_DONE", - "PERFORM", - "TOOFAST", + "DOING_MORE", + "DID", + "PERFORMING", + "RATELIMITING", "DONE", "COMPLETED", "MSGSENT", @@ -105,8 +105,8 @@ static const char * const statename[]={ /* function pointer called once when switching TO a state */ typedef void (*init_multistate_func)(struct Curl_easy *data); -/* called when the PERFORM state starts */ -static void init_perform(struct Curl_easy *data) +/* called in DID state, before PERFORMING state */ +static void before_perform(struct Curl_easy *data) { data->req.chunk = FALSE; Curl_pgrsTime(data, TIMER_PRETRANSFER); @@ -130,21 +130,21 @@ static void mstate(struct Curl_easy *data, CURLMstate state ) { CURLMstate oldstate = data->mstate; - static const init_multistate_func finit[CURLM_STATE_LAST] = { + static const init_multistate_func finit[MSTATE_LAST] = { NULL, /* INIT */ - NULL, /* CONNECT_PEND */ + NULL, /* PENDING */ Curl_init_CONNECT, /* CONNECT */ - NULL, /* WAITRESOLVE */ - NULL, /* WAITCONNECT */ - NULL, /* WAITPROXYCONNECT */ - NULL, /* SENDPROTOCONNECT */ + NULL, /* RESOLVING */ + NULL, /* CONNECTING */ + NULL, /* TUNNELING */ NULL, /* PROTOCONNECT */ + NULL, /* PROTOCONNECTING */ Curl_connect_free, /* DO */ NULL, /* DOING */ - NULL, /* DO_MORE */ - NULL, /* DO_DONE */ - init_perform, /* PERFORM */ - NULL, /* TOOFAST */ + NULL, /* DOING_MORE */ + before_perform, /* DID */ + NULL, /* PERFORMING */ + NULL, /* RATELIMITING */ NULL, /* DONE */ init_completed, /* COMPLETED */ NULL /* MSGSENT */ @@ -161,8 +161,8 @@ static void mstate(struct Curl_easy *data, CURLMstate state data->mstate = state; #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - if(data->mstate >= CURLM_STATE_CONNECT_PEND && - data->mstate < CURLM_STATE_COMPLETED) { + if(data->mstate >= MSTATE_PENDING && + data->mstate < MSTATE_COMPLETED) { long connection_id = -5000; if(data->conn) @@ -175,7 +175,7 @@ static void mstate(struct Curl_easy *data, CURLMstate state } #endif - if(state == CURLM_STATE_COMPLETED) { + if(state == MSTATE_COMPLETED) { /* changing to COMPLETED means there's one less easy handle 'alive' */ DEBUGASSERT(data->multi->num_alive > 0); data->multi->num_alive--; @@ -447,7 +447,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, data->set.errorbuffer[0] = 0; /* set the easy handle */ - multistate(data, CURLM_STATE_INIT); + multistate(data, MSTATE_INIT); /* for multi interface connections, we share DNS cache automatically if the easy handle's one is currently not set. */ @@ -562,8 +562,6 @@ static CURLcode multi_done(struct Curl_easy *data, /* Stop if multi_done() has already been called */ return CURLE_OK; - conn->data = data; /* ensure the connection uses this transfer now */ - /* Stop the resolver and free its own resources (but not dns_entry yet). */ Curl_resolver_kill(data); @@ -604,16 +602,13 @@ static CURLcode multi_done(struct Curl_easy *data, Curl_detach_connnection(data); if(CONN_INUSE(conn)) { /* Stop if still used. */ - /* conn->data must not remain pointing to this transfer since it is going - away! Find another to own it! */ - conn->data = conn->easyq.head->ptr; CONNCACHE_UNLOCK(data); DEBUGF(infof(data, "Connection still in use %zu, " "no more multi_done now!\n", conn->easyq.size)); return CURLE_OK; } - conn->data = NULL; /* the connection now has no owner */ + data->state.done = TRUE; /* called just now! */ if(conn->dns_entry) { @@ -718,7 +713,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, { struct Curl_easy *easy = data; bool premature; - bool easy_owns_conn; struct Curl_llist_element *e; /* First, make some basic checks that the CURLM handle is a good handle */ @@ -740,9 +734,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, if(multi->in_callback) return CURLM_RECURSIVE_API_CALL; - premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE; - easy_owns_conn = (data->conn && (data->conn->data == easy)) ? - TRUE : FALSE; + premature = (data->mstate < MSTATE_COMPLETED) ? TRUE : FALSE; /* If the 'state' is not INIT or COMPLETED, we might need to do something nice to put the easy_handle in a good known state when this returns. */ @@ -753,28 +745,20 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, } if(data->conn && - data->mstate > CURLM_STATE_DO && - data->mstate < CURLM_STATE_COMPLETED) { + data->mstate > MSTATE_DO && + data->mstate < MSTATE_COMPLETED) { /* Set connection owner so that the DONE function closes it. We can safely do this here since connection is killed. */ - data->conn->data = easy; streamclose(data->conn, "Removed with partial response"); - easy_owns_conn = TRUE; } if(data->conn) { + /* multi_done() clears the association between the easy handle and the + connection. - /* we must call multi_done() here (if we still own the connection) so that - we don't leave a half-baked one around */ - if(easy_owns_conn) { - - /* multi_done() clears the association between the easy handle and the - connection. - - Note that this ignores the return code simply because there's - nothing really useful to do with it anyway! */ - (void)multi_done(data, data->result, premature); - } + Note that this ignores the return code simply because there's + nothing really useful to do with it anyway! */ + (void)multi_done(data, data->result, premature); } /* The timer must be shut down before data->multi is set to NULL, else the @@ -802,7 +786,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, /* change state without using multistate(), only to make singlesocket() do what we want */ - data->mstate = CURLM_STATE_COMPLETED; + data->mstate = MSTATE_COMPLETED; singlesocket(multi, easy); /* to let the application know what sockets that vanish with this handle */ @@ -840,6 +824,17 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, } } + /* Remove from the pending list if it is there. Otherwise this will + remain on the pending list forever due to the state change. */ + for(e = multi->pending.head; e; e = e->next) { + struct Curl_easy *curr_data = e->ptr; + + if(curr_data == data) { + Curl_llist_remove(&multi->pending, e, NULL); + break; + } + } + /* make the previous node point to our next */ if(data->prev) data->prev->next = data->next; @@ -856,6 +851,8 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, We do not touch the easy handle here! */ multi->num_easy--; /* one less to care about now */ + process_pending_handles(multi); + Curl_update_timer(multi); return CURLM_OK; } @@ -905,7 +902,7 @@ static int waitconnect_getsock(struct connectdata *conn, #ifdef USE_SSL #ifndef CURL_DISABLE_PROXY if(CONNECT_FIRSTSOCKET_PROXY_SSL()) - return Curl_ssl_getsock(conn, sock); + return Curl_ssl->getsock(conn, sock); #endif #endif @@ -984,40 +981,33 @@ static int multi_getsock(struct Curl_easy *data, if(!conn) return 0; - if(data->mstate > CURLM_STATE_CONNECT && - data->mstate < CURLM_STATE_COMPLETED) { - /* Set up ownership correctly */ - data->conn->data = data; - } - switch(data->mstate) { default: return 0; - case CURLM_STATE_WAITRESOLVE: + case MSTATE_RESOLVING: return Curl_resolv_getsock(data, socks); - case CURLM_STATE_PROTOCONNECT: - case CURLM_STATE_SENDPROTOCONNECT: + case MSTATE_PROTOCONNECTING: + case MSTATE_PROTOCONNECT: return protocol_getsock(data, conn, socks); - case CURLM_STATE_DO: - case CURLM_STATE_DOING: + case MSTATE_DO: + case MSTATE_DOING: return doing_getsock(data, conn, socks); - case CURLM_STATE_WAITPROXYCONNECT: + case MSTATE_TUNNELING: return waitproxyconnect_getsock(conn, socks); - case CURLM_STATE_WAITCONNECT: + case MSTATE_CONNECTING: return waitconnect_getsock(conn, socks); - case CURLM_STATE_DO_MORE: + case MSTATE_DOING_MORE: return domore_getsock(data, conn, socks); - case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch - to waiting for the same as the *PERFORM - states */ - case CURLM_STATE_PERFORM: + case MSTATE_DID: /* since is set after DO is completed, we switch to + waiting for the same as the PERFORMING state */ + case MSTATE_PERFORMING: return Curl_single_getsock(data, conn, socks); } @@ -1383,7 +1373,7 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, Curl_init_do(data, NULL); /* take this handle to the perform state right away */ - multistate(data, CURLM_STATE_PERFORM); + multistate(data, MSTATE_PERFORMING); Curl_attach_connnection(data, conn); k->keepon |= KEEP_RECV; /* setup to receive! */ } @@ -1397,7 +1387,6 @@ static CURLcode multi_do(struct Curl_easy *data, bool *done) DEBUGASSERT(conn); DEBUGASSERT(conn->handler); - DEBUGASSERT(conn->data == data); if(conn->handler->do_it) /* generic protocol-specific function pointer set in curl_connect() */ @@ -1578,31 +1567,30 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, process_pending_handles(multi); /* multiplexed */ } - if(data->mstate > CURLM_STATE_CONNECT && - data->mstate < CURLM_STATE_COMPLETED) { + if(data->mstate > MSTATE_CONNECT && + data->mstate < MSTATE_COMPLETED) { /* Make sure we set the connection's current owner */ DEBUGASSERT(data->conn); if(!data->conn) return CURLM_INTERNAL_ERROR; - data->conn->data = data; } if(data->conn && - (data->mstate >= CURLM_STATE_CONNECT) && - (data->mstate < CURLM_STATE_COMPLETED)) { + (data->mstate >= MSTATE_CONNECT) && + (data->mstate < MSTATE_COMPLETED)) { /* we need to wait for the connect state as only then is the start time stored, but we must not check already completed handles */ timeout_ms = Curl_timeleft(data, nowp, - (data->mstate <= CURLM_STATE_DO)? + (data->mstate <= MSTATE_DO)? TRUE:FALSE); if(timeout_ms < 0) { /* Handle timed out */ - if(data->mstate == CURLM_STATE_WAITRESOLVE) + if(data->mstate == MSTATE_RESOLVING) failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds", Curl_timediff(*nowp, data->progress.t_startsingle)); - else if(data->mstate == CURLM_STATE_WAITCONNECT) + else if(data->mstate == MSTATE_CONNECTING) failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds", Curl_timediff(*nowp, data->progress.t_startsingle)); @@ -1625,7 +1613,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } /* Force connection closed if the connection has indeed been used */ - if(data->mstate > CURLM_STATE_DO) { + if(data->mstate > MSTATE_DO) { streamclose(data->conn, "Disconnected with pending data"); stream_error = TRUE; } @@ -1637,24 +1625,24 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } switch(data->mstate) { - case CURLM_STATE_INIT: + case MSTATE_INIT: /* init this transfer. */ result = Curl_pretransfer(data); if(!result) { /* after init, go CONNECT */ - multistate(data, CURLM_STATE_CONNECT); + multistate(data, MSTATE_CONNECT); *nowp = Curl_pgrsTime(data, TIMER_STARTOP); rc = CURLM_CALL_MULTI_PERFORM; } break; - case CURLM_STATE_CONNECT_PEND: + case MSTATE_PENDING: /* We will stay here until there is a connection available. Then - we try again in the CURLM_STATE_CONNECT state. */ + we try again in the MSTATE_CONNECT state. */ break; - case CURLM_STATE_CONNECT: + case MSTATE_CONNECT: /* Connect. We want to get a connection identifier filled in. */ /* init this transfer. */ result = Curl_preconnect(data); @@ -1672,7 +1660,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(CURLE_NO_CONNECTION_AVAILABLE == result) { /* There was no connection available. We will go to the pending state and wait for an available connection. */ - multistate(data, CURLM_STATE_CONNECT_PEND); + multistate(data, MSTATE_PENDING); /* add this handle to the list of connect-pending handles */ Curl_llist_insert_next(&multi->pending, multi->pending.tail, data, @@ -1689,7 +1677,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(!result) { if(async) /* We're now waiting for an asynchronous name lookup */ - multistate(data, CURLM_STATE_WAITRESOLVE); + multistate(data, MSTATE_RESOLVING); else { /* after the connect has been sent off, go WAITCONNECT unless the protocol connect is already done and we can go directly to @@ -1697,20 +1685,20 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, rc = CURLM_CALL_MULTI_PERFORM; if(protocol_connected) - multistate(data, CURLM_STATE_DO); + multistate(data, MSTATE_DO); else { #ifndef CURL_DISABLE_HTTP if(Curl_connect_ongoing(data->conn)) - multistate(data, CURLM_STATE_WAITPROXYCONNECT); + multistate(data, MSTATE_TUNNELING); else #endif - multistate(data, CURLM_STATE_WAITCONNECT); + multistate(data, MSTATE_CONNECTING); } } } break; - case CURLM_STATE_WAITRESOLVE: + case MSTATE_RESOLVING: /* awaiting an asynch name resolve to complete */ { struct Curl_dns_entry *dns = NULL; @@ -1764,14 +1752,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* call again please so that we get the next socket setup */ rc = CURLM_CALL_MULTI_PERFORM; if(protocol_connected) - multistate(data, CURLM_STATE_DO); + multistate(data, MSTATE_DO); else { #ifndef CURL_DISABLE_HTTP if(Curl_connect_ongoing(data->conn)) - multistate(data, CURLM_STATE_WAITPROXYCONNECT); + multistate(data, MSTATE_TUNNELING); else #endif - multistate(data, CURLM_STATE_WAITCONNECT); + multistate(data, MSTATE_CONNECTING); } } } @@ -1785,7 +1773,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, break; #ifndef CURL_DISABLE_HTTP - case CURLM_STATE_WAITPROXYCONNECT: + case MSTATE_TUNNELING: /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */ DEBUGASSERT(data->conn); result = Curl_http_connect(data, &protocol_connected); @@ -1795,7 +1783,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* connect back to proxy again */ result = CURLE_OK; multi_done(data, CURLE_OK, FALSE); - multistate(data, CURLM_STATE_CONNECT); + multistate(data, MSTATE_CONNECT); } else #endif @@ -1808,7 +1796,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, Curl_connect_complete(data->conn)) { rc = CURLM_CALL_MULTI_PERFORM; /* initiate protocol connect phase */ - multistate(data, CURLM_STATE_SENDPROTOCONNECT); + multistate(data, MSTATE_PROTOCONNECT); } } else @@ -1816,7 +1804,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, break; #endif - case CURLM_STATE_WAITCONNECT: + case MSTATE_CONNECTING: /* awaiting a completion of an asynch TCP connect */ DEBUGASSERT(data->conn); result = Curl_is_connected(data, data->conn, FIRSTSOCKET, &connected); @@ -1828,7 +1816,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, !data->conn->bits.proxy_ssl_connected[FIRSTSOCKET]) || #endif Curl_connect_ongoing(data->conn)) { - multistate(data, CURLM_STATE_WAITPROXYCONNECT); + multistate(data, MSTATE_TUNNELING); break; } #endif @@ -1836,10 +1824,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, #ifndef CURL_DISABLE_PROXY multistate(data, data->conn->bits.tunnel_proxy? - CURLM_STATE_WAITPROXYCONNECT: - CURLM_STATE_SENDPROTOCONNECT); + MSTATE_TUNNELING : MSTATE_PROTOCONNECT); #else - multistate(data, CURLM_STATE_SENDPROTOCONNECT); + multistate(data, MSTATE_PROTOCONNECT); #endif } else if(result) { @@ -1851,14 +1838,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } break; - case CURLM_STATE_SENDPROTOCONNECT: + case MSTATE_PROTOCONNECT: result = protocol_connect(data, &protocol_connected); if(!result && !protocol_connected) /* switch to waiting state */ - multistate(data, CURLM_STATE_PROTOCONNECT); + multistate(data, MSTATE_PROTOCONNECTING); else if(!result) { /* protocol connect has completed, go WAITDO or DO */ - multistate(data, CURLM_STATE_DO); + multistate(data, MSTATE_DO); rc = CURLM_CALL_MULTI_PERFORM; } else { @@ -1869,12 +1856,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } break; - case CURLM_STATE_PROTOCONNECT: + case MSTATE_PROTOCONNECTING: /* protocol-specific connect phase */ result = protocol_connecting(data, &protocol_connected); if(!result && protocol_connected) { /* after the connect has completed, go WAITDO or DO */ - multistate(data, CURLM_STATE_DO); + multistate(data, MSTATE_DO); rc = CURLM_CALL_MULTI_PERFORM; } else if(result) { @@ -1885,11 +1872,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } break; - case CURLM_STATE_DO: + case MSTATE_DO: if(data->set.connect_only) { /* keep connection open for application to use the socket */ connkeep(data->conn, "CONNECT_ONLY"); - multistate(data, CURLM_STATE_DONE); + multistate(data, MSTATE_DONE); result = CURLE_OK; rc = CURLM_CALL_MULTI_PERFORM; } @@ -1911,7 +1898,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* if there's no connection left, skip the DONE state */ multistate(data, data->conn ? - CURLM_STATE_DONE : CURLM_STATE_COMPLETED); + MSTATE_DONE : MSTATE_COMPLETED); rc = CURLM_CALL_MULTI_PERFORM; break; } @@ -1919,7 +1906,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, #endif /* DO was not completed in one function call, we must continue DOING... */ - multistate(data, CURLM_STATE_DOING); + multistate(data, MSTATE_DOING); rc = CURLM_OK; } @@ -1927,12 +1914,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else if(data->conn->bits.do_more) { /* we're supposed to do more, but we need to sit down, relax and wait a little while first */ - multistate(data, CURLM_STATE_DO_MORE); + multistate(data, MSTATE_DOING_MORE); rc = CURLM_OK; } else { - /* we're done with the DO, now DO_DONE */ - multistate(data, CURLM_STATE_DO_DONE); + /* we're done with the DO, now DID */ + multistate(data, MSTATE_DID); rc = CURLM_CALL_MULTI_PERFORM; } } @@ -1964,7 +1951,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, follow = FOLLOW_RETRY; drc = Curl_follow(data, newurl, follow); if(!drc) { - multistate(data, CURLM_STATE_CONNECT); + multistate(data, MSTATE_CONNECT); rc = CURLM_CALL_MULTI_PERFORM; result = CURLE_OK; } @@ -1994,7 +1981,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } break; - case CURLM_STATE_DOING: + case MSTATE_DOING: /* we continue DOING until the DO phase is complete */ DEBUGASSERT(data->conn); result = protocol_doing(data, &dophase_done); @@ -2002,8 +1989,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(dophase_done) { /* after DO, go DO_DONE or DO_MORE */ multistate(data, data->conn->bits.do_more? - CURLM_STATE_DO_MORE: - CURLM_STATE_DO_DONE); + MSTATE_DOING_MORE : MSTATE_DID); rc = CURLM_CALL_MULTI_PERFORM; } /* dophase_done */ } @@ -2015,9 +2001,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } break; - case CURLM_STATE_DO_MORE: + case MSTATE_DOING_MORE: /* - * When we are connected, DO MORE and then go DO_DONE + * When we are connected, DOING MORE and then go DID */ DEBUGASSERT(data->conn); result = multi_do_more(data, &control); @@ -2027,8 +2013,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* if positive, advance to DO_DONE if negative, go back to DOING */ multistate(data, control == 1? - CURLM_STATE_DO_DONE: - CURLM_STATE_DOING); + MSTATE_DID : MSTATE_DOING); rc = CURLM_CALL_MULTI_PERFORM; } else @@ -2043,7 +2028,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } break; - case CURLM_STATE_DO_DONE: + case MSTATE_DID: DEBUGASSERT(data->conn); if(data->conn->bits.multiplex) /* Check if we can move pending requests to send pipe */ @@ -2053,7 +2038,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, Having both BAD is a signal to skip immediately to DONE */ if((data->conn->sockfd != CURL_SOCKET_BAD) || (data->conn->writesockfd != CURL_SOCKET_BAD)) - multistate(data, CURLM_STATE_PERFORM); + multistate(data, MSTATE_PERFORMING); else { #ifndef CURL_DISABLE_FTP if(data->state.wildcardmatch && @@ -2061,12 +2046,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->wildcard.state = CURLWC_DONE; } #endif - multistate(data, CURLM_STATE_DONE); + multistate(data, MSTATE_DONE); } rc = CURLM_CALL_MULTI_PERFORM; break; - case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */ + case MSTATE_RATELIMITING: /* limit-rate exceeded in either direction */ DEBUGASSERT(data->conn); /* if both rates are within spec, resume transfer */ if(Curl_pgrsUpdate(data)) @@ -2084,7 +2069,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } else { send_timeout_ms = 0; - if(data->set.max_send_speed > 0) + if(data->set.max_send_speed) send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded, data->progress.ul_limit_size, @@ -2093,7 +2078,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, *nowp); recv_timeout_ms = 0; - if(data->set.max_recv_speed > 0) + if(data->set.max_recv_speed) recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded, data->progress.dl_limit_size, @@ -2102,7 +2087,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, *nowp); if(!send_timeout_ms && !recv_timeout_ms) { - multistate(data, CURLM_STATE_PERFORM); + multistate(data, MSTATE_PERFORMING); Curl_ratelimit(data, *nowp); } else if(send_timeout_ms >= recv_timeout_ms) @@ -2112,7 +2097,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } break; - case CURLM_STATE_PERFORM: + case MSTATE_PERFORMING: { char *newurl = NULL; bool retry = FALSE; @@ -2120,7 +2105,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, DEBUGASSERT(data->state.buffer); /* check if over send speed */ send_timeout_ms = 0; - if(data->set.max_send_speed > 0) + if(data->set.max_send_speed) send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded, data->progress.ul_limit_size, data->set.max_send_speed, @@ -2129,7 +2114,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* check if over recv speed */ recv_timeout_ms = 0; - if(data->set.max_recv_speed > 0) + if(data->set.max_recv_speed) recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded, data->progress.dl_limit_size, data->set.max_recv_speed, @@ -2138,7 +2123,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(send_timeout_ms || recv_timeout_ms) { Curl_ratelimit(data, *nowp); - multistate(data, CURLM_STATE_TOOFAST); + multistate(data, MSTATE_RATELIMITING); if(send_timeout_ms >= recv_timeout_ms) Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST); else @@ -2173,12 +2158,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(!ret) { infof(data, "Downgrades to HTTP/1.1!\n"); - data->set.httpversion = CURL_HTTP_VERSION_1_1; + connclose(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; if(!newurl) /* typically for HTTP_1_1_REQUIRED error on first flight */ - newurl = strdup(data->change.url); + newurl = strdup(data->state.url); /* if we are to retry, set the result to OK and consider the request as done */ retry = TRUE; @@ -2228,7 +2214,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* multi_done() might return CURLE_GOT_NOTHING */ result = Curl_follow(data, newurl, follow); if(!result) { - multistate(data, CURLM_STATE_CONNECT); + multistate(data, MSTATE_CONNECT); rc = CURLM_CALL_MULTI_PERFORM; } free(newurl); @@ -2251,7 +2237,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } if(!result) { - multistate(data, CURLM_STATE_DONE); + multistate(data, MSTATE_DONE); rc = CURLM_CALL_MULTI_PERFORM; } } @@ -2266,7 +2252,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, break; } - case CURLM_STATE_DONE: + case MSTATE_DONE: /* this state is highly transient, so run another loop after this */ rc = CURLM_CALL_MULTI_PERFORM; @@ -2289,21 +2275,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(data->state.wildcardmatch) { if(data->wildcard.state != CURLWC_DONE) { /* if a wildcard is set and we are not ending -> lets start again - with CURLM_STATE_INIT */ - multistate(data, CURLM_STATE_INIT); + with MSTATE_INIT */ + multistate(data, MSTATE_INIT); break; } } #endif /* after we have DONE what we're supposed to do, go COMPLETED, and it doesn't matter what the multi_done() returned! */ - multistate(data, CURLM_STATE_COMPLETED); + multistate(data, MSTATE_COMPLETED); break; - case CURLM_STATE_COMPLETED: + case MSTATE_COMPLETED: break; - case CURLM_STATE_MSGSENT: + case MSTATE_MSGSENT: data->result = result; return CURLM_OK; /* do nothing */ @@ -2312,7 +2298,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } statemachine_end: - if(data->mstate < CURLM_STATE_COMPLETED) { + if(data->mstate < MSTATE_COMPLETED) { if(result) { /* * If an error was returned, and we aren't in completed state now, @@ -2343,12 +2329,12 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, Curl_disconnect(data, conn, dead_connection); } } - else if(data->mstate == CURLM_STATE_CONNECT) { + else if(data->mstate == MSTATE_CONNECT) { /* Curl_connect() failed */ (void)Curl_posttransfer(data); } - multistate(data, CURLM_STATE_COMPLETED); + multistate(data, MSTATE_COMPLETED); rc = CURLM_CALL_MULTI_PERFORM; } /* if there's still a connection to use, call the progress function */ @@ -2359,13 +2345,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, streamclose(data->conn, "Aborted by callback"); /* if not yet in DONE state, go there, otherwise COMPLETED */ - multistate(data, (data->mstate < CURLM_STATE_DONE)? - CURLM_STATE_DONE: CURLM_STATE_COMPLETED); + multistate(data, (data->mstate < MSTATE_DONE)? + MSTATE_DONE: MSTATE_COMPLETED); rc = CURLM_CALL_MULTI_PERFORM; } } - if(CURLM_STATE_COMPLETED == data->mstate) { + if(MSTATE_COMPLETED == data->mstate) { if(data->set.fmultidone) { /* signal via callback instead */ data->set.fmultidone(data, result); @@ -2381,7 +2367,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, rc = multi_addmsg(multi, msg); DEBUGASSERT(!data->conn); } - multistate(data, CURLM_STATE_MSGSENT); + multistate(data, MSTATE_MSGSENT); } } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE)); @@ -2554,7 +2540,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi, curl_socket_t s; int num; unsigned int curraction; - int actions[MAX_SOCKSPEREASYHANDLE]; + unsigned char actions[MAX_SOCKSPEREASYHANDLE]; for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) socks[i] = CURL_SOCKET_BAD; @@ -2571,9 +2557,9 @@ static CURLMcode singlesocket(struct Curl_multi *multi, for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) && (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))); i++) { - unsigned int action = CURL_POLL_NONE; - unsigned int prevaction = 0; - unsigned int comboaction; + unsigned char action = CURL_POLL_NONE; + unsigned char prevaction = 0; + int comboaction; bool sincebefore = FALSE; s = socks[i]; @@ -2631,10 +2617,10 @@ static CURLMcode singlesocket(struct Curl_multi *multi, } comboaction = (entry->writers? CURL_POLL_OUT : 0) | - (entry->readers ? CURL_POLL_IN : 0); + (entry->readers ? CURL_POLL_IN : 0); /* socket existed before and has the same action set as before */ - if(sincebefore && (entry->action == comboaction)) + if(sincebefore && ((int)entry->action == comboaction)) /* same, continue */ continue; @@ -2667,7 +2653,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi, /* if this is NULL here, the socket has been closed and notified so already by Curl_multi_closed() */ if(entry) { - int oldactions = data->actions[i]; + unsigned char oldactions = data->actions[i]; /* this socket has been removed. Decrease user count */ entry->users--; if(oldactions & CURL_POLL_OUT) @@ -2692,7 +2678,7 @@ static CURLMcode singlesocket(struct Curl_multi *multi, } /* for loop over numsocks */ memcpy(data->sockets, socks, num*sizeof(curl_socket_t)); - memcpy(data->actions, actions, num*sizeof(int)); + memcpy(data->actions, actions, num*sizeof(char)); data->numsocks = num; return CURLM_OK; } @@ -3344,9 +3330,9 @@ static void process_pending_handles(struct Curl_multi *multi) if(e) { struct Curl_easy *data = e->ptr; - DEBUGASSERT(data->mstate == CURLM_STATE_CONNECT_PEND); + DEBUGASSERT(data->mstate == MSTATE_PENDING); - multistate(data, CURLM_STATE_CONNECT); + multistate(data, MSTATE_CONNECT); /* Remove this node from the list */ Curl_llist_remove(&multi->pending, e, NULL); @@ -3384,7 +3370,7 @@ void Curl_multi_dump(struct Curl_multi *multi) fprintf(stderr, "* Multi status: %d handles, %d alive\n", multi->num_easy, multi->num_alive); for(data = multi->easyp; data; data = data->next) { - if(data->mstate < CURLM_STATE_COMPLETED) { + if(data->mstate < MSTATE_COMPLETED) { /* only display handles that are not completed */ fprintf(stderr, "handle %p, state %s, %d sockets\n", (void *)data, diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h index f28c5899b6..edf790132a 100644 --- a/libs/libcurl/src/multihandle.h +++ b/libs/libcurl/src/multihandle.h @@ -40,27 +40,26 @@ struct Curl_message { well! */ typedef enum { - CURLM_STATE_INIT, /* 0 - start in this state */ - CURLM_STATE_CONNECT_PEND, /* 1 - no connections, waiting for one */ - CURLM_STATE_CONNECT, /* 2 - resolve/connect has been sent off */ - CURLM_STATE_WAITRESOLVE, /* 3 - awaiting the resolve to finalize */ - CURLM_STATE_WAITCONNECT, /* 4 - awaiting the TCP connect to finalize */ - CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting HTTPS proxy SSL initialization - to complete and/or proxy CONNECT to - finalize */ - CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */ - CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect - phase */ - CURLM_STATE_DO, /* 8 - start send off the request (part 1) */ - CURLM_STATE_DOING, /* 9 - sending off the request (part 1) */ - CURLM_STATE_DO_MORE, /* 10 - send off the request (part 2) */ - CURLM_STATE_DO_DONE, /* 11 - done sending off request */ - CURLM_STATE_PERFORM, /* 12 - transfer data */ - CURLM_STATE_TOOFAST, /* 13 - wait because limit-rate exceeded */ - CURLM_STATE_DONE, /* 14 - post data transfer operation */ - CURLM_STATE_COMPLETED, /* 15 - operation complete */ - CURLM_STATE_MSGSENT, /* 16 - the operation complete message is sent */ - CURLM_STATE_LAST /* 17 - not a true state, never use this */ + MSTATE_INIT, /* 0 - start in this state */ + MSTATE_PENDING, /* 1 - no connections, waiting for one */ + MSTATE_CONNECT, /* 2 - resolve/connect has been sent off */ + MSTATE_RESOLVING, /* 3 - awaiting the resolve to finalize */ + MSTATE_CONNECTING, /* 4 - awaiting the TCP connect to finalize */ + MSTATE_TUNNELING, /* 5 - awaiting HTTPS proxy SSL initialization to + complete and/or proxy CONNECT to finalize */ + MSTATE_PROTOCONNECT, /* 6 - initiate protocol connect procedure */ + MSTATE_PROTOCONNECTING, /* 7 - completing the protocol-specific connect + phase */ + MSTATE_DO, /* 8 - start send off the request (part 1) */ + MSTATE_DOING, /* 9 - sending off the request (part 1) */ + MSTATE_DOING_MORE, /* 10 - send off the request (part 2) */ + MSTATE_DID, /* 11 - done sending off request */ + MSTATE_PERFORMING, /* 12 - transfer data */ + MSTATE_RATELIMITING, /* 13 - wait because limit-rate exceeded */ + MSTATE_DONE, /* 14 - post data transfer operation */ + MSTATE_COMPLETED, /* 15 - operation complete */ + MSTATE_MSGSENT, /* 16 - the operation complete message is sent */ + MSTATE_LAST /* 17 - not a true state, never use this */ } CURLMstate; /* we support N sockets per easy handle. Set the corresponding bit to what @@ -71,8 +70,7 @@ typedef enum { #define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) -#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS) && \ - !defined(CURL_DISABLE_SOCKETPAIR) +#if !defined(CURL_DISABLE_SOCKETPAIR) #define ENABLE_WAKEUP #endif @@ -96,7 +94,7 @@ struct Curl_multi { struct Curl_llist msglist; /* a list of messages from completed transfers */ struct Curl_llist pending; /* Curl_easys that are in the - CURLM_STATE_CONNECT_PEND state */ + MSTATE_PENDING state */ /* callback function and user data pointer for the *socket() API */ curl_socket_callback socket_cb; diff --git a/libs/libcurl/src/nonblock.c b/libs/libcurl/src/nonblock.c index 4a7bde504f..fda2e9ad79 100644 --- a/libs/libcurl/src/nonblock.c +++ b/libs/libcurl/src/nonblock.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -47,13 +47,7 @@ int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ int nonblock /* TRUE or FALSE */) { -#if defined(USE_BLOCKING_SOCKETS) - (void)sockfd; - (void)nonblock; - return 0; /* returns success */ - -#elif defined(HAVE_FCNTL_O_NONBLOCK) - +#if defined(HAVE_FCNTL_O_NONBLOCK) /* most recent unix versions */ int flags; flags = sfcntl(sockfd, F_GETFL, 0); diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c index 4070bbf88b..b6980c5900 100644 --- a/libs/libcurl/src/openldap.c +++ b/libs/libcurl/src/openldap.c @@ -179,7 +179,7 @@ static CURLcode ldap_setup_connection(struct Curl_easy *data, int rc, proto; CURLcode status; - rc = ldap_url_parse(data->change.url, &lud); + rc = ldap_url_parse(data->state.url, &lud); if(rc != LDAP_URL_SUCCESS) { const char *msg = "url parsing problem"; status = CURLE_URL_MALFORMAT; @@ -278,7 +278,7 @@ static CURLcode ldap_connecting(struct Curl_easy *data, bool *done) if(!li->sslinst) { Sockbuf *sb; ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb); - ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn); + ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, data); li->sslinst = TRUE; li->recv = conn->recv[FIRSTSOCKET]; li->send = conn->send[FIRSTSOCKET]; @@ -365,10 +365,14 @@ static CURLcode ldap_disconnect(struct Curl_easy *data, { struct ldapconninfo *li = conn->proto.ldapc; (void) dead_connection; - (void) data; if(li) { if(li->ld) { + 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); + } ldap_unbind_ext(li->ld, NULL, NULL); li->ld = NULL; } @@ -390,9 +394,9 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) connkeep(conn, "OpenLDAP do"); - infof(data, "LDAP local: %s\n", data->change.url); + infof(data, "LDAP local: %s\n", data->state.url); - rc = ldap_url_parse(data->change.url, &ludp); + rc = ldap_url_parse(data->state.url, &ludp); if(rc != LDAP_URL_SUCCESS) { const char *msg = "url parsing problem"; status = CURLE_URL_MALFORMAT; @@ -716,8 +720,8 @@ ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg) { (void)arg; if(opt == LBER_SB_OPT_DATA_READY) { - struct connectdata *conn = sbiod->sbiod_pvt; - return Curl_ssl_data_pending(conn, FIRSTSOCKET); + struct Curl_easy *data = sbiod->sbiod_pvt; + return Curl_ssl_data_pending(data->conn, FIRSTSOCKET); } return 0; } @@ -725,14 +729,19 @@ ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg) static ber_slen_t ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) { - struct connectdata *conn = sbiod->sbiod_pvt; - struct ldapconninfo *li = conn->proto.ldapc; - ber_slen_t ret; - CURLcode err = CURLE_RECV_ERROR; + struct Curl_easy *data = sbiod->sbiod_pvt; + ber_slen_t ret = 0; + if(data) { + struct connectdata *conn = data->conn; + if(conn) { + struct ldapconninfo *li = conn->proto.ldapc; + CURLcode err = CURLE_RECV_ERROR; - ret = (li->recv)(conn->data, FIRSTSOCKET, buf, len, &err); - if(ret < 0 && err == CURLE_AGAIN) { - SET_SOCKERRNO(EWOULDBLOCK); + ret = (li->recv)(data, FIRSTSOCKET, buf, len, &err); + if(ret < 0 && err == CURLE_AGAIN) { + SET_SOCKERRNO(EWOULDBLOCK); + } + } } return ret; } @@ -740,14 +749,18 @@ ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) static ber_slen_t ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) { - struct connectdata *conn = sbiod->sbiod_pvt; - struct ldapconninfo *li = conn->proto.ldapc; - ber_slen_t ret; - CURLcode err = CURLE_SEND_ERROR; - - ret = (li->send)(conn->data, FIRSTSOCKET, buf, len, &err); - if(ret < 0 && err == CURLE_AGAIN) { - SET_SOCKERRNO(EWOULDBLOCK); + struct Curl_easy *data = sbiod->sbiod_pvt; + ber_slen_t ret = 0; + if(data) { + struct connectdata *conn = data->conn; + if(conn) { + struct ldapconninfo *li = conn->proto.ldapc; + CURLcode err = CURLE_SEND_ERROR; + ret = (li->send)(data, FIRSTSOCKET, buf, len, &err); + if(ret < 0 && err == CURLE_AGAIN) { + SET_SOCKERRNO(EWOULDBLOCK); + } + } } return ret; } diff --git a/libs/libcurl/src/pingpong.h b/libs/libcurl/src/pingpong.h index 4f7d7ea6b9..8f56f3f865 100644 --- a/libs/libcurl/src/pingpong.h +++ b/libs/libcurl/src/pingpong.h @@ -33,10 +33,9 @@ struct connectdata; typedef enum { - FTPTRANSFER_BODY, /* yes do transfer a body */ - FTPTRANSFER_INFO, /* do still go through to get info/headers */ - FTPTRANSFER_NONE, /* don't get anything and don't get info */ - FTPTRANSFER_LAST /* end of list marker, never used */ + PPTRANSFER_BODY, /* yes do transfer a body */ + PPTRANSFER_INFO, /* do still go through to get info/headers */ + PPTRANSFER_NONE /* don't get anything and don't get info */ } curl_pp_transfer; /* diff --git a/libs/libcurl/src/pop3.c b/libs/libcurl/src/pop3.c index 0ed3d3ee18..ccfebd02af 100644 --- a/libs/libcurl/src/pop3.c +++ b/libs/libcurl/src/pop3.c @@ -571,12 +571,12 @@ static CURLcode pop3_perform_command(struct Curl_easy *data) const char *command = NULL; /* Calculate the default command */ - if(pop3->id[0] == '\0' || data->set.ftp_list_only) { + if(pop3->id[0] == '\0' || data->set.list_only) { command = "LIST"; if(pop3->id[0] != '\0') /* Message specific LIST so skip the BODY transfer */ - pop3->transfer = FTPTRANSFER_INFO; + pop3->transfer = PPTRANSFER_INFO; } else command = "RETR"; @@ -916,7 +916,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data, the strip counter here so that these bytes won't be delivered. */ pop3c->strip = 2; - if(pop3->transfer == FTPTRANSFER_BODY) { + if(pop3->transfer == PPTRANSFER_BODY) { /* POP3 download */ Curl_setup_transfer(data, FIRSTSOCKET, -1, FALSE, -1); @@ -1150,7 +1150,7 @@ static CURLcode pop3_done(struct Curl_easy *data, CURLcode status, Curl_safefree(pop3->custom); /* Clear the transfer mode for the next request */ - pop3->transfer = FTPTRANSFER_BODY; + pop3->transfer = PPTRANSFER_BODY; return result; } @@ -1174,7 +1174,7 @@ static CURLcode pop3_perform(struct Curl_easy *data, bool *connected, if(data->set.opt_no_body) { /* Requested no body means no transfer */ - pop3->transfer = FTPTRANSFER_INFO; + pop3->transfer = PPTRANSFER_INFO; } *dophase_done = FALSE; /* not done yet */ diff --git a/libs/libcurl/src/progress.c b/libs/libcurl/src/progress.c index 55e8ded04d..cc040a8733 100644 --- a/libs/libcurl/src/progress.c +++ b/libs/libcurl/src/progress.c @@ -85,7 +85,7 @@ static char *max5data(curl_off_t bytes, char *max5) CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE, (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) ); -#if (CURL_SIZEOF_CURL_OFF_T > 4) +#if (SIZEOF_CURL_OFF_T > 4) else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE) /* 'XXXXM' is good until we're at 10000MB or above */ @@ -321,14 +321,14 @@ void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size) void Curl_ratelimit(struct Curl_easy *data, struct curltime now) { /* don't set a new stamp unless the time since last update is long enough */ - if(data->set.max_recv_speed > 0) { + if(data->set.max_recv_speed) { if(Curl_timediff(now, data->progress.dl_limit_start) >= MIN_RATE_LIMIT_PERIOD) { data->progress.dl_limit_start = now; data->progress.dl_limit_size = data->progress.downloaded; } } - if(data->set.max_send_speed > 0) { + if(data->set.max_send_speed) { if(Curl_timediff(now, data->progress.ul_limit_start) >= MIN_RATE_LIMIT_PERIOD) { data->progress.ul_limit_start = now; diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c index 55766757a8..3029ff5264 100644 --- a/libs/libcurl/src/rtsp.c +++ b/libs/libcurl/src/rtsp.c @@ -404,8 +404,8 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) /* Referrer */ Curl_safefree(data->state.aptr.ref); - if(data->change.referer && !Curl_checkheaders(data, "Referer")) - data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer); + if(data->state.referer && !Curl_checkheaders(data, "Referer")) + data->state.aptr.ref = aprintf("Referer: %s\r\n", data->state.referer); else data->state.aptr.ref = NULL; diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index b3c7fe33d3..b57b7878c2 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -498,9 +498,7 @@ static CURLcode pausewrite(struct Curl_easy *data, /* store this information in the state struct for later use */ Curl_dyn_init(&s->tempwrite[i].b, DYN_PAUSE_BUFFER); s->tempwrite[i].type = type; - - if(newtype) - s->tempcount++; + s->tempcount++; } if(Curl_dyn_addn(&s->tempwrite[i].b, (unsigned char *)ptr, len)) diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index ce73a34a7f..022dd38003 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -177,7 +177,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_SSL_CIPHER_LIST: /* set a list of cipher we want to use in the SSL connection */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG], + result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], va_arg(param, char *)); break; #ifndef CURL_DISABLE_PROXY @@ -190,7 +190,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_TLS13_CIPHERS: if(Curl_ssl_tls13_ciphersuites()) { /* set preferred list of TLS 1.3 cipher suites */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST_ORIG], + result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER13_LIST], va_arg(param, char *)); } else @@ -653,8 +653,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.httpauth = CURLAUTH_AWS_SIGV4; break; -#endif /* CURL_DISABLE_HTTP */ - case CURLOPT_MIMEPOST: /* * Set to make us do MIME/form POST @@ -671,13 +669,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * String to set in the HTTP Referer: field. */ - if(data->change.referer_alloc) { - Curl_safefree(data->change.referer); - data->change.referer_alloc = FALSE; + if(data->state.referer_alloc) { + Curl_safefree(data->state.referer); + data->state.referer_alloc = FALSE; } result = Curl_setstropt(&data->set.str[STRING_SET_REFERER], va_arg(param, char *)); - data->change.referer = data->set.str[STRING_SET_REFERER]; + data->state.referer = data->set.str[STRING_SET_REFERER]; break; case CURLOPT_USERAGENT: @@ -695,7 +693,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.headers = va_arg(param, struct curl_slist *); break; -#ifndef CURL_DISABLE_HTTP #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXYHEADER: /* @@ -747,13 +744,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) return CURLE_BAD_FUNCTION_ARGUMENT; /* append the cookie file name to the list of file names, and deal with them later */ - cl = curl_slist_append(data->change.cookielist, argptr); + cl = curl_slist_append(data->state.cookielist, argptr); if(!cl) { - curl_slist_free_all(data->change.cookielist); - data->change.cookielist = NULL; + curl_slist_free_all(data->state.cookielist); + data->state.cookielist = NULL; return CURLE_OUT_OF_MEMORY; } - data->change.cookielist = cl; /* store the list for later use */ + data->state.cookielist = cl; /* store the list for later use */ } break; @@ -891,7 +888,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) if(arg == CURL_HTTP_VERSION_NONE) arg = CURL_HTTP_VERSION_2TLS; #endif - data->set.httpversion = arg; + data->set.httpwant = (unsigned char)arg; break; case CURLOPT_EXPECT_100_TIMEOUT_MS: @@ -909,7 +906,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) arg = va_arg(param, unsigned long); if(arg > 1L) return CURLE_BAD_FUNCTION_ARGUMENT; +#ifdef USE_HYPER + /* Hyper does not support HTTP/0.9 */ + if(arg) + return CURLE_BAD_FUNCTION_ARGUMENT; +#else data->set.http09_allowed = arg ? TRUE : FALSE; +#endif break; #endif /* CURL_DISABLE_HTTP */ @@ -1160,7 +1163,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * An option that changes the command to one that asks for a list only, no * file info details. Used for FTP, POP3 and SFTP. */ - data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.list_only = (0 != va_arg(param, long)) ? TRUE : FALSE; break; case CURLOPT_APPEND: @@ -1168,7 +1171,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * We want to upload and append to an existing file. Used for FTP and * SFTP. */ - data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE; + data->set.remote_append = (0 != va_arg(param, long)) ? TRUE : FALSE; break; #ifndef CURL_DISABLE_FTP @@ -1335,14 +1338,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * The URL to fetch. */ - if(data->change.url_alloc) { + if(data->state.url_alloc) { /* the already set URL is allocated, free it first! */ - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; + Curl_safefree(data->state.url); + data->state.url_alloc = FALSE; } result = Curl_setstropt(&data->set.str[STRING_SET_URL], va_arg(param, char *)); - data->change.url = data->set.str[STRING_SET_URL]; + data->state.url = data->set.str[STRING_SET_URL]; break; case CURLOPT_PORT: /* @@ -1416,7 +1419,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = Curl_setstropt(&data->set.str[STRING_USERNAME], va_arg(param, char *)); break; - case CURLOPT_PASSWORD: /* * authentication password to use in the operation @@ -1474,7 +1476,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * that aren't actually in use right now will be pruned immediately. */ data->set.resolve = va_arg(param, struct curl_slist *); - data->change.resolve = data->set.resolve; + data->state.resolve = data->set.resolve; break; case CURLOPT_PROGRESSFUNCTION: /* @@ -1666,14 +1668,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * String that holds file name of the SSL certificate to use */ - result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG], + result = Curl_setstropt(&data->set.str[STRING_CERT], va_arg(param, char *)); break; case CURLOPT_SSLCERT_BLOB: /* * Blob that holds file name of the SSL certificate to use */ - result = Curl_setblobopt(&data->set.blobs[BLOB_CERT_ORIG], + result = Curl_setblobopt(&data->set.blobs[BLOB_CERT], va_arg(param, struct curl_blob *)); break; #ifndef CURL_DISABLE_PROXY @@ -1696,7 +1698,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * String that holds file type of the SSL certificate to use */ - result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG], + result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE], va_arg(param, char *)); break; #ifndef CURL_DISABLE_PROXY @@ -1712,14 +1714,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * String that holds file name of the SSL key to use */ - result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG], + result = Curl_setstropt(&data->set.str[STRING_KEY], va_arg(param, char *)); break; case CURLOPT_SSLKEY_BLOB: /* * Blob that holds file name of the SSL key to use */ - result = Curl_setblobopt(&data->set.blobs[BLOB_KEY_ORIG], + result = Curl_setblobopt(&data->set.blobs[BLOB_KEY], va_arg(param, struct curl_blob *)); break; #ifndef CURL_DISABLE_PROXY @@ -1742,7 +1744,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * String that holds file type of the SSL key to use */ - result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG], + result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE], va_arg(param, char *)); break; #ifndef CURL_DISABLE_PROXY @@ -1758,7 +1760,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * String that holds the SSL or SSH private key password. */ - result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG], + result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD], va_arg(param, char *)); break; #ifndef CURL_DISABLE_PROXY @@ -1852,6 +1854,13 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.ssl.primary.verifypeer; } break; + case CURLOPT_DOH_SSL_VERIFYPEER: + /* + * Enable peer SSL verifying for DOH. + */ + data->set.doh_verifypeer = (0 != va_arg(param, long)) ? + TRUE : FALSE; + break; #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_VERIFYPEER: /* @@ -1884,6 +1893,15 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.ssl.primary.verifyhost; } break; + case CURLOPT_DOH_SSL_VERIFYHOST: + /* + * Enable verification of the host name in the peer certificate for DOH + */ + arg = va_arg(param, long); + + /* Treat both 1 and 2 as TRUE */ + data->set.doh_verifyhost = (bool)((arg & 3) ? TRUE : FALSE); + break; #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXY_SSL_VERIFYHOST: /* @@ -1919,6 +1937,18 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.ssl.primary.verifystatus; } break; + case CURLOPT_DOH_SSL_VERIFYSTATUS: + /* + * Enable certificate status verifying for DOH. + */ + if(!Curl_ssl_cert_status_request()) { + result = CURLE_NOT_BUILT_IN; + break; + } + + data->set.doh_verifystatus = (0 != va_arg(param, long)) ? + TRUE : FALSE; + break; case CURLOPT_SSL_CTX_FUNCTION: /* * Set a SSL_CTX callback @@ -1967,7 +1997,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ #ifdef USE_SSL if(Curl_ssl->supports & SSLSUPP_PINNEDPUBKEY) - result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG], + result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY], va_arg(param, char *)); else #endif @@ -1992,7 +2022,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * Set CA info for SSL connection. Specify file name of the CA certificate */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG], + result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE], va_arg(param, char *)); break; #ifndef CURL_DISABLE_PROXY @@ -2013,7 +2043,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #ifdef USE_SSL if(Curl_ssl->supports & SSLSUPP_CA_PATH) /* This does not work on windows. */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG], + result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH], va_arg(param, char *)); else #endif @@ -2040,7 +2070,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Set CRL file info for SSL connection. Specify file name of the CRL * to check certificates revocation */ - result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG], + result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE], va_arg(param, char *)); break; #ifndef CURL_DISABLE_PROXY @@ -2058,14 +2088,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) * Set Issuer certificate file * to check certificates issuer */ - result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG], + result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT], va_arg(param, char *)); break; case CURLOPT_ISSUERCERT_BLOB: /* * Blob that holds Issuer certificate to check certificates issuer */ - result = Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG], + result = Curl_setblobopt(&data->set.blobs[BLOB_SSL_ISSUERCERT], va_arg(param, struct curl_blob *)); break; #ifndef CURL_DISABLE_PROXY @@ -2244,6 +2274,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) 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); + /* 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; #ifndef CURL_DISABLE_PROXY @@ -2662,9 +2694,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif #ifdef USE_TLS_SRP case CURLOPT_TLSAUTH_USERNAME: - result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG], + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], va_arg(param, char *)); - if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype) + if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ break; case CURLOPT_PROXY_TLSAUTH_USERNAME: @@ -2677,9 +2709,9 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif break; case CURLOPT_TLSAUTH_PASSWORD: - result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG], + result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], va_arg(param, char *)); - if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype) + if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ break; case CURLOPT_PROXY_TLSAUTH_PASSWORD: diff --git a/libs/libcurl/src/sha256.c b/libs/libcurl/src/sha256.c index d915117917..c34f97e8f6 100644 --- a/libs/libcurl/src/sha256.c +++ b/libs/libcurl/src/sha256.c @@ -6,7 +6,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2017, Florin Petriuc, <petriuc.florin@gmail.com> - * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -50,11 +50,10 @@ /* Please keep the SSL backend-specific #if branches in this order: * * 1. USE_OPENSSL - * 2. USE_GNUTLS_NETTLE - * 3. USE_GNUTLS - * 4. USE_MBEDTLS - * 5. USE_COMMON_CRYPTO - * 6. USE_WIN32_CRYPTO + * 2. USE_GNUTLS + * 3. USE_MBEDTLS + * 4. USE_COMMON_CRYPTO + * 5. USE_WIN32_CRYPTO * * This ensures that the same SSL branch gets activated throughout this source * file even if multiple backends are enabled at the same time. @@ -65,7 +64,7 @@ /* When OpenSSL is available we use the SHA256-function from OpenSSL */ #include <openssl/sha.h> -#elif defined(USE_GNUTLS_NETTLE) +#elif defined(USE_GNUTLS) #include <nettle/sha.h> @@ -93,35 +92,6 @@ static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) sha256_digest(ctx, SHA256_DIGEST_SIZE, digest); } -#elif defined(USE_GNUTLS) - -#include <gcrypt.h> - -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -typedef gcry_md_hd_t SHA256_CTX; - -static void SHA256_Init(SHA256_CTX *ctx) -{ - gcry_md_open(ctx, GCRY_MD_SHA256, 0); -} - -static void SHA256_Update(SHA256_CTX *ctx, - const unsigned char *data, - unsigned int length) -{ - gcry_md_write(*ctx, data, length); -} - -static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) -{ - memcpy(digest, gcry_md_read(*ctx, 0), SHA256_DIGEST_LENGTH); - gcry_md_close(*ctx); -} - #elif defined(USE_MBEDTLS) #include <mbedtls/sha256.h> diff --git a/libs/libcurl/src/smb.c b/libs/libcurl/src/smb.c index dd4e4fdbf6..183bc12a51 100644 --- a/libs/libcurl/src/smb.c +++ b/libs/libcurl/src/smb.c @@ -24,7 +24,7 @@ #include "curl_setup.h" #if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) + (SIZEOF_CURL_OFF_T > 4) #define BUILDING_CURL_SMB_C @@ -1022,4 +1022,4 @@ static CURLcode smb_parse_url_path(struct Curl_easy *data, } #endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && - CURL_SIZEOF_CURL_OFF_T > 4 */ + SIZEOF_CURL_OFF_T > 4 */ diff --git a/libs/libcurl/src/smb.h b/libs/libcurl/src/smb.h index 907cf0c8e2..0e3c2ec112 100644 --- a/libs/libcurl/src/smb.h +++ b/libs/libcurl/src/smb.h @@ -8,7 +8,7 @@ * \___|\___/|_| \_\_____| * * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies - * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -244,12 +244,12 @@ struct smb_tree_disconnect { #endif /* BUILDING_CURL_SMB_C */ #if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) + (SIZEOF_CURL_OFF_T > 4) extern const struct Curl_handler Curl_handler_smb; extern const struct Curl_handler Curl_handler_smbs; #endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && - CURL_SIZEOF_CURL_OFF_T > 4 */ + SIZEOF_CURL_OFF_T > 4 */ #endif /* HEADER_CURL_SMB_H */ diff --git a/libs/libcurl/src/smtp.c b/libs/libcurl/src/smtp.c index 1fc880065a..be4cd675ca 100644 --- a/libs/libcurl/src/smtp.c +++ b/libs/libcurl/src/smtp.c @@ -1433,7 +1433,7 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status, } /* Clear the transfer mode for the next request */ - smtp->transfer = FTPTRANSFER_BODY; + smtp->transfer = PPTRANSFER_BODY; return result; } @@ -1457,7 +1457,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected, if(data->set.opt_no_body) { /* Requested no body means no transfer */ - smtp->transfer = FTPTRANSFER_INFO; + smtp->transfer = PPTRANSFER_INFO; } *dophase_done = FALSE; /* not done yet */ @@ -1564,7 +1564,7 @@ static CURLcode smtp_dophase_done(struct Curl_easy *data, bool connected) (void)connected; - if(smtp->transfer != FTPTRANSFER_BODY) + if(smtp->transfer != PPTRANSFER_BODY) /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); diff --git a/libs/libcurl/src/socketpair.h b/libs/libcurl/src/socketpair.h index 033a235aa2..cdcc0b921e 100644 --- a/libs/libcurl/src/socketpair.h +++ b/libs/libcurl/src/socketpair.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2019 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,7 +30,4 @@ int Curl_socketpair(int domain, int type, int protocol, #define Curl_socketpair(a,b,c,d) socketpair(a,b,c,d) #endif -/* Defined here to allow specific build configs to disable it completely */ -#define USE_SOCKETPAIR 1 - #endif /* HEADER_CURL_SOCKETPAIR_H */ diff --git a/libs/libcurl/src/tftp.c b/libs/libcurl/src/tftp.c index 3f1d1b51b7..76d3ff4515 100644 --- a/libs/libcurl/src/tftp.c +++ b/libs/libcurl/src/tftp.c @@ -129,8 +129,6 @@ struct tftp_state_data { int retries; int retry_time; int retry_max; - time_t start_time; - time_t max_time; time_t rx_time; struct Curl_sockaddr_storage local_addr; struct Curl_sockaddr_storage remote_addr; @@ -206,8 +204,6 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state) timediff_t timeout_ms; bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE; - time(&state->start_time); - /* Compute drop-dead time */ timeout_ms = Curl_timeleft(state->data, NULL, start); @@ -217,41 +213,17 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state) return CURLE_OPERATION_TIMEDOUT; } - if(start) { - + if(timeout_ms > 0) maxtime = (time_t)(timeout_ms + 500) / 1000; - state->max_time = state->start_time + maxtime; - - /* Set per-block timeout to total */ - timeout = maxtime; - - /* Average restart after 5 seconds */ - state->retry_max = (int)timeout/5; - - if(state->retry_max < 1) - /* avoid division by zero below */ - state->retry_max = 1; - - /* Compute the re-start interval to suit the timeout */ - state->retry_time = (int)timeout/state->retry_max; - if(state->retry_time<1) - state->retry_time = 1; - - } - else { - if(timeout_ms > 0) - maxtime = (time_t)(timeout_ms + 500) / 1000; - else - maxtime = 3600; + else + maxtime = 3600; /* use for calculating block timeouts */ - state->max_time = state->start_time + maxtime; + /* Set per-block timeout to total */ + timeout = maxtime; - /* Set per-block timeout to total */ - timeout = maxtime; + /* Average reposting an ACK after 5 seconds */ + state->retry_max = (int)timeout/5; - /* Average reposting an ACK after 5 seconds */ - state->retry_max = (int)timeout/5; - } /* But bound the total number */ if(state->retry_max<3) state->retry_max = 3; @@ -265,9 +237,9 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state) state->retry_time = 1; infof(state->data, - "set timeouts for state %d; Total %ld, retry %d maxtry %d\n", - (int)state->state, (long)(state->max_time-state->start_time), - state->retry_time, state->retry_max); + "set timeouts for state %d; Total % " CURL_FORMAT_CURL_OFF_T + ", retry %d maxtry %d\n", + (int)state->state, timeout_ms, state->retry_time, state->retry_max); /* init RX time */ time(&state->rx_time); @@ -460,7 +432,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, CURLcode result = CURLE_OK; /* Set ascii mode if -B flag was used */ - if(data->set.prefer_ascii) + if(data->state.prefer_ascii) mode = "netascii"; switch(event) { @@ -1215,33 +1187,32 @@ static CURLcode tftp_receive_packet(struct Curl_easy *data) * Check if timeouts have been reached * **********************************************************/ -static long tftp_state_timeout(struct Curl_easy *data, tftp_event_t *event) +static timediff_t tftp_state_timeout(struct Curl_easy *data, + tftp_event_t *event) { time_t current; struct connectdata *conn = data->conn; struct tftp_state_data *state = conn->proto.tftpc; + timediff_t timeout_ms; if(event) *event = TFTP_EVENT_NONE; - time(¤t); - if(current > state->max_time) { - DEBUGF(infof(data, "timeout: %ld > %ld\n", - (long)current, (long)state->max_time)); + timeout_ms = Curl_timeleft(state->data, NULL, + (state->state == TFTP_STATE_START)); + if(timeout_ms < 0) { state->error = TFTP_ERR_TIMEOUT; state->state = TFTP_STATE_FIN; return 0; } + time(¤t); if(current > state->rx_time + state->retry_time) { if(event) *event = TFTP_EVENT_TIMEOUT; time(&state->rx_time); /* update even though we received nothing */ } - /* there's a typecast below here since 'time_t' may in fact be larger than - 'long', but we estimate that a 'long' will still be able to hold number - of seconds even if "only" 32 bit */ - return (long)(state->max_time - current); + return timeout_ms; } /********************************************************** @@ -1257,11 +1228,11 @@ static CURLcode tftp_multi_statemach(struct Curl_easy *data, bool *done) CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; struct tftp_state_data *state = conn->proto.tftpc; - long timeout_ms = tftp_state_timeout(data, &event); + timediff_t timeout_ms = tftp_state_timeout(data, &event); *done = FALSE; - if(timeout_ms <= 0) { + if(timeout_ms < 0) { failf(data, "TFTP response timeout"); return CURLE_OPERATION_TIMEDOUT; } @@ -1420,14 +1391,14 @@ static CURLcode tftp_setup_connection(struct Curl_easy *data, switch(command) { case 'A': /* ASCII mode */ case 'N': /* NETASCII mode */ - data->set.prefer_ascii = TRUE; + data->state.prefer_ascii = TRUE; break; case 'O': /* octet mode */ case 'I': /* binary mode */ default: /* switch off ASCII */ - data->set.prefer_ascii = FALSE; + data->state.prefer_ascii = FALSE; break; } } diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index 2f29b29d8e..56ad5e612e 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -79,6 +79,7 @@ #include "strcase.h" #include "urlapi-int.h" #include "hsts.h" +#include "setopt.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -286,7 +287,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, * <DATA> CRLF */ /* On non-ASCII platforms the <DATA> may or may not be - translated based on set.prefer_ascii while the protocol + translated based on state.prefer_ascii while the protocol portion must always be translated to the network encoding. To further complicate matters, line end conversion might be done later on, so we need to prevent CRLFs from becoming @@ -301,7 +302,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, if( #ifdef CURL_DO_LINEEND_CONV - (data->set.prefer_ascii) || + (data->state.prefer_ascii) || #endif (data->set.crlf)) { /* \n will become \r\n later on */ @@ -348,7 +349,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, { CURLcode result; size_t length; - if(data->set.prefer_ascii) + if(data->state.prefer_ascii) /* translate the protocol and data */ length = nread; else @@ -389,7 +390,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, nread += strlen(endofline_network); /* for the added end of line */ } #ifdef CURL_DOES_CONVERSIONS - else if((data->set.prefer_ascii) && (!sending_http_headers)) { + else if((data->state.prefer_ascii) && (!sending_http_headers)) { CURLcode result; result = Curl_convert_to_network(data, data->req.upload_fromhere, nread); /* Curl_convert_to_network calls failf if unsuccessful */ @@ -1028,7 +1029,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, if((!sending_http_headers) && ( #ifdef CURL_DO_LINEEND_CONV /* always convert if we're FTPing in ASCII mode */ - (data->set.prefer_ascii) || + (data->state.prefer_ascii) || #endif (data->set.crlf))) { /* Do we need to allocate a scratch buffer? */ @@ -1391,20 +1392,20 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) { CURLcode result; - if(!data->change.url && !data->set.uh) { + if(!data->state.url && !data->set.uh) { /* we can't do anything without URL */ failf(data, "No URL set!"); return CURLE_URL_MALFORMAT; } /* since the URL may have been redirected in a previous use of this handle */ - if(data->change.url_alloc) { + if(data->state.url_alloc) { /* the already set URL is allocated, free it first! */ - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; + Curl_safefree(data->state.url); + data->state.url_alloc = FALSE; } - if(!data->change.url && data->set.uh) { + if(!data->state.url && data->set.uh) { CURLUcode uc; free(data->set.str[STRING_SET_URL]); uc = curl_url_get(data->set.uh, @@ -1415,8 +1416,10 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) } } + data->state.prefer_ascii = data->set.prefer_ascii; + data->state.list_only = data->set.list_only; data->state.httpreq = data->set.method; - data->change.url = data->set.str[STRING_SET_URL]; + data->state.url = data->set.str[STRING_SET_URL]; /* Init the SSL session ID cache here. We do it here since we want to do it after the *_setopt() calls (that could specify the size of the cache) but @@ -1426,11 +1429,11 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) return result; data->state.wildcardmatch = data->set.wildcard_enabled; - data->set.followlocation = 0; /* reset the location-follow counter */ + data->state.followlocation = 0; /* reset the location-follow counter */ data->state.this_is_a_follow = FALSE; /* reset this */ data->state.errorbuf = FALSE; /* no error has occurred */ - data->state.httpversion = 0; /* don't assume any particular server version */ - + data->state.httpwant = data->set.httpwant; + data->state.httpversion = 0; data->state.authproblem = FALSE; data->state.authhost.want = data->set.httpauth; data->state.authproxy.want = data->set.proxyauth; @@ -1448,11 +1451,11 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) data->state.infilesize = 0; /* If there is a list of cookie files to read, do it now! */ - if(data->change.cookielist) + if(data->state.cookielist) Curl_cookie_loadfiles(data); /* If there is a list of host pairs to deal with */ - if(data->change.resolve) + if(data->state.resolve) result = Curl_loadhostpairs(data); if(!result) { @@ -1506,6 +1509,19 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) return CURLE_OUT_OF_MEMORY; } + if(!result) + result = Curl_setstropt(&data->state.aptr.user, + data->set.str[STRING_USERNAME]); + if(!result) + result = Curl_setstropt(&data->state.aptr.passwd, + data->set.str[STRING_PASSWORD]); + if(!result) + result = Curl_setstropt(&data->state.aptr.proxyuser, + data->set.str[STRING_PROXYUSERNAME]); + if(!result) + result = Curl_setstropt(&data->state.aptr.proxypasswd, + data->set.str[STRING_PROXYPASSWORD]); + data->req.headerbytecount = 0; return result; } @@ -1553,7 +1569,7 @@ CURLcode Curl_follow(struct Curl_easy *data, if(type == FOLLOW_REDIR) { if((data->set.maxredirs != -1) && - (data->set.followlocation >= data->set.maxredirs)) { + (data->state.followlocation >= data->set.maxredirs)) { reachedmax = TRUE; type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected to URL */ @@ -1562,22 +1578,43 @@ CURLcode Curl_follow(struct Curl_easy *data, /* mark the next request as a followed location: */ data->state.this_is_a_follow = TRUE; - data->set.followlocation++; /* count location-followers */ + data->state.followlocation++; /* count location-followers */ if(data->set.http_auto_referer) { + CURLU *u; + char *referer = NULL; + /* We are asked to automatically set the previous URL as the referer when we get the next URL. We pick the ->url field, which may or may not be 100% correct */ - if(data->change.referer_alloc) { - Curl_safefree(data->change.referer); - data->change.referer_alloc = FALSE; + if(data->state.referer_alloc) { + Curl_safefree(data->state.referer); + data->state.referer_alloc = FALSE; } - data->change.referer = strdup(data->change.url); - if(!data->change.referer) + /* Make a copy of the URL without crenditals and fragment */ + u = curl_url(); + if(!u) + return CURLE_OUT_OF_MEMORY; + + uc = curl_url_set(u, CURLUPART_URL, data->state.url, 0); + if(!uc) + uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0); + if(!uc) + uc = curl_url_set(u, CURLUPART_USER, NULL, 0); + if(!uc) + uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0); + if(!uc) + uc = curl_url_get(u, CURLUPART_URL, &referer, 0); + + curl_url_cleanup(u); + + if(uc || !referer) return CURLE_OUT_OF_MEMORY; - data->change.referer_alloc = TRUE; /* yes, free this later */ + + data->state.referer = referer; + data->state.referer_alloc = TRUE; /* yes, free this later */ } } } @@ -1625,13 +1662,13 @@ CURLcode Curl_follow(struct Curl_easy *data, if(disallowport) data->state.allow_port = FALSE; - if(data->change.url_alloc) - Curl_safefree(data->change.url); + if(data->state.url_alloc) + Curl_safefree(data->state.url); - data->change.url = newurl; - data->change.url_alloc = TRUE; + data->state.url = newurl; + data->state.url_alloc = TRUE; - infof(data, "Issue another request to this URL: '%s'\n", data->change.url); + infof(data, "Issue another request to this URL: '%s'\n", data->state.url); /* * We get here when the HTTP code is 300-399 (and 401). We need to perform @@ -1792,7 +1829,7 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url) } infof(data, "Connection died, retrying a fresh connect\ (retry count: %d)\n", data->state.retrycount); - *url = strdup(data->change.url); + *url = strdup(data->state.url); if(!*url) return CURLE_OUT_OF_MEMORY; diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index c02d2c2019..19fcfb842c 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -234,7 +234,7 @@ static const struct Curl_handler * const protocols[] = { #endif #if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) + (SIZEOF_CURL_OFF_T > 4) &Curl_handler_smb, #ifdef USE_SSL &Curl_handler_smbs, @@ -312,16 +312,16 @@ void Curl_freeset(struct Curl_easy *data) Curl_safefree(data->set.blobs[j]); } - if(data->change.referer_alloc) { - Curl_safefree(data->change.referer); - data->change.referer_alloc = FALSE; + if(data->state.referer_alloc) { + Curl_safefree(data->state.referer); + data->state.referer_alloc = FALSE; } - data->change.referer = NULL; - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; + data->state.referer = NULL; + if(data->state.url_alloc) { + Curl_safefree(data->state.url); + data->state.url_alloc = FALSE; } - data->change.url = NULL; + data->state.url = NULL; Curl_mime_cleanpart(&data->set.mimepost); } @@ -405,11 +405,11 @@ CURLcode Curl_close(struct Curl_easy **datap) free(data->req.newurl); data->req.newurl = NULL; - if(data->change.referer_alloc) { - Curl_safefree(data->change.referer); - data->change.referer_alloc = FALSE; + if(data->state.referer_alloc) { + Curl_safefree(data->state.referer); + data->state.referer_alloc = FALSE; } - data->change.referer = NULL; + data->state.referer = NULL; up_free(data); Curl_safefree(data->state.buffer); @@ -449,6 +449,10 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_safefree(data->state.aptr.host); Curl_safefree(data->state.aptr.cookiehost); Curl_safefree(data->state.aptr.rtsp_transport); + Curl_safefree(data->state.aptr.user); + Curl_safefree(data->state.aptr.passwd); + Curl_safefree(data->state.aptr.proxyuser); + Curl_safefree(data->state.aptr.proxypasswd); #ifndef CURL_DISABLE_DOH if(data->req.doh) { @@ -530,6 +534,8 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) * libcurl 7.10 introduced SSL verification *by default*! This needs to be * switched off unless wanted. */ + set->doh_verifyhost = TRUE; + set->doh_verifypeer = TRUE; set->ssl.primary.verifypeer = TRUE; set->ssl.primary.verifyhost = TRUE; #ifdef USE_TLS_SRP @@ -569,7 +575,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) */ if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { #if defined(CURL_CA_BUNDLE) - result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE); + result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); if(result) return result; @@ -579,7 +585,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) return result; #endif #if defined(CURL_CA_PATH) - result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH); + result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); if(result) return result; @@ -609,7 +615,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ set->maxage_conn = 118; set->http09_allowed = FALSE; - set->httpversion = + set->httpwant = #ifdef USE_NGHTTP2 CURL_HTTP_VERSION_2TLS #else @@ -837,7 +843,7 @@ CURLcode Curl_disconnect(struct Curl_easy *data, dead_connection = TRUE; /* temporarily attach the connection to this transfer handle for the - disonnect and shutdown */ + disconnect and shutdown */ Curl_attach_connnection(data, conn); if(conn->handler->disconnect) @@ -887,7 +893,7 @@ static int IsMultiplexingPossible(const struct Curl_easy *handle, (!conn->bits.protoconnstart || !conn->bits.close)) { if(Curl_multiplex_wanted(handle->multi) && - (handle->set.httpversion >= CURL_HTTP_VERSION_2)) + (handle->state.httpwant >= CURL_HTTP_VERSION_2)) /* allows HTTP/2 */ avail |= CURLPIPE_MULTIPLEX; } @@ -986,12 +992,12 @@ static bool extract_if_dead(struct connectdata *conn, /* briefly attach the connection to this transfer for the purpose of checking it */ Curl_attach_connnection(data, conn); - conn->data = data; /* find the way back if necessary */ + state = conn->handler->connection_check(data, conn, CONNCHECK_ISDEAD); dead = (state & CONNRESULT_DEAD); /* detach the connection again */ Curl_detach_connnection(data); - conn->data = NULL; /* clear it again */ + } else { /* Use the general method for determining the death of a connection */ @@ -1092,13 +1098,13 @@ ConnectionExists(struct Curl_easy *data, #ifdef USE_NTLM bool wantNTLMhttp = ((data->state.authhost.want & - (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && - (needle->handler->protocol & PROTO_FAMILY_HTTP)); + (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && + (needle->handler->protocol & PROTO_FAMILY_HTTP)); #ifndef CURL_DISABLE_PROXY bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd && - ((data->state.authproxy.want & - (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && - (needle->handler->protocol & PROTO_FAMILY_HTTP))); + ((data->state.authproxy.want & + (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && + (needle->handler->protocol & PROTO_FAMILY_HTTP))); #else bool wantProxyNTLMhttp = FALSE; #endif @@ -1266,17 +1272,19 @@ ConnectionExists(struct Curl_easy *data, } #endif - DEBUGASSERT(!check->data || GOOD_EASY_HANDLE(check->data)); - - if(!canmultiplex && check->data) + if(!canmultiplex && CONN_INUSE(check)) /* this request can't be multiplexed but the checked connection is already in use so we skip it */ continue; - if(check->data && (check->data->multi != needle->data->multi)) - /* this could be subject for multiplex use, but only if they belong to - * the same multi handle */ - continue; + if(CONN_INUSE(check)) { + /* Subject for multiplex use if 'checks' belongs to the same multi + handle as 'data' is. */ + struct Curl_llist_element *e = check->easyq.head; + struct Curl_easy *entry = e->ptr; + if(entry->multi != data->multi) + continue; + } if(needle->localdev || needle->localport) { /* If we are bound to a specific local end (IP+port), we must not @@ -1435,7 +1443,7 @@ ConnectionExists(struct Curl_easy *data, continue; } else if(multiplexed >= - Curl_multi_max_concurrent_streams(needle->data->multi)) { + Curl_multi_max_concurrent_streams(data->multi)) { infof(data, "client side MAX_CONCURRENT_STREAMS reached" ", skip (%zu)\n", multiplexed); @@ -1459,7 +1467,6 @@ ConnectionExists(struct Curl_easy *data, if(chosen) { /* mark it as used before releasing the lock */ - chosen->data = data; /* own it! */ Curl_attach_connnection(data, chosen); CONNCACHE_UNLOCK(data); *usethis = chosen; @@ -1674,9 +1681,6 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) /* Store current time to give a baseline to keepalive connection times. */ conn->keepalive = Curl_now(); - conn->data = data; /* Setup the association between this connection - and the Curl_easy */ - #ifndef CURL_DISABLE_PROXY conn->http_proxy.proxytype = data->set.proxytype; conn->socks_proxy.proxytype = CURLPROXY_SOCKS4; @@ -1699,11 +1703,11 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) } conn->bits.proxy_user_passwd = - (data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE; + (data->state.aptr.proxyuser) ? TRUE : FALSE; conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; #endif /* CURL_DISABLE_PROXY */ - conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE; + conn->bits.user_passwd = (data->state.aptr.user) ? TRUE : FALSE; #ifndef CURL_DISABLE_FTP conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; @@ -1896,28 +1900,27 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; if(data->set.str[STRING_DEFAULT_PROTOCOL] && - !Curl_is_absolute_url(data->change.url, NULL, MAX_SCHEME_LEN)) { - char *url; - if(data->change.url_alloc) - free(data->change.url); - url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL], - data->change.url); + !Curl_is_absolute_url(data->state.url, NULL, MAX_SCHEME_LEN)) { + char *url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL], + data->state.url); if(!url) return CURLE_OUT_OF_MEMORY; - data->change.url = url; - data->change.url_alloc = TRUE; + if(data->state.url_alloc) + free(data->state.url); + data->state.url = url; + data->state.url_alloc = TRUE; } if(!use_set_uh) { char *newurl; - uc = curl_url_set(uh, CURLUPART_URL, data->change.url, + uc = curl_url_set(uh, CURLUPART_URL, data->state.url, CURLU_GUESS_SCHEME | CURLU_NON_SUPPORT_SCHEME | (data->set.disallow_username_in_url ? CURLU_DISALLOW_USER : 0) | (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)); if(uc) { - DEBUGF(infof(data, "curl_url_set rejected %s\n", data->change.url)); + DEBUGF(infof(data, "curl_url_set rejected %s\n", data->state.url)); return Curl_uc_to_curlcode(uc); } @@ -1925,10 +1928,10 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, uc = curl_url_get(uh, CURLUPART_URL, &newurl, 0); if(uc) return Curl_uc_to_curlcode(uc); - if(data->change.url_alloc) - free(data->change.url); - data->change.url = newurl; - data->change.url_alloc = TRUE; + if(data->state.url_alloc) + free(data->state.url); + data->state.url = newurl; + data->state.url_alloc = TRUE; } uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0); @@ -1949,19 +1952,21 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0); if(uc) return Curl_uc_to_curlcode(uc); - if(data->change.url_alloc) - Curl_safefree(data->change.url); + if(data->state.url_alloc) + Curl_safefree(data->state.url); /* after update, get the updated version */ uc = curl_url_get(uh, CURLUPART_URL, &url, 0); if(uc) return Curl_uc_to_curlcode(uc); uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0); - if(uc) + if(uc) { + free(url); return Curl_uc_to_curlcode(uc); - data->change.url = url; - data->change.url_alloc = TRUE; + } + data->state.url = url; + data->state.url_alloc = TRUE; infof(data, "Switched from HTTP to HTTPS due to HSTS => %s\n", - data->change.url); + data->state.url); } } #endif @@ -1970,36 +1975,50 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, if(result) return result; - /* we don't use the URL API's URL decoder option here since it rejects - control codes and we want to allow them for some schemes in the user and - password fields */ - uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0); - if(!uc) { - char *decoded; - result = Curl_urldecode(NULL, data->state.up.user, 0, &decoded, NULL, - conn->handler->flags&PROTOPT_USERPWDCTRL ? - REJECT_ZERO : REJECT_CTRL); - if(result) - return result; - conn->user = decoded; - conn->bits.user_passwd = TRUE; + /* + * User name and password set with their own options override the + * credentials possibly set in the URL. + */ + if(!data->state.aptr.user) { + /* we don't use the URL API's URL decoder option here since it rejects + control codes and we want to allow them for some schemes in the user + and password fields */ + uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0); + if(!uc) { + char *decoded; + result = Curl_urldecode(NULL, data->state.up.user, 0, &decoded, NULL, + conn->handler->flags&PROTOPT_USERPWDCTRL ? + REJECT_ZERO : REJECT_CTRL); + if(result) + return result; + conn->user = decoded; + conn->bits.user_passwd = TRUE; + result = Curl_setstropt(&data->state.aptr.user, decoded); + if(result) + return result; + } + else if(uc != CURLUE_NO_USER) + return Curl_uc_to_curlcode(uc); } - else if(uc != CURLUE_NO_USER) - return Curl_uc_to_curlcode(uc); - uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0); - if(!uc) { - char *decoded; - result = Curl_urldecode(NULL, data->state.up.password, 0, &decoded, NULL, - conn->handler->flags&PROTOPT_USERPWDCTRL ? - REJECT_ZERO : REJECT_CTRL); - if(result) - return result; - conn->passwd = decoded; - conn->bits.user_passwd = TRUE; + if(!data->state.aptr.passwd) { + uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0); + if(!uc) { + char *decoded; + result = Curl_urldecode(NULL, data->state.up.password, 0, &decoded, NULL, + conn->handler->flags&PROTOPT_USERPWDCTRL ? + REJECT_ZERO : REJECT_CTRL); + if(result) + return result; + conn->passwd = decoded; + conn->bits.user_passwd = TRUE; + result = Curl_setstropt(&data->state.aptr.passwd, decoded); + if(result) + return result; + } + else if(uc != CURLUE_NO_PASSWORD) + return Curl_uc_to_curlcode(uc); } - else if(uc != CURLUE_NO_PASSWORD) - return Curl_uc_to_curlcode(uc); uc = curl_url_get(uh, CURLUPART_OPTIONS, &data->state.up.options, CURLU_URLDECODE); @@ -2385,11 +2404,20 @@ static CURLcode parse_proxy(struct Curl_easy *data, proxyinfo->proxytype = proxytype; /* Is there a username and password given in this proxy url? */ - curl_url_get(uhp, CURLUPART_USER, &proxyuser, CURLU_URLDECODE); - curl_url_get(uhp, CURLUPART_PASSWORD, &proxypasswd, CURLU_URLDECODE); + uc = curl_url_get(uhp, CURLUPART_USER, &proxyuser, CURLU_URLDECODE); + if(uc && (uc != CURLUE_NO_USER)) + goto error; + uc = curl_url_get(uhp, CURLUPART_PASSWORD, &proxypasswd, CURLU_URLDECODE); + if(uc && (uc != CURLUE_NO_PASSWORD)) + goto error; + if(proxyuser || proxypasswd) { Curl_safefree(proxyinfo->user); proxyinfo->user = proxyuser; + result = Curl_setstropt(&data->state.aptr.proxyuser, proxyuser); + proxyuser = NULL; + if(result) + goto error; Curl_safefree(proxyinfo->passwd); if(!proxypasswd) { proxypasswd = strdup(""); @@ -2399,6 +2427,10 @@ static CURLcode parse_proxy(struct Curl_easy *data, } } proxyinfo->passwd = proxypasswd; + result = Curl_setstropt(&data->state.aptr.proxypasswd, proxypasswd); + proxypasswd = NULL; + if(result) + goto error; conn->bits.proxy_user_passwd = TRUE; /* enable it */ } @@ -2444,6 +2476,8 @@ static CURLcode parse_proxy(struct Curl_easy *data, proxyinfo->host.name = host; error: + free(proxyuser); + free(proxypasswd); free(scheme); curl_url_cleanup(uhp); return result; @@ -2455,18 +2489,26 @@ static CURLcode parse_proxy(struct Curl_easy *data, static CURLcode parse_proxy_auth(struct Curl_easy *data, struct connectdata *conn) { - const char *proxyuser = data->set.str[STRING_PROXYUSERNAME] ? - data->set.str[STRING_PROXYUSERNAME] : ""; - const char *proxypasswd = data->set.str[STRING_PROXYPASSWORD] ? - data->set.str[STRING_PROXYPASSWORD] : ""; + const char *proxyuser = data->state.aptr.proxyuser ? + data->state.aptr.proxyuser : ""; + const char *proxypasswd = data->state.aptr.proxypasswd ? + data->state.aptr.proxypasswd : ""; CURLcode result = CURLE_OK; - if(proxyuser) + if(proxyuser) { result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL, REJECT_ZERO); - if(!result && proxypasswd) + if(!result) + result = Curl_setstropt(&data->state.aptr.proxyuser, + conn->http_proxy.user); + } + if(!result && proxypasswd) { result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd, NULL, REJECT_ZERO); + if(!result) + result = Curl_setstropt(&data->state.aptr.proxypasswd, + conn->http_proxy.passwd); + } return result; } @@ -2808,44 +2850,19 @@ static CURLcode parse_remote_port(struct Curl_easy *data, * option or a .netrc file, if applicable. */ static CURLcode override_login(struct Curl_easy *data, - struct connectdata *conn, - char **userp, char **passwdp, char **optionsp) + struct connectdata *conn) { - bool user_changed = FALSE; - bool passwd_changed = FALSE; CURLUcode uc; + char **userp = &conn->user; + char **passwdp = &conn->passwd; + char **optionsp = &conn->options; if(data->set.use_netrc == CURL_NETRC_REQUIRED && conn->bits.user_passwd) { - /* ignore user+password in the URL */ - if(*userp) { - Curl_safefree(*userp); - user_changed = TRUE; - } - if(*passwdp) { - Curl_safefree(*passwdp); - passwd_changed = TRUE; - } + Curl_safefree(*userp); + Curl_safefree(*passwdp); conn->bits.user_passwd = FALSE; /* disable user+password */ } - if(data->set.str[STRING_USERNAME]) { - free(*userp); - *userp = strdup(data->set.str[STRING_USERNAME]); - if(!*userp) - return CURLE_OUT_OF_MEMORY; - conn->bits.user_passwd = TRUE; /* enable user+password */ - user_changed = TRUE; - } - - if(data->set.str[STRING_PASSWORD]) { - free(*passwdp); - *passwdp = strdup(data->set.str[STRING_PASSWORD]); - if(!*passwdp) - return CURLE_OUT_OF_MEMORY; - conn->bits.user_passwd = TRUE; /* enable user+password */ - passwd_changed = TRUE; - } - if(data->set.str[STRING_OPTIONS]) { free(*optionsp); *optionsp = strdup(data->set.str[STRING_OPTIONS]); @@ -2854,8 +2871,7 @@ static CURLcode override_login(struct Curl_easy *data, } conn->bits.netrc = FALSE; - if(data->set.use_netrc != CURL_NETRC_IGNORED && - (!*userp || !**userp || !*passwdp || !**passwdp)) { + if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) { bool netrc_user_changed = FALSE; bool netrc_passwd_changed = FALSE; int ret; @@ -2865,8 +2881,8 @@ static CURLcode override_login(struct Curl_easy *data, &netrc_user_changed, &netrc_passwd_changed, data->set.str[STRING_NETRC_FILE]); if(ret > 0) { - infof(data, "Couldn't find host %s in the .netrc file; using defaults\n", - conn->host.name); + infof(data, "Couldn't find host %s in the %s file; using defaults\n", + conn->host.name, data->set.str[STRING_NETRC_FILE]); } else if(ret < 0) { return CURLE_OUT_OF_MEMORY; @@ -2877,29 +2893,44 @@ static CURLcode override_login(struct Curl_easy *data, different host or similar. */ conn->bits.netrc = TRUE; conn->bits.user_passwd = TRUE; /* enable user+password */ - - if(netrc_user_changed) { - user_changed = TRUE; - } - if(netrc_passwd_changed) { - passwd_changed = TRUE; - } } } /* for updated strings, we update them in the URL */ - if(user_changed) { - uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp, + if(*userp) { + CURLcode result = Curl_setstropt(&data->state.aptr.user, *userp); + if(result) + return result; + } + if(data->state.aptr.user) { + uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user, CURLU_URLENCODE); if(uc) return Curl_uc_to_curlcode(uc); + if(!*userp) { + *userp = strdup(data->state.aptr.user); + if(!*userp) + return CURLE_OUT_OF_MEMORY; + } } - if(passwd_changed) { - uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp, - CURLU_URLENCODE); + + if(*passwdp) { + CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp); + if(result) + return result; + } + if(data->state.aptr.passwd) { + uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, + data->state.aptr.passwd, CURLU_URLENCODE); if(uc) return Curl_uc_to_curlcode(uc); + if(!*passwdp) { + *passwdp = strdup(data->state.aptr.passwd); + if(!*passwdp) + return CURLE_OUT_OF_MEMORY; + } } + return CURLE_OK; } @@ -3315,7 +3346,7 @@ static CURLcode resolve_server(struct Curl_easy *data, result = CURLE_OPERATION_TIMEDOUT; else if(!hostaddr) { - failf(data, "Couldn't resolve host '%s'", connhost->dispname); + failf(data, "Could not resolve host: %s", connhost->dispname); result = CURLE_COULDNT_RESOLVE_HOST; /* don't return yet, we need to clean up the timeout first */ } @@ -3367,7 +3398,7 @@ static void reuse_conn(struct Curl_easy *data, ip address and port number whenever an outgoing connection is **established** from the primary socket to a remote address. */ char local_ip[MAX_IPADR_LEN] = ""; - long local_port = -1; + int local_port = -1; #ifndef CURL_DISABLE_PROXY Curl_free_idnconverted_hostname(&old_conn->http_proxy.host); Curl_free_idnconverted_hostname(&old_conn->socks_proxy.host); @@ -3380,8 +3411,6 @@ static void reuse_conn(struct Curl_easy *data, allocated in vain and is targeted for destruction */ Curl_free_primary_ssl_config(&old_conn->ssl_config); - conn->data = data; - /* get the user+password information from the old_conn struct since it may * be new for this request even when we re-use an existing connection */ conn->bits.user_passwd = old_conn->bits.user_passwd; @@ -3469,7 +3498,6 @@ static void reuse_conn(struct Curl_easy *data, * @param async is set TRUE when an async DNS resolution is pending * @see Curl_setup_conn() * - * *NOTE* this function assigns the conn->data pointer! */ static CURLcode create_conn(struct Curl_easy *data, @@ -3492,7 +3520,7 @@ static CURLcode create_conn(struct Curl_easy *data, /************************************************************* * Check input data *************************************************************/ - if(!data->change.url) { + if(!data->state.url) { result = CURLE_URL_MALFORMAT; goto out; } @@ -3560,8 +3588,7 @@ static CURLcode create_conn(struct Curl_easy *data, /* Check for overridden login details and set them accordingly so they they are known when protocol->setup_connection is called! */ - result = override_login(data, conn, &conn->user, &conn->passwd, - &conn->options); + result = override_login(data, conn); if(result) goto out; @@ -3693,17 +3720,17 @@ static CURLcode create_conn(struct Curl_easy *data, that will be freed as part of the Curl_easy struct, but all cloned copies will be separately allocated. */ - data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG]; - data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG]; + data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH]; + data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE]; data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; data->set.ssl.primary.cipher_list = - data->set.str[STRING_SSL_CIPHER_LIST_ORIG]; + data->set.str[STRING_SSL_CIPHER_LIST]; data->set.ssl.primary.cipher_list13 = - data->set.str[STRING_SSL_CIPHER13_LIST_ORIG]; + data->set.str[STRING_SSL_CIPHER13_LIST]; data->set.ssl.primary.pinned_key = - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; - data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_ORIG]; + data->set.str[STRING_SSL_PINNEDPUBLICKEY]; + data->set.ssl.primary.cert_blob = data->set.blobs[BLOB_CERT]; data->set.ssl.primary.curves = data->set.str[STRING_SSL_EC_CURVES]; #ifndef CURL_DISABLE_PROXY @@ -3728,24 +3755,24 @@ static CURLcode create_conn(struct Curl_easy *data, data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY]; data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY]; #endif - data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG]; - data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG]; - data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG]; - data->set.ssl.key = data->set.str[STRING_KEY_ORIG]; - data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG]; - data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG]; - data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG]; + data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; + data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; + data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE]; + data->set.ssl.key = data->set.str[STRING_KEY]; + data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE]; + data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD]; + data->set.ssl.primary.clientcert = data->set.str[STRING_CERT]; #ifdef USE_TLS_SRP - data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG]; - data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG]; + data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME]; + data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; #ifndef CURL_DISABLE_PROXY data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; #endif #endif - data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG]; - data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG]; + data->set.ssl.key_blob = data->set.blobs[BLOB_KEY]; + data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary, &conn->ssl_config)) { @@ -3952,10 +3979,7 @@ out: * create_conn() is all done. * * Curl_setup_conn() also handles reused connections - * - * conn->data MUST already have been setup fine (in create_conn) */ - CURLcode Curl_setup_conn(struct Curl_easy *data, bool *protocol_done) { diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index f7d60b249b..fec875652c 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -371,6 +371,15 @@ struct kerberos5data { }; #endif +/* Struct used for SCRAM-SHA-1 authentication */ +#ifdef USE_GSASL +#include <gsasl.h> +struct gsasldata { + Gsasl *ctx; + Gsasl_session *client; +}; +#endif + /* Struct used for NTLM challenge-response authentication */ #if defined(USE_NTLM) struct ntlmdata { @@ -902,10 +911,6 @@ struct connstate { * unique for an entire connection. */ struct connectdata { - /* 'data' is the CURRENT Curl_easy using this connection -- take great - caution that this might very well vary between different times this - connection is used! */ - struct Curl_easy *data; struct connstate cnnct; struct Curl_llist_element bundle_node; /* conncache */ @@ -981,12 +986,8 @@ struct connectdata { char *user; /* user name string, allocated */ char *passwd; /* password string, allocated */ char *options; /* options string, allocated */ - char *sasl_authzid; /* authorisation identity string, allocated */ - - int httpversion; /* the HTTP version*10 reported by the server */ - int rtspversion; /* the RTSP version*10 reported by the server */ - + unsigned char httpversion; /* the HTTP version*10 reported by the server */ struct curltime now; /* "current" time */ struct curltime created; /* creation time */ struct curltime lastused; /* when returned to the connection cache */ @@ -1065,6 +1066,10 @@ struct connectdata { CtxtHandle *sslContext; #endif +#ifdef USE_GSASL + struct gsasldata gsasl; +#endif + #if defined(USE_NTLM) curlntlm http_ntlm_state; curlntlm proxy_ntlm_state; @@ -1157,9 +1162,9 @@ struct PureInfo { reused, in the connection cache. */ char conn_primary_ip[MAX_IPADR_LEN]; - long conn_primary_port; + int conn_primary_port; char conn_local_ip[MAX_IPADR_LEN]; - long conn_local_port; + int conn_local_port; const char *conn_scheme; unsigned int conn_protocol; struct curl_certinfo certs; /* info about the certs, only populated in @@ -1316,8 +1321,6 @@ struct urlpieces { struct UrlState { /* Points to the connection cache */ struct conncache *conn_cache; - int retrycount; /* number of retries on a new connection */ - /* buffers to store authentication data in, as parsed from input options */ struct curltime keeps_speed; /* for the progress meter really */ @@ -1334,6 +1337,7 @@ struct UrlState { following not keep sending user+password... This is strdup() data. */ + int retrycount; /* number of retries on a new connection */ int first_remote_port; /* remote port of the first (not followed) request */ struct Curl_ssl_session *session; /* array of 'max_ssl_sessions' size */ long sessionage; /* number of the most recent session */ @@ -1341,6 +1345,7 @@ struct UrlState { unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */ int os_errno; /* filled in with errno whenever an error occurs */ char *scratch; /* huge buffer[set.buffer_size*2] for upload CRLF replacing */ + long followlocation; /* redirect counter */ #ifdef HAVE_SIGNAL /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */ void (*prev_signal)(int sig); @@ -1365,9 +1370,10 @@ struct UrlState { /* a place to store the most recently set FTP entrypath */ char *most_recent_ftp_entrypath; - - int httpversion; /* the lowest HTTP version*10 reported by any server - involved in this request */ + unsigned char httpwant; /* when non-zero, a specific HTTP version requested + to be used in the library's request(s) */ + unsigned char httpversion; /* the lowest HTTP version*10 reported by any + server involved in this request */ #if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) /* do FTP line-end conversions on most platforms */ @@ -1400,9 +1406,13 @@ struct UrlState { int stream_weight; CURLU *uh; /* URL handle for the current parsed URL */ struct urlpieces up; -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT) Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */ -#endif + char *url; /* work URL, copied from UserDefined */ + char *referer; /* referer string */ + struct curl_slist *cookielist; /* list of cookie files set by + curl_easy_setopt(COOKIEFILE) calls */ + struct curl_slist *resolve; /* set to point to the set.resolve list when + this should be dealt with in pretransfer */ #ifndef CURL_DISABLE_HTTP size_t trailers_bytes_sent; struct dynbuf trailers_buf; /* a buffer containing the compiled trailing @@ -1427,6 +1437,12 @@ struct UrlState { char *cookiehost; char *rtsp_transport; char *te; /* TE: request header */ + + /* transfer credentials */ + char *user; + char *passwd; + char *proxyuser; + char *proxypasswd; } aptr; #ifdef CURLDEBUG @@ -1454,32 +1470,16 @@ struct UrlState { BIT(use_range); BIT(rangestringalloc); /* the range string is malloc()'ed */ BIT(done); /* set to FALSE when Curl_init_do() is called and set to TRUE - when multi_done() is called, to prevent multi_done() to get - invoked twice when the multi interface is used. */ + when multi_done() is called, to prevent multi_done() to get + invoked twice when the multi interface is used. */ BIT(stream_depends_e); /* set or don't set the Exclusive bit */ BIT(previouslypending); /* this transfer WAS in the multi->pending queue */ BIT(cookie_engine); -}; - - -/* - * This 'DynamicStatic' struct defines dynamic states that actually change - * values in the 'UserDefined' area, which MUST be taken into consideration - * if the UserDefined struct is cloned or similar. You can probably just - * copy these, but each one indicate a special action on other data. - */ - -struct DynamicStatic { - char *url; /* work URL, copied from UserDefined */ - char *referer; /* referer string */ - struct curl_slist *cookielist; /* list of cookie files set by - curl_easy_setopt(COOKIEFILE) calls */ - struct curl_slist *resolve; /* set to point to the set.resolve list when - this should be dealt with in pretransfer */ + BIT(prefer_ascii); /* ASCII rather than binary */ + BIT(list_only); /* list directory contents */ BIT(url_alloc); /* URL string is malloc()'ed */ BIT(referer_alloc); /* referer string is malloc()ed */ - BIT(wildcard_resolve); /* Set to true if any resolve change is a - wildcard */ + BIT(wildcard_resolve); /* Set to true if any resolve change is a wildcard */ }; /* @@ -1502,9 +1502,9 @@ struct Curl_multi; /* declared and used only in multi.c */ * are catered for in curl_easy_setopt_ccsid() */ enum dupstring { - STRING_CERT_ORIG, /* client certificate file name */ + STRING_CERT, /* client certificate file name */ STRING_CERT_PROXY, /* client certificate file name */ - STRING_CERT_TYPE_ORIG, /* format for certificate (default: PEM)*/ + STRING_CERT_TYPE, /* format for certificate (default: PEM)*/ STRING_CERT_TYPE_PROXY, /* format for certificate (default: PEM)*/ STRING_COOKIE, /* HTTP cookie string to send */ STRING_COOKIEJAR, /* dump all cookies to this file */ @@ -1515,11 +1515,11 @@ enum dupstring { STRING_FTP_ACCOUNT, /* ftp account data */ STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */ STRING_FTPPORT, /* port to send with the FTP PORT command */ - STRING_KEY_ORIG, /* private key file name */ + STRING_KEY, /* private key file name */ STRING_KEY_PROXY, /* private key file name */ - STRING_KEY_PASSWD_ORIG, /* plain text private key password */ + STRING_KEY_PASSWD, /* plain text private key password */ STRING_KEY_PASSWD_PROXY, /* plain text private key password */ - STRING_KEY_TYPE_ORIG, /* format for private key (default: PEM) */ + STRING_KEY_TYPE, /* format for private key (default: PEM) */ STRING_KEY_TYPE_PROXY, /* format for private key (default: PEM) */ STRING_KRB_LEVEL, /* krb security level */ STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find @@ -1529,22 +1529,22 @@ enum dupstring { STRING_SET_RANGE, /* range, if used */ STRING_SET_REFERER, /* custom string for the HTTP referer field */ STRING_SET_URL, /* what original URL to work on */ - STRING_SSL_CAPATH_ORIG, /* CA directory name (doesn't work on windows) */ + STRING_SSL_CAPATH, /* CA directory name (doesn't work on windows) */ STRING_SSL_CAPATH_PROXY, /* CA directory name (doesn't work on windows) */ - STRING_SSL_CAFILE_ORIG, /* certificate file to verify peer against */ + STRING_SSL_CAFILE, /* certificate file to verify peer against */ STRING_SSL_CAFILE_PROXY, /* certificate file to verify peer against */ - STRING_SSL_PINNEDPUBLICKEY_ORIG, /* public key file to verify peer against */ + STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */ STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */ - STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */ + STRING_SSL_CIPHER_LIST, /* list of ciphers to use */ STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */ - STRING_SSL_CIPHER13_LIST_ORIG, /* list of TLS 1.3 ciphers to use */ + STRING_SSL_CIPHER13_LIST, /* list of TLS 1.3 ciphers to use */ STRING_SSL_CIPHER13_LIST_PROXY, /* list of TLS 1.3 ciphers to use */ STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */ STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */ STRING_USERAGENT, /* User-Agent string */ - STRING_SSL_CRLFILE_ORIG, /* crl file to check certificate */ + STRING_SSL_CRLFILE, /* crl file to check certificate */ STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */ - STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */ + STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */ STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */ STRING_SSL_ENGINE, /* name of ssl engine */ STRING_USERNAME, /* <username>, if used */ @@ -1565,9 +1565,9 @@ enum dupstring { STRING_SERVICE_NAME, /* Service name */ STRING_MAIL_FROM, STRING_MAIL_AUTH, - STRING_TLSAUTH_USERNAME_ORIG, /* TLS auth <username> */ + STRING_TLSAUTH_USERNAME, /* TLS auth <username> */ STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth <username> */ - STRING_TLSAUTH_PASSWORD_ORIG, /* TLS auth <password> */ + STRING_TLSAUTH_PASSWORD, /* TLS auth <password> */ STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth <password> */ STRING_BEARER, /* <bearer>, if used */ STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */ @@ -1596,11 +1596,11 @@ enum dupstring { }; enum dupblob { - BLOB_CERT_ORIG, + BLOB_CERT, BLOB_CERT_PROXY, - BLOB_KEY_ORIG, + BLOB_KEY, BLOB_KEY_PROXY, - BLOB_SSL_ISSUERCERT_ORIG, + BLOB_SSL_ISSUERCERT, BLOB_SSL_ISSUERCERT_PROXY, BLOB_LAST }; @@ -1625,7 +1625,6 @@ struct UserDefined { unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */ unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */ unsigned long socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */ - long followlocation; /* as in HTTP Location: */ long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1 for infinity */ @@ -1708,11 +1707,9 @@ struct UserDefined { curl_TimeCond timecondition; /* kind of time/date comparison */ curl_proxytype proxytype; /* what kind of proxy that is in use */ time_t timevalue; /* what time to compare with */ -#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT) Curl_HttpReq method; /* what kind of HTTP request (if any) is this */ -#endif - long httpversion; /* when non-zero, a specific HTTP version requested to - be used in the library's request(s) */ + unsigned char httpwant; /* when non-zero, a specific HTTP version requested + to be used in the library's request(s) */ struct ssl_config_data ssl; /* user defined SSL stuff */ #ifndef CURL_DISABLE_PROXY struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */ @@ -1800,8 +1797,8 @@ struct UserDefined { BIT(get_filetime); /* get the time and get of the remote file */ BIT(tunnel_thru_httpproxy); /* use CONNECT through a HTTP proxy */ BIT(prefer_ascii); /* ASCII rather than binary */ - BIT(ftp_append); /* append, not overwrite, on upload */ - BIT(ftp_list_only); /* switch FTP command for listing directories */ + BIT(remote_append); /* append, not overwrite, on upload */ + BIT(list_only); /* list directory */ #ifndef CURL_DISABLE_FTP BIT(ftp_use_port); /* use the FTP PORT command */ BIT(ftp_use_epsv); /* if EPSV is to be attempted or not */ @@ -1858,6 +1855,9 @@ struct UserDefined { BIT(disallow_username_in_url); /* disallow username in url */ BIT(doh); /* DNS-over-HTTPS enabled */ BIT(doh_get); /* use GET for DoH requests, instead of POST */ + BIT(doh_verifypeer); /* DOH certificate peer verification */ + BIT(doh_verifyhost); /* DOH certificate hostname verification */ + BIT(doh_verifystatus); /* DOH certificate status verification */ BIT(http09_allowed); /* allow HTTP/0.9 responses */ BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some recipients */ @@ -1905,8 +1905,8 @@ struct Curl_easy { the state etc are also kept. This array is mostly used to detect when a socket is to be removed from the hash. See singlesocket(). */ curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE]; - int actions[MAX_SOCKSPEREASYHANDLE]; /* action for each socket in - sockets[] */ + unsigned char actions[MAX_SOCKSPEREASYHANDLE]; /* action for each socket in + sockets[] */ int numsocks; struct Names dns; @@ -1922,7 +1922,6 @@ struct Curl_easy { #endif struct SingleRequest req; /* Request-specific data */ struct UserDefined set; /* values set by the libcurl user */ - struct DynamicStatic change; /* possibly modified userdefined data */ struct CookieInfo *cookies; /* the cookies, read from files and servers. NOTE that the 'cookie' field in the UserDefined struct defines if the "engine" diff --git a/libs/libcurl/src/vauth/gsasl.c b/libs/libcurl/src/vauth/gsasl.c new file mode 100644 index 0000000000..02a06357f0 --- /dev/null +++ b/libs/libcurl/src/vauth/gsasl.c @@ -0,0 +1,143 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2020 - 2021, Simon Josefsson, <simon@josefsson.org>, 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. + * + * RFC5802 SCRAM-SHA-1 authentication + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifdef USE_GSASL + +#include <curl/curl.h> + +#include "curl_base64.h" +#include "vauth/vauth.h" +#include "urldata.h" +#include "sendf.h" + +#include <gsasl.h> + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +bool Curl_auth_gsasl_is_supported(struct Curl_easy *data, + const char *mech, + struct gsasldata *gsasl) +{ + int res; + + res = gsasl_init(&gsasl->ctx); + if(res != GSASL_OK) { + failf(data, "gsasl init: %s\n", gsasl_strerror(res)); + return FALSE; + } + + res = gsasl_client_start(gsasl->ctx, mech, &gsasl->client); + if(res != GSASL_OK) { + gsasl_done(gsasl->ctx); + return FALSE; + } + + return true; +} + +CURLcode Curl_auth_gsasl_start(struct Curl_easy *data, + const char *userp, + const char *passwdp, + struct gsasldata *gsasl) +{ +#if GSASL_VERSION_NUMBER >= 0x010b00 + int res; + res = +#endif + gsasl_property_set(gsasl->client, GSASL_AUTHID, userp); +#if GSASL_VERSION_NUMBER >= 0x010b00 + if(res != GSASL_OK) { + failf(data, "setting AUTHID failed: %s\n", gsasl_strerror(res)); + return CURLE_OUT_OF_MEMORY; + } +#endif + +#if GSASL_VERSION_NUMBER >= 0x010b00 + res = +#endif + gsasl_property_set(gsasl->client, GSASL_PASSWORD, passwdp); +#if GSASL_VERSION_NUMBER >= 0x010b00 + if(res != GSASL_OK) { + failf(data, "setting PASSWORD failed: %s\n", gsasl_strerror(res)); + return CURLE_OUT_OF_MEMORY; + } +#endif + + (void)data; + + return CURLE_OK; +} + +CURLcode Curl_auth_gsasl_token(struct Curl_easy *data, + const char *chlg64, + struct gsasldata *gsasl, + char **outptr, size_t *outlen) +{ + 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; + } + + res = gsasl_step(gsasl->client, + (const char *)chlg, chlglen, &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; +} + +void Curl_auth_gsasl_cleanup(struct gsasldata *gsasl) +{ + gsasl_finish(gsasl->client); + gsasl->client = NULL; + + gsasl_done(gsasl->ctx); + gsasl->ctx = NULL; +} +#endif diff --git a/libs/libcurl/src/vauth/vauth.h b/libs/libcurl/src/vauth/vauth.h index f25cfc329f..03a5f8adb5 100644 --- a/libs/libcurl/src/vauth/vauth.h +++ b/libs/libcurl/src/vauth/vauth.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2014 - 2020, Steve Holme, <steve_holme@hotmail.com>. + * Copyright (C) 2014 - 2021, Steve Holme, <steve_holme@hotmail.com>. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -42,6 +42,10 @@ struct kerberos5data; struct negotiatedata; #endif +#if defined(USE_GSASL) +struct gsasldata; +#endif + #if defined(USE_WINDOWS_SSPI) #define GSS_ERROR(status) ((status) & 0x80000000) #endif @@ -115,6 +119,27 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, void Curl_auth_digest_cleanup(struct digestdata *digest); #endif /* !CURL_DISABLE_CRYPTO_AUTH */ +#ifdef USE_GSASL +/* This is used to evaluate if MECH is supported by gsasl */ +bool Curl_auth_gsasl_is_supported(struct Curl_easy *data, + const char *mech, + struct gsasldata *gsasl); +/* This is used to start a gsasl method */ +CURLcode Curl_auth_gsasl_start(struct Curl_easy *data, + const char *userp, + const char *passwdp, + struct gsasldata *gsasl); + +/* This is used to process and generate a new SASL token */ +CURLcode Curl_auth_gsasl_token(struct Curl_easy *data, + const char *chlg64, + struct gsasldata *gsasl, + char **outptr, size_t *outlen); + +/* This is used to clean up the gsasl specific data */ +void Curl_auth_gsasl_cleanup(struct gsasldata *digest); +#endif + #if defined(USE_NTLM) /* This is used to evaluate if NTLM is supported */ bool Curl_auth_is_ntlm_supported(void); diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c index a9102ec1ea..b33f2fe83b 100644 --- a/libs/libcurl/src/version.c +++ b/libs/libcurl/src/version.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -100,7 +100,7 @@ static size_t zstd_version(char *buf, size_t bufsz) * zeros in the data. */ -#define VERSION_PARTS 15 /* number of substrings we can concatenate */ +#define VERSION_PARTS 16 /* number of substrings we can concatenate */ char *curl_version(void) { @@ -147,6 +147,9 @@ char *curl_version(void) #ifdef USE_HYPER char hyper_buf[30]; #endif +#ifdef USE_GSASL + char gsasl_buf[30]; +#endif int i = 0; int j; @@ -235,6 +238,11 @@ char *curl_version(void) msnprintf(hyper_buf, sizeof(hyper_buf), "Hyper/%s", hyper_version()); src[i++] = hyper_buf; #endif +#ifdef USE_GSASL + msnprintf(gsasl_buf, sizeof(gsasl_buf), "libgsasl/%s", + gsasl_check_version(NULL)); + src[i++] = gsasl_buf; +#endif DEBUGASSERT(i <= VERSION_PARTS); @@ -326,7 +334,7 @@ static const char * const protocols[] = { "sftp", #endif #if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) + (SIZEOF_CURL_OFF_T > 4) "smb", # ifdef USE_SSL "smbs", @@ -391,7 +399,7 @@ static curl_version_info_data version_info = { #ifdef CURLRES_ASYNCH | CURL_VERSION_ASYNCHDNS #endif -#if (CURL_SIZEOF_CURL_OFF_T > 4) && \ +#if (SIZEOF_CURL_OFF_T > 4) && \ ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) ) | CURL_VERSION_LARGEFILE #endif @@ -431,6 +439,9 @@ static curl_version_info_data version_info = { #if defined(USE_HSTS) | CURL_VERSION_HSTS #endif +#if defined(USE_GSASL) + | CURL_VERSION_GSASL +#endif , NULL, /* ssl_version */ 0, /* ssl_version_num, this is kept at zero */ diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c index d4d0e8bf43..9569431ca2 100644 --- a/libs/libcurl/src/vquic/ngtcp2.c +++ b/libs/libcurl/src/vquic/ngtcp2.c @@ -580,7 +580,7 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, uint32_t flags, { struct quicsocket *qs = (struct quicsocket *)user_data; ssize_t nconsumed; - int fin = flags & NGTCP2_STREAM_DATA_FLAG_FIN ? 1 : 0; + int fin = (flags & NGTCP2_STREAM_DATA_FLAG_FIN) ? 1 : 0; (void)offset; (void)stream_user_data; @@ -739,7 +739,10 @@ static ngtcp2_callbacks ng_callbacks = { NULL, /* handshake_confirmed */ NULL, /* recv_new_token */ ngtcp2_crypto_delete_crypto_aead_ctx_cb, - ngtcp2_crypto_delete_crypto_cipher_ctx_cb + ngtcp2_crypto_delete_crypto_cipher_ctx_cb, + NULL, /* recv_datagram */ + NULL, /* ack_datagram */ + NULL /* lost_datagram */ }; /* @@ -758,7 +761,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, ngtcp2_path path; /* TODO: this must be initialized properly */ struct quicsocket *qs = &conn->hequic[sockindex]; char ipbuf[40]; - long port; + int port; int qfd; if(qs->conn) @@ -773,7 +776,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, return CURLE_BAD_FUNCTION_ARGUMENT; } - infof(data, "Connect socket %d over QUIC to %s:%ld\n", + infof(data, "Connect socket %d over QUIC to %s:%d\n", sockfd, ipbuf, port); qs->version = NGTCP2_PROTO_VER_MAX; @@ -807,8 +810,8 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, return CURLE_QUIC_CONNECT_ERROR; ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr, - qs->local_addrlen, NULL); - ngtcp2_addr_init(&path.remote, addr, addrlen, NULL); + qs->local_addrlen); + ngtcp2_addr_init(&path.remote, addr, addrlen); rc = ngtcp2_conn_client_new(&qs->qconn, &qs->dcid, &qs->scid, &path, NGTCP2_PROTO_VER_MIN, &ng_callbacks, @@ -827,7 +830,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, */ int Curl_quic_ver(char *p, size_t len) { - ngtcp2_info *ng2 = ngtcp2_version(0); + const ngtcp2_info *ng2 = ngtcp2_version(0); nghttp3_info *ht3 = nghttp3_version(0); return msnprintf(p, len, "ngtcp2/%s nghttp3/%s", ng2->version_str, ht3->version_str); @@ -1291,7 +1294,6 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, { struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.p.http; - int rv; (void)user_data; if(!data->set.postfields) { @@ -1302,7 +1304,7 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, DEBUGASSERT(stream->h3out->used < H3_SEND_SIZE); if(stream->h3out->used == 0) { - rv = nghttp3_conn_resume_stream(conn, stream_id); + int rv = nghttp3_conn_resume_stream(conn, stream_id); if(rv != 0) { return NGTCP2_ERR_CALLBACK_FAILURE; } @@ -1730,9 +1732,9 @@ static CURLcode ng_process_ingress(struct Curl_easy *data, } ngtcp2_addr_init(&path.local, (struct sockaddr *)&qs->local_addr, - qs->local_addrlen, NULL); + qs->local_addrlen); ngtcp2_addr_init(&path.remote, (struct sockaddr *)&remote_addr, - remote_addrlen, NULL); + remote_addrlen); rv = ngtcp2_conn_read_pkt(qs->qconn, &path, &pi, buf, recvd, ts); if(rv != 0) { @@ -1788,7 +1790,6 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, ngtcp2_path_storage_zero(&ps); for(;;) { - outlen = -1; veccnt = 0; stream_id = -1; fin = 0; diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c index d138dd3a24..a3870749b5 100644 --- a/libs/libcurl/src/vquic/quiche.c +++ b/libs/libcurl/src/vquic/quiche.c @@ -180,7 +180,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, struct quicsocket *qs = &conn->hequic[sockindex]; char *keylog_file = NULL; char ipbuf[40]; - long port; + int port; #ifdef DEBUG_QUICHE /* initialize debug log callback only once */ @@ -360,6 +360,8 @@ static CURLcode process_ingress(struct Curl_easy *data, int sockfd, uint8_t *buf = (uint8_t *)data->state.buffer; size_t bufsize = data->set.buffer_size; + DEBUGASSERT(qs->conn); + /* in case the timeout expired */ quiche_conn_on_timeout(qs->conn); diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c index 08896ab5b1..1bb644eedd 100644 --- a/libs/libcurl/src/vssh/libssh.c +++ b/libs/libcurl/src/vssh/libssh.c @@ -1224,7 +1224,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } } - if(data->set.ftp_append) + if(data->set.remote_append) /* Try to open for append, but create if nonexisting */ flags = O_WRONLY|O_CREAT|O_APPEND; else if(data->state.resume_from > 0) @@ -1413,7 +1413,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) sshc->readdir_longentry = sshc->readdir_attrs->longname; sshc->readdir_len = strlen(sshc->readdir_filename); - if(data->set.ftp_list_only) { + if(data->set.list_only) { char *tmpLine; tmpLine = aprintf("%s\n", sshc->readdir_filename); diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c index 3130dcc74d..9d188d0582 100644 --- a/libs/libcurl/src/vssh/libssh2.c +++ b/libs/libcurl/src/vssh/libssh2.c @@ -184,7 +184,7 @@ kbd_callback(const char *name, int name_len, const char *instruction, LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract) { - struct connectdata *conn = (struct connectdata *)*abstract; + struct Curl_easy *data = (struct Curl_easy *)*abstract; #ifdef CURL_LIBSSH2_DEBUG fprintf(stderr, "name=%s\n", name); @@ -199,11 +199,11 @@ kbd_callback(const char *name, int name_len, const char *instruction, (void)instruction_len; #endif /* CURL_LIBSSH2_DEBUG */ if(num_prompts == 1) { + struct connectdata *conn = data->conn; responses[0].text = strdup(conn->passwd); responses[0].length = curlx_uztoui(strlen(conn->passwd)); } (void)prompts; - (void)abstract; } /* kbd_callback */ static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err) @@ -1880,7 +1880,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) } } - if(data->set.ftp_append) + if(data->set.remote_append) /* Try to open for append, but create if nonexisting */ flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND; else if(data->state.resume_from > 0) @@ -2143,7 +2143,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) readdir_len = (size_t) rc; sshp->readdir_filename[readdir_len] = '\0'; - if(data->set.ftp_list_only) { + if(data->set.list_only) { result = Curl_client_write(data, CLIENTWRITE_BODY, sshp->readdir_filename, readdir_len); @@ -3159,6 +3159,7 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) sshc->kh = libssh2_knownhost_init(sshc->ssh_session); if(!sshc->kh) { libssh2_session_free(sshc->ssh_session); + sshc->ssh_session = NULL; return CURLE_FAILED_INIT; } diff --git a/libs/libcurl/src/vssh/wolfssh.c b/libs/libcurl/src/vssh/wolfssh.c index 6020180a5e..de0b1c7776 100644 --- a/libs/libcurl/src/vssh/wolfssh.c +++ b/libs/libcurl/src/vssh/wolfssh.c @@ -585,7 +585,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) } } - if(data->set.ftp_append) + if(data->set.remote_append) /* Try to open for append, but create if nonexisting */ flags = WOLFSSH_FXF_WRITE|WOLFSSH_FXF_CREAT|WOLFSSH_FXF_APPEND; else if(data->state.resume_from > 0) @@ -859,7 +859,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) result = CURLE_OK; while(name) { char *line = aprintf("%s\n", - data->set.ftp_list_only ? + data->set.list_only ? name->fName : name->lName); if(line == NULL) { state(data, SSH_SFTP_CLOSE); diff --git a/libs/libcurl/src/vtls/bearssl.c b/libs/libcurl/src/vtls/bearssl.c index 29b08c0e6d..39fc1a2920 100644 --- a/libs/libcurl/src/vtls/bearssl.c +++ b/libs/libcurl/src/vtls/bearssl.c @@ -375,7 +375,8 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, void *session; Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(data, conn, &session, NULL, sockindex)) { + if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, + &session, NULL, sockindex)) { br_ssl_engine_set_session_parameters(&backend->ctx.eng, session); infof(data, "BearSSL: re-using session ID\n"); } @@ -390,7 +391,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, */ #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 + if(data->state.httpversion >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif @@ -571,10 +572,13 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data, br_ssl_engine_get_session_parameters(&backend->ctx.eng, session); Curl_ssl_sessionid_lock(data); incache = !(Curl_ssl_getsessionid(data, conn, + SSL_IS_PROXY() ? TRUE : FALSE, &oldsession, NULL, sockindex)); if(incache) Curl_ssl_delsessionid(data, oldsession); - ret = Curl_ssl_addsessionid(data, conn, session, 0, sockindex); + ret = Curl_ssl_addsessionid(data, conn, + SSL_IS_PROXY() ? TRUE : FALSE, + session, 0, sockindex); Curl_ssl_sessionid_unlock(data); if(ret) { free(session); @@ -855,6 +859,7 @@ const struct Curl_ssl Curl_ssl_bearssl = { Curl_none_cert_status_request, bearssl_connect, bearssl_connect_nonblocking, + Curl_ssl_getsock, bearssl_get_internals, bearssl_close, Curl_none_close_all, diff --git a/libs/libcurl/src/vtls/gskit.c b/libs/libcurl/src/vtls/gskit.c index 9b5f649f7d..b0c73437bb 100644 --- a/libs/libcurl/src/vtls/gskit.c +++ b/libs/libcurl/src/vtls/gskit.c @@ -610,7 +610,7 @@ static void close_one(struct ssl_connect_data *connssl, struct Curl_easy *data, } -static ssize_t gskit_send(struct connectdata *conn, int sockindex, +static ssize_t gskit_send(struct Curl_easy *data, int sockindex, const void *mem, size_t len, CURLcode *curlcode) { struct connectdata *conn = data->conn; @@ -700,7 +700,6 @@ static CURLcode gskit_connect_step1(struct Curl_easy *data, struct ssl_connect_data *connssl = &conn->ssl[sockindex]; gsk_handle envir; CURLcode result; - int rc; const char * const keyringfile = SSL_CONN_CONFIG(CAfile); const char * const keyringpwd = SSL_SET_OPTION(key_passwd); const char * const keyringlabel = SSL_SET_OPTION(primary.clientcert); @@ -1037,7 +1036,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_ORIG]; + data->set.str[STRING_SSL_PINNEDPUBLICKEY]; if(!result && ptr) { curl_X509certificate x509; curl_asn1Element *p; diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c index 3ddee19742..3b0d940a60 100644 --- a/libs/libcurl/src/vtls/gtls.c +++ b/libs/libcurl/src/vtls/gtls.c @@ -35,14 +35,8 @@ #include <gnutls/abstract.h> #include <gnutls/gnutls.h> #include <gnutls/x509.h> - -#ifdef USE_GNUTLS_NETTLE #include <gnutls/crypto.h> -#include <nettle/md5.h> #include <nettle/sha2.h> -#else -#include <gcrypt.h> -#endif #include "urldata.h" #include "sendf.h" @@ -618,7 +612,7 @@ gtls_connect_step1(struct Curl_easy *data, gnutls_datum_t protocols[2]; #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 + if(data->state.httpversion >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif @@ -733,6 +727,7 @@ gtls_connect_step1(struct Curl_easy *data, Curl_ssl_sessionid_lock(data); if(!Curl_ssl_getsessionid(data, conn, + SSL_IS_PROXY() ? TRUE : FALSE, &ssl_sessionid, &ssl_idsize, sockindex)) { /* we got a session id, use it! */ gnutls_session_set_data(session, ssl_sessionid, ssl_idsize); @@ -1184,7 +1179,7 @@ gtls_connect_step3(struct Curl_easy *data, } ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + data->set.str[STRING_SSL_PINNEDPUBLICKEY]; if(ptr) { result = pkp_pin_peer_pubkey(data, x509_cert, ptr); if(result != CURLE_OK) { @@ -1292,8 +1287,9 @@ gtls_connect_step3(struct Curl_easy *data, gnutls_session_get_data(session, connect_sessionid, &connect_idsize); Curl_ssl_sessionid_lock(data); - incache = !(Curl_ssl_getsessionid(data, conn, &ssl_sessionid, NULL, - sockindex)); + incache = !(Curl_ssl_getsessionid(data, conn, + SSL_IS_PROXY() ? TRUE : FALSE, + &ssl_sessionid, NULL, sockindex)); if(incache) { /* there was one before in the cache, so instead of risking that the previous one was rejected, we just kill that and store the new */ @@ -1301,8 +1297,10 @@ gtls_connect_step3(struct Curl_easy *data, } /* store this session id */ - result = Curl_ssl_addsessionid(data, conn, connect_sessionid, - connect_idsize, sockindex); + result = Curl_ssl_addsessionid(data, conn, + SSL_IS_PROXY() ? TRUE : FALSE, + connect_sessionid, connect_idsize, + sockindex); Curl_ssl_sessionid_unlock(data); if(result) { free(connect_sessionid); @@ -1583,39 +1581,14 @@ static size_t gtls_version(char *buffer, size_t size) return msnprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL)); } -#ifndef USE_GNUTLS_NETTLE -static int gtls_seed(struct Curl_easy *data) -{ - /* we have the "SSL is seeded" boolean static to prevent multiple - time-consuming seedings in vain */ - static bool ssl_seeded = FALSE; - - /* Quickly add a bit of entropy */ - gcry_fast_random_poll(); - - if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] || - data->set.str[STRING_SSL_EGDSOCKET]) { - ssl_seeded = TRUE; - } - return 0; -} -#endif - /* data might be NULL! */ static CURLcode gtls_random(struct Curl_easy *data, unsigned char *entropy, size_t length) { -#if defined(USE_GNUTLS_NETTLE) int rc; (void)data; rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length); return rc?CURLE_FAILED_INIT:CURLE_OK; -#elif defined(USE_GNUTLS) - if(data) - gtls_seed(data); /* Initiate the seed if not already done */ - gcry_randomize(entropy, length, GCRY_STRONG_RANDOM); -#endif - return CURLE_OK; } static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */ @@ -1623,18 +1596,10 @@ static CURLcode gtls_sha256sum(const unsigned char *tmp, /* input */ unsigned char *sha256sum, /* output */ size_t sha256len) { -#if defined(USE_GNUTLS_NETTLE) struct sha256_ctx SHA256pw; sha256_init(&SHA256pw); sha256_update(&SHA256pw, (unsigned int)tmplen, tmp); sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum); -#elif defined(USE_GNUTLS) - gcry_md_hd_t SHA256pw; - gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0); - gcry_md_write(SHA256pw, tmp, tmplen); - memcpy(sha256sum, gcry_md_read(SHA256pw, 0), sha256len); - gcry_md_close(SHA256pw); -#endif return CURLE_OK; } @@ -1671,6 +1636,7 @@ const struct Curl_ssl Curl_ssl_gnutls = { gtls_cert_status_request, /* cert_status_request */ gtls_connect, /* connect */ gtls_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ gtls_get_internals, /* get_internals */ gtls_close, /* close_one */ Curl_none_close_all, /* close_all */ diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c index fc3a948d1e..93a7ac1fd8 100644 --- a/libs/libcurl/src/vtls/mbedtls.c +++ b/libs/libcurl/src/vtls/mbedtls.c @@ -463,7 +463,9 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, void *old_session = NULL; Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(data, conn, &old_session, NULL, sockindex)) { + if(!Curl_ssl_getsessionid(data, conn, + SSL_IS_PROXY() ? TRUE : FALSE, + &old_session, NULL, sockindex)) { ret = mbedtls_ssl_set_session(&backend->ssl, old_session); if(ret) { Curl_ssl_sessionid_unlock(data); @@ -495,7 +497,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, if(conn->bits.tls_enable_alpn) { const char **p = &backend->protocols[0]; #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) + if(data->state.httpversion >= CURL_HTTP_VERSION_2) *p++ = NGHTTP2_PROTO_VERSION_ID; #endif *p++ = ALPN_HTTP_1_1; @@ -550,10 +552,10 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, #ifndef CURL_DISABLE_PROXY const char * const pinnedpubkey = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + data->set.str[STRING_SSL_PINNEDPUBLICKEY]; #else const char * const pinnedpubkey = - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + data->set.str[STRING_SSL_PINNEDPUBLICKEY]; #endif conn->recv[sockindex] = mbed_recv; @@ -724,6 +726,7 @@ mbed_connect_step3(struct Curl_easy *data, struct connectdata *conn, int ret; mbedtls_ssl_session *our_ssl_sessionid; void *old_ssl_sessionid = NULL; + bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE; our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session)); if(!our_ssl_sessionid) @@ -742,11 +745,12 @@ mbed_connect_step3(struct Curl_easy *data, struct connectdata *conn, /* If there's already a matching session in the cache, delete it */ Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(data, conn, &old_ssl_sessionid, NULL, sockindex)) + if(!Curl_ssl_getsessionid(data, conn, isproxy, &old_ssl_sessionid, NULL, + sockindex)) Curl_ssl_delsessionid(data, old_ssl_sessionid); - retcode = Curl_ssl_addsessionid(data, conn, - our_ssl_sessionid, 0, sockindex); + retcode = Curl_ssl_addsessionid(data, conn, isproxy, our_ssl_sessionid, + 0, sockindex); Curl_ssl_sessionid_unlock(data); if(retcode) { mbedtls_ssl_session_free(our_ssl_sessionid); @@ -1100,6 +1104,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = { Curl_none_cert_status_request, /* cert_status_request */ mbedtls_connect, /* connect */ mbedtls_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ mbedtls_get_internals, /* get_internals */ mbedtls_close, /* close_one */ mbedtls_close_all, /* close_all */ diff --git a/libs/libcurl/src/vtls/mesalink.c b/libs/libcurl/src/vtls/mesalink.c index b6d1005ec1..5d6a1495d7 100644 --- a/libs/libcurl/src/vtls/mesalink.c +++ b/libs/libcurl/src/vtls/mesalink.c @@ -261,7 +261,9 @@ mesalink_connect_step1(struct Curl_easy *data, void *ssl_sessionid = NULL; Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(data, conn, &ssl_sessionid, NULL, sockindex)) { + 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); @@ -345,13 +347,14 @@ mesalink_connect_step3(struct connectdata *conn, int sockindex) bool incache; SSL_SESSION *our_ssl_sessionid; void *old_ssl_sessionid = NULL; + bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE; our_ssl_sessionid = SSL_get_session(BACKEND->handle); Curl_ssl_sessionid_lock(data); incache = - !(Curl_ssl_getsessionid(data, conn, - &old_ssl_sessionid, NULL, sockindex)); + !(Curl_ssl_getsessionid(data, conn, isproxy, &old_ssl_sessionid, NULL, + sockindex)); if(incache) { if(old_ssl_sessionid != our_ssl_sessionid) { infof(data, "old SSL session ID is stale, removing\n"); @@ -361,8 +364,9 @@ mesalink_connect_step3(struct connectdata *conn, int sockindex) } if(!incache) { - result = Curl_ssl_addsessionid( - data, conn, our_ssl_sessionid, 0 /* unknown size */, sockindex); + result = + Curl_ssl_addsessionid(data, conn, isproxy, our_ssl_sessionid, 0, + sockindex); if(result) { Curl_ssl_sessionid_unlock(data); failf(data, "failed to store ssl session"); @@ -654,6 +658,7 @@ const struct Curl_ssl Curl_ssl_mesalink = { Curl_none_cert_status_request, /* cert_status_request */ mesalink_connect, /* connect */ mesalink_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ mesalink_get_internals, /* get_internals */ mesalink_close, /* close_one */ Curl_none_close_all, /* close_all */ diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c index e5ab71cdf6..bc6c3caeb9 100644 --- a/libs/libcurl/src/vtls/nss.c +++ b/libs/libcurl/src/vtls/nss.c @@ -542,7 +542,6 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl, if(!result && !cacert) { /* we have successfully loaded a client certificate */ - CERTCertificate *cert; char *nickname = NULL; char *n = strrchr(filename, '/'); if(n) @@ -554,7 +553,7 @@ static CURLcode nss_load_cert(struct ssl_connect_data *ssl, * <https://bugzilla.redhat.com/733685>. */ nickname = aprintf("PEM Token #1:%s", n); if(nickname) { - cert = PK11_FindCertFromNickname(nickname, NULL); + CERTCertificate *cert = PK11_FindCertFromNickname(nickname, NULL); if(cert) CERT_DestroyCertificate(cert); @@ -957,7 +956,6 @@ static CURLcode display_conn_info(struct Curl_easy *data, PRFileDesc *sock) CERTCertificate *cert2; CERTCertificate *cert3; PRTime now; - int i; if(SSL_GetChannelInfo(sock, &channel, sizeof(channel)) == SECSuccess && channel.length == sizeof(channel) && @@ -978,8 +976,8 @@ static CURLcode display_conn_info(struct Curl_easy *data, PRFileDesc *sock) } else { /* Count certificates in chain. */ + int i = 1; now = PR_Now(); - i = 1; if(!cert->isRoot) { cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA); while(cert2) { @@ -1782,12 +1780,11 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl, struct Curl_easy *data, CURLcode curlerr) { - PRErrorCode err = 0; struct ssl_backend_data *backend = connssl->backend; if(is_nss_error(curlerr)) { /* read NSPR error code */ - err = PR_GetError(); + PRErrorCode err = PR_GetError(); if(is_cc_error(err)) curlerr = CURLE_SSL_CERTPROBLEM; @@ -2083,7 +2080,7 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, unsigned char protocols[128]; #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 + if(data->state.httpversion >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif @@ -2435,6 +2432,7 @@ const struct Curl_ssl Curl_ssl_nss = { nss_cert_status_request, /* cert_status_request */ nss_connect, /* connect */ nss_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ nss_get_internals, /* get_internals */ nss_close, /* close_one */ Curl_none_close_all, /* close_all */ diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c index 784d9f70e0..68b98984b4 100644 --- a/libs/libcurl/src/vtls/openssl.c +++ b/libs/libcurl/src/vtls/openssl.c @@ -234,6 +234,8 @@ #endif struct ssl_backend_data { + struct Curl_easy *logger; /* transfer handle to pass trace logs to, only + using sockindex 0 */ /* these ones requires specific SSL-types */ SSL_CTX* ctx; SSL* handle; @@ -391,12 +393,23 @@ static int ossl_get_ssl_conn_index(void) */ static int ossl_get_ssl_sockindex_index(void) { - static int ssl_ex_data_sockindex_index = -1; - if(ssl_ex_data_sockindex_index < 0) { - ssl_ex_data_sockindex_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, - NULL); + static int sockindex_index = -1; + if(sockindex_index < 0) { + sockindex_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); } - return ssl_ex_data_sockindex_index; + return sockindex_index; +} + +/* Return an extra data index for proxy boolean. + * This index can be used with SSL_get_ex_data() and SSL_set_ex_data(). + */ +static int ossl_get_proxy_index(void) +{ + static int proxy_index = -1; + if(proxy_index < 0) { + proxy_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); + } + return proxy_index; } static int passwd_callback(char *buf, int num, int encrypting, @@ -1172,7 +1185,7 @@ static int ossl_init(void) /* Initialize the extra data indexes */ if(ossl_get_ssl_data_index() < 0 || ossl_get_ssl_conn_index() < 0 || - ossl_get_ssl_sockindex_index() < 0) + ossl_get_ssl_sockindex_index() < 0 || ossl_get_proxy_index() < 0) return 0; return 1; @@ -1356,10 +1369,16 @@ static struct curl_slist *ossl_engines_list(struct Curl_easy *data) return list; } -static void ossl_closeone(struct ssl_connect_data *connssl) +#define set_logger(conn, data) \ + conn->ssl[0].backend->logger = data + +static void ossl_closeone(struct Curl_easy *data, + struct connectdata *conn, + struct ssl_connect_data *connssl) { struct ssl_backend_data *backend = connssl->backend; if(backend->handle) { + set_logger(conn, data); (void)SSL_shutdown(backend->handle); SSL_set_connect_state(backend->handle); @@ -1378,10 +1397,9 @@ static void ossl_closeone(struct ssl_connect_data *connssl) static void ossl_close(struct Curl_easy *data, struct connectdata *conn, int sockindex) { - (void) data; - ossl_closeone(&conn->ssl[sockindex]); + ossl_closeone(data, conn, &conn->ssl[sockindex]); #ifndef CURL_DISABLE_PROXY - ossl_closeone(&conn->proxy_ssl[sockindex]); + ossl_closeone(data, conn, &conn->proxy_ssl[sockindex]); #endif } @@ -2055,25 +2073,24 @@ static const char *tls_rt_type(int type) } } - /* * Our callback from the SSL/TLS layers. */ -static void ssl_tls_trace(int direction, int ssl_ver, int content_type, - const void *buf, size_t len, SSL *ssl, - void *userp) +static void ossl_trace(int direction, int ssl_ver, int content_type, + const void *buf, size_t len, SSL *ssl, + void *userp) { - struct Curl_easy *data; char unknown[32]; const char *verstr = NULL; struct connectdata *conn = userp; + struct ssl_connect_data *connssl = &conn->ssl[0]; + struct ssl_backend_data *backend = connssl->backend; + struct Curl_easy *data = backend->logger; - if(!conn || !conn->data || !conn->data->set.fdebug || + if(!conn || !data || !data->set.fdebug || (direction != 0 && direction != 1)) return; - data = conn->data; - switch(ssl_ver) { #ifdef SSL2_VERSION /* removed in recent versions */ case SSL2_VERSION: @@ -2222,7 +2239,7 @@ select_next_proto_cb(SSL *ssl, (void)ssl; #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + 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", @@ -2248,35 +2265,6 @@ select_next_proto_cb(SSL *ssl, } #endif /* HAS_NPN */ -#ifndef CURL_DISABLE_VERBOSE_STRINGS -static const char * -get_ssl_version_txt(SSL *ssl) -{ - if(!ssl) - return ""; - - switch(SSL_version(ssl)) { -#ifdef TLS1_3_VERSION - case TLS1_3_VERSION: - return "TLSv1.3"; -#endif -#if OPENSSL_VERSION_NUMBER >= 0x1000100FL - case TLS1_2_VERSION: - return "TLSv1.2"; - case TLS1_1_VERSION: - return "TLSv1.1"; -#endif - case TLS1_VERSION: - return "TLSv1.0"; - case SSL3_VERSION: - return "SSLv3"; - case SSL2_VERSION: - return "SSLv2"; - } - return "unknown"; -} -#endif - #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ static CURLcode set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn) @@ -2455,8 +2443,10 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_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(); + bool isproxy; - if(data_idx < 0 || connectdata_idx < 0 || sockindex_idx < 0) + if(data_idx < 0 || connectdata_idx < 0 || sockindex_idx < 0 || proxy_idx < 0) return 0; conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx); @@ -2469,13 +2459,18 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) sockindex_ptr = (curl_socket_t*) SSL_get_ex_data(ssl, sockindex_idx); sockindex = (int)(sockindex_ptr - conn->sock); + isproxy = SSL_get_ex_data(ssl, proxy_idx) ? TRUE : FALSE; + if(SSL_SET_OPTION(primary.sessionid)) { bool incache; void *old_ssl_sessionid = NULL; Curl_ssl_sessionid_lock(data); - incache = !(Curl_ssl_getsessionid(data, conn, &old_ssl_sessionid, NULL, - sockindex)); + if(isproxy) + incache = FALSE; + else + incache = !(Curl_ssl_getsessionid(data, conn, isproxy, + &old_ssl_sessionid, NULL, sockindex)); if(incache) { if(old_ssl_sessionid != ssl_sessionid) { infof(data, "old SSL session ID is stale, removing\n"); @@ -2485,8 +2480,8 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) } if(!incache) { - if(!Curl_ssl_addsessionid(data, conn, ssl_sessionid, - 0 /* unknown size */, sockindex)) { + if(!Curl_ssl_addsessionid(data, conn, isproxy, ssl_sessionid, + 0 /* unknown size */, sockindex)) { /* the session has been put into the session cache */ res = 1; } @@ -2609,8 +2604,9 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, #ifdef SSL_CTRL_SET_MSG_CALLBACK if(data->set.fdebug && data->set.verbose) { /* the SSL trace callback is only used for verbose logging */ - SSL_CTX_set_msg_callback(backend->ctx, ssl_tls_trace); + SSL_CTX_set_msg_callback(backend->ctx, ossl_trace); SSL_CTX_set_msg_callback_arg(backend->ctx, conn); + set_logger(conn, data); } #endif @@ -2749,7 +2745,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, unsigned char protocols[128]; #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 + if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif @@ -2771,7 +2767,10 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, /* expects length prefixed preference ordered list of protocols in wire * format */ - SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur); + if(SSL_CTX_set_alpn_protos(backend->ctx, protocols, cur)) { + failf(data, "Error setting ALPN"); + return CURLE_SSL_CONNECT_ERROR; + } } #endif @@ -3212,17 +3211,27 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, 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) { + 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_sessionid, NULL, sockindex)) { + 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); @@ -3380,7 +3389,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, /* Informational message */ infof(data, "SSL connection using %s / %s\n", - get_ssl_version_txt(backend->handle), + SSL_get_version(backend->handle), SSL_get_cipher(backend->handle)); #ifdef HAS_ALPN @@ -3515,6 +3524,12 @@ typedef size_t numcert_t; typedef int numcert_t; #endif +#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) +#define OSSL3_CONST const +#else +#define OSSL3_CONST +#endif + static CURLcode get_cert_chain(struct Curl_easy *data, struct ssl_connect_data *connssl) { @@ -3622,7 +3637,7 @@ static CURLcode get_cert_chain(struct Curl_easy *data, switch(pktype) { case EVP_PKEY_RSA: { - RSA *rsa; + OSSL3_CONST RSA *rsa; #ifdef HAVE_OPAQUE_EVP_PKEY rsa = EVP_PKEY_get0_RSA(pubkey); #else @@ -3652,7 +3667,7 @@ static CURLcode get_cert_chain(struct Curl_easy *data, case EVP_PKEY_DSA: { #ifndef OPENSSL_NO_DSA - DSA *dsa; + OSSL3_CONST DSA *dsa; #ifdef HAVE_OPAQUE_EVP_PKEY dsa = EVP_PKEY_get0_DSA(pubkey); #else @@ -3684,7 +3699,7 @@ static CURLcode get_cert_chain(struct Curl_easy *data, } case EVP_PKEY_DH: { - DH *dh; + OSSL3_CONST DH *dh; #ifdef HAVE_OPAQUE_EVP_PKEY dh = EVP_PKEY_get0_DH(pubkey); #else @@ -3965,7 +3980,7 @@ static CURLcode servercert(struct Curl_easy *data, result = CURLE_OK; ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + data->set.str[STRING_SSL_PINNEDPUBLICKEY]; if(!result && ptr) { result = pkp_pin_peer_pubkey(data, backend->server_cert, ptr); if(result) @@ -4176,6 +4191,7 @@ static ssize_t ossl_send(struct Curl_easy *data, ERR_clear_error(); memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; + set_logger(conn, data); rc = SSL_write(backend->handle, mem, memlen); if(rc <= 0) { @@ -4254,6 +4270,7 @@ static ssize_t ossl_recv(struct Curl_easy *data, /* transfer */ ERR_clear_error(); buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; + set_logger(conn, data); nread = (ssize_t)SSL_read(backend->handle, buf, buffsize); if(nread <= 0) { /* failed SSL_read */ @@ -4477,6 +4494,7 @@ const struct Curl_ssl Curl_ssl_openssl = { ossl_cert_status_request, /* cert_status_request */ ossl_connect, /* connect */ ossl_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ ossl_get_internals, /* get_internals */ ossl_close, /* close_one */ ossl_close_all, /* close_all */ diff --git a/libs/libcurl/src/vtls/rustls.c b/libs/libcurl/src/vtls/rustls.c new file mode 100644 index 0000000000..e4f589de57 --- /dev/null +++ b/libs/libcurl/src/vtls/rustls.c @@ -0,0 +1,560 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2020 - 2021, Jacob Hoffman-Andrews, + * <github@hoffman-andrews.com> + * + * 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" + +#ifdef USE_RUSTLS + +#include "curl_printf.h" + +#include <errno.h> +#include <crustls.h> + +#include "inet_pton.h" +#include "urldata.h" +#include "sendf.h" +#include "vtls.h" +#include "select.h" + +#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; + bool data_pending; + uint8_t *tlsbuf; +}; + +/* For a given rustls_result error code, return the best-matching CURLcode. */ +static CURLcode map_error(rustls_result r) +{ + if(rustls_result_is_cert_error(r)) { + return CURLE_PEER_FAILED_VERIFICATION; + } + switch(r) { + case RUSTLS_RESULT_OK: + return CURLE_OK; + case RUSTLS_RESULT_NULL_PARAMETER: + return CURLE_BAD_FUNCTION_ARGUMENT; + default: + return CURLE_READ_ERROR; + } +} + +static bool +cr_data_pending(const struct connectdata *conn, int sockindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + return backend->data_pending; +} + +static CURLcode +cr_connect(struct Curl_easy *data UNUSED_PARAM, + struct connectdata *conn UNUSED_PARAM, + int sockindex UNUSED_PARAM) +{ + infof(data, "rustls_connect: unimplemented\n"); + return CURLE_SSL_CONNECT_ERROR; +} + +/* + * On each run: + * - Read a chunk of bytes from the socket into rustls' TLS input buffer. + * - Tell rustls to process any new packets. + * - Read out as many plaintext bytes from rustls as possible, until hitting + * error, EOF, or EAGAIN/EWOULDBLOCK, or plainbuf/plainlen is filled up. + * + * It's okay to call this function with plainbuf == NULL and plainlen == 0. + * In that case, it will copy bytes from the socket into rustls' TLS input + * buffer, and process packets, but won't consume bytes from rustls' plaintext + * output buffer. + */ +static ssize_t +cr_recv(struct Curl_easy *data, int sockindex, + char *plainbuf, size_t plainlen, CURLcode *err) +{ + 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]; + size_t n = 0; + ssize_t tls_bytes_read = 0; + size_t tls_bytes_processed = 0; + size_t plain_bytes_copied = 0; + rustls_result rresult = 0; + char errorbuf[255]; + + tls_bytes_read = sread(sockfd, backend->tlsbuf, TLSBUF_SIZE); + if(tls_bytes_read == 0) { + failf(data, "connection closed without TLS close_notify alert"); + *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)); + *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; + } + + 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; + } + + while(plain_bytes_copied < plainlen) { + rresult = rustls_client_session_read(session, + (uint8_t *)plainbuf + plain_bytes_copied, + plainlen - plain_bytes_copied, + &n); + if(rresult == RUSTLS_RESULT_ALERT_CLOSE_NOTIFY) { + *err = CURLE_OK; + return 0; + } + else if(rresult != RUSTLS_RESULT_OK) { + failf(data, "error in rustls_client_session_read"); + *err = CURLE_READ_ERROR; + return -1; + } + else if(n == 0) { + /* rustls returns 0 from client_session_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"); + backend->data_pending = FALSE; + break; + } + else { + plain_bytes_copied += n; + } + } + + /* If we wrote out 0 plaintext bytes, it might just mean we haven't yet + read a full TLS record. Return CURLE_AGAIN so curl doesn't treat this + as EOF. */ + if(plain_bytes_copied == 0) { + *err = CURLE_AGAIN; + return -1; + } + + return plain_bytes_copied; +} + +/* + * On each call: + * - Copy `plainlen` bytes into rustls' plaintext input buffer (if > 0). + * - Fully drain rustls' plaintext output buffer into the socket until + * we get either an error or EAGAIN/EWOULDBLOCK. + * + * It's okay to call this function with plainbuf == NULL and plainlen == 0. + * In that case, it won't read anything into rustls' plaintext input buffer. + * It will only drain rustls' plaintext output buffer into the socket. + */ +static ssize_t +cr_send(struct Curl_easy *data, int sockindex, + const void *plainbuf, size_t plainlen, CURLcode *err) +{ + 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; + size_t plainwritten = 0; + size_t tlslen = 0; + size_t tlswritten = 0; + rustls_result rresult; + + if(plainlen > 0) { + rresult = rustls_client_session_write(session, + plainbuf, plainlen, &plainwritten); + if(rresult != RUSTLS_RESULT_OK) { + failf(data, "error in rustls_client_session_write"); + *err = CURLE_WRITE_ERROR; + return -1; + } + else if(plainwritten == 0) { + failf(data, "EOF in rustls_client_session_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; + return -1; + } + else if(tlslen == 0) { + failf(data, "EOF in rustls_client_session_write_tls"); + *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; + } + + DEBUGASSERT(tlswritten <= tlslen); + } + + return plainwritten; +} + +/* A server certificate verify callback for rustls that always returns + RUSTLS_RESULT_OK, or in other words disable certificate verification. */ +static enum rustls_result +cr_verify_none(void *userdata UNUSED_PARAM, + const rustls_verify_server_cert_params *params UNUSED_PARAM) +{ + return RUSTLS_RESULT_OK; +} + +static bool +cr_hostname_is_ip(const char *hostname) +{ + struct in_addr in; +#ifdef ENABLE_IPV6 + struct in6_addr in6; + if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0) { + return true; + } +#endif /* ENABLE_IPV6 */ + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) { + return true; + } + return false; +} + +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_client_config_builder *config_builder = NULL; + const char *const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const char *hostname = conn->host.name; + char errorbuf[256]; + size_t errorlen; + int result; + + backend->tlsbuf = calloc(TLSBUF_SIZE, 1); + if(backend->tlsbuf == NULL) { + return CURLE_OUT_OF_MEMORY; + } + + config_builder = rustls_client_config_builder_new(); + if(!verifypeer) { + rustls_client_config_builder_dangerous_set_certificate_verifier( + config_builder, cr_verify_none, NULL); + /* 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. */ + if(cr_hostname_is_ip(hostname)) { + rustls_client_config_builder_set_enable_sni(config_builder, false); + hostname = "example.invalid"; + } + } + else if(ssl_cafile) { + result = rustls_client_config_builder_load_roots_from_file( + config_builder, ssl_cafile); + if(result != RUSTLS_RESULT_OK) { + failf(data, "failed to load trusted certificates"); + rustls_client_config_free( + rustls_client_config_builder_build(config_builder)); + return CURLE_SSL_CACERT_BADFILE; + } + } + else { + result = rustls_client_config_builder_load_native_roots(config_builder); + if(result != RUSTLS_RESULT_OK) { + failf(data, "failed to load trusted certificates"); + rustls_client_config_free( + rustls_client_config_builder_build(config_builder)); + return CURLE_SSL_CACERT_BADFILE; + } + } + + backend->config = rustls_client_config_builder_build(config_builder); + DEBUGASSERT(session == NULL); + result = rustls_client_session_new( + backend->config, hostname, &session); + if(result != RUSTLS_RESULT_OK) { + rustls_error(result, errorbuf, sizeof(errorbuf), &errorlen); + failf(data, "failed to create client session: %.*s", errorlen, errorbuf); + return CURLE_COULDNT_CONNECT; + } + backend->session = session; + return CURLE_OK; +} + +static CURLcode +cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, + int sockindex, bool *done) +{ + 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; + CURLcode tmperr = CURLE_OK; + int result; + int what; + bool wants_read; + bool wants_write; + curl_socket_t writefd; + curl_socket_t readfd; + + if(ssl_connection_none == connssl->state) { + result = cr_init_backend(data, conn, connssl->backend); + if(result != CURLE_OK) { + return result; + } + connssl->state = ssl_connection_negotiating; + } + + session = backend->session; + + /* Read/write data until the handshake is done or the socket would block. */ + for(;;) { + /* + * Connection has been established according to rustls. Set send/recv + * handlers, and update the state machine. + * This check has to come last because is_handshaking starts out false, + * then becomes true when we first write data, then becomes false again + * once the handshake is done. + */ + if(!rustls_client_session_is_handshaking(session)) { + infof(data, "Done handshaking\n"); + /* Done with the handshake. Set up callbacks to send/receive data. */ + connssl->state = ssl_connection_complete; + 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); + DEBUGASSERT(wants_read || wants_write); + writefd = wants_write?sockfd:CURL_SOCKET_BAD; + readfd = wants_read?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, 0); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + if(0 == what) { + infof(data, "Curl_socket_check: %s would block\n", + wants_read&&wants_write ? + "writing and reading" : + wants_write ? + "writing" : + "reading"); + *done = FALSE; + return CURLE_OK; + } + /* socket is readable or writable */ + + if(wants_write) { + infof(data, "ClientSession wants us to write_tls.\n"); + cr_send(data, sockindex, NULL, 0, &tmperr); + if(tmperr == CURLE_AGAIN) { + infof(data, "writing would block\n"); + /* fall through */ + } + else if(tmperr != CURLE_OK) { + return tmperr; + } + } + + if(wants_read) { + infof(data, "ClientSession wants us to read_tls.\n"); + + cr_recv(data, sockindex, NULL, 0, &tmperr); + if(tmperr == CURLE_AGAIN) { + infof(data, "reading would block\n"); + /* fall through */ + } + else if(tmperr != CURLE_OK) { + if(tmperr == CURLE_READ_ERROR) { + return CURLE_SSL_CONNECT_ERROR; + } + else { + return tmperr; + } + } + } + } + + /* We should never fall through the loop. We should return either because + the handshake is done or because we can't read/write without blocking. */ + DEBUGASSERT(false); +} + +/* returns a bitmap of flags for this connection's first socket indicating + whether we want to read or write */ +static int +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; + + if(rustls_client_session_wants_write(session)) { + socks[0] = sockfd; + return GETSOCK_WRITESOCK(0); + } + if(rustls_client_session_wants_read(session)) { + socks[0] = sockfd; + return GETSOCK_READSOCK(0); + } + + return GETSOCK_BLANK; +} + +static void * +cr_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + struct ssl_backend_data *backend = connssl->backend; + return &backend->session; +} + +static void +cr_close(struct Curl_easy *data, struct connectdata *conn, + int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + struct ssl_backend_data *backend = connssl->backend; + CURLcode tmperr = CURLE_OK; + ssize_t n = 0; + + if(backend->session) { + rustls_client_session_send_close_notify(backend->session); + 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; + } + if(backend->config) { + rustls_client_config_free(backend->config); + backend->config = NULL; + } + free(backend->tlsbuf); +} + +const struct Curl_ssl Curl_ssl_rustls = { + { CURLSSLBACKEND_RUSTLS, "rustls" }, + SSLSUPP_TLS13_CIPHERSUITES, /* supports */ + sizeof(struct ssl_backend_data), + + Curl_none_init, /* init */ + Curl_none_cleanup, /* cleanup */ + rustls_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_none_shutdown, /* shutdown */ + cr_data_pending, /* data_pending */ + Curl_none_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + cr_connect, /* connect */ + cr_connect_nonblocking, /* connect_nonblocking */ + cr_getsock, /* cr_getsock */ + cr_get_internals, /* get_internals */ + cr_close, /* close_one */ + Curl_none_close_all, /* close_all */ + Curl_none_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + NULL /* sha256sum */ +}; + +#endif /* USE_RUSTLS */ diff --git a/libs/libcurl/src/vtls/rustls.h b/libs/libcurl/src/vtls/rustls.h new file mode 100644 index 0000000000..056211dd8b --- /dev/null +++ b/libs/libcurl/src/vtls/rustls.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2020 - 2021, Jacob Hoffman-Andrews, + * <github@hoffman-andrews.com> + * + * 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. + * + ***************************************************************************/ +#ifndef HEADER_CURL_RUSTLS_H +#define HEADER_CURL_RUSTLS_H + +#include "curl_setup.h" + +#ifdef USE_RUSTLS + +extern const struct Curl_ssl Curl_ssl_rustls; + +#endif /* USE_RUSTLS */ +#endif /* HEADER_CURL_RUSTLS_H */ diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index 0668f98f29..931bd853eb 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.c @@ -496,6 +496,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, if(SSL_SET_OPTION(primary.sessionid)) { Curl_ssl_sessionid_lock(data); if(!Curl_ssl_getsessionid(data, conn, + SSL_IS_PROXY() ? TRUE : FALSE, (void **)&old_cred, NULL, sockindex)) { BACKEND->cred = old_cred; DEBUGF(infof(data, "schannel: re-using existing credential handle\n")); @@ -522,14 +523,14 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, #endif schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION; - if(data->set.ssl.no_revoke) { + if(SSL_SET_OPTION(no_revoke)) { schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE; DEBUGF(infof(data, "schannel: disabled server certificate revocation " "checks\n")); } - else if(data->set.ssl.revoke_best_effort) { + else if(SSL_SET_OPTION(revoke_best_effort)) { schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN; @@ -861,7 +862,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, list_start_index = cur; #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { + if(data->state.httpversion >= 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); @@ -1252,7 +1253,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, pubkey_ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + data->set.str[STRING_SSL_PINNEDPUBLICKEY]; if(pubkey_ptr) { result = pkp_pin_peer_pubkey(data, conn, sockindex, pubkey_ptr); if(result) { @@ -1337,8 +1338,9 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, struct ssl_connect_data *connssl = &conn->ssl[sockindex]; SECURITY_STATUS sspi_status = SEC_E_OK; CERT_CONTEXT *ccert_context = NULL; + bool isproxy = SSL_IS_PROXY(); #ifdef DEBUGBUILD - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + const char * const hostname = isproxy ? conn->http_proxy.host.name : conn->host.name; #endif #ifdef HAS_ALPN @@ -1414,8 +1416,8 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, struct Curl_schannel_cred *old_cred = NULL; Curl_ssl_sessionid_lock(data); - incache = !(Curl_ssl_getsessionid(data, conn, (void **)&old_cred, NULL, - sockindex)); + incache = !(Curl_ssl_getsessionid(data, conn, isproxy, (void **)&old_cred, + NULL, sockindex)); if(incache) { if(old_cred != BACKEND->cred) { DEBUGF(infof(data, @@ -1426,7 +1428,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, } } if(!incache) { - result = Curl_ssl_addsessionid(data, conn, (void *)BACKEND->cred, + result = Curl_ssl_addsessionid(data, conn, isproxy, BACKEND->cred, sizeof(struct Curl_schannel_cred), sockindex); if(result) { @@ -2418,6 +2420,7 @@ const struct Curl_ssl Curl_ssl_schannel = { Curl_none_cert_status_request, /* cert_status_request */ schannel_connect, /* connect */ schannel_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ schannel_get_internals, /* get_internals */ schannel_close, /* close_one */ Curl_none_close_all, /* close_all */ diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c index 2ef39cc0f4..e0fdbd5b63 100644 --- a/libs/libcurl/src/vtls/schannel_verify.c +++ b/libs/libcurl/src/vtls/schannel_verify.c @@ -624,7 +624,7 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data, NULL, pCertContextServer->hCertStore, &ChainPara, - (data->set.ssl.no_revoke ? 0 : + (SSL_SET_OPTION(no_revoke) ? 0 : CERT_CHAIN_REVOCATION_CHECK_CHAIN), NULL, &pChainContext)) { diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c index 9a8f7de8d5..e69b99b72c 100644 --- a/libs/libcurl/src/vtls/sectransp.c +++ b/libs/libcurl/src/vtls/sectransp.c @@ -1400,10 +1400,12 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, 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 - const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + 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 @@ -1611,9 +1613,9 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, &kCFTypeArrayCallBacks); #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2 + if(data->state.httpversion >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY - && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) + && (!isproxy || !conn->bits.tunnel_proxy) #endif ) { CFArrayAppendValue(alpnArr, CFSTR(NGHTTP2_PROTO_VERSION_ID)); @@ -1941,7 +1943,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, specifically doesn't want us doing that: */ if(SSLSetSessionOption != NULL) { SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord, - !data->set.ssl.enable_beast); + !SSL_SET_OPTION(enable_beast)); SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart, data->set.ssl.falsestart); /* false start support */ } @@ -1953,7 +1955,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, size_t ssl_sessionid_len; Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(data, conn, (void **)&ssl_sessionid, + if(!Curl_ssl_getsessionid(data, conn, isproxy, (void **)&ssl_sessionid, &ssl_sessionid_len, sockindex)) { /* we got a session id, use it! */ err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len); @@ -1981,7 +1983,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } - result = Curl_ssl_addsessionid(data, conn, ssl_sessionid, + result = Curl_ssl_addsessionid(data, conn, isproxy, ssl_sessionid, ssl_sessionid_len, sockindex); Curl_ssl_sessionid_unlock(data); if(result) { @@ -2621,9 +2623,10 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, connssl->connecting_state = ssl_connect_3; #ifdef SECTRANSP_PINNEDPUBKEY - if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) { - CURLcode result = pkp_pin_peer_pubkey(data, backend->ssl_ctx, - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]); + if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { + CURLcode result = + pkp_pin_peer_pubkey(data, backend->ssl_ctx, + data->set.str[STRING_SSL_PINNEDPUBLICKEY]); if(result) { failf(data, "SSL: public key does not match pinned public key!"); return result; @@ -3301,6 +3304,7 @@ const struct Curl_ssl Curl_ssl_sectransp = { Curl_none_cert_status_request, /* cert_status_request */ sectransp_connect, /* connect */ sectransp_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ sectransp_get_internals, /* get_internals */ sectransp_close, /* close_one */ Curl_none_close_all, /* close_all */ diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c index b8ab7494fd..2e07df0a04 100644 --- a/libs/libcurl/src/vtls/vtls.c +++ b/libs/libcurl/src/vtls/vtls.c @@ -367,6 +367,7 @@ void Curl_ssl_sessionid_unlock(struct Curl_easy *data) */ bool Curl_ssl_getsessionid(struct Curl_easy *data, struct connectdata *conn, + const bool isProxy, void **ssl_sessionid, size_t *idsize, /* set 0 if unknown */ int sockindex) @@ -377,7 +378,6 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data, bool no_match = TRUE; #ifndef CURL_DISABLE_PROXY - const bool isProxy = CONNECT_PROXY_SSL(); struct ssl_primary_config * const ssl_config = isProxy ? &conn->proxy_ssl_config : &conn->ssl_config; @@ -389,10 +389,15 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data, struct ssl_primary_config * const ssl_config = &conn->ssl_config; const char * const name = conn->host.name; int port = conn->remote_port; - (void)sockindex; #endif + (void)sockindex; *ssl_sessionid = NULL; +#ifdef CURL_DISABLE_PROXY + if(isProxy) + return TRUE; +#endif + DEBUGASSERT(SSL_SET_OPTION(primary.sessionid)); if(!SSL_SET_OPTION(primary.sessionid)) @@ -480,6 +485,7 @@ void Curl_ssl_delsessionid(struct Curl_easy *data, void *ssl_sessionid) */ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, struct connectdata *conn, + bool isProxy, void *ssl_sessionid, size_t idsize, int sockindex) @@ -492,19 +498,16 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, int conn_to_port; long *general_age; #ifndef CURL_DISABLE_PROXY - const bool isProxy = CONNECT_PROXY_SSL(); struct ssl_primary_config * const ssl_config = isProxy ? &conn->proxy_ssl_config : &conn->ssl_config; const char *hostname = isProxy ? conn->http_proxy.host.name : conn->host.name; #else - /* proxy support disabled */ - const bool isProxy = FALSE; struct ssl_primary_config * const ssl_config = &conn->ssl_config; const char *hostname = conn->host.name; - (void)sockindex; #endif + (void)sockindex; DEBUGASSERT(SSL_SET_OPTION(primary.sessionid)); clone_host = strdup(hostname); @@ -593,9 +596,6 @@ void Curl_ssl_close_all(struct Curl_easy *data) Curl_ssl->close_all(data); } -#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ - defined(USE_SECTRANSP) || defined(USE_NSS) || \ - defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_BEARSSL) int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks) { struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; @@ -613,16 +613,6 @@ int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks) return GETSOCK_BLANK; } -#else -int Curl_ssl_getsock(struct connectdata *conn, - curl_socket_t *socks) -{ - (void)conn; - (void)socks; - return GETSOCK_BLANK; -} -/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_SECTRANSP || USE_NSS */ -#endif void Curl_ssl_close(struct Curl_easy *data, struct connectdata *conn, int sockindex) @@ -1170,6 +1160,13 @@ static CURLcode multissl_connect_nonblocking(struct Curl_easy *data, return Curl_ssl->connect_nonblocking(data, conn, sockindex, done); } +static int multissl_getsock(struct connectdata *conn, curl_socket_t *socks) +{ + if(multissl_setup(NULL)) + return 0; + return Curl_ssl->getsock(conn, socks); +} + static void *multissl_get_internals(struct ssl_connect_data *connssl, CURLINFO info) { @@ -1201,6 +1198,7 @@ static const struct Curl_ssl Curl_ssl_multi = { Curl_none_cert_status_request, /* cert_status_request */ multissl_connect, /* connect */ multissl_connect_nonblocking, /* connect_nonblocking */ + multissl_getsock, /* getsock */ multissl_get_internals, /* get_internals */ multissl_close, /* close_one */ Curl_none_close_all, /* close_all */ @@ -1227,6 +1225,8 @@ const struct Curl_ssl *Curl_ssl = &Curl_ssl_mbedtls; #elif defined(USE_NSS) &Curl_ssl_nss; +#elif defined(USE_RUSTLS) + &Curl_ssl_rustls; #elif defined(USE_OPENSSL) &Curl_ssl_openssl; #elif defined(USE_SCHANNEL) @@ -1270,6 +1270,9 @@ static const struct Curl_ssl *available_backends[] = { #if defined(USE_BEARSSL) &Curl_ssl_bearssl, #endif +#if defined(USE_RUSTLS) + &Curl_ssl_rustls, +#endif NULL }; diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index 9666682ec2..2b43e7744b 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -62,6 +62,14 @@ struct Curl_ssl { CURLcode (*connect_nonblocking)(struct Curl_easy *data, struct connectdata *conn, int sockindex, bool *done); + + /* If the SSL backend wants to read or write on this connection during a + handshake, set socks[0] to the connection's FIRSTSOCKET, and return + a bitmap indicating read or write with GETSOCK_WRITESOCK(0) or + GETSOCK_READSOCK(0). Otherwise return GETSOCK_BLANK. + Mandatory. */ + int (*getsock)(struct connectdata *conn, curl_socket_t *socks); + void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info); void (*close_one)(struct Curl_easy *data, struct connectdata *conn, int sockindex); @@ -108,6 +116,7 @@ bool Curl_ssl_tls13_ciphersuites(void); #include "mbedtls.h" /* mbedTLS versions */ #include "mesalink.h" /* MesaLink versions */ #include "bearssl.h" /* BearSSL versions */ +#include "rustls.h" /* rustls versions */ #ifndef MAX_PINNED_PUBKEY_SIZE #define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */ @@ -141,7 +150,7 @@ bool Curl_ssl_tls13_ciphersuites(void); (SSL_IS_PROXY() ? conn->http_proxy.host.dispname : conn->host.dispname) #define SSL_PINNED_PUB_KEY() (SSL_IS_PROXY() \ ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] \ - : data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) + : data->set.str[STRING_SSL_PINNEDPUBLICKEY]) #else #define SSL_IS_PROXY() FALSE #define SSL_SET_OPTION(var) data->set.ssl.var @@ -150,7 +159,7 @@ bool Curl_ssl_tls13_ciphersuites(void); #define SSL_HOST_NAME() conn->host.name #define SSL_HOST_DISPNAME() conn->host.dispname #define SSL_PINNED_PUB_KEY() \ - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG] + data->set.str[STRING_SSL_PINNEDPUBLICKEY] #endif bool Curl_ssl_config_matches(struct ssl_primary_config *data, @@ -158,6 +167,10 @@ bool Curl_ssl_config_matches(struct ssl_primary_config *data, bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source, struct ssl_primary_config *dest); void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc); +/* An implementation of the getsock field of Curl_ssl that relies + on the ssl_connect_state enum. Asks for read or write depending + on whether conn->state is ssl_connect_2_reading or + ssl_connect_2_writing. */ int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks); int Curl_ssl_backend(void); @@ -222,6 +235,7 @@ void Curl_ssl_sessionid_unlock(struct Curl_easy *data); */ bool Curl_ssl_getsessionid(struct Curl_easy *data, struct connectdata *conn, + const bool isproxy, void **ssl_sessionid, size_t *idsize, /* set 0 if unknown */ int sockindex); @@ -232,6 +246,7 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data, */ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, struct connectdata *conn, + const bool isProxy, void *ssl_sessionid, size_t idsize, int sockindex); diff --git a/libs/libcurl/src/vtls/wolfssl.c b/libs/libcurl/src/vtls/wolfssl.c index e1fa459265..8fb2ea7acf 100644 --- a/libs/libcurl/src/vtls/wolfssl.c +++ b/libs/libcurl/src/vtls/wolfssl.c @@ -475,7 +475,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, protocols in descending order of preference, eg: "h2,http/1.1" */ #ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { + if(data->state.httpversion >= CURL_HTTP_VERSION_2) { strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ","); infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); } @@ -516,7 +516,9 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, void *ssl_sessionid = NULL; Curl_ssl_sessionid_lock(data); - if(!Curl_ssl_getsessionid(data, conn, &ssl_sessionid, NULL, sockindex)) { + 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)) { char error_buffer[WOLFSSL_MAX_ERROR_SZ]; @@ -557,12 +559,12 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, 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_ORIG]; + 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_ORIG]; + data->set.str[STRING_SSL_PINNEDPUBLICKEY]; #endif conn->recv[sockindex] = wolfssl_recv; @@ -724,7 +726,7 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) conn->negnpn = CURL_HTTP_VERSION_1_1; #ifdef USE_NGHTTP2 - else if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + else if(data->state.httpversion >= CURL_HTTP_VERSION_2 && protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN && !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN)) @@ -770,32 +772,33 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn, if(SSL_SET_OPTION(primary.sessionid)) { bool incache; - SSL_SESSION *our_ssl_sessionid; void *old_ssl_sessionid = NULL; - - our_ssl_sessionid = SSL_get_session(backend->handle); - - Curl_ssl_sessionid_lock(data); - incache = !(Curl_ssl_getsessionid(data, conn, &old_ssl_sessionid, NULL, - sockindex)); - if(incache) { - if(old_ssl_sessionid != our_ssl_sessionid) { - infof(data, "old SSL session ID is stale, removing\n"); - Curl_ssl_delsessionid(data, old_ssl_sessionid); - incache = FALSE; + SSL_SESSION *our_ssl_sessionid = SSL_get_session(backend->handle); + bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE; + + if(our_ssl_sessionid) { + Curl_ssl_sessionid_lock(data); + incache = !(Curl_ssl_getsessionid(data, conn, isproxy, + &old_ssl_sessionid, NULL, sockindex)); + if(incache) { + if(old_ssl_sessionid != our_ssl_sessionid) { + infof(data, "old SSL session ID is stale, removing\n"); + Curl_ssl_delsessionid(data, old_ssl_sessionid); + incache = FALSE; + } } - } - if(!incache) { - result = Curl_ssl_addsessionid(data, conn, our_ssl_sessionid, - 0 /* unknown size */, sockindex); - if(result) { - Curl_ssl_sessionid_unlock(data); - failf(data, "failed to store ssl session"); - return result; + if(!incache) { + result = Curl_ssl_addsessionid(data, conn, isproxy, our_ssl_sessionid, + 0, sockindex); + if(result) { + Curl_ssl_sessionid_unlock(data); + failf(data, "failed to store ssl session"); + return result; + } } + Curl_ssl_sessionid_unlock(data); } - Curl_ssl_sessionid_unlock(data); } connssl->connecting_state = ssl_connect_done; @@ -1152,6 +1155,7 @@ const struct Curl_ssl Curl_ssl_wolfssl = { Curl_none_cert_status_request, /* cert_status_request */ wolfssl_connect, /* connect */ wolfssl_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ wolfssl_get_internals, /* get_internals */ wolfssl_close, /* close_one */ Curl_none_close_all, /* close_all */ |