diff options
author | dartraiden <dartraiden@protonmail.com> | 2020-01-12 14:12:42 +0300 |
---|---|---|
committer | dartraiden <dartraiden@protonmail.com> | 2020-01-12 14:14:27 +0300 |
commit | 69d3b201c14db069ad0aef4b21e8efb45e21df9b (patch) | |
tree | 9c168030e03459dfe2d2d6cf64511321786b41f8 | |
parent | dcb62e4830223c1f5233d90b855e74006fd0942b (diff) |
libcurl: update to 7.68
137 files changed, 3888 insertions, 2405 deletions
diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES index d35f541998..b1f1e20ee3 100644 --- a/libs/libcurl/docs/CHANGES +++ b/libs/libcurl/docs/CHANGES @@ -6,6 +6,1546 @@ Changelog +Version 7.68.0 (8 Jan 2020) + +Daniel Stenberg (8 Jan 2020) +- RELEASE-NOTES: 7.68.0 + +- THANKS: updated with names from the 7.68.0 release + +- RELEASE-PROCEDURE: add four future release dates + + and remove four past release dates + + [skip ci] + +Marcel Raad (6 Jan 2020) +- TrackMemory tests: always remove CR before LF + + It was removed for output containing ' =' via `s/ =.*//`. With classic + MinGW, this made lines with `free()` end with CRLF, but lines with e.g. + `malloc()` end with only LF. The tests expect LF only. + + Closes https://github.com/curl/curl/pull/4788 + +Daniel Stenberg (6 Jan 2020) +- multi.h: move INITIAL_MAX_CONCURRENT_STREAMS from public header + + ... to the private multihhandle.h. It is not for public use and it + wasn't prefixed correctly anyway! + + Closes #4790 + +- file: fix copyright year range + + Follow-up to 1b71bc532bd + +- curl -w: handle a blank input file correctly + + Previously it would end up with an uninitialized memory buffer that + would lead to a crash or junk getting output. + + Added test 1271 to verify. + + Reported-by: Brian Carpenter + Closes #4786 + +- file: on Windows, refuse paths that start with \\ + + ... as that might cause an unexpected SMB connection to a given host + name. + + Reported-by: Fernando Muñoz + CVE-2019-15601 + Bug: https://curl.haxx.se/docs/CVE-2019-15601.html + +Jay Satiro (6 Jan 2020) +- CURLOPT_READFUNCTION.3: fix fopen params in example + +- CURLOPT_READFUNCTION.3: fix variable name in example + + Reported-by: Paul Joyce + + Fixes https://github.com/curl/curl/issues/4787 + +Daniel Stenberg (5 Jan 2020) +- curl:getparameter return error for --http3 if libcurl doesn't support + + Closes #4785 + +- docs: mention CURL_MAX_INPUT_LENGTH restrictions + + ... for curl_easy_setopt() and curl_url_set(). + + [skip ci] + + Closes #4783 + +- curl: properly free mimepost data + + ... as it could otherwise leak memory when a transfer failed. + + Added test 1293 to verify. + + Reported-by: Brian Carpenter + Fixes #4781 + Closes #4782 + +- curl: cleanup multi handle on failure + + ... to fix memory leak in error path. + + Fixes #4772 + Closes #4780 + Reported-by: Brian Carpenter + +Marcel Raad (3 Jan 2020) +- lib: fix compiler warnings with `CURL_DISABLE_VERBOSE_STRINGS` + + Closes https://github.com/curl/curl/pull/4775 + +Daniel Stenberg (3 Jan 2020) +- COPYING: it's 2020! + + [skip ci] + +Jay Satiro (3 Jan 2020) +- [Marc Aldorasi brought this change] + + tests: Fix bounce requests with truncated writes + + Prior to this change the swsbounce check in service_connection could + fail because prevtestno and prevpartno were not set, which would cause + the wrong response data to be sent to some tests and cause them to fail. + + Ref: https://github.com/curl/curl/pull/4717#issuecomment-570240785 + +Marcel Raad (31 Dec 2019) +- tool: make a few char pointers point to const char instead + + These are read-only. + + Closes https://github.com/curl/curl/pull/4771 + +Jay Satiro (31 Dec 2019) +- tests: Change NTLM tests to require SSL + + Prior to this change tests that required NTLM feature did not require + SSL feature. + + There are pending changes to cmake builds that will allow enabling NTLM + in non-SSL builds in Windows. In that case the NTLM auth strings created + are different from what is expected by the NTLM tests and they fail: + + "The issue with NTLM is that previous non-SSL builds would not enable + NTLM and so the NTLM tests would be skipped." + + Assisted-by: marc-groundctl@users.noreply.github.com + + Ref: https://github.com/curl/curl/pull/4717#issuecomment-566218729 + + Closes https://github.com/curl/curl/pull/4768 + +- [Michael Forney brought this change] + + bearssl: Improve I/O handling + + Factor out common I/O loop as bearssl_run_until, which reads/writes TLS + records until the desired engine state is reached. This is now used for + the handshake, read, write, and close. + + Match OpenSSL SSL_write behavior, and don't return the number of bytes + written until the corresponding records have been completely flushed + across the socket. This involves keeping track of the length of data + buffered into the TLS engine, and assumes that when CURLE_AGAIN is + returned, the write function will be called again with the same data + and length arguments. This is the same requirement of SSL_write. + + Handle TLS close notify as EOF when reading by returning 0. + + Closes https://github.com/curl/curl/pull/4748 + +- travis: Fix error detection + + - Stop using inline shell scripts for before_script and script sections. + + Prior to this change Travis could ignore errors from commands in inline + scripts. I don't understand how or why it happens. This is a workaround. + + Assisted-by: Simon Warta + + Ref: https://github.com/travis-ci/travis-ci/issues/1066 + + Fixes https://github.com/curl/curl/issues/3730 + Closes https://github.com/curl/curl/pull/3755 + +- tool_operate: fix mem leak when failed config parse + + Found by fuzzing the config file. + + Reported-by: Geeknik Labs + + Fixes https://github.com/curl/curl/issues/4767 + +- [Xiang Xiao brought this change] + + lib: remove erroneous +x file permission on some c files + + Modified by commit eb9a604 accidentally. + + Closes https://github.com/curl/curl/pull/4756 + +- [Xiang Xiao brought this change] + + lib: fix warnings found when porting to NuttX + + - Undefine DEBUGASSERT in curl_setup_once.h in case it was already + defined as a system macro. + + - Don't compile write32_le in curl_endian unless + CURL_SIZEOF_CURL_OFF_T > 4, since it's only used by Curl_write64_le. + + - Include <arpa/inet.h> in socketpair.c. + + Closes https://github.com/curl/curl/pull/4756 + +- os400: Add missing CURLE error constants + + Bug: https://github.com/curl/curl/pull/4754#issuecomment-569126922 + Reported-by: Emil Engler + +- CURLOPT_HEADERFUNCTION.3: Document that size is always 1 + + For compatibility with `fwrite`, the `CURLOPT_HEADERFUNCTION` callback + is passed two `size_t` parameters which, when multiplied, designate the + number of bytes of data passed in. In practice, CURL always sets the + first parameter (`size`) to 1. + + This practice is also enshrined in documentation and cannot be changed + in future. The documentation states that the default callback is + `fwrite`, which means `fwrite` must be a suitable function for this + purpose. However, the documentation also states that the callback must + return the number of *bytes* it successfully handled, whereas ISO C + `fwrite` returns the number of items (each of size `size`) which it + wrote. The only way these numbers can be equal is if `size` is 1. + + Since `size` is 1 and can never be changed in future anyway, document + that fact explicitly and let users rely on it. + + Reported-by: Frank Gevaerts + Commit-message-by: Christopher Head + + Ref: https://github.com/curl/curl/pull/2787 + + Fixes https://github.com/curl/curl/issues/4758 + +- examples/postinmemory.c: Call curl_global_cleanup always + + Prior to this change curl_global_cleanup was not called if + curl_easy_init failed. + + Reported-by: kouzhudong@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/4751 + +Daniel Stenberg (21 Dec 2019) +- url2file.c: fix copyright year + + Follow-up to 525787269599b5 + +- [Rickard Hallerbäck brought this change] + + examples/url2file.c: corrected a comment + + The comment was confusing and suggested that setting CURLOPT_NOPROGRESS + to 0L would both enable and disable debug output at the same time, like + a Schrödinger's cat of CURLOPTs. + + Closes #4745 + +- HISTORY: OSS-Fuzz started fuzzing libcurl in 2017 + +- RELEASE-NOTES: synced + +Jay Satiro (20 Dec 2019) +- ngtcp2: Support the latest update key callback type + + - Remove our cb_update_key in favor of ngtcp2's new + ngtcp2_crypto_update_key_cb which does the same thing. + + Several days ago the ngtcp2_update_key callback function prototype was + changed in ngtcp2/ngtcp2@42ce09c. Though it would be possible to + fix up our cb_update_key for that change they also added + ngtcp2_crypto_update_key_cb which does the same thing so we'll use that + instead. + + Ref: https://github.com/ngtcp2/ngtcp2/commit/42ce09c + + Closes https://github.com/curl/curl/pull/4735 + +Daniel Stenberg (19 Dec 2019) +- sws: search for "Testno:" header uncondtionally if no testno + + Even if the initial request line wasn't found. With the fix to 1455, the + test number is now detected correctly. + + (Problem found when running tests in random order.) + + Closes #4744 + +- tests: set LC_ALL in more tests + + Follow-up to 23208e330ac0c21 + + Closes #4743 + +- test165: set LC_ALL=en_US.UTF-8 too + + On my current Debian Unstable with libidn2 2.2.0, I get an error if + LC_ALL is set to blank. Then curl errors out with: + + curl: (3) Failed to convert www.åäö.se to ACE; could not convert string to UTF-8 + + Closes #4738 + +- curl.h: add two defines for the "pre ISO C" case + + Without this fix, this caused a compilation failure on AIX with IBM xlc + 13.1.3 compiler. + + Reported-by: Ram Krushna Mishra + Fixes #4739 + Closes #4740 + +- create_conn: prefer multiplexing to using new connections + + ... as it would previously prefer new connections rather than + multiplexing in most conditions! The (now removed) code was a leftover + from the Pipelining code that was translated wrongly into a + multiplex-only world. + + Reported-by: Kunal Ekawde + Bug: https://curl.haxx.se/mail/lib-2019-12/0060.html + Closes #4732 + +- test1456: remove the use of a fixed local port + + Fixup the test to instead not compare the port number. It sometimes + caused problems like this: + + "curl: (45) bind failed with errno 98: Address already in use" + + Closes #4733 + +Jay Satiro (18 Dec 2019) +- CURLOPT_QUOTE.3: fix typos + + Prior to this change the EXAMPLE in the QUOTE/PREQUOTE/POSTQUOTE man + pages would not compile because a variable name was incorrect. + + Reported-by: Bylon2@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/4736 + +- [Gisle Vanem brought this change] + + strerror: Fix compiler warning "empty expression" + + - Remove the final semi-colon in the SEC2TXT() macro definition. + + Before: #define SEC2TXT(sec) case sec: txt = #sec; break; + + After: #define SEC2TXT(sec) case sec: txt = #sec; break + + Prior to this change SEC2TXT(foo); would generate break;; which caused + the empty expression warning. + + Ref: https://github.com/curl/curl/commit/5b22e1a#r36458547 + +Daniel Stenberg (18 Dec 2019) +- curl/parseconfig: use curl_free() to free memory allocated by libcurl + + Reported-by: bxac on github + Fixes #4730 + Closes #4731 + +- curl/parseconfig: fix mem-leak + + When looping, first trying '.curlrc' and then '_curlrc', the function + would not free the first string. + + Closes #4731 + +- CURLOPT_URL.3: "curl supports SMB version 1 (only)" + + [skip ci] + +- test1270: a basic -w redirect_url test + + Closes #4728 + +- HISTORY: the SMB(S) support landed in 2014 + +- define: remove HAVE_ENGINE_LOAD_BUILTIN_ENGINES, not used anymore + + It is covered by USE_OPENSSL_ENGINE now. + + Reported-by: Gisle Vanem + Bug: https://github.com/curl/curl/commit/87b9337c8f76c21c57b204e88b68c6ecf3bd1ac0#commitcomment-36447951 + + Closes #4725 + +- lib: remove ASSIGNWITHINCONDITION exceptions, use our code style + + ... even for macros + + Reviewed-by: Daniel Gustafsson + Reviewed-by: Jay Satiro + Reported-by: Jay Satiro + Fixes #4683 + Closes #4722 + +- tests: make sure checksrc runs on header files too + +- Revert "checksrc: fix regexp for ASSIGNWITHINCONDITION" + + This reverts commit ba82673dac3e8d00a76aa5e3779a0cb80e7442af. + + Bug: #4683 + +- KNOWN_BUGS: TLS session cache doesn't work with TFO + + [skip ci] + Closes #4301 + +- KNOWN_BUGS: Connection information when using TCP Fast Open + + Also point to #4296 for more details + Closes #4296 + +- KNOWN_BUGS: LDAP on Windows doesn't work + + Closes #4261 + +- docs: TLS SRP doesn't work with TLS 1.3 + + Reported-by: sayrer on github + Closes #4262 + [skip ci] + +Dan Fandrich (16 Dec 2019) +- cirrus: Switch to the FreeBSD 12.1 point release & enable more tests. + + A few tests are now passing on FreeBSD, so no longer skip them. + [skip ci] + +Daniel Stenberg (16 Dec 2019) +- azure: the macos cmake doesn't need to install cmake + + Error: cmake 3.15.5 is already installed + To upgrade to 3.16.1, run `brew upgrade cmake`. + + Closes #4723 + +Jay Satiro (15 Dec 2019) +- winbuild: Document CURL_STATICLIB requirement for static libcurl + + A static libcurl (ie winbuild mode=static) requires that the user define + CURL_STATICLIB when using it in their application. This is already + covered in the FAQ and INSTALL.md, but is a pretty important point so + now it's noted in the BUILD.WINDOWS.txt as well. + + Assisted-by: Michael Vittiglio + + Closes https://github.com/curl/curl/pull/4721 + +Daniel Stenberg (15 Dec 2019) +- [Santino Keupp brought this change] + + libssh2: add support for ECDSA and ed25519 knownhost keys + + ... if a new enough libssh2 version is present. + + Source: https://curl.haxx.se/mail/archive-2019-12/0023.html + Co-Authored-by: Daniel Stenberg + Closes #4714 + +- lib1591: free memory properly on OOM, in the trailers callback + + Detected by torture tests. + + Closes #4720 + +- runtests: --repeat=[num] to repeat tests + + Closes #4715 + +- RELEASE-NOTES: synced + +- azure: add a torture test on mac + + Uses --shallow=25 to keep it small enough to get through in time. + + Closes #4712 + +- multi: free sockhash on OOM + + This would otherwise leak memory in the error path. + + Detected by torture test 1540. + + Closes #4713 + +Marcel Raad (13 Dec 2019) +- tests: use DoH feature for DoH tests + + Previously, http/2 was used instead. + + Assisted-by: Jay Satiro + Closes https://github.com/curl/curl/pull/4692 + +- hostip: suppress compiler warning + + With `--disable-doh --disable-threaded-resolver`, the `dns` parameter + is not used. + + Closes https://github.com/curl/curl/pull/4692 + +- tests: fix build with `CURL_DISABLE_DOH` + + Closes https://github.com/curl/curl/pull/4692 + +Daniel Stenberg (13 Dec 2019) +- azure: add a torture test + + Skipping all FTP tests for speed reasons. + + Closes #4697 + +- azure: make the default build use --enable-debug --enable-werror + +- ntlm_wb: fix double-free in OOM + + Detected by torture testing test 1310 + + Closes #4710 + +Dan Fandrich (13 Dec 2019) +- cirrus: Drop the FreeBSD 10.4 build + + Upstream support for 10.4 ended a year ago, and it looks like the image + is now gone, too. + [skip ci] + +Daniel Stenberg (13 Dec 2019) +- unit1620: fix bad free in OOM + + Closes #4709 + +- unit1609: fix mem-leak in OOM + + Closes #4709 + +- unit1607: fix mem-leak in OOM + + Closes #4709 + +- lib1559: fix mem-leak in OOM + + Closes #4709 + +- lib1557: fix mem-leak in OOM + + Closes #4709 + +- altsvc: make the save function ignore NULL filenames + + It might happen in OOM situations. Detected bv torture tests. + + Closes #4707 + +- curl: fix memory leak in OOM in etags logic + + Detected by torture tests + + Closes #4706 + +- doh: make it behave when built without proxy support + + Reported-by: Marcel Raad + Bug: https://github.com/curl/curl/pull/4692#issuecomment-564115734 + + Closes #4704 + +- curl: improved cleanup in upload error path + + Memory leak found by torture test 58 + + Closes #4705 + +- mailmap: fix Andrew Ishchuk + +- travis: make torture use --shallow=40 + + As a first step to enable it to run over a more diverse set of tests in + a reasonable time. + +- runtests: introduce --shallow to reduce huge torture tests + + When set, shallow mode limits runtests -t to make no more than NUM fails + per test case. If more are found, it will randomly discard entries until + the number is right. The random seed can also be set. + + This is particularly useful when running MANY tests as then most torture + failures will already fail the same functions over and over and make the + total operation painfully tedious. + + Closes #4699 + +- conncache: CONNECT_ONLY connections assumed always in-use + + This makes them never to be considered "the oldest" to be discarded when + reaching the connection cache limit. The reasoning here is that + CONNECT_ONLY is primarily used in combination with using the + connection's socket post connect and since that is used outside of + curl's knowledge we must assume that it is in use until explicitly + closed. + + Reported-by: Pavel Pavlov + Reported-by: Pavel Löbl + Fixes #4426 + Fixes #4369 + Closes #4696 + +- [Gisle Vanem brought this change] + + vtls: make BearSSL possible to set with CURL_SSL_BACKEND + + Ref: https://github.com/curl/curl/commit/9b879160df01e7ddbb4770904391d3b74114302b#commitcomment-36355622 + + Closes #4698 + +- RELEASE-NOTES: synced + +- travis: remove "coverage", make it "torture" + + The coveralls service and test coverage numbers are just too unreliable. + Removed badge from README.md as well. + + Fixes #4694 + Closes #4695 + +- azure: add libssh2 and cmake macos builds + + Removed the macos libssh2 build from travis + + Closes #4686 + +- curl: use errorf() better + + Change series of error outputs to use errorf(). + + Only errors that are due to mistakes in command line option usage should + use helpf(), other types of errors in the tool should rather use + errorf(). + + Closes #4691 + +Jay Satiro (9 Dec 2019) +- [Marc Hoersken brought this change] + + tests: make it possible to set executable extensions + + This enables the use of Windows Subsystem for Linux (WSL) to run the + testsuite against Windows binaries while using Linux servers. + + This commit introduces the following environment variables: + - CURL_TEST_EXE_EXT: set the executable extension for all components + - CURL_TEST_EXE_EXT_TOOL: set it for the curl tool only + - CURL_TEST_EXE_EXT_SSH: set it for the SSH tools only + + Later testcurl.pl could be adjusted to make use of those variables. + - CURL_TEST_EXE_EXT_SRV: set it for the test servers only + + (This is one of several commits to support use of WSL for the tests.) + + Closes https://github.com/curl/curl/pull/3899 + +- [Marc Hoersken brought this change] + + tests: fix permissions of ssh keys in WSL + + Keys created on Windows Subsystem for Linux (WSL) require it for some + reason. + + (This is one of several commits to support use of WSL for the tests.) + + Ref: https://github.com/curl/curl/pull/3899 + +- [Marc Hoersken brought this change] + + tests: use \r\n for log messages in WSL + + Bash in Windows Subsystem for Linux (WSL) requires it for some reason. + + (This is one of several commits to support use of WSL for the tests.) + + Ref: https://github.com/curl/curl/pull/3899 + +- [Andrew Ishchuk brought this change] + + winbuild: Define CARES_STATICLIB when WITH_CARES=static + + When libcurl is built with MODE=static, c-ares is forced into static + linkage too. That doesn't happen when MODE=dll so linker would break + over undefined symbols. + + closes https://github.com/curl/curl/pull/4688 + +Daniel Stenberg (9 Dec 2019) +- conn: always set bits.close with connclose() + + Closes #4690 + +- cirrus: enable clang sanitizers on freebsd 13 + +- conncache: fix multi-thread use of shared connection cache + + It could accidentally let the connection get used by more than one + thread, leading to double-free and more. + + Reported-by: Christopher Reid + Fixes #4544 + Closes #4557 + +- azure: add a vanilla macos build + + Closes #4685 + +- curl: make the etag load logic work without fseek + + The fseek()s were unnecessary and caused Coverity warning CID 1456554 + + Closes #4681 + +- mailmap: Mohammad Hasbini + +- [Mohammad Hasbini brought this change] + + docs: fix some typos + + Closes #4680 + +- RELEASE-NOTES: synced + +Jay Satiro (5 Dec 2019) +- lib: fix some loose ends for recently added CURLSSLOPT_NO_PARTIALCHAIN + + Add support for CURLSSLOPT_NO_PARTIALCHAIN in CURLOPT_PROXY_SSL_OPTIONS + and OS400 package spec. + + Also I added the option to the NameValue list in the tool even though it + isn't exposed as a command-line option (...yet?). (NameValue stringizes + the option name for the curl cmd -> libcurl source generator) + + Follow-up to 564d88a which added CURLSSLOPT_NO_PARTIALCHAIN. + + Ref: https://github.com/curl/curl/pull/4655 + +- setopt: Fix ALPN / NPN user option when built without HTTP2 + + - Stop treating lack of HTTP2 as an unknown option error result for + CURLOPT_SSL_ENABLE_ALPN and CURLOPT_SSL_ENABLE_NPN. + + Prior to this change it was impossible to disable ALPN / NPN if libcurl + was built without HTTP2. Setting either option would result in + CURLE_UNKNOWN_OPTION and the respective internal option would not be + set. That was incorrect since ALPN and NPN are used independent of + HTTP2. + + Reported-by: Shailesh Kapse + + Fixes https://github.com/curl/curl/issues/4668 + Closes https://github.com/curl/curl/pull/4672 + +Daniel Stenberg (5 Dec 2019) +- etag: allow both --etag-compare and --etag-save in same cmdline + + Fixes #4669 + Closes #4678 + +Marcel Raad (5 Dec 2019) +- curl_setup: fix `CURLRES_IPV6` condition + + Move the definition of `CURLRES_IPV6` to before undefining + `HAVE_GETADDRINFO`. Regression from commit 67a08dca27a which caused + some tests to fail and others to be skipped with c-ares. + + Fixes https://github.com/curl/curl/issues/4673 + Closes https://github.com/curl/curl/pull/4677 + +Daniel Stenberg (5 Dec 2019) +- test342: make it return a 304 as the tag matches + +Peter Wu (4 Dec 2019) +- CMake: add support for building with the NSS vtls backend + + Options are cross-checked with configure.ac and acinclude.m4. + Tested on Arch Linux, untested on other platforms like Windows or macOS. + + Closes #4663 + Reviewed-by: Kamil Dudka + +Daniel Stenberg (4 Dec 2019) +- azure: add more builds + + ... removed two from travis (that now runs on azure instead) + + Closes #4671 + +- CURLOPT_VERBOSE.3: see also ERRORBUFFER + +- hostip4.c: bump copyright year range + +Marcel Raad (3 Dec 2019) +- configure: enable IPv6 support without `getaddrinfo` + + This makes it possible to recognize and connect to literal IPv6 + addresses when `getaddrinfo` is not available, which is already the + case for the CMake build. This affects e.g. classic MinGW because it + still targets Windows 2000 by default, where `getaddrinfo` is not + available, but general IPv6 support is. + + Instead of checking for `getaddrinfo`, check for `sockaddr_in6` as the + CMake build does. + + Closes https://github.com/curl/curl/pull/4662 + +- curl_setup: disable IPv6 resolver without `getaddrinfo` + + Also, use `CURLRES_IPV6` only for actual DNS resolution, not for IPv6 + address support. This makes it possible to connect to IPv6 literals by + setting `ENABLE_IPV6` even without `getaddrinfo` support. It also fixes + the CMake build when using the synchronous resolver without + `getaddrinfo` support. + + Closes https://github.com/curl/curl/pull/4662 + +Daniel Stenberg (3 Dec 2019) +- github action/azure pipeline: run 'make test-nonflaky' for tests + + To match travis and give more info on failures. + +- openssl: CURLSSLOPT_NO_PARTIALCHAIN can disable partial cert chains + + Closes #4655 + +- openssl: set X509_V_FLAG_PARTIAL_CHAIN + + Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert + only, instead of needing the whole chain. + + Other TLS backends already accept partial chains. + + Reported-by: Jeffrey Walton + Bug: https://curl.haxx.se/mail/lib-2019-11/0094.html + +- curl: show better error message when no homedir is found + + Reported-by: Vlastimil Ovčáčík + Fixes #4644 + Closes #4665 + +- OPENSOCKETFUNCTION.3: correct the purpose description + + Reported-by: Jeff Mears + Bug: https://curl.haxx.se/mail/lib-2019-12/0007.html + + Closes #4667 + +- [Peter Wu brought this change] + + travis: do not use OVERRIDE_CC or OVERRIDE_CXX if empty + + Fixes the macOS builds where OVERRIDE_CC and OVERRIDE_CXX are not set. + + Reported-by: Jay Satiro + Fixes #4659 + Closes #4661 + Closes #4664 + +- azure-pipelines: fix the test script + +- Azure Pipelines: initial CI setup + + [skip ci] + +- docs: add "added: 7.68.0" to the --etag-* docs + +- copyright: fix the year ranges for two files + + Follow-up to 9c1806ae + +Jay Satiro (1 Dec 2019) +- build: Disable Visual Studio warning "conditional expression is constant" + + - Disable warning C4127 "conditional expression is constant" globally + in curl_setup.h for when building with Microsoft's compiler. + + This mainly affects building with the Visual Studio project files found + in the projects dir. + + Prior to this change the cmake and winbuild build systems already + disabled 4127 globally for when building with Microsoft's compiler. + Also, 4127 was already disabled for all build systems in the limited + circumstance of the WHILE_FALSE macro which disabled the warning + specifically for while(0). This commit removes the WHILE_FALSE macro and + all other cruft in favor of disabling globally in curl_setup. + + Background: + + We have various macros that cause 0 or 1 to be evaluated, which would + cause warning C4127 in Visual Studio. For example this causes it: + + #define Curl_resolver_asynch() 1 + + Full behavior is not clearly defined and inconsistent across versions. + However it is documented that since VS 2015 Update 3 Microsoft has + addressed this somewhat but not entirely, not warning on while(true) for + example. + + Prior to this change some C4127 warnings occurred when I built with + Visual Studio using the generated projects in the projects dir. + + Closes https://github.com/curl/curl/pull/4658 + +- openssl: retrieve reported LibreSSL version at runtime + + - Retrieve LibreSSL runtime version when supported (>= 2.7.1). + + For earlier versions we continue to use the compile-time version. + + Ref: https://man.openbsd.org/OPENSSL_VERSION_NUMBER.3 + + Closes https://github.com/curl/curl/pull/2425 + +- strerror: Add Curl_winapi_strerror for Win API specific errors + + - In all code call Curl_winapi_strerror instead of Curl_strerror when + the error code is known to be from Windows GetLastError. + + Curl_strerror prefers CRT error codes (errno) over Windows API error + codes (GetLastError) when the two overlap. When we know the error code + is from GetLastError it is more accurate to prefer the Windows API error + messages. + + Reported-by: Richard Alcock + + Fixes https://github.com/curl/curl/issues/4550 + Closes https://github.com/curl/curl/pull/4581 + +Daniel Stenberg (2 Dec 2019) +- global_init: undo the "intialized" bump in case of failure + + ... so that failures in the global init function don't count as a + working init and it can then be called again. + + Reported-by: Paul Groke + Fixes #4636 + Closes #4653 + +- parsedate: offer a getdate_capped() alternative + + ... and use internally. This function will return TIME_T_MAX instead of + failure if the parsed data is found to be larger than what can be + represented. TIME_T_MAX being the largest value curl can represent. + + Reviewed-by: Daniel Gustafsson + Reported-by: JanB on github + Fixes #4152 + Closes #4651 + +- docs: add more references to curl_multi_poll + + Fixes #4643 + Closes #4652 + +- sha256: bump the copyright year range + + Follow-up from 66e21520f + +Daniel Gustafsson (28 Nov 2019) +- curl_setup_once: consistently use WHILE_FALSE in macros + + The WHILE_FALSE construction is used to avoid compiler warnings in + macro constructions. This fixes a few instances where it was not + used in order to keep the code consistent. + + Closes #4649 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +Daniel Stenberg (28 Nov 2019) +- [Steve Holme brought this change] + + http_ntlm: Remove duplicate NSS initialisation + + Given that this is performed by the NTLM code there is no need to + perform the initialisation in the HTTP layer. This also keeps the + initialisation the same as the SASL based protocols and also fixes a + possible compilation issue if both NSS and SSPI were to be used as + multiple SSL backends. + + Reviewed-by: Kamil Dudka + Closes #3935 + +Daniel Gustafsson (28 Nov 2019) +- checksrc: fix regexp for ASSIGNWITHINCONDITION + + The regexp looking for assignments within conditions was too greedy + and matched a too long string in the case of multiple conditionals + on the same line. This is basically only a problem in single line + macros, and the code which exemplified this was essentially: + + do { if((x) != NULL) { x = NULL; } } while(0) + + ..where the final parenthesis of while(0) matched the regexp, and + the legal assignment in the block triggered the warning. Fix by + making the regexp less greedy by matching for the tell-tale signs + of the if statement ending. + + Also remove the one occurrence where the warning was disabled due + to a construction like the above, where the warning didn't apply + when fixed. + + Closes #4647 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +Daniel Stenberg (28 Nov 2019) +- RELEASE-NOTES: synced + +- [Maros Priputen brought this change] + + curl: two new command line options for etags + + --etag-compare and --etag-save + + Suggested-by: Paul Hoffman + Fixes #4277 + Closes #4543 + +Daniel Gustafsson (28 Nov 2019) +- docs: fix typos + +Daniel Stenberg (28 Nov 2019) +- mailmap: Niall O'Reilly's name + +- [Niall O'Reilly brought this change] + + doh: use dedicated probe slots + + ... to easier allow additional DNS transactions. + + Closes #4629 + +- travis: build ngtcp2 with --enable-lib-only + + ... makes it skip the examples and other stuff we don't neeed. + + Closes #4646 + +- [David Benjamin brought this change] + + ngtcp2: fix thread-safety bug in error-handling + + ERR_error_string(NULL) should never be called. It places the error in a + global buffer, which is not thread-safe. Use ERR_error_string_n with a + local buffer instead. + + Closes #4645 + +- travis: export the CC/CXX variables when set + + Suggested-by: Peter Wu + Fixes #4637 + Closes #4640 + +Marcel Raad (26 Nov 2019) +- dist: add error-codes.pl + + Follow-up to commit 74f441c6d31. + This should fix test 1175 when run via the daily source tarballs. + + Closes https://github.com/curl/curl/pull/4638 + +Daniel Stenberg (26 Nov 2019) +- [John Schroeder brought this change] + + curl: fix --upload-file . hangs if delay in STDIN + + Attempt to unpause a busy read in the CURLOPT_XFERINFOFUNCTION. + + When uploading from stdin in non-blocking mode, a delay in reading + the stream (EAGAIN) causes curl to pause sending data + (CURL_READFUNC_PAUSE). Prior to this change, a busy read was + detected and unpaused only in the CURLOPT_WRITEFUNCTION handler. + This change performs the same busy read handling in a + CURLOPT_XFERINFOFUNCTION handler. + + Fixes #2051 + Closes #4599 + Reported-by: bdry on github + +- [John Schroeder brought this change] + + XFERINFOFUNCTION: support CURL_PROGRESSFUNC_CONTINUE + + (also for PROGRESSFUNCTION) + + By returning this value from the callback, the internal progress + function call is still called afterward. + + Closes #4599 + +- [Michael Forney brought this change] + + TLS: add BearSSL vtls implementation + + Closes #4597 + +- curl_multi_wakeup.3: add example and AVAILABILITY + + Reviewed-by: Gergely Nagy + Closes #4635 + +- [Gergely Nagy brought this change] + + multi: add curl_multi_wakeup() + + This commit adds curl_multi_wakeup() which was previously in the TODO + list under the curl_multi_unblock name. + + On some platforms and with some configurations this feature might not be + available or can fail, in these cases a new error code + (CURLM_WAKEUP_FAILURE) is returned from curl_multi_wakeup(). + + Fixes #4418 + Closes #4608 + +Jay Satiro (24 Nov 2019) +- [Xiaoyin Liu brought this change] + + schannel: fix --tls-max for when min is --tlsv1 or default + + Prior to this change schannel ignored --tls-max (CURL_SSLVERSION_MAX_ + macros) when --tlsv1 (CURL_SSLVERSION_TLSv1) or default TLS + (CURL_SSLVERSION_DEFAULT), using a max of TLS 1.2 always. + + Closes https://github.com/curl/curl/pull/4633 + +- checksrc.bat: Add a check for vquic and vssh directories + + Ref: https://github.com/curl/curl/pull/4607 + +- projects: Fix Visual Studio projects SSH builds + + - Generate VQUIC and VSSH filenames in Visual Studio project files. + + Prior to this change generated Visual Studio project configurations that + enabled SSH did not build properly. Broken since SSH files were moved to + lib/vssh 3 months ago in 5b2d703. + + Fixes https://github.com/curl/curl/issues/4492 + Fixes https://github.com/curl/curl/issues/4630 + Closes https://github.com/curl/curl/pull/4607 + +Daniel Stenberg (23 Nov 2019) +- RELEASE-NOTES: synced + +Jay Satiro (22 Nov 2019) +- openssl: Revert to less sensitivity for SYSCALL errors + + - Disable the extra sensitivity except in debug builds (--enable-debug). + + - Improve SYSCALL error message logic in ossl_send and ossl_recv so that + "No error" / "Success" socket error text isn't shown on SYSCALL error. + + Prior to this change 0ab38f5 (precedes 7.67.0) increased the sensitivity + of OpenSSL's SSL_ERROR_SYSCALL error so that abrupt server closures were + also considered errors. For example, a server that does not send a known + protocol termination point (eg HTTP content length or chunked encoding) + _and_ does not send a TLS termination point (close_notify alert) would + cause an error if it closed the connection. + + To be clear that behavior made it into release build 7.67.0 + unintentionally. Several users have reported it as an issue. + + Ultimately the idea is a good one, since it can help prevent against a + truncation attack. Other SSL backends may already behave similarly (such + as Windows native OS SSL Schannel). However much more of our user base + is using OpenSSL and there is a mass of legacy users in that space, so I + think that behavior should be partially reverted and then rolled out + slowly. + + This commit changes the behavior so that the increased sensitivity is + disabled in all curl builds except curl debug builds (DEBUGBUILD). If + after a period of time there are no major issues then it can be enabled + in dev and release builds with the newest OpenSSL (1.1.1+), since users + using the newest OpenSSL are the least likely to have legacy problems. + + Bug: https://github.com/curl/curl/issues/4409#issuecomment-555955794 + Reported-by: Bjoern Franke + + Fixes https://github.com/curl/curl/issues/4624 + Closes https://github.com/curl/curl/pull/4623 + +- [Daniel Stenberg brought this change] + + openssl: improve error message for SYSCALL during connect + + Reported-by: Paulo Roberto Tomasi + Bug: https://curl.haxx.se/mail/archive-2019-11/0005.html + + Closes https://github.com/curl/curl/pull/4593 + +Daniel Stenberg (22 Nov 2019) +- test1175: verify symbols-in-versions and libcurl-errors.3 in sync + + Closes #4628 + +- include: make CURLE_HTTP3 use a new error code + + To avoid potential issues with error code reuse. + + Reported-by: Christoph M. Becker + Assisted-by: Dan Fandrich + Fixes #4601 + Closes #4627 + +- bump: next release will be 7.68.0 + +- curl: add --parallel-immediate + + Starting with this change when doing parallel transfers, without this + option set, curl will prefer to create new transfers multiplexed on an + existing connection rather than creating a brand new one. + + --parallel-immediate can be set to tell curl to prefer to use new + connections rather than to wait and try to multiplex. + + libcurl-wise, this means that curl will set CURLOPT_PIPEWAIT by default + on parallel transfers. + + Suggested-by: Tom van der Woerdt + Closes #4500 + +Daniel Gustafsson (20 Nov 2019) +- [Victor Magierski brought this change] + + docs: fix typos + + Change 'experiemental' to 'experimental'. + + Closes #4618 + Reviewed-by: Daniel Gustafsson <daniel@yesql.se> + +Jay Satiro (18 Nov 2019) +- projects: Fix Visual Studio wolfSSL configurations + + - s/USE_CYASSL/USE_WOLFSSL/ + + - Remove old compatibility macros. + + Follow-up to 1c6c59a from several months ago when CyaSSL named symbols + were renamed to wolfSSL. The wolfSSL library was formerly named CyaSSL + and we kept using their old name for compatibility reasons, until + earlier this year. + +Daniel Stenberg (18 Nov 2019) +- RELEASE-NOTES: synced + +- [Javier Blazquez brought this change] + + ngtcp2: use overflow buffer for extra HTTP/3 data + + Fixes #4525 + Closes #4603 + +- altsvc: bump to h3-24 + + ... as both ngtcp2 and quiche now support that in their master branches + + Closes #4604 + +- ngtcp2: free used resources on disconnect + + Fixes #4614 + Closes #4615 + +- ngtcp2: handle key updates as ngtcp2 master branch tells us + + Reviewed-by: Tatsuhiro Tsujikawa + + Fixes #4612 + Closes #4613 + +Jay Satiro (17 Nov 2019) +- [Gergely Nagy brought this change] + + multi: Fix curl_multi_poll wait when extra_fds && !extra_nfds + + Prior to this change: + + The check if an extra wait is necessary was based not on the + number of extra fds but on the pointer. + + If a non-null pointer was given in extra_fds, but extra_nfds + was zero, then the wait was skipped even though poll was not + called. + + Closes https://github.com/curl/curl/pull/4610 + +- lib: Move lib/ssh.h -> lib/vssh/ssh.h + + Follow-up to 5b2d703 which moved ssh source files to vssh. + + Closes https://github.com/curl/curl/pull/4609 + +Daniel Stenberg (16 Nov 2019) +- [Andreas Falkenhahn brought this change] + + INSTALL.md: provide Android build instructions + + Closes #4606 + +- [Niall O'Reilly brought this change] + + doh: improced both encoding and decoding + + Improved estimation of expected_len and updated related comments; + increased strictness of QNAME-encoding, adding error detection for empty + labels and names longer than the overall limit; avoided treating DNAME + as unexpected; + + updated unit test 1655 with more thorough set of proofs and tests + + Closes #4598 + +- ngtcp2: increase QUIC window size when data is consumed + + Assisted-by: Javier Blazquez + Ref #4525 (partial fix) + Closes #4600 + +- [Melissa Mears brought this change] + + config-win32: cpu-machine-OS for Windows on ARM + + Define the OS macro properly for Windows on ARM builds. Also, we might + as well add the GCC-style IA-64 macro. + + Closes #4590 + +- examples: add multi-poll.c + + Show how curl_multi_poll() makes it even easier to use the multi + interface. + + Closes #4596 + +- multi_poll: avoid busy-loop when called without easy handles attached + + Fixes #4594 + Closes #4595 + Reported-by: 3dyd on github + +- curl: fix -T globbing + + Regression from e59371a4936f8 (7.67.0) + + Added test 490, 491 and 492 to verify the functionality. + + Reported-by: Kamil Dudka + Reported-by: Anderson Sasaki + + Fixes #4588 + Closes #4591 + +- HISTORY: added cmake, HTTP/3 and parallel downloads with curl + +- quiche: reject headers in the wrong order + + Pseudo header MUST come before regular headers or cause an error. + + Reported-by: Cynthia Coan + Fixes #4571 + Closes #4584 + +- openssl: prevent recursive function calls from ctx callbacks + + Follow the pattern of many other callbacks. + + Ref: #4546 + Closes #4585 + +- CURL-DISABLE: initial docs for the CURL_DISABLE_* defines + + The disable-scan script used in test 1165 is extended to also verify + that the docs cover all used defines and all defines offered by + configure. + + Reported-by: SLDiggie on github + Fixes #4545 + Closes #4587 + +- remove_handle: clear expire timers after multi_done() + + Since 59041f0, a new timer might be set in multi_done() so the clearing + of the timers need to happen afterwards! + + Reported-by: Max Kellermann + Fixes #4575 + Closes #4583 + +Marcel Raad (10 Nov 2019) +- test1558: use double slash after file: + + Classic MinGW / MSYS 1 doesn't support `MSYS2_ARG_CONV_EXCL`, so this + test unnecessarily failed when using `file:/` instead of `file:///`. + + Closes https://github.com/curl/curl/pull/4554 + +Daniel Stenberg (10 Nov 2019) +- pause: avoid updating socket if done was already called + + ... avoids unnecesary recursive risk when the transfer is already done. + + Reported-by: Richard Bowker + Fixes #4563 + Closes #4574 + +Jay Satiro (9 Nov 2019) +- strerror: Fix an error looking up some Windows error strings + + - Use FORMAT_MESSAGE_IGNORE_INSERTS to ignore format specifiers in + Windows error strings. + + Since we are not in control of the error code we don't know what + information may be needed by the error string's format specifiers. + + Prior to this change Windows API error strings which contain specifiers + (think specifiers like similar to printf specifiers) would not be shown. + The FormatMessage Windows API call which turns a Windows error code into + a string could fail and set error ERROR_INVALID_PARAMETER if that error + string contained a format specifier. FormatMessage expects a va_list for + the specifiers, unless inserts are ignored in which case no substitution + is attempted. + + Ref: https://devblogs.microsoft.com/oldnewthing/20071128-00/?p=24353 + +- [r-a-sattarov brought this change] + + system.h: fix for MCST lcc compiler + + Fixed build by MCST lcc compiler on MCST Elbrus 2000 architecture and do + some code cleanup. + + e2k (Elbrus 2000) - this is VLIW/EPIC architecture, like Intel Itanium + architecture. + + Ref: https://en.wikipedia.org/wiki/Elbrus_2000 + + Closes https://github.com/curl/curl/pull/4576 + +Daniel Stenberg (8 Nov 2019) +- TODO: curl_multi_unblock + + Closes #4418 + +- TODO: Run web-platform-tests url tests + + Closes #4477 + +- TODO: 1.4 alt-svc sharing + + Closes #4476 + +- test1560: require IPv6 for IPv6 aware URL parsing + + The URL parser function can't reject a bad IPv6 address properly when + curl was built without IPv6 support. + + Reported-by: Marcel Raad + Fixes #4556 + Closes #4572 + +- checksrc: repair the copyrightyear check + + - Consider a modified file to be committed this year. + + - Make the travis CHECKSRC also do COPYRIGHTYEAR scan in examples and + includes + + - Ignore 0 parents when getting latest commit date of file. + + since in the CI we're dealing with a truncated repo of last 50 commits, + the file's most recent commit may not be available. when this happens + git log and rev-list show the initial commit (ie first commit not to be + truncated) but that's incorrect so ignore it. + + Ref: https://github.com/curl/curl/pull/4547 + + Closes https://github.com/curl/curl/pull/4549 + + Co-authored-by: Jay Satiro + +- copyrights: fix copyright year range + + .. because checksrc's copyright year check stopped working. + + Ref: https://github.com/curl/curl/pull/4547 + + Closes https://github.com/curl/curl/pull/4549 + +- RELEASE-NOTES: synced + +- curlver: bump to 7.67.1 + +- mailmap: fixup Massimiliano Fantuzzi + +- scripts/contributors: make committers get included too + + in addition to authors + +Jay Satiro (8 Nov 2019) +- [Massimiliano Fantuzzi brought this change] + + configure: fix typo in help text + + Closes https://github.com/curl/curl/pull/4570 + +Daniel Stenberg (7 Nov 2019) +- [Christian Schmitz brought this change] + + ntlm: USE_WIN32_CRYPTO check removed to get USE_NTLM2SESSION set + + Closes #3704 + +Jay Satiro (6 Nov 2019) +- [Wyatt O'Day brought this change] + + build: fix for CURL_DISABLE_DOH + + Fixes https://github.com/curl/curl/issues/4565 + Closes https://github.com/curl/curl/pull/4566 + +- [Leonardo Taccari brought this change] + + configure: avoid unportable `==' test(1) operator + + Closes https://github.com/curl/curl/pull/4567 + Version 7.67.0 (5 Nov 2019) Daniel Stenberg (5 Nov 2019) @@ -606,7 +2146,7 @@ Daniel Stenberg (4 Oct 2019) - CURLMOPT_MAX_CONCURRENT_STREAMS.3: fix SEE ALSO typo -- [Niall brought this change] +- [Niall O'Reilly brought this change] ESNI: initial build/setup @@ -5588,1512 +7128,3 @@ Jay Satiro (4 Apr 2019) ~~~~~~~~~~~~~~~~^~~~ Closes https://github.com/curl/curl/pull/3729 - -Marcel Raad (4 Apr 2019) -- VS projects: use Unicode for VC10+ - - All Windows APIs have been natively UTF-16 since Windows 2000 and the - non-Unicode variants are just wrappers around them. Only Windows 9x - doesn't understand Unicode without the UnicoWS DLL. As later Visual - Studio versions cannot target Windows 9x anyway, using the ANSI API - doesn't really have any benefit there. - - This avoids issues like KNOWN_BUGS 6.5. - - Ref: https://github.com/curl/curl/issues/2120 - Closes https://github.com/curl/curl/pull/3720 - -Daniel Gustafsson (3 Apr 2019) -- RELEASE-NOTES: synced - - Bump the version in progress to 7.64.2, if we merge any "change" - before the cut-off date we can update the version. - -- [Tim Rühsen brought this change] - - documentation: Fix several typos - - Closes #3724 - Reviewed-by: Jakub Zakrzewski - Reviewed-by: Daniel Gustafsson - -Jay Satiro (2 Apr 2019) -- [Mert Yazıcıoğlu brought this change] - - vauth/oauth2: Fix OAUTHBEARER token generation - - OAUTHBEARER tokens were incorrectly generated in a format similar to - XOAUTH2 tokens. These changes make OAUTHBEARER tokens conform to the - RFC7628. - - Fixes: #2487 - Reported-by: Paolo Mossino - - Closes https://github.com/curl/curl/pull/3377 - -Marcel Raad (2 Apr 2019) -- tool_cb_wrt: fix bad-function-cast warning - - Commit f5bc578f4cdfdc6c708211dfc2962a0e9d79352d reintroduced the - warning fixed in commit 2f5f31bb57d68b54e03bffcd9648aece1fe564f8. - Extend fhnd's scope and reuse that variable instead of calling - _get_osfhandle a second time to fix the warning again. - - Closes https://github.com/curl/curl/pull/3718 - -- VC15 project: remove MinimalRebuild - - Already done in commit d5cfefd0ea8e331b884186bff484210fad36e345 for the - library project, but I forgot the tool project template. Now also - removed for that. - -Dan Fandrich (1 Apr 2019) -- cirrus: Customize the disabled tests per FreeBSD version - - Try to run as many test cases as possible on each OS version. - 12.0 passes 13 more tests than the older versions, so we might as well - run them. - -Daniel Stenberg (1 Apr 2019) -- tool_help: include <strings.h> for strcasecmp - - Reported-by: Wyatt O'Day - Fixes #3715 - Closes #3716 - -Daniel Gustafsson (31 Mar 2019) -- scripts: fix typos - -Dan Fandrich (28 Mar 2019) -- travis: allow builds on branches named "ci" - - This allows a way to test changes other than through PRs. - -Daniel Stenberg (27 Mar 2019) -- [Brad Spencer brought this change] - - resolve: apply Happy Eyeballs philosophy to parallel c-ares queries - - Closes #3699 - -- multi: improved HTTP_1_1_REQUIRED handling - - Make sure to downgrade to 1.1 even when we get this HTTP/2 stream error - on first flight. - - Reported-by: niner on github - Fixes #3696 - Closes #3707 - -- [Leonardo Taccari brought this change] - - configure: avoid unportable `==' test(1) operator - - Closes #3709 - -Version 7.64.1 (27 Mar 2019) - -Daniel Stenberg (27 Mar 2019) -- RELEASE: 7.64.1 - -- Revert "ntlm: remove USE_WIN32_CRYPTO check to get USE_NTLM2SESSION set" - - This reverts commit 9130ead9fcabdb6b8fbdb37c0b38be2d326adb00. - - Fixes #3708 - -- [Christian Schmitz brought this change] - - ntlm: remove USE_WIN32_CRYPTO check to get USE_NTLM2SESSION set - - Closes #3704 - -Jay Satiro (26 Mar 2019) -- tool_cb_wrt: fix writing to Windows null device NUL - - - Improve console detection. - - Prior to this change WriteConsole could be called to write to a handle - that may not be a console, which would cause an error. This issue is - limited to character devices that are not also consoles such as the null - device NUL. - - Bug: https://github.com/curl/curl/issues/3175#issuecomment-439068724 - Reported-by: Gisle Vanem - -- CURLMOPT_PIPELINING.3: fix typo - -Daniel Stenberg (25 Mar 2019) -- TODO: config file parsing - - Closes #3698 - -Jay Satiro (24 Mar 2019) -- os400: Disable Alt-Svc by default since it's experimental - - Follow-up to 520f0b4 which added Alt-Svc support and enabled it by - default for OS400. Since the feature is experimental, it should be - disabled by default. - - Ref: https://github.com/curl/curl/commit/520f0b4#commitcomment-32792332 - Ref: https://curl.haxx.se/mail/lib-2019-02/0008.html - - Closes https://github.com/curl/curl/pull/3688 - -Dan Fandrich (24 Mar 2019) -- tests: Fixed XML validation errors in some test files. - -- tests: Fix some incorrect precheck error messages. - - [ci skip] - -Daniel Stenberg (22 Mar 2019) -- curl_url.3: this is not experimental anymore - -- travis: bump the used wolfSSL version to 4.0.0 - - Test 311 is now fine, leaving only 313 (CRL) disabled. - - Test 313 details can be found here: - https://github.com/wolfSSL/wolfssl/issues/1546 - - Closes #3697 - -Daniel Gustafsson (22 Mar 2019) -- lib: Fix typos in comments - -David Woodhouse (20 Mar 2019) -- openssl: if cert type is ENG and no key specified, key is ENG too - - Fixes #3692 - Closes #3692 - -Daniel Stenberg (20 Mar 2019) -- sectransp: tvOS 11 is required for ALPN support - - Reported-by: nianxuejie on github - Assisted-by: Nick Zitzmann - Assisted-by: Jay Satiro - Fixes #3689 - Closes #3690 - -- test1541: threaded connection sharing - - The threaded-shared-conn.c example turned into test case. Only works if - pthread was detected. - - An attempt to detect future regressions such as e3a53e3efb942a5 - - Closes #3687 - -Patrick Monnerat (17 Mar 2019) -- os400: alt-svc support. - - Although experimental, enable it in the platform config file. - Upgrade ILE/RPG binding. - -Daniel Stenberg (17 Mar 2019) -- conncache: use conn->data to know if a transfer owns it - - - make sure an already "owned" connection isn't returned unless - multiplexed. - - - clear ->data when returning the connection to the cache again - - Regression since 7.62.0 (probably in commit 1b76c38904f0) - - Bug: https://curl.haxx.se/mail/lib-2019-03/0064.html - - Closes #3686 - -- RELEASE-NOTES: synced - -- [Chris Young brought this change] - - configure: add --with-amissl - - AmiSSL is an Amiga native library which provides a wrapper over OpenSSL. - It also requires all programs using it to use bsdsocket.library - directly, rather than accessing socket functions through clib, which - libcurl was not necessarily doing previously. Configure will now check - for the headers and ensure they are included if found. - - Closes #3677 - -- [Chris Young brought this change] - - vtls: rename some of the SSL functions - - ... in the SSL structure as AmiSSL is using macros for the socket API - functions. - -- [Chris Young brought this change] - - tool_getpass: termios.h is present on AmigaOS 3, but no tcgetattr/tcsetattr - -- [Chris Young brought this change] - - tool_operate: build on AmigaOS - -- makefile: make checksrc and hugefile commands "silent" - - ... to match the style already used for compiling, linking - etc. Acknowledges 'make V=1' to enable verbose. - - Closes #3681 - -- curl.1: --user and --proxy-user are hidden from ps output - - Suggested-by: Eric Curtin - Improved-by: Dan Fandrich - Ref: #3680 - - Closes #3683 - -- curl.1: mark the argument to --cookie as <data|filename> - - From a discussion in #3676 - - Suggested-by: Tim Rühsen - - Closes #3682 - -Dan Fandrich (14 Mar 2019) -- fuzzer: Only clone the latest fuzzer code, for speed. - -Daniel Stenberg (14 Mar 2019) -- [Dominik Hölzl brought this change] - - Negotiate: fix for HTTP POST with Negotiate - - * Adjusted unit tests 2056, 2057 - * do not generally close connections with CURLAUTH_NEGOTIATE after every request - * moved negotiatedata from UrlState to connectdata - * Added stream rewind logic for CURLAUTH_NEGOTIATE - * introduced negotiatedata::GSS_AUTHDONE and negotiatedata::GSS_AUTHSUCC - * Consider authproblem state for CURLAUTH_NEGOTIATE - * Consider reuse_forbid for CURLAUTH_NEGOTIATE - * moved and adjusted negotiate authentication state handling from - output_auth_headers into Curl_output_negotiate - * Curl_output_negotiate: ensure auth done is always set - * Curl_output_negotiate: Set auth done also if result code is - GSS_S_CONTINUE_NEEDED/SEC_I_CONTINUE_NEEDED as this result code may - also indicate the last challenge request (only works with disabled - Expect: 100-continue and CURLOPT_KEEP_SENDING_ON_ERROR -> 1) - * Consider "Persistent-Auth" header, detect if not present; - Reset/Cleanup negotiate after authentication if no persistent - authentication - * apply changes introduced with #2546 for negotiate rewind logic - - Fixes #1261 - Closes #1975 - -- [Marc Schlatter brought this change] - - http: send payload when (proxy) authentication is done - - The check that prevents payload from sending in case of authentication - doesn't check properly if the authentication is done or not. - - They're cases where the proxy respond "200 OK" before sending - authentication challenge. This change takes care of that. - - Fixes #2431 - Closes #3669 - -- file: fix "Checking if unsigned variable 'readcount' is less than zero." - - Pointed out by codacy - - Closes #3672 - -- memdebug: log pointer before freeing its data - - Coverity warned for two potentional "Use after free" cases. Both are false - positives because the memory wasn't used, it was only the actual pointer - value that was logged. - - The fix still changes the order of execution to avoid the warnings. - - Coverity CID 1443033 and 1443034 - - Closes #3671 - -- RELEASE-NOTES: synced - -Marcel Raad (12 Mar 2019) -- travis: actually use updated compiler versions - - For the Linux builds, GCC 8 and 7 and clang 7 were installed, but the - new GCC versions were only used for the coverage build and for building - nghttp2, while the new clang version was not used at all. - - BoringSSL needs to use the default GCC as it respects CC, but not CXX, - so it would otherwise pass gcc 8 options to g++ 4.8 and fail. - - Also remove GCC 7, it's not needed anymore. - - Ref: https://docs.travis-ci.com/user/languages/c/#c11c11-and-beyond-and-toolchain-versioning - - Closes https://github.com/curl/curl/pull/3670 - -- travis: update clang to version 7 - - Closes https://github.com/curl/curl/pull/3670 - -Jay Satiro (11 Mar 2019) -- [Andre Guibert de Bruet brought this change] - - examples/externalsocket: add missing close socket calls - - .. and for Windows also call WSACleanup since we call WSAStartup. - - The example is to demonstrate handling the socket independently of - libcurl. In this case libcurl is not responsible for creating, opening - or closing the socket, it is handled by the application (our example). - - Fixes https://github.com/curl/curl/pull/3663 - -Daniel Stenberg (11 Mar 2019) -- multi: removed unused code for request retries - - This code was once used for the non multi-interface using code path, but - ever since easy_perform was turned into a wrapper around the multi - interface, this code path never runs. - - Closes #3666 - -Jay Satiro (11 Mar 2019) -- doh: inherit some SSL options from user's easy handle - - - Inherit SSL options for the doh handle but not SSL client certs, - SSL ALPN/NPN, SSL engine, SSL version, SSL issuer cert, - SSL pinned public key, SSL ciphers, SSL id cache setting, - SSL kerberos or SSL gss-api settings. - - - Fix inheritance of verbose setting. - - - Inherit NOSIGNAL. - - There is no way for the user to set options for the doh (DNS-over-HTTPS) - handles and instead we inherit some options from the user's easy handle. - - My thinking for the SSL options not inherited is they are most likely - not intended by the user for the DOH transfer. I did inherit insecure - because I think that should still be in control of the user. - - Prior to this change doh did not work for me because CAINFO was not - inherited. Also verbose was set always which AFAICT was a bug (#3660). - - Fixes https://github.com/curl/curl/issues/3660 - Closes https://github.com/curl/curl/pull/3661 - -Daniel Stenberg (9 Mar 2019) -- test331: verify set-cookie for dotless host name - - Reproduced bug #3649 - Closes #3659 - -- Revert "cookies: extend domain checks to non psl builds" - - This reverts commit 3773de378d48b06c09931e44dca4d274d0bfdce0. - - Regression shipped in 7.64.0 - Fixes #3649 - -- memdebug: make debug-specific functions use curl_dbg_ prefix - - To not "collide" or use up the regular curl_ name space. Also makes them - easier to detect in helper scripts. - - Closes #3656 - -- cmdline-opts/proxytunnel.d: the option tunnnels all protocols - - Clarify the language and simplify. - - Reported-by: Daniel Lublin - Closes #3658 - -- KNOWN_BUGS: Client cert (MTLS) issues with Schannel - - Closes #3145 - -- ROADMAP: updated to some more current things to work on - -- tests: fix multiple may be used uninitialized warnings - -- RELEASE-NOTES: synced - -- source: fix two 'nread' may be used uninitialized warnings - - Both seem to be false positives but we don't like warnings. - - Closes #3646 - -- gopher: remove check for path == NULL - - Since it can't be NULL and it makes Coverity believe we lack proper NULL - checks. Verified by test 659, landed in commit 15401fa886b. - - Pointed out by Coverity CID 1442746. - - Assisted-by: Dan Fandrich - Fixes #3617 - Closes #3642 - -- examples: only include <curl/curl.h> - - That's the only public curl header we should encourage use of. - - Reviewed-by: Marcel Raad - Closes #3645 - -- ssh: loop the state machine if not done and not blocking - - If the state machine isn't complete, didn't fail and it didn't return - due to blocking it can just as well loop again. - - This addresses the problem with SFTP directory listings where we would - otherwise return back to the parent and as the multi state machine - doesn't have any code for using CURLM_CALL_MULTI_PERFORM for as long the - doing phase isn't complete, it would return out when in reality there - was more data to deal with. - - Fixes #3506 - Closes #3644 - -Jay Satiro (5 Mar 2019) -- multi: support verbose conncache closure handle - - - Change closure handle to receive verbose setting from the easy handle - most recently added via curl_multi_add_handle. - - The closure handle is a special easy handle used for closing cached - connections. It receives limited settings from the easy handle most - recently added to the multi handle. Prior to this change that did not - include verbose which was a problem because on connection shutdown - verbose mode was not acknowledged. - - Ref: https://github.com/curl/curl/pull/3598 - - Co-authored-by: Daniel Stenberg - - Closes https://github.com/curl/curl/pull/3618 - -Daniel Stenberg (4 Mar 2019) -- CURLU: fix NULL dereference when used over proxy - - Test 659 verifies - - Also fixed the test 658 name - - Closes #3641 - -- altsvc_out: check the return code from Curl_gmtime - - Pointed out by Coverity, CID 1442956. - - Closes #3640 - -- docs/ALTSVC.md: docs describing the approach - - Closes #3498 - -- alt-svc: add a travis build - -- alt-svc: add test 355 and 356 to verify with command line curl - -- alt-svc: the curl command line bits - -- alt-svc: the libcurl bits - -- travis: add build using gnutls - - Closes #3637 - -- RELEASE-NOTES: synced - -- [Simon Legner brought this change] - - scripts/completion.pl: also generate fish completion file - - This is the renamed script formerly known as zsh.pl - - Closes #3545 - -- gnutls: remove call to deprecated gnutls_compression_get_name - - It has been deprecated by GnuTLS since a year ago and now causes build - warnings. - - Ref: https://gitlab.com/gnutls/gnutls/commit/b0041897d2846737f5fb0f - Docs: https://www.gnutls.org/manual/html_node/Compatibility-API.html - - Closes #3636 - -Jay Satiro (2 Mar 2019) -- system_win32: move win32_init here from easy.c - - .. since system_win32 is a more appropriate location for the functions - and to extern the globals. - - Ref: https://github.com/curl/curl/commit/ca597ad#r32446578 - Reported-by: Gisle Vanem - - Closes https://github.com/curl/curl/pull/3625 - -Daniel Stenberg (1 Mar 2019) -- curl_easy_duphandle.3: clarify that a duped handle has no shares - - Reported-by: Sara Golemon - - Fixes #3592 - Closes #3634 - -- 10-at-a-time.c: fix too long line - -- [Arnaud Rebillout brought this change] - - examples: various fixes in ephiperfifo.c - - The main change here is the timer value that was wrong, it was given in - usecs (ms * 1000), while the itimerspec struct wants nsecs (ms * 1000 * - 1000). This resulted in the callback being invoked WAY TOO OFTEN. - - As a quick check you can run this command before and after applying this - commit: - - # shell 1 - ./ephiperfifo 2>&1 | tee ephiperfifo.log - # shell 2 - echo http://hacking.elboulangero.com > hiper.fifo - - Then just compare the size of the logs files. - - Closes #3633 - Fixes #3632 - Signed-off-by: Arnaud Rebillout <arnaud.rebillout@collabora.com> - -- urldata: simplify bytecounters - - - no need to have them protocol specific - - - no need to set pointers to them with the Curl_setup_transfer() call - - - make Curl_setup_transfer() operate on a transfer pointer, not - connection - - - switch some counters from long to the more proper curl_off_t type - - Closes #3627 - -- examples/10-at-a-time.c: improve readability and simplify - - - use better variable names to explain their purposes - - convert logic to curl_multi_wait() - -- threaded-resolver: shutdown the resolver thread without error message - - When a transfer is done, the resolver thread will be brought down. That - could accidentally generate an error message in the error buffer even - though this is not an error situationand the transfer would still return - OK. An application that still reads the error buffer could find a - "Could not resolve host: [host name]" message there and get confused. - - Reported-by: Michael Schmid - Fixes #3629 - Closes #3630 - -- [Ԝеѕ brought this change] - - docs: update max-redirs.d phrasing - - clarify redir - "in absurdum" doesn't seem to make sense in this context - - Closes #3631 - -- ssh: fix Condition '!status' is always true - - in the same sftp_done function in both SSH backends. Simplify them - somewhat. - - Pointed out by Codacy. - - Closes #3628 - -- test578: make it read data from the correct test - -- Curl_easy: remove req.maxfd - never used! - - Introduced in 8b6314ccfb, but not used anymore in current code. Unclear - since when. - - Closes #3626 - -- http: set state.infilesize when sending formposts - - Without it set, we would unwillingly triger the "HTTP error before end - of send, stop sending" condition even if the entire POST body had been - sent (since it wouldn't know the expected size) which would - unnecessarily log that message and close the connection when it didn't - have to. - - Reported-by: Matt McClure - Bug: https://curl.haxx.se/mail/archive-2019-02/0023.html - Closes #3624 - -- INSTALL: refer to the current TLS library names and configure options - -- FAQ: minor updates and spelling fixes - -- GOVERNANCE.md: minor spelling fixes - -- Secure Transport: no more "darwinssl" - - Everyone calls it Secure Transport, now we do too. - - Reviewed-by: Nick Zitzmann - - Closes #3619 - -Marcel Raad (27 Feb 2019) -- AppVeyor: add classic MinGW build - - But use the MSYS2 shell rather than the default MSYS shell because of - POSIX path conversion issues. Classic MinGW is only available on the - Visual Studio 2015 image. - - Closes https://github.com/curl/curl/pull/3623 - -- AppVeyor: add MinGW-w64 build - - Add a MinGW-w64 build using CMake's MSYS Makefiles generator. - Use the Visual Studio 2015 image as it has GCC 8, while the - Visual Studio 2017 image only has GCC 7.2. - - Closes https://github.com/curl/curl/pull/3623 - -Daniel Stenberg (27 Feb 2019) -- cookies: only save the cookie file if the engine is enabled - - Follow-up to 8eddb8f4259. - - If the cookieinfo pointer is NULL there really is nothing to save. - - Without this fix, we got a problem when a handle was using shared object - with cookies and is told to "FLUSH" it to file (which worked) and then - the share object was removed and when the easy handle was closed just - afterwards it has no cookieinfo and no cookies so it decided to save an - empty jar (overwriting the file just flushed). - - Test 1905 now verifies that this works. - - Assisted-by: Michael Wallner - Assisted-by: Marcel Raad - - Closes #3621 - -- [DaVieS brought this change] - - cacertinmem.c: use multiple certificates for loading CA-chain - - Closes #3421 - -- urldata: convert bools to bitfields and move to end - - This allows the compiler to pack and align the structs better in - memory. For a rather feature-complete build on x86_64 Linux, gcc 8.1.2 - makes the Curl_easy struct 4.9% smaller. From 6312 bytes to 6000. - - Removed an unused struct field. - - No functionality changes. - - Closes #3610 - -- [Don J Olmstead brought this change] - - curl.h: use __has_declspec_attribute for shared builds - - Closes #3616 - -- curl: display --version features sorted alphabetically - - Closes #3611 - -- runtests: detect "schannel" as an alias for "winssl" - - Follow-up to 180501cb02 - - Reported-by: Marcel Raad - Fixes #3609 - Closes #3620 - -Marcel Raad (26 Feb 2019) -- AppVeyor: update to Visual Studio 2017 - - Switch all Visual Studio 2015 builds to Visual Studio 2017. It's not a - moving target anymore as the last update, Update 9, has been released. - - Closes https://github.com/curl/curl/pull/3606 - -- AppVeyor: switch VS 2015 builds to VS 2017 image - - The Visual Studio 2017 image has Visual Studio 2015 and 2017 installed. - - Closes https://github.com/curl/curl/pull/3606 - -- AppVeyor: explicitly select worker image - - Currently, we're using the default Visual Studio 2015 image for - everything. - - Closes https://github.com/curl/curl/pull/3606 - -Daniel Stenberg (26 Feb 2019) -- strerror: make the strerror function use local buffers - - Instead of using a fixed 256 byte buffer in the connectdata struct. - - In my build, this reduces the size of the connectdata struct by 11.8%, - from 2160 to 1904 bytes with no functionality or performance loss. - - This also fixes a bug in schannel's Curl_verify_certificate where it - called Curl_sspi_strerror when it should have called Curl_strerror for - string from GetLastError. the only effect would have been no text or the - wrong text being shown for the error. - - Co-authored-by: Jay Satiro - - Closes #3612 - -- [Michael Wallner brought this change] - - cookies: fix NULL dereference if flushing cookies with no CookieInfo set - - Regression brought by a52e46f3900fb0 (shipped in 7.63.0) - - Closes #3613 - -Marcel Raad (26 Feb 2019) -- AppVeyor: re-enable test 500 - - It's passing now. - - Closes https://github.com/curl/curl/pull/3615 - -- AppVeyor: remove redundant builds - - Remove the Visual Studio 2012 and 2013 builds as they add little value. - - Ref: https://github.com/curl/curl/pull/3606 - Closes https://github.com/curl/curl/pull/3614 - -Daniel Stenberg (25 Feb 2019) -- RELEASE-NOTES: synced - -- [Bernd Mueller brought this change] - - OpenSSL: add support for TLS ASYNC state - - Closes #3591 - -Jay Satiro (25 Feb 2019) -- [Michael Felt brought this change] - - acinclude: add additional libraries to check for LDAP support - - - Add an additional check for LDAP that also checks for OpenSSL since - on AIX those libraries may be required to link LDAP properly. - - Fixes https://github.com/curl/curl/issues/3595 - Closes https://github.com/curl/curl/pull/3596 - -- [Giorgos Oikonomou brought this change] - - schannel: support CALG_ECDH_EPHEM algorithm - - Add support for Ephemeral elliptic curve Diffie-Hellman key exchange - algorithm option when selecting ciphers. This became available on the - Win10 SDK. - - Closes https://github.com/curl/curl/pull/3608 - -Daniel Stenberg (24 Feb 2019) -- multi: call multi_done on connect timeouts - - Failing to do so would make the CURLINFO_TOTAL_TIME timeout to not get - updated correctly and could end up getting reported to the application - completely wrong (way too small). - - Reported-by: accountantM on github - Fixes #3602 - Closes #3605 - -- examples: remove recursive calls to curl_multi_socket_action - - From within the timer callbacks. Recursive is problematic for several - reasons. They should still work, but this way the examples and the - documentation becomes simpler. I don't think we need to encourage - recursive calls. - - Discussed in #3537 - Closes #3601 - -Marcel Raad (23 Feb 2019) -- configure: remove CURL_CHECK_FUNC_FDOPEN call - - The macro itself has been removed in commit - 11974ac859c5d82def59e837e0db56fef7f6794e. - - Closes https://github.com/curl/curl/pull/3604 - -Daniel Stenberg (23 Feb 2019) -- wolfssl: stop custom-adding curves - - since wolfSSL PR https://github.com/wolfSSL/wolfssl/pull/717 (shipped in - wolfSSL 3.10.2 and later) it sends these curves by default already. - - Pointed-out-by: David Garske - - Closes #3599 - -- configure: remove the unused fdopen macro - - and the two remaining #ifdefs for it - - Closes #3600 - -Jay Satiro (22 Feb 2019) -- url: change conn shutdown order to unlink data as last step - - - Split off connection shutdown procedure from Curl_disconnect into new - function conn_shutdown. - - - Change the shutdown procedure to close the sockets before - disassociating the transfer. - - Prior to this change the sockets were closed after disassociating the - transfer so SOCKETFUNCTION wasn't called since the transfer was already - disassociated. That likely came about from recent work started in - Jan 2019 (#3442) to separate transfers from connections. - - Bug: https://curl.haxx.se/mail/lib-2019-02/0101.html - Reported-by: Pavel Löbl - - Closes https://github.com/curl/curl/issues/3597 - Closes https://github.com/curl/curl/pull/3598 - -Marcel Raad (22 Feb 2019) -- Fix strict-prototypes GCC warning - - As seen in the MinGW autobuilds. Caused by commit - f26bc29cfec0be84c67cf74065cf8e5e78fd68b7. - -Dan Fandrich (21 Feb 2019) -- tests: Fixed XML validation errors in some test files. - -Daniel Stenberg (20 Feb 2019) -- TODO: Allow SAN names in HTTP/2 server push - - Suggested-by: Nicolas Grekas - -- RELEASE-NOTES: synced - -- curl: remove MANUAL from -M output - - ... and remove it from the dist tarball. It has served its time, it - barely gets updated anymore and "everything curl" is now convering all - this document once tried to include, and does it more and better. - - In the compressed scenario, this removes ~15K data from the binary, - which is 25% of the -M output. - - It remains in the git repo for now for as long as the web site builds a - page using that as source. It renders poorly on the site (especially for - mobile users) so its not even good there. - - Closes #3587 - -- http2: verify :athority in push promise requests - - RFC 7540 says we should verify that the push is for an "authoritative" - server. We make sure of this by only allowing push with an :athority - header that matches the host that was asked for in the URL. - - Fixes #3577 - Reported-by: Nicolas Grekas - Bug: https://curl.haxx.se/mail/lib-2019-02/0057.html - Closes #3581 - -- singlesocket: fix the 'sincebefore' placement - - The variable wasn't properly reset within the loop and thus could remain - set for sockets that hadn't been set before and miss notifying the app. - - This is a follow-up to 4c35574 (shipped in curl 7.64.0) - - Reported-by: buzo-ffm on github - Detected-by: Jan Alexander Steffens - Fixes #3585 - Closes #3589 - -- connection: never reuse CONNECT_ONLY conections - - and make CONNECT_ONLY conections never reuse any existing ones either. - - Reported-by: Pavel Löbl - Bug: https://curl.haxx.se/mail/lib-2019-02/0064.html - Closes #3586 - -Patrick Monnerat (19 Feb 2019) -- cli tool: fix mime post with --disable-libcurl-option configure option - - Reported-by: Marcel Raad - Fixes #3576 - Closes #3583 - -Daniel Stenberg (19 Feb 2019) -- x509asn1: cleanup and unify code layout - - - rename 'n' to buflen in functions, and use size_t for them. Don't pass - in negative buffer lengths. - - - move most function comments to above the function starts like we use - to - - - remove several unnecessary typecasts (especially of NULL) - - Reviewed-by: Patrick Monnerat - Closes #3582 - -- curl_multi_remove_handle.3: use at any time, just not from within callbacks - - [ci skip] - -- http: make adding a blank header thread-safe - - Previously the function would edit the provided header in-place when a - semicolon is used to signify an empty header. This made it impossible to - use the same set of custom headers in multiple threads simultaneously. - - This approach now makes a local copy when it needs to edit the string. - - Reported-by: d912e3 on github - Fixes #3578 - Closes #3579 - -- unit1651: survive curl_easy_init() fails - -- [Frank Gevaerts brought this change] - - rand: Fix a mismatch between comments in source and header. - - Reported-by: Björn Stenberg <bjorn@haxx.se> - Closes #3584 - -Patrick Monnerat (18 Feb 2019) -- x509asn1: replace single char with an array - - Although safe in this context, using a single char as an array may - cause invalid accesses to adjacent memory locations. - - Detected by Coverity. - -Daniel Stenberg (18 Feb 2019) -- examples/http2-serverpush: add some sensible error checks - - To avoid NULL pointer dereferences etc in the case of problems. - - Closes #3580 - -Jay Satiro (18 Feb 2019) -- easy: fix win32 init to work without CURL_GLOBAL_WIN32 - - - Change the behavior of win32_init so that the required initialization - procedures are not affected by CURL_GLOBAL_WIN32 flag. - - libcurl via curl_global_init supports initializing for win32 with an - optional flag CURL_GLOBAL_WIN32, which if omitted was meant to stop - Winsock initialization. It did so internally by skipping win32_init() - when that flag was set. Since then win32_init() has been expanded to - include required initialization routines that are separate from - Winsock and therefore must be called in all cases. This commit fixes - it so that CURL_GLOBAL_WIN32 only controls the optional win32 - initialization (which is Winsock initialization, according to our doc). - - The only users affected by this change are those that don't pass - CURL_GLOBAL_WIN32 to curl_global_init. For them this commit removes the - risk of a potential crash. - - Ref: https://github.com/curl/curl/pull/3573 - - Fixes https://github.com/curl/curl/issues/3313 - Closes https://github.com/curl/curl/pull/3575 - -Daniel Gustafsson (17 Feb 2019) -- cookie: Add support for cookie prefixes - - The draft-ietf-httpbis-rfc6265bis-02 draft, specify a set of prefixes - and how they should affect cookie initialization, which has been - adopted by the major browsers. This adds support for the two prefixes - defined, __Host- and __Secure, and updates the testcase with the - supplied examples from the draft. - - Closes #3554 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - -- mbedtls: release sessionid resources on error - - If mbedtls_ssl_get_session() fails, it may still have allocated - memory that needs to be freed to avoid leaking. Call the library - API function to release session resources on this errorpath as - well as on Curl_ssl_addsessionid() errors. - - Closes: #3574 - Reported-by: Michał Antoniak <M.Antoniak@posnet.com> - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - -Patrick Monnerat (16 Feb 2019) -- cli tool: refactor encoding conversion sequence for switch case fallthrough. - -- version.c: silent scan-build even when librtmp is not enabled - -Daniel Stenberg (15 Feb 2019) -- RELEASE-NOTES: synced - -- Curl_now: figure out windows version in win32_init - - ... and avoid use of static variables that aren't thread safe. - - Fixes regression from e9ababd4f5a (present in the 7.64.0 release) - - Reported-by: Paul Groke - Fixes #3572 - Closes #3573 - -Marcel Raad (15 Feb 2019) -- unit1307: just fail without FTP support - - I missed to check this in with commit - 71786c0505926aaf7e9b2477b2fb7ee16a915ec6, which only disabled the test. - This fixes the actual linker error. - - Closes https://github.com/curl/curl/pull/3568 - -Daniel Stenberg (15 Feb 2019) -- travis: enable valgrind for the iconv tests too - - Closes #3571 - -- travis: add scan-build - - Closes #3564 - -- examples/sftpuploadresume: Value stored to 'result' is never read - - Detected by scan-build - -- examples/http2-upload: cleaned up - - Fix scan-build warnings, no globals, no silly handle scan. Also remove - handles from the multi before cleaning up. - -- examples/http2-download: cleaned up - - To avoid scan-build warnings and global variables. - -- examples/postinmemory: Potential leak of memory pointed to by 'chunk.memory' - - Detected by scan-build - -- examples/httpcustomheader: Value stored to 'res' is never read - - Detected by scan-build - -- examples: remove superfluous null-pointer checks - - in ftpget, ftpsget and sftpget, so that scan-build stops warning for - potential NULL pointer dereference below! - - Detected by scan-build - -- strip_trailing_dot: make sure NULL is never used for strlen - - scan-build warning: Null pointer passed as an argument to a 'nonnull' - parameter - -- [Jay Satiro brought this change] - - connection_check: restore original conn->data after the check - - - Save the original conn->data before it's changed to the specified - data transfer for the connection check and then restore it afterwards. - - This is a follow-up to 38d8e1b 2019-02-11. - - History: - - It was discovered a month ago that before checking whether to extract a - dead connection that that connection should be associated with a "live" - transfer for the check (ie original conn->data ignored and set to the - passed in data). A fix was landed in 54b201b which did that and also - cleared conn->data after the check. The original conn->data was not - restored, so presumably it was thought that a valid conn->data was no - longer needed. - - Several days later it was discovered that a valid conn->data was needed - after the check and follow-up fix was landed in bbae24c which partially - reverted the original fix and attempted to limit the scope of when - conn->data was changed to only when pruning dead connections. In that - case conn->data was not cleared and the original conn->data not - restored. - - A month later it was discovered that the original fix was somewhat - correct; a "live" transfer is needed for the check in all cases - because original conn->data could be null which could cause a bad deref - at arbitrary points in the check. A fix was landed in 38d8e1b which - expanded the scope to all cases. conn->data was not cleared and the - original conn->data not restored. - - A day later it was discovered that not restoring the original conn->data - may lead to busy loops in applications that use the event interface, and - given this observation it's a pretty safe assumption that there is some - code path that still needs the original conn->data. This commit is the - follow-up fix for that, it restores the original conn->data after the - connection check. - - Assisted-by: tholin@users.noreply.github.com - Reported-by: tholin@users.noreply.github.com - - Fixes https://github.com/curl/curl/issues/3542 - Closes #3559 - -- memdebug: bring back curl_mark_sclose - - Used by debug builds with NSS. - - Reverted from 05b100aee247bb - -Patrick Monnerat (14 Feb 2019) -- transfer.c: do not compute length of undefined hex buffer. - - On non-ascii platforms, the chunked hex header was measured for char code - conversion length, even for chunked trailers that do not have an hex header. - In addition, the efective length is already known: use it. - Since the hex length can be zero, only convert if needed. - - Reported by valgrind. - -Daniel Stenberg (14 Feb 2019) -- KNOWN_BUGS: Cannot compile against a static build of OpenLDAP - - Closes #2367 - -Patrick Monnerat (14 Feb 2019) -- x509asn1: "Dereference of null pointer" - - Detected by scan-build (false positive). - -Daniel Stenberg (14 Feb 2019) -- configure: show features as well in the final summary - - Closes #3569 - -- KNOWN_BUGS: curl compiled on OSX 10.13 failed to run on OSX 10.10 - - Closes #2905 - -- KNOWN_BUGS: Deflate error after all content was received - - Closes #2719 - -- gssapi: fix deprecated header warnings - - Heimdal includes on FreeBSD spewed out lots of them. Less so now. - - Closes #3566 - -- TODO: Upgrade to websockets - - Closes #3523 - -- TODO: cmake test suite improvements - - Closes #3109 - -Patrick Monnerat (13 Feb 2019) -- curl: "Dereference of null pointer" - - Rephrase to satisfy scan-build. - -Marcel Raad (13 Feb 2019) -- unit1307: require FTP support - - This test doesn't link without FTP support after - fc7ab4835b5fd09d0a6f57000633bb6bb6edfda1, which made Curl_fnmatch - unavailable without FTP support. - - Closes https://github.com/curl/curl/pull/3565 - -Daniel Stenberg (13 Feb 2019) -- TODO: TFO support on Windows - - Nobody works on this now. - - Closes #3378 - -- multi: Dereference of null pointer - - Mostly a false positive, but this makes the code easier to read anyway. - - Detected by scan-build. - - Closes #3563 - -- urlglob: Argument with 'nonnull' attribute passed null - - Detected by scan-build. - -Jay Satiro (12 Feb 2019) -- schannel: restore some debug output but only for debug builds - - Follow-up to 84c10dc from earlier today which wrapped a lot of the noisy - debug output in DEBUGF but omitted a few lines. - - Ref: https://github.com/curl/curl/commit/84c10dc#r32292900 - -- examples/crawler: Fix the Accept-Encoding setting - - - Pass an empty string to CURLOPT_ACCEPT_ENCODING to use the default - supported encodings. - - Prior to this change the specific encodings of gzip and deflate were set - but there's no guarantee they'd be supported by the user's libcurl. - -Daniel Stenberg (12 Feb 2019) -- mime: put the boundary buffer into the curl_mime struct - - ... instead of allocating it separately and point to it. It is - fixed-size and always used for each part. - - Closes #3561 - -- schannel: be quiet - - Convert numerous infof() calls into debug-build only messages since they - are annoyingly verbose for regular applications. Removed a few. - - Bug: https://curl.haxx.se/mail/lib-2019-02/0027.html - Reported-by: Volker Schmid - Closes #3552 - -- [Romain Geissler brought this change] - - Curl_resolv: fix a gcc -Werror=maybe-uninitialized warning - - Closes #3562 - -- http2: multi_connchanged() moved from multi.c, only used for h2 - - Closes #3557 - -- curl: "Function call argument is an uninitialized value" - - Follow-up to cac0e4a6ad14b42471eb - - Detected by scan-build - Closes #3560 - -- pretransfer: don't strlen() POSTFIELDS set for GET requests - - ... since that data won't be used in the request anyway. - - Fixes #3548 - Reported-by: Renaud Allard - Close #3549 - -- multi: remove verbose "Expire in" ... messages - - Reported-by: James Brown - Bug: https://curl.haxx.se/mail/archive-2019-02/0013.html - Closes #3558 - -- mbedtls: make it build even if MBEDTLS_VERSION_C isn't set - - Reported-by: MAntoniak on github - Fixes #3553 - Closes #3556 - -Daniel Gustafsson (12 Feb 2019) -- non-ascii.c: fix typos in comments - - Fix two occurrences of s/convers/converts/ spotted while reading code. - -Daniel Stenberg (12 Feb 2019) -- fnmatch: disable if FTP is disabled - - Closes #3551 - -- curl_path: only enabled for SSH builds - -- [Frank Gevaerts brought this change] - - tests: add stderr comparison to the test suite - - The code is more or less copied from the stdout comparison code, maybe - some better reuse is possible. - - test 1457 is adjusted to make the output actually match (by using --silent) - test 506 used <stderr> without actually needing it, so that <stderr> block is removed - - Closes #3536 - -Patrick Monnerat (11 Feb 2019) -- cli tool: do not use mime.h private structures. - - Option -F generates an intermediate representation of the mime structure - that is used later to create the libcurl mime structure and generate - the --libcurl statements. - - Reported-by: Daniel Stenberg - Fixes #3532 - Closes #3546 - -Daniel Stenberg (11 Feb 2019) -- curlver: bump to 7.64.1-dev - -- RELEASE-NOTES: synced - - and bump the version in progress to 7.64.1. If we merge any "change" - before the cut-off date, we update again. - -Daniel Gustafsson (11 Feb 2019) -- curl: follow-up to 3f16990ec84 - - Commit 3f16990ec84cc4b followed-up a bug in b49652ac66cc0 but was - inadvertently introducing a new bug in the ternary expression. - - Close #3555 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - -- dns: release sharelock as soon as possible - - There is no benefit to holding the data sharelock when freeing the - addrinfo in case it fails, so ensure releaseing it as soon as we can - rather than holding on to it. This also aligns the code with other - consumers of sharelocks. - - Closes #3516 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - -Daniel Stenberg (11 Feb 2019) -- curl: follow-up to b49652ac66cc0 - - On FreeBSD, return non-zero on error otherwise zero. - - Reported-by: Marcel Raad - -- multi: (void)-prefix when ignoring return values - - ... and added braces to two function calls which fixes warnings if they - are replace by empty macros at build-time. - -- curl: fix FreeBSD compiler warning in the --xattr code - - Closes #3550 - -- connection_check: set ->data to the transfer doing the check - - The http2 code for connection checking needs a transfer to use. Make - sure a working one is set before handler->connection_check() is called. - - Reported-by: jnbr on github - Fixes #3541 - Closes #3547 - -- hostip: make create_hostcache_id avoid alloc + free - - Closes #3544 - -- scripts/singleuse: script to use to track single-use functions - - That is functions that are declared global but are not used from outside - of the file in which it is declared. Such functions should be made - static or even at times be removed. - - It also verifies that all used curl_ prefixed functions are "blessed" - - Closes #3538 - -- cleanup: make local functions static - - urlapi: turn three local-only functions into statics - - conncache: make conncache_find_first_connection static - - multi: make detach_connnection static - - connect: make getaddressinfo static - - curl_ntlm_core: make hmac_md5 static - - http2: make two functions static - - http: make http_setup_conn static - - connect: make tcpnodelay static - - tests: make UNITTEST a thing to mark functions with, so they can be static for - normal builds and non-static for unit test builds - - ... and mark Curl_shuffle_addr accordingly. - - url: make up_free static - - setopt: make vsetopt static - - curl_endian: make write32_le static - - rtsp: make rtsp_connisdead static - - warnless: remove unused functions - - memdebug: remove one unused function, made another static - -Dan Fandrich (10 Feb 2019) -- cirrus: Added FreeBSD builds using Cirrus CI. - - The build logs will be at https://cirrus-ci.com/github/curl/curl - - Some tests are currently failing and so disabled for now. The SSH server - isn't starting for the SSH tests due to unsupported options used in its - config file. The DICT server also is failing on startup. - -Daniel Stenberg (9 Feb 2019) -- url/idnconvert: remove scan for <= 32 ascii values - - The check was added back in fa939220df before the URL parser would catch - these problems and therefore these will never trigger now. - - Closes #3539 - -- urlapi: reduce variable scope, remove unreachable 'break' - - Both nits pointed out by codacy.com - - Closes #3540 - -Alessandro Ghedini (7 Feb 2019) -- zsh.pl: escape ':' character - - ':' is interpreted as separator by zsh, so if used as part of the argument - or option's description it needs to be escaped. - - The problem can be reproduced as follows: - - % curl --reso<TAB> - % curl -E <TAB> - - Bug: https://bugs.debian.org/921452 diff --git a/libs/libcurl/docs/COPYING b/libs/libcurl/docs/COPYING index 3528bd7566..9d9e4af8d8 100644 --- a/libs/libcurl/docs/COPYING +++ b/libs/libcurl/docs/COPYING @@ -1,6 +1,6 @@ COPYRIGHT AND PERMISSION NOTICE -Copyright (c) 1996 - 2019, Daniel Stenberg, <daniel@haxx.se>, and many +Copyright (c) 1996 - 2020, Daniel Stenberg, <daniel@haxx.se>, and many contributors, see the THANKS file. All rights reserved. diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS index 884906ae26..af74c0bd6a 100644 --- a/libs/libcurl/docs/THANKS +++ b/libs/libcurl/docs/THANKS @@ -7,6 +7,7 @@ "Captain Basil" "Spoon Man" 1ocalhost on github +3dyd on github Aaro Koskinen Aaron Oneal Aaron Orenstein @@ -96,11 +97,13 @@ Anders Bakken Anders Gustafsson Anders Havn Anders Roxell +Anderson Sasaki Anderson Toshiyuki Sasaki Andi Jahja Andre Guibert de Bruet Andre Heinecke Andreas Damm +Andreas Falkenhahn Andreas Farber Andreas Kostyrka Andreas Malzahn @@ -126,6 +129,7 @@ Andrew Biggs Andrew Bushnell Andrew Francis Andrew Fuller +Andrew Ishchuk Andrew Krieger Andrew Kurushin Andrew Lambert @@ -221,6 +225,7 @@ Bill Middlecamp Bill Nagel Bill Pyne Bjarni Ingi Gislason +Bjoern Franke Bjoern Sikora Bjorn Augustsson Bjorn Reese @@ -318,6 +323,7 @@ Christopher Conroy Christopher Head Christopher Palow Christopher R. Palmer +Christopher Reid Christopher Stone Chungtsun Li Ciprian Badescu @@ -347,6 +353,7 @@ Craig de Stigter Cris Bailiff Cristian Rodríguez Curt Bogmine +Cynthia Coan Cyril B Cyrill Osterwalder Cédric Connes @@ -792,6 +799,7 @@ Jan Kunder Jan Schaumann Jan Schmidt Jan Van Boghout +JanB on github Janne Johansson Jared Jennings Jared Lundell @@ -826,6 +834,7 @@ Jeff Hodges Jeff Johnson Jeff King Jeff Lawson +Jeff Mears Jeff Phillips Jeff Pohlmeyer Jeff Weber @@ -901,6 +910,7 @@ John Marino John Marshall John McGowan John P. McCaskey +John Schroeder John Starks John Suprock John V. Chow @@ -1165,6 +1175,7 @@ Markus Koetter Markus Moeller Markus Oberhumer Markus Westerlind +Maros Priputen Marquis de Muesli Martijn Koster Martin Ankerl @@ -1186,6 +1197,7 @@ Martin Storsjö Martin Vejnár Marty Kuhrt Maruko +Massimiliano Fantuzzi Massimiliano Ziccardi Massimo Callegari Mateusz Loskot @@ -1215,6 +1227,7 @@ Mauro Iorio Mauro Rappa Max Dymond Max Katsev +Max Kellermann Max Khon Max Savenkov Maxim Ivanov @@ -1235,6 +1248,7 @@ Michael Cronenworth Michael Curtis Michael Day Michael Felt +Michael Forney Michael Gmelin Michael Goffioul Michael Jahn @@ -1254,6 +1268,7 @@ Michael Smith Michael Stapelberg Michael Steuer Michael Stillwell +Michael Vittiglio Michael Wallner Michal Bonino Michal Marek @@ -1293,6 +1308,7 @@ Miroslav Spousta Mitz Wark Mohamed Lrhazi Mohammad AlSaleh +Mohammad Hasbini Mohun Biswas Mostyn Bramley-Moore Moti Avrahami @@ -1401,6 +1417,7 @@ Paul Dreik Paul Groke Paul Harrington Paul Harris +Paul Hoffman Paul Howarth Paul Joyce Paul Marks @@ -1410,6 +1427,7 @@ Paul Nolan Paul Oliver Paul Querna Paul Saab +Paulo Roberto Tomasi Pavel Cenek Pavel Gushchin Pavel Löbl @@ -1504,6 +1522,7 @@ Rajkumar Mandal Ralf S. Engelschall Ralph Beckmann Ralph Mitchell +Ram Krushna Mishra Ran Mozes Randall S. Becker Randy Armstrong @@ -1541,6 +1560,7 @@ Richard Adams Richard Alcock Richard Archer Richard Atterer +Richard Bowker Richard Bramante Richard Clayton Richard Cooper @@ -1558,6 +1578,7 @@ Rick Deist Rick Jones Rick Richardson Rick Welykochy +Rickard Hallerbäck Ricki Hirner Ricky Leverence Ricky-Tigg on github @@ -1626,6 +1647,7 @@ Ryuichi KAWAMATA Rémy Léone S. Moonesamy SBKarr on github +SLDiggie on github Salah-Eddin Shaban Salvador Dávila Salvatore Sorrentino @@ -1641,6 +1663,7 @@ Samuel Thibault Sander Gates Sandor Feldi Santhana Todatry +Santino Keupp Saqib Ali Sara Golemon Saran Neti @@ -1677,6 +1700,7 @@ Seth Mos Sevan Janiyan Sh Diao Shachaf Ben-Kiki +Shailesh Kapse Shankar Jadhavar Shao Shuchao Sharad Gupta @@ -1883,6 +1907,7 @@ Vasy Okhin Venkat Akella Venkataramana Mokkapati Vicente Garcia +Victor Magierski Victor Snezhko Vijay Panghal Vikram Saxena @@ -1901,6 +1926,7 @@ Vlad Ureche Vladimir Grishchenko Vladimir Kotal Vladimir Lazarenko +Vlastimil Ovčáčík Vojtech Janota Vojtech Minarik Vojtěch Král @@ -1930,7 +1956,9 @@ Wu Yongzheng Wyatt O'Day Xavier Bouchoux XhstormR on github +Xiang Xiao Xiangbin Li +Xiaoyin Liu XmiliaH on github Yaakov Selkowitz Yang Tse @@ -1971,9 +1999,11 @@ anshnd on github arainchik on github asavah on github baumanj on github +bdry on github bobmitchell1956 on github bsammon on github buzo-ffm on github +bxac on github cbartl on github cclauss on github clbr on github @@ -2007,6 +2037,7 @@ jungle-boogie on github jveazey on github jzinn on github ka7 on github +kouzhudong on github kreshano on github l00p3r on Hackerone lijian996 on github @@ -2037,6 +2068,7 @@ patelvivekv1993 on github patnyb on github pendrek at hackerone pszemus on github +sayrer on github silveja1 on github smuellerDD on github sstruchtrup on github diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h index dcbe8995cb..a9754fd648 100644 --- a/libs/libcurl/include/curl/curl.h +++ b/libs/libcurl/include/curl/curl.h @@ -154,7 +154,8 @@ typedef enum { CURLSSLBACKEND_SECURETRANSPORT = 9, CURLSSLBACKEND_AXTLS = 10, /* never used since 7.63.0 */ CURLSSLBACKEND_MBEDTLS = 11, - CURLSSLBACKEND_MESALINK = 12 + CURLSSLBACKEND_MESALINK = 12, + CURLSSLBACKEND_BEARSSL = 13 } curl_sslbackend; /* aliases for library clones and renames */ @@ -209,6 +210,11 @@ struct curl_httppost { set. Added in 7.46.0 */ }; + +/* This is a return code for the progress callback that, when returned, will + signal libcurl to continue executing the default progress function */ +#define CURL_PROGRESSFUNC_CONTINUE 0x10000001 + /* This is the CURLOPT_PROGRESSFUNCTION callback prototype. It is now considered deprecated but was the only choice up until 7.31.0 */ typedef int (*curl_progress_callback)(void *clientp, @@ -602,6 +608,7 @@ typedef enum { inside a callback */ CURLE_AUTH_ERROR, /* 94 - an authentication function returned an error */ + CURLE_HTTP3, /* 95 - An HTTP/3 layer problem */ CURL_LAST /* never use! */ } CURLcode; @@ -821,6 +828,10 @@ typedef enum { SSL backends where such behavior is present. */ #define CURLSSLOPT_NO_REVOKE (1<<1) +/* - NO_PARTIALCHAIN tells libcurl to *NOT* accept a partial certificate chain + if possible. The OpenSSL backend has this ability. */ +#define CURLSSLOPT_NO_PARTIALCHAIN (1<<2) + /* The default connection attempt delay in milliseconds for happy eyeballs. CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.3 and happy-eyeballs-timeout-ms.d document this value, keep them in sync. */ @@ -945,6 +956,8 @@ typedef enum { /* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ #define LONG CURLOPTTYPE_LONG #define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define SLISTPOINT CURLOPTTYPE_OBJECTPOINT #define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT #define OFF_T CURLOPTTYPE_OFF_T #define CINIT(name,type,number) CURLOPT_/**/name = type + number diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h index cab09eebda..85b93553ca 100644 --- a/libs/libcurl/include/curl/curlver.h +++ b/libs/libcurl/include/curl/curlver.h @@ -30,12 +30,12 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.67.0" +#define LIBCURL_VERSION "7.68.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 67 +#define LIBCURL_VERSION_MINOR 68 #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 0x074300 +#define LIBCURL_VERSION_NUM 0x074400 /* * This is the date and time when the full source package was created. The @@ -68,7 +68,7 @@ * * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "2019-11-06" +#define LIBCURL_TIMESTAMP "2020-01-08" #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/include/curl/multi.h b/libs/libcurl/include/curl/multi.h index b392183954..04996ffcaf 100644 --- a/libs/libcurl/include/curl/multi.h +++ b/libs/libcurl/include/curl/multi.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -72,6 +72,7 @@ typedef enum { attempted to get added - again */ CURLM_RECURSIVE_API_CALL, /* an api function was called from inside a callback */ + CURLM_WAKEUP_FAILURE, /* wakeup is unavailable or failed */ CURLM_LAST } CURLMcode; @@ -187,6 +188,15 @@ CURL_EXTERN CURLMcode curl_multi_poll(CURLM *multi_handle, int timeout_ms, int *ret); +/* + * Name: curl_multi_wakeup() + * + * Desc: wakes up a sleeping curl_multi_poll call. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wakeup(CURLM *multi_handle); + /* * Name: curl_multi_perform() * @@ -451,9 +461,6 @@ typedef int (*curl_push_callback)(CURL *parent, struct curl_pushheaders *headers, void *userp); -/* value for MAXIMUM CONCURRENT STREAMS upper limit */ -#define INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1) - #ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/libs/libcurl/include/curl/system.h b/libs/libcurl/include/curl/system.h index cd37c2bf54..867af61418 100644 --- a/libs/libcurl/include/curl/system.h +++ b/libs/libcurl/include/curl/system.h @@ -137,15 +137,26 @@ # define CURL_TYPEOF_CURL_SOCKLEN_T int #elif defined(__LCC__) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int +# if defined(__e2k__) /* MCST eLbrus C Compiler */ +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# else /* Local (or Little) C Compiler */ +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# endif #elif defined(__SYMBIAN32__) -# if defined(__EABI__) /* Treat all ARM compilers equally */ +# if defined(__EABI__) /* Treat all ARM compilers equally */ # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -288,7 +299,6 @@ # define CURL_TYPEOF_CURL_SOCKLEN_T int #elif defined(__TINYC__) /* also known as tcc */ - # define CURL_TYPEOF_CURL_OFF_T long long # define CURL_FORMAT_CURL_OFF_T "lld" # define CURL_FORMAT_CURL_OFF_TU "llu" @@ -377,6 +387,7 @@ # define CURL_SUFFIX_CURL_OFF_TU ULL # elif defined(__LP64__) || \ defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \ + defined(__e2k__) || \ (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8) || \ (defined(__LONG_MAX__) && __LONG_MAX__ == 9223372036854775807L) # define CURL_TYPEOF_CURL_OFF_T long diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt index eca9a8af93..a9c90b6650 100644 --- a/libs/libcurl/src/CMakeLists.txt +++ b/libs/libcurl/src/CMakeLists.txt @@ -20,7 +20,6 @@ list(APPEND HHEADERS if(MSVC) list(APPEND CSOURCES libcurl.rc) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4127") endif() # SET(CSOURCES diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in index 27101a8eea..9259841744 100644 --- a/libs/libcurl/src/Makefile.in +++ b/libs/libcurl/src/Makefile.in @@ -245,14 +245,15 @@ am__objects_3 = vtls/libcurl_la-openssl.lo vtls/libcurl_la-gtls.lo \ vtls/libcurl_la-wolfssl.lo vtls/libcurl_la-schannel.lo \ vtls/libcurl_la-schannel_verify.lo \ vtls/libcurl_la-sectransp.lo vtls/libcurl_la-gskit.lo \ - vtls/libcurl_la-mbedtls.lo vtls/libcurl_la-mesalink.lo + vtls/libcurl_la-mbedtls.lo vtls/libcurl_la-mesalink.lo \ + vtls/libcurl_la-bearssl.lo am__objects_4 = vquic/libcurl_la-ngtcp2.lo vquic/libcurl_la-quiche.lo am__objects_5 = vssh/libcurl_la-libssh2.lo vssh/libcurl_la-libssh.lo am__objects_6 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) am__objects_7 = am__objects_8 = $(am__objects_7) $(am__objects_7) $(am__objects_7) \ - $(am__objects_7) + $(am__objects_7) $(am__objects_7) am_libcurl_la_OBJECTS = $(am__objects_6) $(am__objects_8) libcurl_la_OBJECTS = $(am_libcurl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -332,7 +333,8 @@ am__objects_11 = vtls/libcurlu_la-openssl.lo vtls/libcurlu_la-gtls.lo \ vtls/libcurlu_la-wolfssl.lo vtls/libcurlu_la-schannel.lo \ vtls/libcurlu_la-schannel_verify.lo \ vtls/libcurlu_la-sectransp.lo vtls/libcurlu_la-gskit.lo \ - vtls/libcurlu_la-mbedtls.lo vtls/libcurlu_la-mesalink.lo + vtls/libcurlu_la-mbedtls.lo vtls/libcurlu_la-mesalink.lo \ + vtls/libcurlu_la-bearssl.lo am__objects_12 = vquic/libcurlu_la-ngtcp2.lo \ vquic/libcurlu_la-quiche.lo am__objects_13 = vssh/libcurlu_la-libssh2.lo \ @@ -610,6 +612,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ vssh/$(DEPDIR)/libcurl_la-libssh2.Plo \ vssh/$(DEPDIR)/libcurlu_la-libssh.Plo \ vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo \ + vtls/$(DEPDIR)/libcurl_la-bearssl.Plo \ vtls/$(DEPDIR)/libcurl_la-gskit.Plo \ vtls/$(DEPDIR)/libcurl_la-gtls.Plo \ vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo \ @@ -623,6 +626,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ vtls/$(DEPDIR)/libcurl_la-sectransp.Plo \ vtls/$(DEPDIR)/libcurl_la-vtls.Plo \ vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo \ + vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo \ vtls/$(DEPDIR)/libcurlu_la-gskit.Plo \ vtls/$(DEPDIR)/libcurlu_la-gtls.Plo \ vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo \ @@ -815,6 +819,7 @@ STRIP = @STRIP@ SUPPORT_FEATURES = @SUPPORT_FEATURES@ SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ USE_ARES = @USE_ARES@ +USE_BEARSSL = @USE_BEARSSL@ USE_GNUTLS = @USE_GNUTLS@ USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@ USE_LIBRTMP = @USE_LIBRTMP@ @@ -975,16 +980,18 @@ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ vtls/polarssl.c vtls/polarssl_threadlock.c \ vtls/wolfssl.c vtls/schannel.c vtls/schannel_verify.c \ - vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c + vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c \ + vtls/bearssl.c LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \ vtls/wolfssl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \ - vtls/mbedtls.h vtls/mesalink.h + vtls/mbedtls.h vtls/mesalink.h vtls/bearssl.h LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c +LIB_VSSH_HFILES = vssh/ssh.h LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \ ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \ @@ -1014,7 +1021,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \ inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \ easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \ - socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \ + socks.h curl_base64.h curl_addrinfo.h curl_sspi.h \ slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \ rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \ curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \ @@ -1031,7 +1038,7 @@ CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \ $(LIB_VQUIC_CFILES) $(LIB_VSSH_CFILES) HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) \ - $(LIB_VQUIC_HFILES) + $(LIB_VQUIC_HFILES) $(LIB_VSSH_HFILES) # Makefile.inc provides the CSOURCES and HHEADERS defines @@ -1205,6 +1212,8 @@ vtls/libcurl_la-mbedtls.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurl_la-mesalink.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurl_la-bearssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) vquic/$(am__dirstamp): @$(MKDIR_P) vquic @: > vquic/$(am__dirstamp) @@ -1278,6 +1287,8 @@ vtls/libcurlu_la-mbedtls.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) vtls/libcurlu_la-mesalink.lo: vtls/$(am__dirstamp) \ vtls/$(DEPDIR)/$(am__dirstamp) +vtls/libcurlu_la-bearssl.lo: vtls/$(am__dirstamp) \ + vtls/$(DEPDIR)/$(am__dirstamp) vquic/libcurlu_la-ngtcp2.lo: vquic/$(am__dirstamp) \ vquic/$(DEPDIR)/$(am__dirstamp) vquic/libcurlu_la-quiche.lo: vquic/$(am__dirstamp) \ @@ -1558,6 +1569,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurl_la-libssh2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurlu_la-libssh.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-bearssl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gskit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-gtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo@am__quote@ # am--include-marker @@ -1571,6 +1583,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-sectransp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-vtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gskit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-gtls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo@am__quote@ # am--include-marker @@ -2567,6 +2580,13 @@ vtls/libcurl_la-mesalink.lo: vtls/mesalink.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-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c +vtls/libcurl_la-bearssl.lo: vtls/bearssl.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-bearssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurl_la-bearssl.Tpo -c -o vtls/libcurl_la-bearssl.lo `test -f 'vtls/bearssl.c' || echo '$(srcdir)/'`vtls/bearssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurl_la-bearssl.Tpo vtls/$(DEPDIR)/libcurl_la-bearssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/bearssl.c' object='vtls/libcurl_la-bearssl.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-bearssl.lo `test -f 'vtls/bearssl.c' || echo '$(srcdir)/'`vtls/bearssl.c + vquic/libcurl_la-ngtcp2.lo: vquic/ngtcp2.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 vquic/libcurl_la-ngtcp2.lo -MD -MP -MF vquic/$(DEPDIR)/libcurl_la-ngtcp2.Tpo -c -o vquic/libcurl_la-ngtcp2.lo `test -f 'vquic/ngtcp2.c' || echo '$(srcdir)/'`vquic/ngtcp2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurl_la-ngtcp2.Tpo vquic/$(DEPDIR)/libcurl_la-ngtcp2.Plo @@ -3547,6 +3567,13 @@ vtls/libcurlu_la-mesalink.lo: vtls/mesalink.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-mesalink.lo `test -f 'vtls/mesalink.c' || echo '$(srcdir)/'`vtls/mesalink.c +vtls/libcurlu_la-bearssl.lo: vtls/bearssl.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-bearssl.lo -MD -MP -MF vtls/$(DEPDIR)/libcurlu_la-bearssl.Tpo -c -o vtls/libcurlu_la-bearssl.lo `test -f 'vtls/bearssl.c' || echo '$(srcdir)/'`vtls/bearssl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vtls/$(DEPDIR)/libcurlu_la-bearssl.Tpo vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='vtls/bearssl.c' object='vtls/libcurlu_la-bearssl.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-bearssl.lo `test -f 'vtls/bearssl.c' || echo '$(srcdir)/'`vtls/bearssl.c + vquic/libcurlu_la-ngtcp2.lo: vquic/ngtcp2.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 vquic/libcurlu_la-ngtcp2.lo -MD -MP -MF vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Tpo -c -o vquic/libcurlu_la-ngtcp2.lo `test -f 'vquic/ngtcp2.c' || echo '$(srcdir)/'`vquic/ngtcp2.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Tpo vquic/$(DEPDIR)/libcurlu_la-ngtcp2.Plo @@ -3976,6 +4003,7 @@ distclean: distclean-am -rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo -rm -f vssh/$(DEPDIR)/libcurlu_la-libssh.Plo -rm -f vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-bearssl.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo @@ -3989,6 +4017,7 @@ distclean: distclean-am -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-vtls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo @@ -4301,6 +4330,7 @@ maintainer-clean: maintainer-clean-am -rm -f vssh/$(DEPDIR)/libcurl_la-libssh2.Plo -rm -f vssh/$(DEPDIR)/libcurlu_la-libssh.Plo -rm -f vssh/$(DEPDIR)/libcurlu_la-libssh2.Plo + -rm -f vtls/$(DEPDIR)/libcurl_la-bearssl.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-mbedtls.Plo @@ -4314,6 +4344,7 @@ maintainer-clean: maintainer-clean-am -rm -f vtls/$(DEPDIR)/libcurl_la-sectransp.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-vtls.Plo -rm -f vtls/$(DEPDIR)/libcurl_la-wolfssl.Plo + -rm -f vtls/$(DEPDIR)/libcurlu_la-bearssl.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gskit.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-gtls.Plo -rm -f vtls/$(DEPDIR)/libcurlu_la-mbedtls.Plo diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc index 72ef428ee6..6c90c26752 100644 --- a/libs/libcurl/src/Makefile.inc +++ b/libs/libcurl/src/Makefile.inc @@ -30,12 +30,13 @@ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ vtls/polarssl.c vtls/polarssl_threadlock.c \ vtls/wolfssl.c vtls/schannel.c vtls/schannel_verify.c \ - vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c + vtls/sectransp.c vtls/gskit.c vtls/mbedtls.c vtls/mesalink.c \ + vtls/bearssl.c LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h \ vtls/wolfssl.h vtls/schannel.h vtls/sectransp.h vtls/gskit.h \ - vtls/mbedtls.h vtls/mesalink.h + vtls/mbedtls.h vtls/mesalink.h vtls/bearssl.h LIB_VQUIC_CFILES = vquic/ngtcp2.c vquic/quiche.c @@ -43,6 +44,8 @@ LIB_VQUIC_HFILES = vquic/ngtcp2.h vquic/quiche.h LIB_VSSH_CFILES = vssh/libssh2.c vssh/libssh.c +LIB_VSSH_HFILES = vssh/ssh.h + LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \ ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \ @@ -72,7 +75,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \ inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \ easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \ - socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \ + socks.h curl_base64.h curl_addrinfo.h curl_sspi.h \ slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \ rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \ curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \ @@ -89,4 +92,4 @@ LIB_RCFILES = libcurl.rc CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \ $(LIB_VQUIC_CFILES) $(LIB_VSSH_CFILES) HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) \ - $(LIB_VQUIC_HFILES) + $(LIB_VQUIC_HFILES) $(LIB_VSSH_HFILES) diff --git a/libs/libcurl/src/Makefile.m32 b/libs/libcurl/src/Makefile.m32 index ae88f4dced..b6ef0a5cbd 100644 --- a/libs/libcurl/src/Makefile.m32 +++ b/libs/libcurl/src/Makefile.m32 @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1999 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 1999 - 2019, 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 @@ -271,7 +271,7 @@ ifdef SSL endif INCLUDES += -I"$(OPENSSL_INCLUDE)" CFLAGS += -DUSE_OPENSSL -DHAVE_OPENSSL_ENGINE_H -DHAVE_OPENSSL_PKCS12_H \ - -DHAVE_ENGINE_LOAD_BUILTIN_ENGINES -DOPENSSL_NO_KRB5 + -DOPENSSL_NO_KRB5 DLL_LIBS += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS) ifdef SRP ifeq "$(wildcard $(OPENSSL_INCLUDE)/openssl/srp.h)" "$(OPENSSL_INCLUDE)/openssl/srp.h" diff --git a/libs/libcurl/src/altsvc.c b/libs/libcurl/src/altsvc.c index 64971a9f0f..bf869c37a5 100644 --- a/libs/libcurl/src/altsvc.c +++ b/libs/libcurl/src/altsvc.c @@ -55,7 +55,7 @@ static enum alpnid alpn2alpnid(char *name) if(strcasecompare(name, "h2")) return ALPN_h2; #if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS) - if(strcasecompare(name, "h3-23")) + if(strcasecompare(name, "h3-24")) return ALPN_h3; #else if(strcasecompare(name, "h3")) @@ -74,7 +74,7 @@ const char *Curl_alpnid2str(enum alpnid id) return "h2"; case ALPN_h3: #if (defined(USE_QUICHE) || defined(USE_NGTCP2)) && !defined(UNITTESTS) - return "h3-23"; + return "h3-24"; #else return "h3"; #endif @@ -161,7 +161,7 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char *line) date, &persist, &prio); if(9 == rc) { struct altsvc *as; - time_t expires = curl_getdate(date, NULL); + time_t expires = Curl_getdate_capped(date); as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport); if(as) { as->expires = expires; @@ -320,8 +320,8 @@ CURLcode Curl_altsvc_save(struct altsvcinfo *altsvc, const char *file) /* no cache activated */ return CURLE_OK; - if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file[0]) - /* marked as read-only or zero length file name */ + if((altsvc->flags & CURLALTSVC_READONLYFILE) || !file || !file[0]) + /* marked as read-only, no file or zero length file name */ return CURLE_OK; out = fopen(file, FOPEN_WRITETEXT); if(!out) diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c index 8c552baa9a..b08497aaa0 100644 --- a/libs/libcurl/src/asyn-thread.c +++ b/libs/libcurl/src/asyn-thread.c @@ -698,6 +698,16 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, *waitp = 0; /* default to synchronous response */ +#ifdef ENABLE_IPV6 + { + struct in6_addr in6; + /* check if this is an IPv6 address string */ + if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0) + /* This is an IPv6 address literal */ + return Curl_ip2addr(AF_INET6, &in6, hostname, port); + } +#endif /* ENABLE_IPV6 */ + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) /* This is a dotted IP address 123.123.123.123-style */ return Curl_ip2addr(AF_INET, &in, hostname, port); @@ -741,7 +751,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, /* This is a dotted IP address 123.123.123.123-style */ return Curl_ip2addr(AF_INET, &in, hostname, port); } -#ifdef CURLRES_IPV6 +#ifdef ENABLE_IPV6 { struct in6_addr in6; /* check if this is an IPv6 address string */ @@ -749,7 +759,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, /* This is an IPv6 address literal */ return Curl_ip2addr(AF_INET6, &in6, hostname, port); } -#endif /* CURLRES_IPV6 */ +#endif /* ENABLE_IPV6 */ #endif /* !USE_RESOLVE_ON_IPS */ #ifdef CURLRES_IPV6 diff --git a/libs/libcurl/src/checksrc.pl b/libs/libcurl/src/checksrc.pl index b2cfa83559..8343645610 100644 --- a/libs/libcurl/src/checksrc.pl +++ b/libs/libcurl/src/checksrc.pl @@ -6,7 +6,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. +# Copyright (C) 2011 - 2019, 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 @@ -717,12 +717,17 @@ sub scanfile { my $commityear = undef; @copyright = sort {$$b{year} cmp $$a{year}} @copyright; + # if the file is modified, assume commit year this year if(`git status -s -- $file` =~ /^ [MARCU]/) { $commityear = (localtime(time))[5] + 1900; } - elsif (`git rev-list --count origin/master..HEAD -- $file` !~ /^0/) { - my $grl = `git rev-list --max-count=1 --timestamp HEAD -- $file`; - $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900; + else { + # min-parents=1 to ignore wrong initial commit in truncated repos + my $grl = `git rev-list --max-count=1 --min-parents=1 --timestamp HEAD -- $file`; + if($grl) { + chomp $grl; + $commityear = (localtime((split(/ /, $grl))[0]))[5] + 1900; + } } if(defined($commityear) && scalar(@copyright) && diff --git a/libs/libcurl/src/config-dos.h b/libs/libcurl/src/config-dos.h index 3e973de0b4..25f751eb56 100644 --- a/libs/libcurl/src/config-dos.h +++ b/libs/libcurl/src/config-dos.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/config-mac.h b/libs/libcurl/src/config-mac.h index 3c12bdfacc..14b98fe572 100644 --- a/libs/libcurl/src/config-mac.h +++ b/libs/libcurl/src/config-mac.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/config-plan9.h b/libs/libcurl/src/config-plan9.h index 64bfbdea05..4063d4bbd6 100644 --- a/libs/libcurl/src/config-plan9.h +++ b/libs/libcurl/src/config-plan9.h @@ -102,7 +102,6 @@ #define HAVE_BASENAME 1 #define HAVE_BOOL_T 1 #define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 #define HAVE_ERRNO_H 1 #define HAVE_FCNTL 1 #define HAVE_FCNTL_H 1 diff --git a/libs/libcurl/src/config-symbian.h b/libs/libcurl/src/config-symbian.h index cb2e96d5d1..c01e1bfab8 100644 --- a/libs/libcurl/src/config-symbian.h +++ b/libs/libcurl/src/config-symbian.h @@ -128,9 +128,6 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #define HAVE_DLFCN_H 1 -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -/*#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1*/ - /* Define to 1 if you have the <errno.h> header file. */ #define HAVE_ERRNO_H 1 diff --git a/libs/libcurl/src/config-tpf.h b/libs/libcurl/src/config-tpf.h index f0c095bb04..85b634f9d4 100644 --- a/libs/libcurl/src/config-tpf.h +++ b/libs/libcurl/src/config-tpf.h @@ -119,10 +119,6 @@ /* #undef HAVE_DES_H */ #define HAVE_DES_H 1 -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */ -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - /* Define to 1 if you have the <errno.h> header file. */ #define HAVE_ERRNO_H 1 diff --git a/libs/libcurl/src/config-vxworks.h b/libs/libcurl/src/config-vxworks.h index d352578e33..004fd4e800 100644 --- a/libs/libcurl/src/config-vxworks.h +++ b/libs/libcurl/src/config-vxworks.h @@ -143,9 +143,6 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #define HAVE_DLFCN_H 1 -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - /* Define to 1 if you have the <errno.h> header file. */ #define HAVE_ERRNO_H 1 diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index 5b028f193f..1dcce0db41 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -246,10 +246,6 @@ /* Define if you have the socket function. */ #define HAVE_SOCKET 1 -/* Define if libSSH2 is in use */ -#define USE_LIBSSH2 1 -#define HAVE_LIBSSH2_H 1 - /* Define if you have the strcasecmp function. */ /* #define HAVE_STRCASECMP 1 */ @@ -739,8 +735,12 @@ Vista #define OS "i386-pc-win32" #elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */ #define OS "x86_64-pc-win32" -#elif defined(_M_IA64) /* Itanium */ +#elif defined(_M_IA64) || defined(__ia64__) /* Itanium */ #define OS "ia64-pc-win32" +#elif defined(_M_ARM_NT) || defined(__arm__) /* ARMv7-Thumb2 (Windows RT) */ +#define OS "thumbv7a-pc-win32" +#elif defined(_M_ARM64) || defined(__aarch64__) /* ARM64 (Windows 10) */ +#define OS "aarch64-pc-win32" #else #define OS "unknown-pc-win32" #endif diff --git a/libs/libcurl/src/config-win32ce.h b/libs/libcurl/src/config-win32ce.h index 182052290e..5eb1c18f6f 100644 --- a/libs/libcurl/src/config-win32ce.h +++ b/libs/libcurl/src/config-win32ce.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/conncache.c b/libs/libcurl/src/conncache.c index 57d6061fda..28044644bf 100644 --- a/libs/libcurl/src/conncache.c +++ b/libs/libcurl/src/conncache.c @@ -40,27 +40,6 @@ #include "curl_memory.h" #include "memdebug.h" -#ifdef CURLDEBUG -/* the debug versions of these macros make extra certain that the lock is - never doubly locked or unlocked */ -#define CONN_LOCK(x) if((x)->share) { \ - Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \ - DEBUGASSERT(!(x)->state.conncache_lock); \ - (x)->state.conncache_lock = TRUE; \ - } - -#define CONN_UNLOCK(x) if((x)->share) { \ - DEBUGASSERT((x)->state.conncache_lock); \ - (x)->state.conncache_lock = FALSE; \ - Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \ - } -#else -#define CONN_LOCK(x) if((x)->share) \ - Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE) -#define CONN_UNLOCK(x) if((x)->share) \ - Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT) -#endif - #define HASHKEY_SIZE 128 static void conn_llist_dtor(void *user, void *element) @@ -122,6 +101,7 @@ static int bundle_remove_conn(struct connectbundle *cb_ptr, } curr = curr->next; } + DEBUGASSERT(0); return 0; } @@ -428,17 +408,15 @@ conncache_find_first_connection(struct conncache *connc) * * Return TRUE if stored, FALSE if closed. */ -bool Curl_conncache_return_conn(struct connectdata *conn) +bool Curl_conncache_return_conn(struct Curl_easy *data, + struct connectdata *conn) { - struct Curl_easy *data = conn->data; - /* data->multi->maxconnects can be negative, deal with it. */ size_t maxconnects = (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: data->multi->maxconnects; struct connectdata *conn_candidate = NULL; - conn->data = NULL; /* no owner anymore */ conn->lastused = Curl_now(); /* it was used up until now */ if(maxconnects > 0 && Curl_conncache_size(data) > maxconnects) { @@ -541,7 +519,8 @@ Curl_conncache_extract_oldest(struct Curl_easy *data) while(curr) { conn = curr->ptr; - if(!CONN_INUSE(conn) && !conn->data) { + if(!CONN_INUSE(conn) && !conn->data && !conn->bits.close && + !conn->bits.connect_only) { /* Set higher score for the age passed since the connection was used */ score = Curl_timediff(now, conn->lastused); diff --git a/libs/libcurl/src/conncache.h b/libs/libcurl/src/conncache.h index 58f9024093..5fe80b4c8d 100644 --- a/libs/libcurl/src/conncache.h +++ b/libs/libcurl/src/conncache.h @@ -42,6 +42,27 @@ struct conncache { #define BUNDLE_UNKNOWN 0 /* initial value */ #define BUNDLE_MULTIPLEX 2 +#ifdef CURLDEBUG +/* the debug versions of these macros make extra certain that the lock is + never doubly locked or unlocked */ +#define CONN_LOCK(x) if((x)->share) { \ + Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE); \ + DEBUGASSERT(!(x)->state.conncache_lock); \ + (x)->state.conncache_lock = TRUE; \ + } + +#define CONN_UNLOCK(x) if((x)->share) { \ + DEBUGASSERT((x)->state.conncache_lock); \ + (x)->state.conncache_lock = FALSE; \ + Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT); \ + } +#else +#define CONN_LOCK(x) if((x)->share) \ + Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE) +#define CONN_UNLOCK(x) if((x)->share) \ + Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT) +#endif + struct connectbundle { int multiuse; /* supports multi-use */ size_t num_connections; /* Number of connections in the bundle */ @@ -61,7 +82,8 @@ void Curl_conncache_unlock(struct Curl_easy *data); size_t Curl_conncache_size(struct Curl_easy *data); size_t Curl_conncache_bundle_size(struct connectdata *conn); -bool Curl_conncache_return_conn(struct connectdata *conn); +bool Curl_conncache_return_conn(struct Curl_easy *data, + struct connectdata *conn); CURLcode Curl_conncache_add_conn(struct conncache *connc, struct connectdata *conn) WARN_UNUSED_RESULT; void Curl_conncache_remove_conn(struct Curl_easy *data, diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index 3b88a59623..611d6d2f02 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -932,9 +932,11 @@ CURLcode Curl_is_connected(struct connectdata *conn, SET_SOCKERRNO(error); if(conn->tempaddr[i]) { CURLcode status; +#ifndef CURL_DISABLE_VERBOSE_STRINGS char ipaddress[MAX_IPADR_LEN]; char buffer[STRERROR_LEN]; Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN); +#endif infof(data, "connect to %s port %ld failed: %s\n", ipaddress, conn->port, Curl_strerror(error, buffer, sizeof(buffer))); @@ -992,14 +994,12 @@ CURLcode Curl_is_connected(struct connectdata *conn, static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) { #if defined(TCP_NODELAY) -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) - struct Curl_easy *data = conn->data; -#endif curl_socklen_t onoff = (curl_socklen_t) 1; int level = IPPROTO_TCP; +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) + struct Curl_easy *data = conn->data; char buffer[STRERROR_LEN]; - -#if defined(CURL_DISABLE_VERBOSE_STRINGS) +#else (void) conn; #endif diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c index f56bd85a93..0091132aa3 100644 --- a/libs/libcurl/src/cookie.c +++ b/libs/libcurl/src/cookie.c @@ -96,6 +96,7 @@ Example set of cookies: #include "curl_get_line.h" #include "curl_memrchr.h" #include "inet_pton.h" +#include "parsedate.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -715,7 +716,7 @@ Curl_cookie_add(struct Curl_easy *data, else if(co->expirestr) { /* Note that if the date couldn't get parsed for whatever reason, the cookie will be treated as a session cookie */ - co->expires = curl_getdate(co->expirestr, NULL); + co->expires = Curl_getdate_capped(co->expirestr); /* Session cookies have expires set to 0 so if we get that back from the date parser let's add a second to make it a diff --git a/libs/libcurl/src/curl_base64.h b/libs/libcurl/src/curl_base64.h index 7e9fc26062..cfb6ee75b2 100644 --- a/libs/libcurl/src/curl_base64.h +++ b/libs/libcurl/src/curl_base64.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake index e0793a7ee4..2c3b6562d4 100644 --- a/libs/libcurl/src/curl_config.h.cmake +++ b/libs/libcurl/src/curl_config.h.cmake @@ -148,9 +148,6 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #cmakedefine HAVE_DLFCN_H 1 -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - /* Define to 1 if you have the <errno.h> header file. */ #cmakedefine HAVE_ERRNO_H 1 @@ -948,6 +945,9 @@ ${SIZEOF_TIME_T_CODE} /* if mbedTLS is enabled */ #cmakedefine USE_MBEDTLS 1 +/* if BearSSL is enabled */ +#cmakedefine USE_BEARSSL 1 + /* if libSSH2 is in use */ #cmakedefine USE_LIBSSH2 1 @@ -957,6 +957,9 @@ ${SIZEOF_TIME_T_CODE} /* if NSS is enabled */ #cmakedefine USE_NSS 1 +/* if you have the PK11_CreateManagedGenericObject function */ +#cmakedefine HAVE_PK11_CREATEMANAGEDGENERICOBJECT 1 + /* if you want to use OpenLDAP code instead of legacy ldap implementation */ #cmakedefine USE_OPENLDAP 1 diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in index 32a87bd293..bb7f4e3402 100644 --- a/libs/libcurl/src/curl_config.h.in +++ b/libs/libcurl/src/curl_config.h.in @@ -955,6 +955,9 @@ /* Define to enable c-ares support */ #undef USE_ARES +/* if BearSSL is enabled */ +#undef USE_BEARSSL + /* if ESNI support is available */ #undef USE_ESNI diff --git a/libs/libcurl/src/curl_des.c b/libs/libcurl/src/curl_des.c index b123a00f01..39c0f35ee6 100644 --- a/libs/libcurl/src/curl_des.c +++ b/libs/libcurl/src/curl_des.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>. + * Copyright (C) 2015 - 2019, 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 diff --git a/libs/libcurl/src/curl_des.h b/libs/libcurl/src/curl_des.h index 129060ff7d..a42eeb53f3 100644 --- a/libs/libcurl/src/curl_des.h +++ b/libs/libcurl/src/curl_des.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>. + * Copyright (C) 2015 - 2019, 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 diff --git a/libs/libcurl/src/curl_endian.c b/libs/libcurl/src/curl_endian.c index b7563b3ded..a774d136e4 100644 --- a/libs/libcurl/src/curl_endian.c +++ b/libs/libcurl/src/curl_endian.c @@ -81,6 +81,7 @@ unsigned short Curl_read16_be(const unsigned char *buf) ((unsigned short)buf[1])); } +#if (CURL_SIZEOF_CURL_OFF_T > 4) /* * write32_le() * @@ -100,7 +101,6 @@ static void write32_le(const int value, unsigned char *buffer) buffer[3] = (char)((value & 0xFF000000) >> 24); } -#if (CURL_SIZEOF_CURL_OFF_T > 4) /* * Curl_write64_le() * diff --git a/libs/libcurl/src/curl_fnmatch.h b/libs/libcurl/src/curl_fnmatch.h index 69ffe392fd..34fccae488 100644 --- a/libs/libcurl/src/curl_fnmatch.h +++ b/libs/libcurl/src/curl_fnmatch.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/curl_gethostname.h b/libs/libcurl/src/curl_gethostname.h index 07517c5359..8ae15e6c19 100644 --- a/libs/libcurl/src/curl_gethostname.h +++ b/libs/libcurl/src/curl_gethostname.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/curl_ldap.h b/libs/libcurl/src/curl_ldap.h index 94c002948c..912e13107c 100644 --- a/libs/libcurl/src/curl_ldap.h +++ b/libs/libcurl/src/curl_ldap.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/curl_memrchr.h b/libs/libcurl/src/curl_memrchr.h index 747509c45a..90a8a07cce 100644 --- a/libs/libcurl/src/curl_memrchr.h +++ b/libs/libcurl/src/curl_memrchr.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/curl_multibyte.c b/libs/libcurl/src/curl_multibyte.c index e48334faff..e3843449bb 100644 --- a/libs/libcurl/src/curl_multibyte.c +++ b/libs/libcurl/src/curl_multibyte.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/curl_multibyte.h b/libs/libcurl/src/curl_multibyte.h index 615f5c086c..3becf41cfa 100644 --- a/libs/libcurl/src/curl_multibyte.h +++ b/libs/libcurl/src/curl_multibyte.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 @@ -61,8 +61,13 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w); #define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr)) #define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr)) -#define Curl_unicodefree(ptr) \ - do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE +#define Curl_unicodefree(ptr) \ + do { \ + if(ptr) { \ + free(ptr); \ + (ptr) = NULL; \ + } \ + } while(0) typedef union { unsigned short *tchar_ptr; @@ -76,7 +81,7 @@ typedef union { #define Curl_convert_UTF8_to_tchar(ptr) (ptr) #define Curl_convert_tchar_to_UTF8(ptr) (ptr) #define Curl_unicodefree(ptr) \ - do {(ptr) = NULL;} WHILE_FALSE + do {(ptr) = NULL;} while(0) typedef union { char *tchar_ptr; diff --git a/libs/libcurl/src/curl_ntlm_core.h b/libs/libcurl/src/curl_ntlm_core.h index 3b4b8053c3..392a1b81de 100644 --- a/libs/libcurl/src/curl_ntlm_core.h +++ b/libs/libcurl/src/curl_ntlm_core.h @@ -48,7 +48,9 @@ /* Define USE_NTLM2SESSION in order to make the type-3 message include the NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a Crypto engine that we have curl_ssl_md5sum() for. */ -#if defined(USE_NTRESPONSES) && !defined(USE_WIN32_CRYPTO) +#if defined(USE_NTRESPONSES) && \ + (!defined(USE_WIN32_CRYPTO) || \ + (defined(USE_SSL) && !defined(CURL_DISABLE_CRYPTO_AUTH))) #define USE_NTLM2SESSION #endif diff --git a/libs/libcurl/src/curl_ntlm_wb.c b/libs/libcurl/src/curl_ntlm_wb.c index 80266e2a45..30b54de444 100644 --- a/libs/libcurl/src/curl_ntlm_wb.c +++ b/libs/libcurl/src/curl_ntlm_wb.c @@ -108,10 +108,8 @@ void Curl_http_auth_cleanup_ntlm_wb(struct connectdata *conn) conn->ntlm_auth_hlpr_pid = 0; } - free(conn->challenge_header); - conn->challenge_header = NULL; - free(conn->response_header); - conn->response_header = NULL; + Curl_safefree(conn->challenge_header); + Curl_safefree(conn->response_header); } static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) @@ -393,7 +391,6 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, struct auth *authp; CURLcode res = CURLE_OK; - char *input; DEBUGASSERT(conn); DEBUGASSERT(conn->data); @@ -444,19 +441,17 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, proxy ? "Proxy-" : "", conn->response_header); DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); - free(conn->response_header); + Curl_safefree(conn->response_header); if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; - conn->response_header = NULL; break; - case NTLMSTATE_TYPE2: - input = aprintf("TT %s\n", conn->challenge_header); + case NTLMSTATE_TYPE2: { + char *input = aprintf("TT %s\n", conn->challenge_header); if(!input) return CURLE_OUT_OF_MEMORY; res = ntlm_wb_response(conn, input, *state); free(input); - input = NULL; if(res) return res; @@ -471,7 +466,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, if(!*allocuserpwd) return CURLE_OUT_OF_MEMORY; break; - + } case NTLMSTATE_TYPE3: /* connection is already authenticated, * don't send a header in future requests */ diff --git a/libs/libcurl/src/curl_rtmp.h b/libs/libcurl/src/curl_rtmp.h index 3306e22005..86a01382da 100644 --- a/libs/libcurl/src/curl_rtmp.h +++ b/libs/libcurl/src/curl_rtmp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com> + * Copyright (C) 2010 - 2019, Howard Chu, <hyc@highlandsun.com> * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index 13af8cdec9..4ecda6a9b4 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -27,6 +27,14 @@ #endif /* + * Disable Visual Studio warnings: + * 4127 "conditional expression is constant" + */ +#ifdef _MSC_VER +#pragma warning(disable:4127) +#endif + +/* * Define WIN32 when build target is Win32 API */ @@ -563,6 +571,12 @@ * Mutually exclusive CURLRES_* definitions. */ +#if defined(ENABLE_IPV6) && defined(HAVE_GETADDRINFO) +# define CURLRES_IPV6 +#else +# define CURLRES_IPV4 +#endif + #ifdef USE_ARES # define CURLRES_ASYNCH # define CURLRES_ARES @@ -577,12 +591,6 @@ # define CURLRES_SYNCH #endif -#ifdef ENABLE_IPV6 -# define CURLRES_IPV6 -#else -# define CURLRES_IPV4 -#endif - /* ---------------------------------------------------------------- */ /* @@ -644,7 +652,8 @@ int netware_init(void); #if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ defined(USE_MBEDTLS) || \ defined(USE_WOLFSSL) || defined(USE_SCHANNEL) || \ - defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) + defined(USE_SECTRANSP) || defined(USE_GSKIT) || defined(USE_MESALINK) || \ + defined(USE_BEARSSL) #define USE_SSL /* SSL support has been enabled */ #endif @@ -713,7 +722,7 @@ int netware_init(void); */ #ifndef Curl_nop_stmt -# define Curl_nop_stmt do { } WHILE_FALSE +# define Curl_nop_stmt do { } while(0) #endif /* diff --git a/libs/libcurl/src/curl_setup_once.h b/libs/libcurl/src/curl_setup_once.h index 413ccea917..8890f3890d 100644 --- a/libs/libcurl/src/curl_setup_once.h +++ b/libs/libcurl/src/curl_setup_once.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 @@ -330,27 +330,6 @@ struct timeval { #include "curl_ctype.h" /* - * Macro WHILE_FALSE may be used to build single-iteration do-while loops, - * avoiding compiler warnings. Mostly intended for other macro definitions. - */ - -#define WHILE_FALSE while(0) - -#if defined(_MSC_VER) && !defined(__POCC__) -# undef WHILE_FALSE -# if (_MSC_VER < 1500) -# define WHILE_FALSE while(1, 0) -# else -# define WHILE_FALSE \ -__pragma(warning(push)) \ -__pragma(warning(disable:4127)) \ -while(0) \ -__pragma(warning(pop)) -# endif -#endif - - -/* * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type. */ @@ -387,7 +366,7 @@ typedef int sig_atomic_t; #ifdef DEBUGBUILD #define DEBUGF(x) x #else -#define DEBUGF(x) do { } WHILE_FALSE +#define DEBUGF(x) do { } while(0) #endif @@ -395,10 +374,11 @@ typedef int sig_atomic_t; * Macro used to include assertion code only in debug builds. */ +#undef DEBUGASSERT #if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H) #define DEBUGASSERT(x) assert(x) #else -#define DEBUGASSERT(x) do { } WHILE_FALSE +#define DEBUGASSERT(x) do { } while(0) #endif diff --git a/libs/libcurl/src/curl_sha256.h b/libs/libcurl/src/curl_sha256.h index 6db4b04dbb..14b6414ea0 100644 --- a/libs/libcurl/src/curl_sha256.h +++ b/libs/libcurl/src/curl_sha256.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Florin Petriuc, <petriuc.florin@gmail.com> + * Copyright (C) 1998 - 2019, Florin Petriuc, <petriuc.florin@gmail.com> * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/curl_sspi.c b/libs/libcurl/src/curl_sspi.c index 1d0de4ed33..f7cc10f804 100644 --- a/libs/libcurl/src/curl_sspi.c +++ b/libs/libcurl/src/curl_sspi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/curl_sspi.h b/libs/libcurl/src/curl_sspi.h index 2bbf9477bb..c09026ebbb 100644 --- a/libs/libcurl/src/curl_sspi.h +++ b/libs/libcurl/src/curl_sspi.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/curl_threads.c b/libs/libcurl/src/curl_threads.c index 8e5937aa0b..064c075d0e 100644 --- a/libs/libcurl/src/curl_threads.c +++ b/libs/libcurl/src/curl_threads.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/curl_threads.h b/libs/libcurl/src/curl_threads.h index 2a93644c56..65d1a790c1 100644 --- a/libs/libcurl/src/curl_threads.h +++ b/libs/libcurl/src/curl_threads.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/dict.h b/libs/libcurl/src/dict.h index 12c0f3394d..38a55ac0de 100644 --- a/libs/libcurl/src/dict.h +++ b/libs/libcurl/src/dict.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/doh.c b/libs/libcurl/src/doh.c index d1795789e5..7f4eee5d81 100644 --- a/libs/libcurl/src/doh.c +++ b/libs/libcurl/src/doh.c @@ -86,12 +86,36 @@ UNITTEST DOHcode doh_encode(const char *host, unsigned char *orig = dnsp; const char *hostp = host; - /* The expected output length does not depend on the number of dots within - * the host name. It will always be two more than the length of the host - * name, one for the size and one trailing null. In case there are dots, - * each dot adds one size but removes the need to store the dot, net zero. + /* The expected output length is 16 bytes more than the length of + * the QNAME-encoding of the host name. + * + * A valid DNS name may not contain a zero-length label, except at + * the end. For this reason, a name beginning with a dot, or + * containing a sequence of two or more consecutive dots, is invalid + * and cannot be encoded as a QNAME. + * + * If the host name ends with a trailing dot, the corresponding + * QNAME-encoding is one byte longer than the host name. If (as is + * also valid) the hostname is shortened by the omission of the + * trailing dot, then its QNAME-encoding will be two bytes longer + * than the host name. + * + * Each [ label, dot ] pair is encoded as [ length, label ], + * preserving overall length. A final [ label ] without a dot is + * also encoded as [ length, label ], increasing overall length + * by one. The encoding is completed by appending a zero byte, + * representing the zero-length root label, again increasing + * the overall length by one. */ - const size_t expected_len = 12 + ( 1 + hostlen + 1) + 4; + + size_t expected_len; + DEBUGASSERT(hostlen); + expected_len = 12 + 1 + hostlen + 4; + if(host[hostlen-1]!='.') + expected_len++; + + if(expected_len > (256 + 16)) /* RFCs 1034, 1035 */ + return DOH_DNS_NAME_TOO_LONG; if(len < expected_len) return DOH_TOO_SMALL_BUFFER; @@ -109,31 +133,30 @@ UNITTEST DOHcode doh_encode(const char *host, *dnsp++ = '\0'; *dnsp++ = '\0'; /* ARCOUNT */ - /* store a QNAME */ - do { - char *dot = strchr(hostp, '.'); + /* encode each label and store it in the QNAME */ + while(*hostp) { size_t labellen; - bool found = false; - if(dot) { - found = true; + char *dot = strchr(hostp, '.'); + if(dot) labellen = dot - hostp; - } else labellen = strlen(hostp); - if(labellen > 63) { - /* too long label, error out */ + if((labellen > 63) || (!labellen)) { + /* label is too long or too short, error out */ *olen = 0; return DOH_DNS_BAD_LABEL; } + /* label is non-empty, process it */ *dnsp++ = (unsigned char)labellen; memcpy(dnsp, hostp, labellen); dnsp += labellen; - hostp += labellen + 1; - if(!found) { - *dnsp++ = 0; /* terminating zero */ - break; - } - } while(1); + hostp += labellen; + /* advance past dot, but only if there is one */ + if(dot) + hostp++; + } /* next label */ + + *dnsp++ = 0; /* append zero-length label for root */ /* There are assigned TYPE codes beyond 255: use range [1..65535] */ *dnsp++ = (unsigned char)(255 & (dnstype>>8)); /* upper 8 bit TYPE */ @@ -144,8 +167,8 @@ UNITTEST DOHcode doh_encode(const char *host, *olen = dnsp - orig; - /* verify that our assumption of length is valid, since - * this has lead to buffer overflows in this function */ + /* verify that our estimation of length is valid, since + * this has led to buffer overflows in this function */ DEBUGASSERT(*olen == expected_len); return DOH_OK; } @@ -195,7 +218,7 @@ do { \ result = curl_easy_setopt(doh, x, y); \ if(result) \ goto error; \ -} WHILE_FALSE +} while(0) static CURLcode dohprobe(struct Curl_easy *data, struct dnsprobe *p, DNStype dnstype, @@ -280,38 +303,42 @@ static CURLcode dohprobe(struct Curl_easy *data, 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.ssl.primary.verifypeer) - ERROR_CHECK_SETOPT(CURLOPT_SSL_VERIFYPEER, 1L); 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); + 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]) { ERROR_CHECK_SETOPT(CURLOPT_CAINFO, data->set.str[STRING_SSL_CAFILE_ORIG]); } - 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_CAPATH_ORIG]) { ERROR_CHECK_SETOPT(CURLOPT_CAPATH, data->set.str[STRING_SSL_CAPATH_ORIG]); } - if(data->set.str[STRING_SSL_CAPATH_PROXY]) { - ERROR_CHECK_SETOPT(CURLOPT_PROXY_CAPATH, - data->set.str[STRING_SSL_CAPATH_PROXY]); - } if(data->set.str[STRING_SSL_CRLFILE_ORIG]) { ERROR_CHECK_SETOPT(CURLOPT_CRLFILE, data->set.str[STRING_SSL_CRLFILE_ORIG]); } - if(data->set.str[STRING_SSL_CRLFILE_PROXY]) { - ERROR_CHECK_SETOPT(CURLOPT_PROXY_CRLFILE, - data->set.str[STRING_SSL_CRLFILE_PROXY]); - } if(data->set.ssl.certinfo) ERROR_CHECK_SETOPT(CURLOPT_CERTINFO, 1L); if(data->set.str[STRING_SSL_RANDOM_FILE]) { @@ -324,8 +351,6 @@ static CURLcode dohprobe(struct Curl_easy *data, } if(data->set.ssl.no_revoke) ERROR_CHECK_SETOPT(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); - if(data->set.proxy_ssl.no_revoke) - ERROR_CHECK_SETOPT(CURLOPT_PROXY_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); if(data->set.ssl.fsslctx) ERROR_CHECK_SETOPT(CURLOPT_SSL_CTX_FUNCTION, data->set.ssl.fsslctx); if(data->set.ssl.fsslctxp) @@ -362,6 +387,7 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn, { struct Curl_easy *data = conn->data; CURLcode result = CURLE_OK; + int slot; *waitp = TRUE; /* this never returns synchronously */ (void)conn; (void)hostname; @@ -380,8 +406,8 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn, if(conn->ip_version != CURL_IPRESOLVE_V6) { /* create IPv4 DOH request */ - result = dohprobe(data, &data->req.doh.probe[0], DNS_TYPE_A, - hostname, data->set.str[STRING_DOH], + result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4], + DNS_TYPE_A, hostname, data->set.str[STRING_DOH], data->multi, data->req.doh.headers); if(result) goto error; @@ -390,8 +416,8 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn, if(conn->ip_version != CURL_IPRESOLVE_V4) { /* create IPv6 DOH request */ - result = dohprobe(data, &data->req.doh.probe[1], DNS_TYPE_AAAA, - hostname, data->set.str[STRING_DOH], + result = dohprobe(data, &data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6], + DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH], data->multi, data->req.doh.headers); if(result) goto error; @@ -402,8 +428,9 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn, error: curl_slist_free_all(data->req.doh.headers); data->req.doh.headers = NULL; - Curl_close(&data->req.doh.probe[0].easy); - Curl_close(&data->req.doh.probe[1].easy); + for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { + Curl_close(&data->req.doh.probe[slot].easy); + } return NULL; } @@ -586,6 +613,9 @@ static DOHcode rdata(unsigned char *doh, if(rc) return rc; break; + case DNS_TYPE_DNAME: + /* explicit for clarity; just skip; rely on synthesized CNAME */ + break; default: /* unsupported type, just skip it */ break; @@ -647,8 +677,10 @@ UNITTEST DOHcode doh_decode(unsigned char *doh, return DOH_DNS_OUT_OF_RANGE; type = get16bit(doh, index); - if((type != DNS_TYPE_CNAME) && (type != dnstype)) - /* Not the same type as was asked for nor CNAME */ + if((type != DNS_TYPE_CNAME) /* may be synthesized from DNAME */ + && (type != DNS_TYPE_DNAME) /* if present, accept and ignore */ + && (type != dnstype)) + /* Not the same type as was asked for nor CNAME nor DNAME */ return DOH_DNS_UNEXPECTED_TYPE; index += 2; @@ -909,46 +941,43 @@ UNITTEST void de_cleanup(struct dohentry *d) CURLcode Curl_doh_is_resolved(struct connectdata *conn, struct Curl_dns_entry **dnsp) { + CURLcode result; struct Curl_easy *data = conn->data; *dnsp = NULL; /* defaults to no response */ - if(!data->req.doh.probe[0].easy && !data->req.doh.probe[1].easy) { + if(!data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V4].easy && + !data->req.doh.probe[DOH_PROBE_SLOT_IPADDR_V6].easy) { failf(data, "Could not DOH-resolve: %s", conn->async.hostname); return conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY: CURLE_COULDNT_RESOLVE_HOST; } else if(!data->req.doh.pending) { - DOHcode rc; - DOHcode rc2; + DOHcode rc[DOH_PROBE_SLOTS]; struct dohentry de; + int slot; /* remove DOH handles from multi handle and close them */ - curl_multi_remove_handle(data->multi, data->req.doh.probe[0].easy); - Curl_close(&data->req.doh.probe[0].easy); - curl_multi_remove_handle(data->multi, data->req.doh.probe[1].easy); - Curl_close(&data->req.doh.probe[1].easy); + for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { + curl_multi_remove_handle(data->multi, data->req.doh.probe[slot].easy); + Curl_close(&data->req.doh.probe[slot].easy); + } /* parse the responses, create the struct and return it! */ init_dohentry(&de); - rc = doh_decode(data->req.doh.probe[0].serverdoh.memory, - data->req.doh.probe[0].serverdoh.size, - data->req.doh.probe[0].dnstype, - &de); - Curl_safefree(data->req.doh.probe[0].serverdoh.memory); - if(rc) { - infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc), - type2name(data->req.doh.probe[0].dnstype), - data->req.doh.host); - } - rc2 = doh_decode(data->req.doh.probe[1].serverdoh.memory, - data->req.doh.probe[1].serverdoh.size, - data->req.doh.probe[1].dnstype, - &de); - Curl_safefree(data->req.doh.probe[1].serverdoh.memory); - if(rc2) { - infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc2), - type2name(data->req.doh.probe[1].dnstype), - data->req.doh.host); - } - if(!rc || !rc2) { + for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { + rc[slot] = doh_decode(data->req.doh.probe[slot].serverdoh.memory, + data->req.doh.probe[slot].serverdoh.size, + data->req.doh.probe[slot].dnstype, + &de); + Curl_safefree(data->req.doh.probe[slot].serverdoh.memory); + if(rc[slot]) { + infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc[slot]), + type2name(data->req.doh.probe[slot].dnstype), + data->req.doh.host); + } + } /* next slot */ + + result = CURLE_COULDNT_RESOLVE_HOST; /* until we know better */ + if(!rc[DOH_PROBE_SLOT_IPADDR_V4] || !rc[DOH_PROBE_SLOT_IPADDR_V6]) { + /* we have an address, of one kind or other */ struct Curl_dns_entry *dns; struct Curl_addrinfo *ai; @@ -970,21 +999,26 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn, if(data->share) Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - de_cleanup(&de); - if(!dns) + if(!dns) { /* returned failure, bail out nicely */ Curl_freeaddrinfo(ai); + } else { conn->async.dns = dns; *dnsp = dns; - return CURLE_OK; + result = CURLE_OK; /* address resolution OK */ } - } + } /* address processing done */ + + /* Now process any build-specific attributes retrieved from DNS */ + + /* All done */ de_cleanup(&de); + return result; - return CURLE_COULDNT_RESOLVE_HOST; - } + } /* !data->req.doh.pending */ + /* else wait for pending DOH transactions to complete */ return CURLE_OK; } diff --git a/libs/libcurl/src/doh.h b/libs/libcurl/src/doh.h index f522d33085..fc053eddf9 100644 --- a/libs/libcurl/src/doh.h +++ b/libs/libcurl/src/doh.h @@ -55,14 +55,16 @@ typedef enum { DOH_DNS_UNEXPECTED_TYPE, /* 9 */ DOH_DNS_UNEXPECTED_CLASS, /* 10 */ DOH_NO_CONTENT, /* 11 */ - DOH_DNS_BAD_ID /* 12 */ + DOH_DNS_BAD_ID, /* 12 */ + DOH_DNS_NAME_TOO_LONG /* 13 */ } DOHcode; typedef enum { DNS_TYPE_A = 1, DNS_TYPE_NS = 2, DNS_TYPE_CNAME = 5, - DNS_TYPE_AAAA = 28 + DNS_TYPE_AAAA = 28, + DNS_TYPE_DNAME = 39 /* RFC6672 */ } DNStype; #define DOH_MAX_ADDR 24 diff --git a/libs/libcurl/src/dotdot.c b/libs/libcurl/src/dotdot.c index 2c6177aead..fe4f4971f1 100644 --- a/libs/libcurl/src/dotdot.c +++ b/libs/libcurl/src/dotdot.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/dotdot.h b/libs/libcurl/src/dotdot.h index 125af43671..f70b1db3fe 100644 --- a/libs/libcurl/src/dotdot.h +++ b/libs/libcurl/src/dotdot.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c index 001648d49b..6382cee3d5 100644 --- a/libs/libcurl/src/easy.c +++ b/libs/libcurl/src/easy.c @@ -72,7 +72,7 @@ #include "warnless.h" #include "multiif.h" #include "sigpipe.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "setopt.h" #include "http_digest.h" #include "system_win32.h" @@ -157,20 +157,20 @@ static CURLcode global_init(long flags, bool memoryfuncs) if(!Curl_ssl_init()) { DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n")); - return CURLE_FAILED_INIT; + goto fail; } #ifdef WIN32 if(Curl_win32_init(flags)) { DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); - return CURLE_FAILED_INIT; + goto fail; } #endif #ifdef __AMIGA__ if(!Curl_amiga_init()) { DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n")); - return CURLE_FAILED_INIT; + goto fail; } #endif @@ -182,14 +182,14 @@ static CURLcode global_init(long flags, bool memoryfuncs) if(Curl_resolver_global_init()) { DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n")); - return CURLE_FAILED_INIT; + goto fail; } (void)Curl_ipv6works(); #if defined(USE_SSH) if(Curl_ssh_init()) { - return CURLE_FAILED_INIT; + goto fail; } #endif @@ -201,6 +201,10 @@ static CURLcode global_init(long flags, bool memoryfuncs) Curl_version_init(); return CURLE_OK; + + fail: + initialized--; /* undo the increase */ + return CURLE_FAILED_INIT; } @@ -1027,9 +1031,10 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) Curl_update_timer(data->multi); } - /* This transfer may have been moved in or out of the bundle, update - the corresponding socket callback, if used */ - Curl_updatesocket(data); + if(!data->state.done) + /* This transfer may have been moved in or out of the bundle, update the + corresponding socket callback, if used */ + Curl_updatesocket(data); return result; } diff --git a/libs/libcurl/src/easyif.h b/libs/libcurl/src/easyif.h index 6ba7e549d7..8a309c55b6 100644 --- a/libs/libcurl/src/easyif.h +++ b/libs/libcurl/src/easyif.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/file.c b/libs/libcurl/src/file.c index d349cd9241..249237073f 100644 --- a/libs/libcurl/src/file.c +++ b/libs/libcurl/src/file.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -136,7 +136,7 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) struct Curl_easy *data = conn->data; char *real_path; struct FILEPROTO *file = data->req.protop; - int fd; + int fd = -1; #ifdef DOS_FILESYSTEM size_t i; char *actual_path; @@ -181,7 +181,9 @@ static CURLcode file_connect(struct connectdata *conn, bool *done) return CURLE_URL_MALFORMAT; } - fd = open_readonly(actual_path, O_RDONLY|O_BINARY); + if(strncmp("\\\\", actual_path, 2)) + /* refuse to open path that starts with two backslashes */ + fd = open_readonly(actual_path, O_RDONLY|O_BINARY); file->path = actual_path; #else if(memchr(real_path, 0, real_path_len)) { diff --git a/libs/libcurl/src/file.h b/libs/libcurl/src/file.h index 20828ad4a9..f6b74a7f72 100644 --- a/libs/libcurl/src/file.h +++ b/libs/libcurl/src/file.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c index 8072a33d5d..469096f0f6 100644 --- a/libs/libcurl/src/ftp.c +++ b/libs/libcurl/src/ftp.c @@ -2039,13 +2039,11 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn, &year, &month, &day, &hour, &minute, &second)) { /* we have a time, reformat it */ char timebuf[24]; - time_t secs = time(NULL); - msnprintf(timebuf, sizeof(timebuf), "%04d%02d%02d %02d:%02d:%02d GMT", year, month, day, hour, minute, second); /* now, convert this into a time() value: */ - data->info.filetime = curl_getdate(timebuf, &secs); + data->info.filetime = Curl_getdate_capped(timebuf); } #ifdef CURL_FTP_HTTPSTYLE_HEAD diff --git a/libs/libcurl/src/ftplistparser.h b/libs/libcurl/src/ftplistparser.h index 8128887c0b..b34ae9b63a 100644 --- a/libs/libcurl/src/ftplistparser.h +++ b/libs/libcurl/src/ftplistparser.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/getinfo.h b/libs/libcurl/src/getinfo.h index aecf717f75..8d2af4266d 100644 --- a/libs/libcurl/src/getinfo.h +++ b/libs/libcurl/src/getinfo.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/gopher.h b/libs/libcurl/src/gopher.h index 501c990a85..dec2557fc6 100644 --- a/libs/libcurl/src/gopher.h +++ b/libs/libcurl/src/gopher.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/hostcheck.h b/libs/libcurl/src/hostcheck.h index f562df9ae7..9c180856ad 100644 --- a/libs/libcurl/src/hostcheck.h +++ b/libs/libcurl/src/hostcheck.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c index d4e8f9366a..b434b390a2 100644 --- a/libs/libcurl/src/hostip.c +++ b/libs/libcurl/src/hostip.c @@ -1021,6 +1021,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) CURLcode Curl_resolv_check(struct connectdata *conn, struct Curl_dns_entry **dns) { +#if defined(CURL_DISABLE_DOH) && !defined(CURLRES_ASYNCH) + (void)dns; +#endif + if(conn->data->set.doh) return Curl_doh_is_resolved(conn, dns); return Curl_resolver_is_resolved(conn, dns); diff --git a/libs/libcurl/src/hostip4.c b/libs/libcurl/src/hostip4.c index e6ba710d83..2636851e68 100644 --- a/libs/libcurl/src/hostip4.c +++ b/libs/libcurl/src/hostip4.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 @@ -131,6 +131,16 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, struct in_addr in; struct hostent *buf = NULL; +#ifdef ENABLE_IPV6 + { + struct in6_addr in6; + /* check if this is an IPv6 address string */ + if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0) + /* This is an IPv6 address literal */ + return Curl_ip2addr(AF_INET6, &in6, hostname, port); + } +#endif /* ENABLE_IPV6 */ + if(Curl_inet_pton(AF_INET, hostname, &in) > 0) /* This is a dotted IP address 123.123.123.123-style */ return Curl_ip2addr(AF_INET, &in, hostname, port); diff --git a/libs/libcurl/src/hostsyn.c b/libs/libcurl/src/hostsyn.c index 3de6746f52..9e31008d2c 100644 --- a/libs/libcurl/src/hostsyn.c +++ b/libs/libcurl/src/hostsyn.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c index 4631a7f36b..837f53c415 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -641,7 +641,7 @@ output_auth_headers(struct connectdata *conn, { const char *auth = NULL; CURLcode result = CURLE_OK; -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO) +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) struct Curl_easy *data = conn->data; #endif @@ -1617,7 +1617,8 @@ CURLcode Curl_http_done(struct connectdata *conn, Curl_add_buffer_free(&http->send_buffer); } - Curl_http2_done(conn, premature); + Curl_http2_done(data, premature); + Curl_quic_done(data, premature); Curl_mime_cleanpart(&http->form); @@ -3973,7 +3974,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, else if(checkprefix("Retry-After:", k->p)) { /* Retry-After = HTTP-date / delay-seconds */ curl_off_t retry_after = 0; /* zero for unknown or "now" */ - time_t date = curl_getdate(&k->p[12], NULL); + time_t date = Curl_getdate_capped(&k->p[12]); if(-1 == date) { /* not a date, try it as a decimal number */ (void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after); @@ -4031,9 +4032,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, #endif else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) && (data->set.timecondition || data->set.get_filetime) ) { - time_t secs = time(NULL); - k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"), - &secs); + k->timeofdoc = Curl_getdate_capped(k->p + strlen("Last-Modified:")); if(data->set.get_filetime) data->info.filetime = k->timeofdoc; } diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h index a3a2757025..70d5dccec6 100644 --- a/libs/libcurl/src/http.h +++ b/libs/libcurl/src/http.h @@ -193,12 +193,17 @@ struct HTTP { #ifdef ENABLE_QUIC /*********** for HTTP/3 we store stream-local data here *************/ int64_t stream3_id; /* stream we are interested in */ + bool firstheader; /* FALSE until headers arrive */ bool firstbody; /* FALSE until body arrives */ bool h3req; /* FALSE until request is issued */ bool upload_done; #endif #ifdef USE_NGHTTP3 + size_t unacked_window; struct h3out *h3out; /* per-stream buffers for upload */ + char *overflow_buf; /* excess data received during a single Curl_read */ + size_t overflow_buflen; /* amount of data currently in overflow_buf */ + size_t overflow_bufsize; /* size of the overflow_buf allocation */ #endif }; diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index 6315fc4014..65f3513ee5 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -68,7 +68,7 @@ #ifdef DEBUG_HTTP2 #define H2BUGF(x) x #else -#define H2BUGF(x) do { } WHILE_FALSE +#define H2BUGF(x) do { } while(0) #endif @@ -1169,11 +1169,10 @@ static void populate_settings(struct connectdata *conn, httpc->local_settings_num = 3; } -void Curl_http2_done(struct connectdata *conn, bool premature) +void Curl_http2_done(struct Curl_easy *data, bool premature) { - struct Curl_easy *data = conn->data; struct HTTP *http = data->req.protop; - struct http_conn *httpc = &conn->proto.httpc; + struct http_conn *httpc = &data->conn->proto.httpc; /* there might be allocated resources done before this got the 'h2' pointer setup */ diff --git a/libs/libcurl/src/http2.h b/libs/libcurl/src/http2.h index 93058ccb31..12d36eef9b 100644 --- a/libs/libcurl/src/http2.h +++ b/libs/libcurl/src/http2.h @@ -50,7 +50,7 @@ CURLcode Curl_http2_switched(struct connectdata *conn, /* called from http_setup_conn */ void Curl_http2_setup_conn(struct connectdata *conn); void Curl_http2_setup_req(struct Curl_easy *data); -void Curl_http2_done(struct connectdata *conn, bool premature); +void Curl_http2_done(struct Curl_easy *data, bool premature); CURLcode Curl_http2_done_sending(struct connectdata *conn); CURLcode Curl_http2_add_child(struct Curl_easy *parent, struct Curl_easy *child, diff --git a/libs/libcurl/src/http_ntlm.c b/libs/libcurl/src/http_ntlm.c index e4a4fe05d0..342b2424f3 100644 --- a/libs/libcurl/src/http_ntlm.c +++ b/libs/libcurl/src/http_ntlm.c @@ -44,9 +44,7 @@ /* SSL backend-specific #if branches in this file must be kept in the order documented in curl_ntlm_core. */ -#if defined(NTLM_NEEDS_NSS_INIT) -#include "vtls/nssg.h" -#elif defined(USE_WINDOWS_SSPI) +#if defined(USE_WINDOWS_SSPI) #include "curl_sspi.h" #endif @@ -137,11 +135,6 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) DEBUGASSERT(conn); DEBUGASSERT(conn->data); -#if defined(NTLM_NEEDS_NSS_INIT) - if(CURLE_OK != Curl_nss_force_init(conn->data)) - return CURLE_OUT_OF_MEMORY; -#endif - if(proxy) { allocuserpwd = &conn->allocptr.proxyuserpwd; userp = conn->http_proxy.user; diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c index f095455a51..75c7a60c35 100644 --- a/libs/libcurl/src/http_proxy.c +++ b/libs/libcurl/src/http_proxy.c @@ -58,8 +58,9 @@ static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex) Curl_ssl_connect_nonblocking(conn, sockindex, &conn->bits.proxy_ssl_connected[sockindex]); if(result) - conn->bits.close = TRUE; /* a failed connection is marked for closure to - prevent (bad) re-use or similar */ + /* a failed connection is marked for closure to prevent (bad) re-use or + similar */ + connclose(conn, "TLS handshake failed"); } return result; #else diff --git a/libs/libcurl/src/imap.h b/libs/libcurl/src/imap.h index 0efcfd293c..4786f56241 100644 --- a/libs/libcurl/src/imap.h +++ b/libs/libcurl/src/imap.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2009 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2009 - 2019, 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 diff --git a/libs/libcurl/src/inet_ntop.c b/libs/libcurl/src/inet_ntop.c index 855981c666..9a5af7f421 100644 --- a/libs/libcurl/src/inet_ntop.c +++ b/libs/libcurl/src/inet_ntop.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1996-2001 Internet Software Consortium. + * Copyright (C) 1996-2019 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/libcurl/src/inet_ntop.h b/libs/libcurl/src/inet_ntop.h index d150bb6937..9d3f237f37 100644 --- a/libs/libcurl/src/inet_ntop.h +++ b/libs/libcurl/src/inet_ntop.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/inet_pton.c b/libs/libcurl/src/inet_pton.c index 0d65ae0ec7..9c87a05620 100644 --- a/libs/libcurl/src/inet_pton.c +++ b/libs/libcurl/src/inet_pton.c @@ -1,6 +1,6 @@ /* This is from the BIND 4.9.4 release, modified to compile by itself */ -/* Copyright (c) 1996 by Internet Software Consortium. +/* Copyright (c) 1996 - 2019 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/libs/libcurl/src/inet_pton.h b/libs/libcurl/src/inet_pton.h index 0209b9b7b7..e695af9c66 100644 --- a/libs/libcurl/src/inet_pton.h +++ b/libs/libcurl/src/inet_pton.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/krb5.c b/libs/libcurl/src/krb5.c index 5a47d481b4..f50287aec6 100644 --- a/libs/libcurl/src/krb5.c +++ b/libs/libcurl/src/krb5.c @@ -2,7 +2,7 @@ * * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). - * Copyright (c) 2004 - 2017 Daniel Stenberg + * Copyright (c) 2004 - 2019 Daniel Stenberg * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c index af3d61c57e..771edb4e98 100644 --- a/libs/libcurl/src/ldap.c +++ b/libs/libcurl/src/ldap.c @@ -112,7 +112,7 @@ static void _ldap_free_urldesc(LDAPURLDesc *ludp); #define LDAP_TRACE(x) do { \ _ldap_trace("%u: ", __LINE__); \ _ldap_trace x; \ - } WHILE_FALSE + } while(0) static void _ldap_trace(const char *fmt, ...); #else diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index 55c2ed494d..236ec4279b 100644 --- a/libs/libcurl/src/libcurl.plist +++ b/libs/libcurl/src/libcurl.plist @@ -15,7 +15,7 @@ <string>se.haxx.curl.libcurl</string> <key>CFBundleVersion</key> - <string>7.67.0</string> + <string>7.68.0</string> <key>CFBundleName</key> <string>libcurl</string> @@ -27,9 +27,9 @@ <string>????</string> <key>CFBundleShortVersionString</key> - <string>libcurl 7.67.0</string> + <string>libcurl 7.68.0</string> <key>CFBundleGetInfoString</key> - <string>libcurl.plist 7.67.0</string> + <string>libcurl.plist 7.68.0</string> </dict> </plist> diff --git a/libs/libcurl/src/llist.h b/libs/libcurl/src/llist.h index b9d4c89a98..a5e2ecbfb4 100644 --- a/libs/libcurl/src/llist.h +++ b/libs/libcurl/src/llist.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/memdebug.h b/libs/libcurl/src/memdebug.h index 5236f60fa5..7ca4426269 100644 --- a/libs/libcurl/src/memdebug.h +++ b/libs/libcurl/src/memdebug.h @@ -169,6 +169,6 @@ CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); */ #define Curl_safefree(ptr) \ - do { free((ptr)); (ptr) = NULL;} WHILE_FALSE + do { free((ptr)); (ptr) = NULL;} while(0) #endif /* HEADER_CURL_MEMDEBUG_H */ diff --git a/libs/libcurl/src/mprintf.c b/libs/libcurl/src/mprintf.c index e190936782..bc0091351d 100644 --- a/libs/libcurl/src/mprintf.c +++ b/libs/libcurl/src/mprintf.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1999 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1999 - 2019, 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 @@ -104,7 +104,7 @@ static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; done++; \ else \ return done; /* return immediately on failure */ \ - } WHILE_FALSE + } while(0) /* Data type to read from the arglist */ typedef enum { diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index 6dfe8842e7..6d819b4aaa 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -46,6 +46,7 @@ #include "connect.h" #include "http_proxy.h" #include "http2.h" +#include "socketpair.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -259,6 +260,7 @@ static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh, /* make/add new hash entry */ if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) { + Curl_hash_destroy(&check->transfers); free(check); return NULL; /* major failure */ } @@ -367,6 +369,21 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ /* -1 means it not set by user, use the default value */ multi->maxconnects = -1; + +#ifdef ENABLE_WAKEUP + if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) { + multi->wakeup_pair[0] = CURL_SOCKET_BAD; + multi->wakeup_pair[1] = CURL_SOCKET_BAD; + } + else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 || + curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) { + sclose(multi->wakeup_pair[0]); + sclose(multi->wakeup_pair[1]); + multi->wakeup_pair[0] = CURL_SOCKET_BAD; + multi->wakeup_pair[1] = CURL_SOCKET_BAD; + } +#endif + return multi; error: @@ -531,6 +548,8 @@ 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(conn); @@ -567,15 +586,17 @@ static CURLcode multi_done(struct Curl_easy *data, process_pending_handles(data->multi); /* connection / multiplex */ + CONN_LOCK(data); detach_connnection(data); if(CONN_INUSE(conn)) { /* Stop if still used. */ + CONN_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) { @@ -618,7 +639,10 @@ static CURLcode multi_done(struct Curl_easy *data, #endif ) || conn->bits.close || (premature && !(conn->handler->flags & PROTOPT_STREAM))) { - CURLcode res2 = Curl_disconnect(data, conn, premature); + CURLcode res2; + connclose(conn, "disconnecting"); + CONN_UNLOCK(data); + res2 = Curl_disconnect(data, conn, premature); /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ @@ -635,9 +659,9 @@ static CURLcode multi_done(struct Curl_easy *data, conn->bits.httpproxy ? conn->http_proxy.host.dispname : conn->bits.conn_to_host ? conn->conn_to_host.dispname : conn->host.dispname); - /* the connection is no longer in use by this transfer */ - if(Curl_conncache_return_conn(conn)) { + CONN_UNLOCK(data); + if(Curl_conncache_return_conn(data, conn)) { /* remember the most recently used connection */ data->state.lastconnect = conn; infof(data, "%s\n", buffer); @@ -695,11 +719,6 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, easy_owns_conn = TRUE; } - /* The timer must be shut down before data->multi is set to NULL, - else the timenode will remain in the splay tree after - curl_easy_cleanup is called. */ - Curl_expire_clear(data); - if(data->conn) { /* we must call multi_done() here (if we still own the connection) so that @@ -715,6 +734,11 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, } } + /* The timer must be shut down before data->multi is set to NULL, else the + timenode will remain in the splay tree after curl_easy_cleanup is + called. Do it after multi_done() in case that sets another time! */ + Curl_expire_clear(data); + if(data->connect_queue.ptr) /* the handle was in the pending list waiting for an available connection, so go ahead and remove it */ @@ -744,10 +768,8 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, vanish with this handle */ /* Remove the association between the connection and the handle */ - if(data->conn) { - data->conn->data = NULL; + if(data->conn) detach_connnection(data); - } #ifdef USE_LIBPSL /* Remove the PSL association. */ @@ -1005,7 +1027,8 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, unsigned int extra_nfds, int timeout_ms, int *ret, - bool extrawait) /* when no socket, wait */ + bool extrawait, /* when no socket, wait */ + bool use_wakeup) { struct Curl_easy *data; curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; @@ -1059,6 +1082,12 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, curlfds = nfds; /* number of internal file descriptors */ nfds += extra_nfds; /* add the externally provided ones */ +#ifdef ENABLE_WAKEUP + if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { + ++nfds; + } +#endif + if(nfds > NUM_POLLS_ON_STACK) { /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes big, so at 2^29 sockets this value might wrap. When a process gets @@ -1117,6 +1146,14 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, ++nfds; } +#ifdef ENABLE_WAKEUP + if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { + ufds[nfds].fd = multi->wakeup_pair[0]; + ufds[nfds].events = POLLIN; + ++nfds; + } +#endif + if(nfds) { int pollrc; /* wait... */ @@ -1140,6 +1177,29 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, extra_fds[i].revents = mask; } + +#ifdef ENABLE_WAKEUP + if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { + if(ufds[curlfds + extra_nfds].revents & POLLIN) { + char buf[64]; + while(1) { + /* the reading socket is non-blocking, try to read + data from it until it receives an error (except EINTR). + In normal cases it will get EAGAIN or EWOULDBLOCK + when there is no more data, breaking the loop. */ + if(sread(multi->wakeup_pair[0], buf, sizeof(buf)) < 0) { +#ifndef USE_WINSOCK + if(EINTR == SOCKERRNO) + continue; +#endif + break; + } + } + /* do not count the wakeup socket into the returned value */ + retcode--; + } + } +#endif } } @@ -1147,7 +1207,7 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, free(ufds); if(ret) *ret = retcode; - if(!extrawait || extra_fds || curlfds) + if(!extrawait || nfds) /* if any socket was checked */ ; else { @@ -1157,6 +1217,10 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, if(!curl_multi_timeout(multi, &sleep_ms) && sleep_ms) { if(sleep_ms > timeout_ms) sleep_ms = timeout_ms; + /* when there are no easy handles in the multi, this holds a -1 + timeout */ + else if((sleep_ms < 0) && extrawait) + sleep_ms = timeout_ms; Curl_wait_ms((int)sleep_ms); } } @@ -1170,7 +1234,8 @@ CURLMcode curl_multi_wait(struct Curl_multi *multi, int timeout_ms, int *ret) { - return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE); + return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, FALSE, + FALSE); } CURLMcode curl_multi_poll(struct Curl_multi *multi, @@ -1179,7 +1244,55 @@ CURLMcode curl_multi_poll(struct Curl_multi *multi, int timeout_ms, int *ret) { - return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE); + return Curl_multi_wait(multi, extra_fds, extra_nfds, timeout_ms, ret, TRUE, + TRUE); +} + +CURLMcode curl_multi_wakeup(struct Curl_multi *multi) +{ + /* this function is usually called from another thread, + it has to be careful only to access parts of the + Curl_multi struct that are constant */ + + /* GOOD_MULTI_HANDLE can be safely called */ + if(!GOOD_MULTI_HANDLE(multi)) + return CURLM_BAD_HANDLE; + +#ifdef ENABLE_WAKEUP + /* the wakeup_pair variable is only written during init and cleanup, + making it safe to access from another thread after the init part + and before cleanup */ + if(multi->wakeup_pair[1] != CURL_SOCKET_BAD) { + char buf[1]; + buf[0] = 1; + while(1) { + /* swrite() is not thread-safe in general, because concurrent calls + can have their messages interleaved, but in this case the content + of the messages does not matter, which makes it ok to call. + + The write socket is set to non-blocking, this way this function + cannot block, making it safe to call even from the same thread + that will call Curl_multi_wait(). If swrite() returns that it + would block, it's considered successful because it means that + previous calls to this function will wake up the poll(). */ + if(swrite(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) { + int err = SOCKERRNO; + int return_success; +#ifdef USE_WINSOCK + return_success = WSAEWOULDBLOCK == err; +#else + if(EINTR == err) + continue; + return_success = EWOULDBLOCK == err || EAGAIN == err; +#endif + if(!return_success) + return CURLM_WAKEUP_FAILURE; + } + return CURLM_OK; + } + } +#endif + return CURLM_WAKEUP_FAILURE; } /* @@ -1242,6 +1355,7 @@ 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() */ @@ -2305,6 +2419,11 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) Curl_hash_destroy(&multi->hostcache); Curl_psl_destroy(&multi->psl); + +#ifdef ENABLE_WAKEUP + sclose(multi->wakeup_pair[0]); + sclose(multi->wakeup_pair[1]); +#endif free(multi); return CURLM_OK; diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h index b65bd96386..0bf09e6bb5 100644 --- a/libs/libcurl/src/multihandle.h +++ b/libs/libcurl/src/multihandle.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2020, 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 @@ -24,6 +24,7 @@ #include "conncache.h" #include "psl.h" +#include "socketpair.h" struct Curl_message { struct curl_llist_element list; @@ -66,6 +67,14 @@ typedef enum { #define CURLPIPE_ANY (CURLPIPE_MULTIPLEX) +#if defined(USE_SOCKETPAIR) && !defined(USE_BLOCKING_SOCKETS) +#define ENABLE_WAKEUP +#endif + + +/* value for MAXIMUM CONCURRENT STREAMS upper limit */ +#define INITIAL_MAX_CONCURRENT_STREAMS ((1U << 31) - 1) + /* This is the struct known as CURLM on the outside */ struct Curl_multi { /* First a simple identifier to easier detect if a user mix up @@ -134,6 +143,11 @@ struct Curl_multi { previous callback */ bool in_callback; /* true while executing a callback */ long max_concurrent_streams; /* max concurrent streams client to support */ + +#ifdef ENABLE_WAKEUP + curl_socket_t wakeup_pair[2]; /* socketpair() used for wakeup + 0 is used for read, 1 is used for write */ +#endif }; #endif /* HEADER_CURL_MULTIHANDLE_H */ diff --git a/libs/libcurl/src/nonblock.c b/libs/libcurl/src/nonblock.c index 4d105c1fea..abeb6598c2 100644 --- a/libs/libcurl/src/nonblock.c +++ b/libs/libcurl/src/nonblock.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/nonblock.h b/libs/libcurl/src/nonblock.h index eb18ea1c34..d50d315944 100644 --- a/libs/libcurl/src/nonblock.h +++ b/libs/libcurl/src/nonblock.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/parsedate.c b/libs/libcurl/src/parsedate.c index f4b18d091a..585d7ea404 100644 --- a/libs/libcurl/src/parsedate.c +++ b/libs/libcurl/src/parsedate.c @@ -587,6 +587,30 @@ time_t curl_getdate(const char *p, const time_t *now) return -1; } +/* Curl_getdate_capped() differs from curl_getdate() in that this will return + TIME_T_MAX in case the parsed time value was too big, instead of an + error. */ + +time_t Curl_getdate_capped(const char *p) +{ + time_t parsed = -1; + int rc = parsedate(p, &parsed); + + switch(rc) { + case PARSEDATE_OK: + if(parsed == -1) + /* avoid returning -1 for a working scenario */ + parsed++; + return parsed; + case PARSEDATE_LATER: + /* this returns the maximum time value */ + return parsed; + default: + return -1; /* everything else is fail */ + } + /* UNREACHABLE */ +} + /* * Curl_gmtime() is a gmtime() replacement for portability. Do not use the * gmtime_r() or gmtime() functions anywhere else but here. diff --git a/libs/libcurl/src/parsedate.h b/libs/libcurl/src/parsedate.h index 8dc3b90ec7..8c7ae94e43 100644 --- a/libs/libcurl/src/parsedate.h +++ b/libs/libcurl/src/parsedate.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 @@ -27,4 +27,10 @@ extern const char * const Curl_month[12]; CURLcode Curl_gmtime(time_t intime, struct tm *store); +/* Curl_getdate_capped() differs from curl_getdate() in that this will return + TIME_T_MAX in case the parsed time value was too big, instead of an + error. */ + +time_t Curl_getdate_capped(const char *p); + #endif /* HEADER_CURL_PARSEDATE_H */ diff --git a/libs/libcurl/src/pop3.h b/libs/libcurl/src/pop3.h index a8e697cde2..3ba7999771 100644 --- a/libs/libcurl/src/pop3.h +++ b/libs/libcurl/src/pop3.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2009 - 2019, 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 diff --git a/libs/libcurl/src/progress.c b/libs/libcurl/src/progress.c index 2aa9295993..60a941ab2d 100644 --- a/libs/libcurl/src/progress.c +++ b/libs/libcurl/src/progress.c @@ -594,11 +594,13 @@ int Curl_pgrsUpdate(struct connectdata *conn) data->progress.size_ul, data->progress.uploaded); Curl_set_in_callback(data, false); - if(result) - failf(data, "Callback aborted"); - return result; + if(result != CURL_PROGRESSFUNC_CONTINUE) { + if(result) + failf(data, "Callback aborted"); + return result; + } } - if(data->set.fprogress) { + else if(data->set.fprogress) { int result; /* The older deprecated callback is set, call that */ Curl_set_in_callback(data, true); @@ -608,9 +610,11 @@ int Curl_pgrsUpdate(struct connectdata *conn) (double)data->progress.size_ul, (double)data->progress.uploaded); Curl_set_in_callback(data, false); - if(result) - failf(data, "Callback aborted"); - return result; + if(result != CURL_PROGRESSFUNC_CONTINUE) { + if(result) + failf(data, "Callback aborted"); + return result; + } } if(showprogress) diff --git a/libs/libcurl/src/quic.h b/libs/libcurl/src/quic.h index 6c132a3247..1eb23e9766 100644 --- a/libs/libcurl/src/quic.h +++ b/libs/libcurl/src/quic.h @@ -45,9 +45,13 @@ CURLcode Curl_quic_is_connected(struct connectdata *conn, bool *connected); int Curl_quic_ver(char *p, size_t len); CURLcode Curl_quic_done_sending(struct connectdata *conn); +void Curl_quic_done(struct Curl_easy *data, bool premature); +bool Curl_quic_data_pending(const struct Curl_easy *data); #else /* ENABLE_QUIC */ #define Curl_quic_done_sending(x) +#define Curl_quic_done(x,y) +#define Curl_quic_data_pending(x) #endif /* !ENABLE_QUIC */ #endif /* HEADER_CURL_QUIC_H */ diff --git a/libs/libcurl/src/rtsp.h b/libs/libcurl/src/rtsp.h index 2f9cc32c8e..1aae86456d 100644 --- a/libs/libcurl/src/rtsp.h +++ b/libs/libcurl/src/rtsp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/select.c b/libs/libcurl/src/select.c index 8cd9eb2add..2de503d370 100644 --- a/libs/libcurl/src/select.c +++ b/libs/libcurl/src/select.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/select.h b/libs/libcurl/src/select.h index f5652a74f7..687ab164c4 100644 --- a/libs/libcurl/src/select.h +++ b/libs/libcurl/src/select.h @@ -109,7 +109,7 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, SET_SOCKERRNO(EINVAL); \ return -1; \ } \ -} WHILE_FALSE +} while(0) #endif #endif /* HEADER_CURL_SELECT_H */ diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index 5913ea4060..6c38b04b23 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -36,7 +36,7 @@ #include "sendf.h" #include "connect.h" #include "vtls/vtls.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "easyif.h" #include "multiif.h" #include "non-ascii.h" @@ -224,7 +224,7 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex) (void)sockindex; return false; } -#define pre_receive_plain(c,n) do {} WHILE_FALSE +#define pre_receive_plain(c,n) do {} while(0) #define get_pre_recved(c,n,b,l) 0 #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index 64c29e3336..5f88ad3afd 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -2133,6 +2133,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.ssl.enable_beast = (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); + data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); break; #ifndef CURL_DISABLE_PROXY @@ -2141,6 +2142,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.proxy_ssl.enable_beast = (bool)((arg&CURLSSLOPT_ALLOW_BEAST) ? TRUE : FALSE); data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); + data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN); break; #endif @@ -2612,14 +2614,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) result = CURLE_NOT_BUILT_IN; #endif break; -#ifdef USE_NGHTTP2 case CURLOPT_SSL_ENABLE_NPN: data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE; break; case CURLOPT_SSL_ENABLE_ALPN: data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE; break; -#endif #ifdef USE_UNIX_SOCKETS case CURLOPT_UNIX_SOCKET_PATH: data->set.abstract_unix_socket = FALSE; diff --git a/libs/libcurl/src/sha256.c b/libs/libcurl/src/sha256.c index f9287af232..bcaaeae308 100644 --- a/libs/libcurl/src/sha256.c +++ b/libs/libcurl/src/sha256.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2018, Florin Petriuc, <petriuc.florin@gmail.com> + * Copyright (C) 1998 - 2019, Florin Petriuc, <petriuc.florin@gmail.com> * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms diff --git a/libs/libcurl/src/slist.c b/libs/libcurl/src/slist.c index 392b84d13a..d27fbe19bc 100644 --- a/libs/libcurl/src/slist.c +++ b/libs/libcurl/src/slist.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/slist.h b/libs/libcurl/src/slist.h index d73dbf672d..799b3c060f 100644 --- a/libs/libcurl/src/slist.h +++ b/libs/libcurl/src/slist.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/smtp.h b/libs/libcurl/src/smtp.h index b67340a40c..20fc081190 100644 --- a/libs/libcurl/src/smtp.h +++ b/libs/libcurl/src/smtp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2009 - 2019, 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 diff --git a/libs/libcurl/src/sockaddr.h b/libs/libcurl/src/sockaddr.h index db146803ab..b037ee06c2 100644 --- a/libs/libcurl/src/sockaddr.h +++ b/libs/libcurl/src/sockaddr.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/socketpair.c b/libs/libcurl/src/socketpair.c index 1f0e2e4a4f..1ec0d75a46 100644 --- a/libs/libcurl/src/socketpair.c +++ b/libs/libcurl/src/socketpair.c @@ -40,6 +40,9 @@ #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> /* IPPROTO_TCP */ #endif +#ifdef HAVE_ARPA_INET_H +#include <arpa/inet.h> +#endif #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 #endif /* !INADDR_LOOPBACK */ diff --git a/libs/libcurl/src/socks.h b/libs/libcurl/src/socks.h index daa07c1275..3b319a6ef1 100644 --- a/libs/libcurl/src/socks.h +++ b/libs/libcurl/src/socks.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/strdup.c b/libs/libcurl/src/strdup.c index 51e7978b7f..1ab10fd644 100644 --- a/libs/libcurl/src/strdup.c +++ b/libs/libcurl/src/strdup.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c index d0650d80c5..29df5aa55a 100644 --- a/libs/libcurl/src/strerror.c +++ b/libs/libcurl/src/strerror.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2004 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2004 - 2020, 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 @@ -314,6 +314,9 @@ curl_easy_strerror(CURLcode error) case CURLE_AUTH_ERROR: return "An authentication function returned an error"; + case CURLE_HTTP3: + return "HTTP/3 error"; + /* error codes not used by current libcurl */ case CURLE_OBSOLETE20: case CURLE_OBSOLETE24: @@ -386,6 +389,9 @@ curl_multi_strerror(CURLMcode error) case CURLM_RECURSIVE_API_CALL: return "API function called from within callback"; + case CURLM_WAKEUP_FAILURE: + return "Wakeup is unavailable or failed"; + case CURLM_LAST: break; } @@ -436,19 +442,26 @@ curl_share_strerror(CURLSHcode error) } #ifdef USE_WINSOCK - -/* This function handles most / all (?) Winsock errors curl is able to produce. +/* This is a helper function for Curl_strerror that converts Winsock error + * codes (WSAGetLastError) to error messages. + * Returns NULL if no error message was found for error code. */ static const char * get_winsock_error (int err, char *buf, size_t len) { -#ifdef PRESERVE_WINDOWS_ERROR_CODE - DWORD old_win_err = GetLastError(); -#endif - int old_errno = errno; +#ifndef CURL_DISABLE_VERBOSE_STRINGS const char *p; +#endif -#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(!len) + return NULL; + + *buf = '\0'; + +#ifdef CURL_DISABLE_VERBOSE_STRINGS + (void)err; + return NULL; +#else switch(err) { case WSAEINTR: p = "Call interrupted"; @@ -617,26 +630,63 @@ get_winsock_error (int err, char *buf, size_t len) default: return NULL; } -#else - if(!err) - return NULL; - else - p = "error"; -#endif strncpy(buf, p, len); buf [len-1] = '\0'; + return buf; +#endif +} +#endif /* USE_WINSOCK */ - if(errno != old_errno) - errno = old_errno; +#if defined(WIN32) || defined(_WIN32_WCE) +/* This is a helper function for Curl_strerror that converts Windows API error + * codes (GetLastError) to error messages. + * Returns NULL if no error message was found for error code. + */ +static const char * +get_winapi_error(int err, char *buf, size_t buflen) +{ + char *p; -#ifdef PRESERVE_WINDOWS_ERROR_CODE - if(old_win_err != GetLastError()) - SetLastError(old_win_err); + if(!buflen) + return NULL; + + *buf = '\0'; + +#ifdef _WIN32_WCE + { + wchar_t wbuf[256]; + wbuf[0] = L'\0'; + + if(FormatMessage((FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, + LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { + size_t written = wcstombs(buf, wbuf, buflen - 1); + if(written != (size_t)-1) + buf[written] = '\0'; + else + *buf = '\0'; + } + } +#else + if(!FormatMessageA((FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS), NULL, err, + LANG_NEUTRAL, buf, (DWORD)buflen, NULL)) { + *buf = '\0'; + } #endif - return buf; + /* Truncate multiple lines */ + p = strchr(buf, '\n'); + if(p) { + if(p > buf && *(p-1) == '\r') + *(p-1) = '\0'; + else + *p = '\0'; + } + + return (*buf ? buf : NULL); } -#endif /* USE_WINSOCK */ +#endif /* WIN32 || _WIN32_WCE */ /* * Our thread-safe and smart strerror() replacement. @@ -648,6 +698,14 @@ get_winsock_error (int err, char *buf, size_t len) * * We don't do range checking (on systems other than Windows) since there is * no good reliable and portable way to do it. + * + * On Windows different types of error codes overlap. This function has an + * order of preference when trying to match error codes: + * CRT (errno), Winsock (WSAGetLastError), Windows API (GetLastError). + * + * It may be more correct to call one of the variant functions instead: + * Call Curl_sspi_strerror if the error code is definitely Windows SSPI. + * Call Curl_winapi_strerror if the error code is definitely Windows API. */ const char *Curl_strerror(int err, char *buf, size_t buflen) { @@ -658,35 +716,30 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) char *p; size_t max; + if(!buflen) + return NULL; + DEBUGASSERT(err >= 0); max = buflen - 1; *buf = '\0'; -#ifdef USE_WINSOCK - -#ifdef _WIN32_WCE - { - wchar_t wbuf[256]; - wbuf[0] = L'\0'; - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL); - wcstombs(buf, wbuf, max); - } -#else +#if defined(WIN32) || defined(_WIN32_WCE) +#if defined(WIN32) /* 'sys_nerr' is the maximum errno number, it is not widely portable */ if(err >= 0 && err < sys_nerr) strncpy(buf, strerror(err), max); - else { - if(!get_winsock_error(err, buf, max) && - !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - LANG_NEUTRAL, buf, (DWORD)max, NULL)) + else +#endif + { + if( +#ifdef USE_WINSOCK + !get_winsock_error(err, buf, max) && +#endif + !get_winapi_error((DWORD)err, buf, max)) msnprintf(buf, max, "Unknown error %d (%#x)", err, err); } -#endif - -#else /* not USE_WINSOCK coming up */ +#else /* not Windows coming up */ #if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R) /* @@ -734,7 +787,7 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) } #endif -#endif /* end of ! USE_WINSOCK */ +#endif /* end of not Windows */ buf[max] = '\0'; /* make sure the string is zero terminated */ @@ -757,7 +810,52 @@ const char *Curl_strerror(int err, char *buf, size_t buflen) return buf; } +/* + * Curl_winapi_strerror: + * Variant of Curl_strerror if the error code is definitely Windows API. + */ +#if defined(WIN32) || defined(_WIN32_WCE) +const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen) +{ +#ifdef PRESERVE_WINDOWS_ERROR_CODE + DWORD old_win_err = GetLastError(); +#endif + int old_errno = errno; + + if(!buflen) + return NULL; + + *buf = '\0'; + +#ifndef CURL_DISABLE_VERBOSE_STRINGS + if(!get_winapi_error(err, buf, buflen)) { + msnprintf(buf, buflen, "Unknown error %u (0x%08X)", err, err); + } +#else + { + const char *txt = (err == ERROR_SUCCESS) ? "No error" : "Error"; + strncpy(buf, txt, buflen); + buf[buflen - 1] = '\0'; + } +#endif + + if(errno != old_errno) + errno = old_errno; + +#ifdef PRESERVE_WINDOWS_ERROR_CODE + if(old_win_err != GetLastError()) + SetLastError(old_win_err); +#endif + + return buf; +} +#endif /* WIN32 || _WIN32_WCE */ + #ifdef USE_WINDOWS_SSPI +/* + * Curl_sspi_strerror: + * Variant of Curl_strerror if the error code is definitely Windows SSPI. + */ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) { #ifdef PRESERVE_WINDOWS_ERROR_CODE @@ -765,18 +863,11 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) #endif int old_errno = errno; const char *txt; - char *outbuf; - size_t outmax; -#ifndef CURL_DISABLE_VERBOSE_STRINGS - char txtbuf[80]; - char msgbuf[256]; - char *p, *str, *msg = NULL; - bool msg_formatted = FALSE; -#endif - outbuf = buf; - outmax = buflen - 1; - *outbuf = '\0'; + if(!buflen) + return NULL; + + *buf = '\0'; #ifndef CURL_DISABLE_VERBOSE_STRINGS @@ -784,314 +875,121 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) case SEC_E_OK: txt = "No error"; break; - case CRYPT_E_REVOKED: - txt = "CRYPT_E_REVOKED"; - break; - case SEC_E_ALGORITHM_MISMATCH: - txt = "SEC_E_ALGORITHM_MISMATCH"; - break; - case SEC_E_BAD_BINDINGS: - txt = "SEC_E_BAD_BINDINGS"; - break; - case SEC_E_BAD_PKGID: - txt = "SEC_E_BAD_PKGID"; - break; - case SEC_E_BUFFER_TOO_SMALL: - txt = "SEC_E_BUFFER_TOO_SMALL"; - break; - case SEC_E_CANNOT_INSTALL: - txt = "SEC_E_CANNOT_INSTALL"; - break; - case SEC_E_CANNOT_PACK: - txt = "SEC_E_CANNOT_PACK"; - break; - case SEC_E_CERT_EXPIRED: - txt = "SEC_E_CERT_EXPIRED"; - break; - case SEC_E_CERT_UNKNOWN: - txt = "SEC_E_CERT_UNKNOWN"; - break; - case SEC_E_CERT_WRONG_USAGE: - txt = "SEC_E_CERT_WRONG_USAGE"; - break; - case SEC_E_CONTEXT_EXPIRED: - txt = "SEC_E_CONTEXT_EXPIRED"; - break; - case SEC_E_CROSSREALM_DELEGATION_FAILURE: - txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE"; - break; - case SEC_E_CRYPTO_SYSTEM_INVALID: - txt = "SEC_E_CRYPTO_SYSTEM_INVALID"; - break; - case SEC_E_DECRYPT_FAILURE: - txt = "SEC_E_DECRYPT_FAILURE"; - break; - case SEC_E_DELEGATION_POLICY: - txt = "SEC_E_DELEGATION_POLICY"; - break; - case SEC_E_DELEGATION_REQUIRED: - txt = "SEC_E_DELEGATION_REQUIRED"; - break; - case SEC_E_DOWNGRADE_DETECTED: - txt = "SEC_E_DOWNGRADE_DETECTED"; - break; - case SEC_E_ENCRYPT_FAILURE: - txt = "SEC_E_ENCRYPT_FAILURE"; - break; - case SEC_E_ILLEGAL_MESSAGE: - txt = "SEC_E_ILLEGAL_MESSAGE"; - break; - case SEC_E_INCOMPLETE_CREDENTIALS: - txt = "SEC_E_INCOMPLETE_CREDENTIALS"; - break; - case SEC_E_INCOMPLETE_MESSAGE: - txt = "SEC_E_INCOMPLETE_MESSAGE"; - break; - case SEC_E_INSUFFICIENT_MEMORY: - txt = "SEC_E_INSUFFICIENT_MEMORY"; - break; - case SEC_E_INTERNAL_ERROR: - txt = "SEC_E_INTERNAL_ERROR"; - break; - case SEC_E_INVALID_HANDLE: - txt = "SEC_E_INVALID_HANDLE"; - break; - case SEC_E_INVALID_PARAMETER: - txt = "SEC_E_INVALID_PARAMETER"; - break; - case SEC_E_INVALID_TOKEN: - txt = "SEC_E_INVALID_TOKEN"; - break; - case SEC_E_ISSUING_CA_UNTRUSTED: - txt = "SEC_E_ISSUING_CA_UNTRUSTED"; - break; - case SEC_E_ISSUING_CA_UNTRUSTED_KDC: - txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC"; - break; - case SEC_E_KDC_CERT_EXPIRED: - txt = "SEC_E_KDC_CERT_EXPIRED"; - break; - case SEC_E_KDC_CERT_REVOKED: - txt = "SEC_E_KDC_CERT_REVOKED"; - break; - case SEC_E_KDC_INVALID_REQUEST: - txt = "SEC_E_KDC_INVALID_REQUEST"; - break; - case SEC_E_KDC_UNABLE_TO_REFER: - txt = "SEC_E_KDC_UNABLE_TO_REFER"; - break; - case SEC_E_KDC_UNKNOWN_ETYPE: - txt = "SEC_E_KDC_UNKNOWN_ETYPE"; - break; - case SEC_E_LOGON_DENIED: - txt = "SEC_E_LOGON_DENIED"; - break; - case SEC_E_MAX_REFERRALS_EXCEEDED: - txt = "SEC_E_MAX_REFERRALS_EXCEEDED"; - break; - case SEC_E_MESSAGE_ALTERED: - txt = "SEC_E_MESSAGE_ALTERED"; - break; - case SEC_E_MULTIPLE_ACCOUNTS: - txt = "SEC_E_MULTIPLE_ACCOUNTS"; - break; - case SEC_E_MUST_BE_KDC: - txt = "SEC_E_MUST_BE_KDC"; - break; - case SEC_E_NOT_OWNER: - txt = "SEC_E_NOT_OWNER"; - break; - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY"; - break; - case SEC_E_NO_CREDENTIALS: - txt = "SEC_E_NO_CREDENTIALS"; - break; - case SEC_E_NO_IMPERSONATION: - txt = "SEC_E_NO_IMPERSONATION"; - break; - case SEC_E_NO_IP_ADDRESSES: - txt = "SEC_E_NO_IP_ADDRESSES"; - break; - case SEC_E_NO_KERB_KEY: - txt = "SEC_E_NO_KERB_KEY"; - break; - case SEC_E_NO_PA_DATA: - txt = "SEC_E_NO_PA_DATA"; - break; - case SEC_E_NO_S4U_PROT_SUPPORT: - txt = "SEC_E_NO_S4U_PROT_SUPPORT"; - break; - case SEC_E_NO_TGT_REPLY: - txt = "SEC_E_NO_TGT_REPLY"; - break; - case SEC_E_OUT_OF_SEQUENCE: - txt = "SEC_E_OUT_OF_SEQUENCE"; - break; - case SEC_E_PKINIT_CLIENT_FAILURE: - txt = "SEC_E_PKINIT_CLIENT_FAILURE"; - break; - case SEC_E_PKINIT_NAME_MISMATCH: - txt = "SEC_E_PKINIT_NAME_MISMATCH"; - break; - case SEC_E_POLICY_NLTM_ONLY: - txt = "SEC_E_POLICY_NLTM_ONLY"; - break; - case SEC_E_QOP_NOT_SUPPORTED: - txt = "SEC_E_QOP_NOT_SUPPORTED"; - break; - case SEC_E_REVOCATION_OFFLINE_C: - txt = "SEC_E_REVOCATION_OFFLINE_C"; - break; - case SEC_E_REVOCATION_OFFLINE_KDC: - txt = "SEC_E_REVOCATION_OFFLINE_KDC"; - break; - case SEC_E_SECPKG_NOT_FOUND: - txt = "SEC_E_SECPKG_NOT_FOUND"; - break; - case SEC_E_SECURITY_QOS_FAILED: - txt = "SEC_E_SECURITY_QOS_FAILED"; - break; - case SEC_E_SHUTDOWN_IN_PROGRESS: - txt = "SEC_E_SHUTDOWN_IN_PROGRESS"; - break; - case SEC_E_SMARTCARD_CERT_EXPIRED: - txt = "SEC_E_SMARTCARD_CERT_EXPIRED"; - break; - case SEC_E_SMARTCARD_CERT_REVOKED: - txt = "SEC_E_SMARTCARD_CERT_REVOKED"; - break; - case SEC_E_SMARTCARD_LOGON_REQUIRED: - txt = "SEC_E_SMARTCARD_LOGON_REQUIRED"; - break; - case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED: - txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED"; - break; - case SEC_E_TARGET_UNKNOWN: - txt = "SEC_E_TARGET_UNKNOWN"; - break; - case SEC_E_TIME_SKEW: - txt = "SEC_E_TIME_SKEW"; - break; - case SEC_E_TOO_MANY_PRINCIPALS: - txt = "SEC_E_TOO_MANY_PRINCIPALS"; - break; - case SEC_E_UNFINISHED_CONTEXT_DELETED: - txt = "SEC_E_UNFINISHED_CONTEXT_DELETED"; - break; - case SEC_E_UNKNOWN_CREDENTIALS: - txt = "SEC_E_UNKNOWN_CREDENTIALS"; - break; - case SEC_E_UNSUPPORTED_FUNCTION: - txt = "SEC_E_UNSUPPORTED_FUNCTION"; - break; - case SEC_E_UNSUPPORTED_PREAUTH: - txt = "SEC_E_UNSUPPORTED_PREAUTH"; - break; - case SEC_E_UNTRUSTED_ROOT: - txt = "SEC_E_UNTRUSTED_ROOT"; - break; - case SEC_E_WRONG_CREDENTIAL_HANDLE: - txt = "SEC_E_WRONG_CREDENTIAL_HANDLE"; - break; - case SEC_E_WRONG_PRINCIPAL: - txt = "SEC_E_WRONG_PRINCIPAL"; - break; - case SEC_I_COMPLETE_AND_CONTINUE: - txt = "SEC_I_COMPLETE_AND_CONTINUE"; - break; - case SEC_I_COMPLETE_NEEDED: - txt = "SEC_I_COMPLETE_NEEDED"; - break; - case SEC_I_CONTEXT_EXPIRED: - txt = "SEC_I_CONTEXT_EXPIRED"; - break; - case SEC_I_CONTINUE_NEEDED: - txt = "SEC_I_CONTINUE_NEEDED"; - break; - case SEC_I_INCOMPLETE_CREDENTIALS: - txt = "SEC_I_INCOMPLETE_CREDENTIALS"; - break; - case SEC_I_LOCAL_LOGON: - txt = "SEC_I_LOCAL_LOGON"; - break; - case SEC_I_NO_LSA_CONTEXT: - txt = "SEC_I_NO_LSA_CONTEXT"; - break; - case SEC_I_RENEGOTIATE: - txt = "SEC_I_RENEGOTIATE"; - break; - case SEC_I_SIGNATURE_NEEDED: - txt = "SEC_I_SIGNATURE_NEEDED"; - break; +#define SEC2TXT(sec) case sec: txt = #sec; break + SEC2TXT(CRYPT_E_REVOKED); + SEC2TXT(SEC_E_ALGORITHM_MISMATCH); + SEC2TXT(SEC_E_BAD_BINDINGS); + SEC2TXT(SEC_E_BAD_PKGID); + SEC2TXT(SEC_E_BUFFER_TOO_SMALL); + SEC2TXT(SEC_E_CANNOT_INSTALL); + SEC2TXT(SEC_E_CANNOT_PACK); + SEC2TXT(SEC_E_CERT_EXPIRED); + SEC2TXT(SEC_E_CERT_UNKNOWN); + SEC2TXT(SEC_E_CERT_WRONG_USAGE); + SEC2TXT(SEC_E_CONTEXT_EXPIRED); + SEC2TXT(SEC_E_CROSSREALM_DELEGATION_FAILURE); + SEC2TXT(SEC_E_CRYPTO_SYSTEM_INVALID); + SEC2TXT(SEC_E_DECRYPT_FAILURE); + SEC2TXT(SEC_E_DELEGATION_POLICY); + SEC2TXT(SEC_E_DELEGATION_REQUIRED); + SEC2TXT(SEC_E_DOWNGRADE_DETECTED); + SEC2TXT(SEC_E_ENCRYPT_FAILURE); + SEC2TXT(SEC_E_ILLEGAL_MESSAGE); + SEC2TXT(SEC_E_INCOMPLETE_CREDENTIALS); + SEC2TXT(SEC_E_INCOMPLETE_MESSAGE); + SEC2TXT(SEC_E_INSUFFICIENT_MEMORY); + SEC2TXT(SEC_E_INTERNAL_ERROR); + SEC2TXT(SEC_E_INVALID_HANDLE); + SEC2TXT(SEC_E_INVALID_PARAMETER); + SEC2TXT(SEC_E_INVALID_TOKEN); + SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED); + SEC2TXT(SEC_E_ISSUING_CA_UNTRUSTED_KDC); + SEC2TXT(SEC_E_KDC_CERT_EXPIRED); + SEC2TXT(SEC_E_KDC_CERT_REVOKED); + SEC2TXT(SEC_E_KDC_INVALID_REQUEST); + SEC2TXT(SEC_E_KDC_UNABLE_TO_REFER); + SEC2TXT(SEC_E_KDC_UNKNOWN_ETYPE); + SEC2TXT(SEC_E_LOGON_DENIED); + SEC2TXT(SEC_E_MAX_REFERRALS_EXCEEDED); + SEC2TXT(SEC_E_MESSAGE_ALTERED); + SEC2TXT(SEC_E_MULTIPLE_ACCOUNTS); + SEC2TXT(SEC_E_MUST_BE_KDC); + SEC2TXT(SEC_E_NOT_OWNER); + SEC2TXT(SEC_E_NO_AUTHENTICATING_AUTHORITY); + SEC2TXT(SEC_E_NO_CREDENTIALS); + SEC2TXT(SEC_E_NO_IMPERSONATION); + SEC2TXT(SEC_E_NO_IP_ADDRESSES); + SEC2TXT(SEC_E_NO_KERB_KEY); + SEC2TXT(SEC_E_NO_PA_DATA); + SEC2TXT(SEC_E_NO_S4U_PROT_SUPPORT); + SEC2TXT(SEC_E_NO_TGT_REPLY); + SEC2TXT(SEC_E_OUT_OF_SEQUENCE); + SEC2TXT(SEC_E_PKINIT_CLIENT_FAILURE); + SEC2TXT(SEC_E_PKINIT_NAME_MISMATCH); + SEC2TXT(SEC_E_POLICY_NLTM_ONLY); + SEC2TXT(SEC_E_QOP_NOT_SUPPORTED); + SEC2TXT(SEC_E_REVOCATION_OFFLINE_C); + SEC2TXT(SEC_E_REVOCATION_OFFLINE_KDC); + SEC2TXT(SEC_E_SECPKG_NOT_FOUND); + SEC2TXT(SEC_E_SECURITY_QOS_FAILED); + SEC2TXT(SEC_E_SHUTDOWN_IN_PROGRESS); + SEC2TXT(SEC_E_SMARTCARD_CERT_EXPIRED); + SEC2TXT(SEC_E_SMARTCARD_CERT_REVOKED); + SEC2TXT(SEC_E_SMARTCARD_LOGON_REQUIRED); + SEC2TXT(SEC_E_STRONG_CRYPTO_NOT_SUPPORTED); + SEC2TXT(SEC_E_TARGET_UNKNOWN); + SEC2TXT(SEC_E_TIME_SKEW); + SEC2TXT(SEC_E_TOO_MANY_PRINCIPALS); + SEC2TXT(SEC_E_UNFINISHED_CONTEXT_DELETED); + SEC2TXT(SEC_E_UNKNOWN_CREDENTIALS); + SEC2TXT(SEC_E_UNSUPPORTED_FUNCTION); + SEC2TXT(SEC_E_UNSUPPORTED_PREAUTH); + SEC2TXT(SEC_E_UNTRUSTED_ROOT); + SEC2TXT(SEC_E_WRONG_CREDENTIAL_HANDLE); + SEC2TXT(SEC_E_WRONG_PRINCIPAL); + SEC2TXT(SEC_I_COMPLETE_AND_CONTINUE); + SEC2TXT(SEC_I_COMPLETE_NEEDED); + SEC2TXT(SEC_I_CONTEXT_EXPIRED); + SEC2TXT(SEC_I_CONTINUE_NEEDED); + SEC2TXT(SEC_I_INCOMPLETE_CREDENTIALS); + SEC2TXT(SEC_I_LOCAL_LOGON); + SEC2TXT(SEC_I_NO_LSA_CONTEXT); + SEC2TXT(SEC_I_RENEGOTIATE); + SEC2TXT(SEC_I_SIGNATURE_NEEDED); default: txt = "Unknown error"; } - if(err == SEC_E_OK) - strncpy(outbuf, txt, outmax); - else if(err == SEC_E_ILLEGAL_MESSAGE) - msnprintf(outbuf, outmax, + if(err == SEC_E_ILLEGAL_MESSAGE) { + msnprintf(buf, buflen, "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs " "when a fatal SSL/TLS alert is received (e.g. handshake failed)." " More detail may be available in the Windows System event log.", err); + } else { - str = txtbuf; + char txtbuf[80]; + char msgbuf[256]; + msnprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err); - txtbuf[sizeof(txtbuf)-1] = '\0'; -#ifdef _WIN32_WCE - { - wchar_t wbuf[256]; - wbuf[0] = L'\0'; - - if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, LANG_NEUTRAL, - wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { - wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1); - msg_formatted = TRUE; - } - } -#else - if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, LANG_NEUTRAL, - msgbuf, sizeof(msgbuf)-1, NULL)) { - msg_formatted = TRUE; + if(get_winapi_error(err, msgbuf, sizeof(msgbuf))) + msnprintf(buf, buflen, "%s - %s", txtbuf, msgbuf); + else { + strncpy(buf, txtbuf, buflen); + buf[buflen - 1] = '\0'; } -#endif - if(msg_formatted) { - msgbuf[sizeof(msgbuf)-1] = '\0'; - /* strip trailing '\r\n' or '\n' */ - p = strrchr(msgbuf, '\n'); - if(p && (p - msgbuf) >= 2) - *p = '\0'; - p = strrchr(msgbuf, '\r'); - if(p && (p - msgbuf) >= 1) - *p = '\0'; - msg = msgbuf; - } - if(msg) - msnprintf(outbuf, outmax, "%s - %s", str, msg); - else - strncpy(outbuf, str, outmax); } #else - if(err == SEC_E_OK) txt = "No error"; else txt = "Error"; - - strncpy(outbuf, txt, outmax); - + strncpy(buf, txt, buflen); + buf[buflen - 1] = '\0'; #endif - outbuf[outmax] = '\0'; - if(errno != old_errno) errno = old_errno; @@ -1100,6 +998,6 @@ const char *Curl_sspi_strerror(int err, char *buf, size_t buflen) SetLastError(old_win_err); #endif - return outbuf; + return buf; } #endif /* USE_WINDOWS_SSPI */ diff --git a/libs/libcurl/src/strerror.h b/libs/libcurl/src/strerror.h index 683b5b4a3a..278c1082f0 100644 --- a/libs/libcurl/src/strerror.h +++ b/libs/libcurl/src/strerror.h @@ -27,6 +27,9 @@ #define STRERROR_LEN 128 /* a suitable length */ const char *Curl_strerror(int err, char *buf, size_t buflen); +#if defined(WIN32) || defined(_WIN32_WCE) +const char *Curl_winapi_strerror(DWORD err, char *buf, size_t buflen); +#endif #ifdef USE_WINDOWS_SSPI const char *Curl_sspi_strerror(int err, char *buf, size_t buflen); #endif diff --git a/libs/libcurl/src/strtok.c b/libs/libcurl/src/strtok.c index 460eb87e51..be8f481282 100644 --- a/libs/libcurl/src/strtok.c +++ b/libs/libcurl/src/strtok.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/strtok.h b/libs/libcurl/src/strtok.h index 90b831eb67..e221fa680f 100644 --- a/libs/libcurl/src/strtok.h +++ b/libs/libcurl/src/strtok.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/strtoofft.c b/libs/libcurl/src/strtoofft.c index 546a3ff75d..96e3820600 100644 --- a/libs/libcurl/src/strtoofft.c +++ b/libs/libcurl/src/strtoofft.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/telnet.c b/libs/libcurl/src/telnet.c index 955255c36c..4bf4c652c2 100644 --- a/libs/libcurl/src/telnet.c +++ b/libs/libcurl/src/telnet.c @@ -69,12 +69,12 @@ do { \ x->subend = x->subpointer; \ CURL_SB_CLEAR(x); \ - } WHILE_FALSE + } while(0) #define CURL_SB_ACCUM(x,c) \ do { \ if(x->subpointer < (x->subbuffer + sizeof(x->subbuffer))) \ *x->subpointer++ = (c); \ - } WHILE_FALSE + } while(0) #define CURL_SB_GET(x) ((*x->subpointer++)&0xff) #define CURL_SB_LEN(x) (x->subend - x->subpointer) diff --git a/libs/libcurl/src/telnet.h b/libs/libcurl/src/telnet.h index 668a78a133..431427f395 100644 --- a/libs/libcurl/src/telnet.h +++ b/libs/libcurl/src/telnet.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/tftp.h b/libs/libcurl/src/tftp.h index 1335f64bd1..33348300fe 100644 --- a/libs/libcurl/src/tftp.h +++ b/libs/libcurl/src/tftp.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index d0d4aeb500..ead8b36db9 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -484,8 +484,9 @@ CURLcode Curl_readrewind(struct connectdata *conn) return CURLE_OK; } -static int data_pending(const struct connectdata *conn) +static int data_pending(const struct Curl_easy *data) { + struct connectdata *conn = data->conn; /* in the case of libssh2, we can never be really sure that we have emptied its internal buffers so we MUST always try until we get EAGAIN back */ return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) || @@ -499,6 +500,8 @@ static int data_pending(const struct connectdata *conn) be called and we cannot signal the HTTP/2 stream has closed. As a workaround, we return nonzero here to call http2_recv. */ ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20); +#elif defined(ENABLE_QUIC) + Curl_ssl_data_pending(conn, FIRSTSOCKET) || Curl_quic_data_pending(data); #else Curl_ssl_data_pending(conn, FIRSTSOCKET); #endif @@ -918,7 +921,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, break; } - } while(data_pending(conn) && maxloops--); + } while(data_pending(data) && maxloops--); if(maxloops <= 0) { /* we mark it as read-again-please */ @@ -1174,7 +1177,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, } - } WHILE_FALSE; /* just to break out from! */ + } while(0); /* just to break out from! */ return CURLE_OK; } diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index 8285474fd7..56fb736368 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -106,7 +106,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "http2.h" #include "file.h" #include "curl_ldap.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "imap.h" #include "url.h" #include "connect.h" @@ -403,9 +403,11 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } +#ifndef CURL_DISABLE_DOH free(data->req.doh.probe[0].serverdoh.memory); free(data->req.doh.probe[1].serverdoh.memory); curl_slist_free_all(data->req.doh.headers); +#endif /* destruct wildcard structures if it is needed */ Curl_wildcard_dtor(&data->wildcard); @@ -672,7 +674,7 @@ static void conn_reset_all_postponed_data(struct connectdata *conn) } #else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ /* Use "do-nothing" macro instead of function when workaround not used */ -#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE +#define conn_reset_all_postponed_data(c) do {} while(0) #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ @@ -1080,16 +1082,15 @@ ConnectionExists(struct Curl_easy *data, check = curr->ptr; curr = curr->next; - if(check->bits.connect_only) - /* connect-only connections will not be reused */ + if(check->bits.connect_only || check->bits.close) + /* connect-only or to-be-closed connections will not be reused */ continue; multiplexed = CONN_INUSE(check) && (bundle->multiuse == BUNDLE_MULTIPLEX); if(canmultiplex) { - if(check->bits.protoconnstart && check->bits.close) - continue; + ; } else { if(multiplexed) { @@ -1109,12 +1110,9 @@ ConnectionExists(struct Curl_easy *data, } } - if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || - check->bits.close) { - if(!check->bits.close) - foundPendingCandidate = TRUE; - /* Don't pick a connection that hasn't connected yet or that is going - to get closed. */ + if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) { + foundPendingCandidate = TRUE; + /* Don't pick a connection that hasn't connected yet */ infof(data, "Connection #%ld isn't open enough, can't reuse\n", check->connection_id); continue; @@ -1192,8 +1190,7 @@ ConnectionExists(struct Curl_easy *data, already in use so we skip it */ continue; - if(CONN_INUSE(check) && check->data && - (check->data->multi != needle->data->multi)) + 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; @@ -1641,6 +1638,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) it may live on without (this specific) Curl_easy */ conn->fclosesocket = data->set.fclosesocket; conn->closesocket_client = data->set.closesocket_client; + conn->lastused = Curl_now(); /* used now */ return conn; error: @@ -1987,8 +1985,11 @@ void Curl_free_request_state(struct Curl_easy *data) { Curl_safefree(data->req.protop); Curl_safefree(data->req.newurl); + +#ifndef CURL_DISABLE_DOH Curl_close(&data->req.doh.probe[0].easy); Curl_close(&data->req.doh.probe[1].easy); +#endif } @@ -3593,25 +3594,6 @@ static CURLcode create_conn(struct Curl_easy *data, else reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe); - /* If we found a reusable connection that is now marked as in use, we may - still want to open a new connection if we are multiplexing. */ - if(reuse && !force_reuse && IsMultiplexingPossible(data, conn_temp)) { - size_t multiplexed = CONN_INUSE(conn_temp); - if(multiplexed > 0) { - infof(data, "Found connection %ld, with %zu requests on it\n", - conn_temp->connection_id, multiplexed); - - if(Curl_conncache_bundle_size(conn_temp) < max_host_connections && - Curl_conncache_size(data) < max_total_connections) { - /* We want a new connection anyway */ - reuse = FALSE; - - infof(data, "We can reuse, but we want a new connection anyway\n"); - Curl_conncache_return_conn(conn_temp); - } - } - } - if(reuse) { /* * We already have a connection for this, we got the former connection diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index f9365b2e68..3effb1626f 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -124,7 +124,7 @@ typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ #include "smtp.h" #include "ftp.h" #include "file.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "http.h" #include "rtsp.h" #include "smb.h" @@ -257,6 +257,7 @@ struct ssl_config_data { BIT(falsestart); BIT(enable_beast); /* allow this flaw for interoperability's sake*/ BIT(no_revoke); /* disable SSL certificate revocation checks */ + BIT(no_partialchain); /* don't accept partial certificate chains */ }; struct ssl_general_config { @@ -528,6 +529,24 @@ enum upgrade101 { UPGR101_WORKING /* talking upgraded protocol */ }; +enum doh_slots { + /* Explicit values for first two symbols so as to match hard-coded + * constants in existing code + */ + DOH_PROBE_SLOT_IPADDR_V4 = 0, /* make 'V4' stand out for readability */ + DOH_PROBE_SLOT_IPADDR_V6 = 1, /* 'V6' likewise */ + + /* Space here for (possibly build-specific) additional slot definitions */ + + /* for example */ + /* #ifdef WANT_DOH_FOOBAR_TXT */ + /* DOH_PROBE_SLOT_FOOBAR_TXT, */ + /* #endif */ + + /* AFTER all slot definitions, establish how many we have */ + DOH_PROBE_SLOTS +}; + struct dohresponse { unsigned char *memory; size_t size; @@ -544,7 +563,7 @@ struct dnsprobe { struct dohdata { struct curl_slist *headers; - struct dnsprobe probe[2]; + struct dnsprobe probe[DOH_PROBE_SLOTS]; unsigned int pending; /* still outstanding requests */ const char *host; int port; diff --git a/libs/libcurl/src/vauth/cram.c b/libs/libcurl/src/vauth/cram.c index d148618b0d..04438fa740 100644 --- a/libs/libcurl/src/vauth/cram.c +++ b/libs/libcurl/src/vauth/cram.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/vauth/digest.h b/libs/libcurl/src/vauth/digest.h index 8686c44a42..cc05fdb769 100644 --- a/libs/libcurl/src/vauth/digest.h +++ b/libs/libcurl/src/vauth/digest.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c index cfd09e36d7..6405d369d7 100644 --- a/libs/libcurl/src/version.c +++ b/libs/libcurl/src/version.c @@ -26,7 +26,7 @@ #include "urldata.h" #include "vtls/vtls.h" #include "http2.h" -#include "ssh.h" +#include "vssh/ssh.h" #include "quic.h" #include "curl_printf.h" diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c index c0f9b16e38..e97e9e871b 100644 --- a/libs/libcurl/src/vquic/ngtcp2.c +++ b/libs/libcurl/src/vquic/ngtcp2.c @@ -49,7 +49,7 @@ #ifdef DEBUG_HTTP3 #define H3BUGF(x) x #else -#define H3BUGF(x) do { } WHILE_FALSE +#define H3BUGF(x) do { } while(0) #endif /* @@ -174,8 +174,10 @@ static int quic_set_encryption_secrets(SSL *ssl, tx_secret, secretlen, NGTCP2_CRYPTO_SIDE_CLIENT) != 0) return 0; - if(level == NGTCP2_CRYPTO_LEVEL_APP && init_ngh3_conn(qs) != CURLE_OK) - return 0; + if(level == NGTCP2_CRYPTO_LEVEL_APP) { + if(init_ngh3_conn(qs) != CURLE_OK) + return 0; + } return 1; } @@ -188,11 +190,12 @@ static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level, ngtcp2_crypto_level level = quic_from_ossl_level(ossl_level); int rv; - crypto_data = &qs->client_crypto_data[level]; + crypto_data = &qs->crypto_data[level]; if(crypto_data->buf == NULL) { crypto_data->buf = malloc(4096); + if(!crypto_data->buf) + return 0; crypto_data->alloclen = 4096; - /* TODO Explode if malloc failed */ } /* TODO Just pretend that handshake does not grow more than 4KiB for @@ -203,8 +206,8 @@ static int quic_add_handshake_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL ossl_level, crypto_data->len += len; rv = ngtcp2_conn_submit_crypto_data( - qs->qconn, level, (uint8_t *)(&crypto_data->buf[crypto_data->len] - len), - len); + qs->qconn, level, (uint8_t *)(&crypto_data->buf[crypto_data->len] - len), + len); if(rv) { H3BUGF(fprintf(stderr, "write_client_handshake failed\n")); } @@ -244,8 +247,9 @@ static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data) SSL_CTX_set_default_verify_paths(ssl_ctx); if(SSL_CTX_set_ciphersuites(ssl_ctx, QUIC_CIPHERS) != 1) { - failf(data, "SSL_CTX_set_ciphersuites: %s", - ERR_error_string(ERR_get_error(), NULL)); + char error_buffer[256]; + ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer)); + failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer); return NULL; } @@ -305,7 +309,7 @@ static int cb_initial(ngtcp2_conn *quic, void *user_data) struct quicsocket *qs = (struct quicsocket *)user_data; if(ngtcp2_crypto_read_write_crypto_data( - quic, qs->ssl, NGTCP2_CRYPTO_LEVEL_INITIAL, NULL, 0) != 0) + quic, qs->ssl, NGTCP2_CRYPTO_LEVEL_INITIAL, NULL, 0) != 0) return NGTCP2_ERR_CALLBACK_FAILURE; return 0; @@ -336,6 +340,16 @@ static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data) return 0; } +static void extend_stream_window(ngtcp2_conn *tconn, + struct HTTP *stream) +{ + size_t thismuch = stream->unacked_window; + ngtcp2_conn_extend_max_stream_offset(tconn, stream->stream3_id, thismuch); + ngtcp2_conn_extend_max_offset(tconn, thismuch); + stream->unacked_window = 0; +} + + static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t stream_id, int fin, uint64_t offset, const uint8_t *buf, size_t buflen, @@ -346,9 +360,6 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t stream_id, (void)offset; (void)stream_user_data; - infof(qs->conn->data, "Received %ld bytes data on stream %u\n", - buflen, stream_id); - nconsumed = nghttp3_conn_read_stream(qs->h3conn, stream_id, buf, buflen, fin); if(nconsumed < 0) { @@ -357,6 +368,9 @@ static int cb_recv_stream_data(ngtcp2_conn *tconn, int64_t stream_id, return NGTCP2_ERR_CALLBACK_FAILURE; } + /* number of bytes inside buflen which consists of framing overhead + * including QPACK HEADERS. In other words, it does not consume payload of + * DATA frame. */ ngtcp2_conn_extend_max_stream_offset(tconn, stream_id, nconsumed); ngtcp2_conn_extend_max_offset(tconn, nconsumed); @@ -514,7 +528,7 @@ static ngtcp2_conn_callbacks ng_callbacks = { NULL, /* rand */ cb_get_new_connection_id, NULL, /* remove_connection_id */ - NULL, /* update_key */ + ngtcp2_crypto_update_key_cb, /* update_key */ NULL, /* path_validation */ NULL, /* select_preferred_addr */ cb_stream_reset, @@ -656,8 +670,16 @@ static int ng_perform_getsock(const struct connectdata *conn, static CURLcode ng_disconnect(struct connectdata *conn, bool dead_connection) { - (void)conn; + int i; + struct quicsocket *qs = &conn->hequic[0]; (void)dead_connection; + if(qs->ssl) + SSL_free(qs->ssl); + for(i = 0; i < 3; i++) + free(qs->crypto_data[i].buf); + nghttp3_conn_del(qs->h3conn); + ngtcp2_conn_del(qs->qconn); + SSL_CTX_free(qs->sslctx); return CURLE_OK; } @@ -704,42 +726,121 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, stream->closed = TRUE; Curl_expire(data, 0, EXPIRE_QUIC); + /* make sure that ngh3_stream_recv is called again to complete the transfer + even if there are no more packets to be received from the server. */ + data->state.drain = 1; return 0; } -static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id, - const uint8_t *buf, size_t buflen, - void *user_data, void *stream_user_data) -{ - struct quicsocket *qs = user_data; - size_t ncopy; - struct Curl_easy *data = stream_user_data; - struct HTTP *stream = data->req.protop; - (void)conn; - H3BUGF(infof(data, "cb_h3_recv_data CALLED with %d bytes\n", buflen)); +/* Minimum size of the overflow buffer */ +#define OVERFLOWSIZE 1024 - /* TODO: this needs to be handled properly */ - DEBUGASSERT(buflen <= stream->len); +/* + * allocate_overflow() ensures that there is room for incoming data in the + * overflow buffer, growing it to accommodate the new data if necessary. We + * may need to use the overflow buffer because we can't precisely limit the + * amount of HTTP/3 header data we receive using QUIC flow control mechanisms. + */ +static CURLcode allocate_overflow(struct Curl_easy *data, + struct HTTP *stream, + size_t length) +{ + size_t maxleft; + size_t newsize; + /* length can be arbitrarily large, so take care not to overflow newsize */ + maxleft = CURL_MAX_READ_SIZE - stream->overflow_buflen; + if(length > maxleft) { + /* The reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a highly compressed list of headers that + will cause our overflow buffer to grow too large */ + failf(data, "Rejected %zu bytes of overflow data (max is %d)!", + stream->overflow_buflen + length, CURL_MAX_READ_SIZE); + return CURLE_OUT_OF_MEMORY; + } + newsize = stream->overflow_buflen + length; + if(newsize > stream->overflow_bufsize) { + /* We enlarge the overflow buffer as it is too small */ + char *newbuff; + newsize = CURLMAX(newsize * 3 / 2, stream->overflow_bufsize*2); + newsize = CURLMIN(CURLMAX(OVERFLOWSIZE, newsize), CURL_MAX_READ_SIZE); + newbuff = realloc(stream->overflow_buf, newsize); + if(!newbuff) { + failf(data, "Failed to alloc memory for overflow buffer!"); + return CURLE_OUT_OF_MEMORY; + } + stream->overflow_buf = newbuff; + stream->overflow_bufsize = newsize; + infof(data, "Grew HTTP/3 overflow buffer to %zu bytes\n", newsize); + } + return CURLE_OK; +} - ncopy = CURLMIN(stream->len, buflen); - memcpy(stream->mem, buf, ncopy); - stream->len -= ncopy; - stream->memlen += ncopy; +/* + * write_data() copies data to the stream's receive buffer. If not enough + * space is available in the receive buffer, it copies the rest to the + * stream's overflow buffer. + */ +static CURLcode write_data(struct Curl_easy *data, + struct HTTP *stream, + const void *mem, size_t memlen) +{ + CURLcode result = CURLE_OK; + const char *buf = mem; + size_t ncopy = memlen; + /* copy as much as possible to the receive buffer */ + if(stream->len) { + size_t len = CURLMIN(ncopy, stream->len); +#if 0 /* extra debugging of incoming h3 data */ + fprintf(stderr, "!! Copies %zd bytes to %p (total %zd)\n", + len, stream->mem, stream->memlen); +#endif + memcpy(stream->mem, buf, len); + stream->len -= len; + stream->memlen += len; + stream->mem += len; + buf += len; + ncopy -= len; + } + /* copy the rest to the overflow buffer */ + if(ncopy) { + result = allocate_overflow(data, stream, ncopy); + if(result) { + return result; + } +#if 0 /* extra debugging of incoming h3 data */ + fprintf(stderr, "!! Copies %zd overflow bytes to %p (total %zd)\n", + ncopy, stream->overflow_buf, stream->overflow_buflen); +#endif + memcpy(stream->overflow_buf + stream->overflow_buflen, buf, ncopy); + stream->overflow_buflen += ncopy; + } #if 0 /* extra debugging of incoming h3 data */ - fprintf(stderr, "!! Copies %zd bytes to %p (total %zd)\n", - ncopy, stream->mem, stream->memlen); { size_t i; - for(i = 0; i < ncopy; i++) { + for(i = 0; i < memlen; i++) { fprintf(stderr, "!! data[%d]: %02x '%c'\n", i, buf[i], buf[i]); } } #endif - stream->mem += ncopy; + return result; +} - ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, buflen); - ngtcp2_conn_extend_max_offset(qs->qconn, buflen); +static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream_id, + const uint8_t *buf, size_t buflen, + void *user_data, void *stream_user_data) +{ + struct Curl_easy *data = stream_user_data; + struct HTTP *stream = data->req.protop; + CURLcode result = CURLE_OK; + (void)conn; + result = write_data(data, stream, buf, buflen); + if(result) { + return -1; + } + stream->unacked_window += buflen; + (void)stream_id; + (void)user_data; return 0; } @@ -750,10 +851,10 @@ static int cb_h3_deferred_consume(nghttp3_conn *conn, int64_t stream_id, struct quicsocket *qs = user_data; (void)conn; (void)stream_user_data; + (void)stream_id; ngtcp2_conn_extend_max_stream_offset(qs->qconn, stream_id, consumed); ngtcp2_conn_extend_max_offset(qs->qconn, consumed); - return 0; } @@ -789,15 +890,17 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id, { struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.protop; + CURLcode result = CURLE_OK; (void)conn; (void)stream_id; (void)user_data; - if(stream->memlen >= 2) { - memcpy(stream->mem, "\r\n", 2); - stream->len -= 2; - stream->memlen += 2; - stream->mem += 2; + /* add a CRLF only if we've received some headers */ + if(stream->firstheader) { + result = write_data(data, stream, "\r\n", 2); + if(result) { + return -1; + } } return 0; } @@ -811,7 +914,7 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, nghttp3_vec h3val = nghttp3_rcbuf_get_buf(value); struct Curl_easy *data = stream_user_data; struct HTTP *stream = data->req.protop; - size_t ncopy; + CURLcode result = CURLE_OK; (void)conn; (void)stream_id; (void)token; @@ -820,20 +923,37 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, if(h3name.len == sizeof(":status") - 1 && !memcmp(":status", h3name.base, h3name.len)) { + char line[14]; /* status line is always 13 characters long */ + size_t ncopy; int status = decode_status_code(h3val.base, h3val.len); DEBUGASSERT(status != -1); - msnprintf(stream->mem, stream->len, "HTTP/3 %03d \r\n", status); + ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", status); + result = write_data(data, stream, line, ncopy); + if(result) { + return -1; + } } else { /* store as a HTTP1-style header */ - msnprintf(stream->mem, stream->len, "%.*s: %.*s\n", - h3name.len, h3name.base, h3val.len, h3val.base); + result = write_data(data, stream, h3name.base, h3name.len); + if(result) { + return -1; + } + result = write_data(data, stream, ": ", 2); + if(result) { + return -1; + } + result = write_data(data, stream, h3val.base, h3val.len); + if(result) { + return -1; + } + result = write_data(data, stream, "\r\n", 2); + if(result) { + return -1; + } } - ncopy = strlen(stream->mem); - stream->len -= ncopy; - stream->memlen += ncopy; - stream->mem += ncopy; + stream->firstheader = TRUE; return 0; } @@ -933,6 +1053,21 @@ static int init_ngh3_conn(struct quicsocket *qs) static Curl_recv ngh3_stream_recv; static Curl_send ngh3_stream_send; +static size_t drain_overflow_buffer(struct HTTP *stream) +{ + size_t ncopy = CURLMIN(stream->overflow_buflen, stream->len); + if(ncopy > 0) { + memcpy(stream->mem, stream->overflow_buf, ncopy); + stream->len -= ncopy; + stream->mem += ncopy; + stream->memlen += ncopy; + stream->overflow_buflen -= ncopy; + memmove(stream->overflow_buf, stream->overflow_buf + ncopy, + stream->overflow_buflen); + } + return ncopy; +} + /* incoming data frames on the h3 stream */ static ssize_t ngh3_stream_recv(struct connectdata *conn, int sockindex, @@ -952,6 +1087,10 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn, } /* else, there's data in the buffer already */ + /* if there's data in the overflow buffer from a previous call, copy as much + as possible to the receive buffer before receiving more */ + drain_overflow_buffer(stream); + if(ng_process_ingress(conn, sockfd, qs)) { *curlcode = CURLE_RECV_ERROR; return -1; @@ -969,8 +1108,13 @@ static ssize_t ngh3_stream_recv(struct connectdata *conn, stream->memlen = 0; stream->mem = buf; stream->len = buffersize; - H3BUGF(infof(conn->data, "!! ngh3_stream_recv returns %zd bytes at %p\n", - memlen, buf)); + /* extend the stream window with the data we're consuming and send out + any additional packets to tell the server that we can receive more */ + extend_stream_window(qs->qconn, stream); + if(ng_flush_egress(conn, sockfd, qs)) { + *curlcode = CURLE_SEND_ERROR; + return -1; + } return memlen; } @@ -1590,4 +1734,32 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn) return CURLE_OK; } + +/* + * Called from http.c:Curl_http_done when a request completes. + */ +void Curl_quic_done(struct Curl_easy *data, bool premature) +{ + (void)premature; + if(data->conn->handler == &Curl_handler_http3) { + /* only for HTTP/3 transfers */ + struct HTTP *stream = data->req.protop; + Curl_safefree(stream->overflow_buf); + } +} + +/* + * Called from transfer.c:data_pending to know if we should keep looping + * to receive more data from the connection. + */ +bool Curl_quic_data_pending(const struct Curl_easy *data) +{ + /* We may have received more data than we're able to hold in the receive + buffer and allocated an overflow buffer. Since it's possible that + there's no more data coming on the socket, we need to keep reading + until the overflow buffer is empty. */ + const struct HTTP *stream = data->req.protop; + return stream->overflow_buflen > 0; +} + #endif diff --git a/libs/libcurl/src/vquic/ngtcp2.h b/libs/libcurl/src/vquic/ngtcp2.h index 5570fc7e78..30d442fdde 100644 --- a/libs/libcurl/src/vquic/ngtcp2.h +++ b/libs/libcurl/src/vquic/ngtcp2.h @@ -46,7 +46,7 @@ struct quicsocket { ngtcp2_settings settings; SSL_CTX *sslctx; SSL *ssl; - struct quic_handshake client_crypto_data[3]; + struct quic_handshake crypto_data[3]; /* the last TLS alert description generated by the local endpoint */ uint8_t tls_alert; struct sockaddr_storage local_addr; diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c index 0ee360d07f..e2f43237fa 100644 --- a/libs/libcurl/src/vquic/quiche.c +++ b/libs/libcurl/src/vquic/quiche.c @@ -45,7 +45,7 @@ #ifdef DEBUG_HTTP3 #define H3BUGF(x) x #else -#define H3BUGF(x) do { } WHILE_FALSE +#define H3BUGF(x) do { } while(0) #endif #define QUIC_MAX_STREAMS (256*1024) @@ -379,6 +379,9 @@ static int cb_each_header(uint8_t *name, size_t name_len, headers->destlen, "HTTP/3 %.*s\n", (int) value_len, value); } + else if(!headers->nlen) { + return CURLE_HTTP3; + } else { msnprintf(headers->dest, headers->destlen, "%.*s: %.*s\n", @@ -433,7 +436,9 @@ static ssize_t h3_stream_recv(struct connectdata *conn, case QUICHE_H3_EVENT_HEADERS: rc = quiche_h3_event_for_each_header(ev, cb_each_header, &headers); if(rc) { - /* what do we do about this? */ + *curlcode = rc; + failf(data, "Error in HTTP/3 response header"); + break; } recvd = headers.nlen; break; @@ -780,4 +785,23 @@ CURLcode Curl_quic_done_sending(struct connectdata *conn) return CURLE_OK; } +/* + * Called from http.c:Curl_http_done when a request completes. + */ +void Curl_quic_done(struct Curl_easy *data, bool premature) +{ + (void)data; + (void)premature; +} + +/* + * Called from transfer.c:data_pending to know if we should keep looping + * to receive more data from the connection. + */ +bool Curl_quic_data_pending(const struct Curl_easy *data) +{ + (void)data; + return FALSE; +} + #endif diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c index cad8b37864..62a7f1960c 100644 --- a/libs/libcurl/src/vssh/libssh.c +++ b/libs/libcurl/src/vssh/libssh.c @@ -97,9 +97,13 @@ /* A recent macro provided by libssh. Or make our own. */ #ifndef SSH_STRING_FREE_CHAR -/* !checksrc! disable ASSIGNWITHINCONDITION 1 */ -#define SSH_STRING_FREE_CHAR(x) \ - do { if((x) != NULL) { ssh_string_free_char(x); x = NULL; } } while(0) +#define SSH_STRING_FREE_CHAR(x) \ + do { \ + if(x) { \ + ssh_string_free_char(x); \ + x = NULL; \ + } \ + } while(0) #endif /* Local functions: */ diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c index c71cfbc9fd..063f3d2ae6 100644 --- a/libs/libcurl/src/vssh/libssh2.c +++ b/libs/libcurl/src/vssh/libssh2.c @@ -466,61 +466,95 @@ static CURLcode ssh_knownhost(struct connectdata *conn) struct curl_khkey *knownkeyp = NULL; struct curl_khkey foundkey; - keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? - LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS; - + switch(keytype) { + case LIBSSH2_HOSTKEY_TYPE_RSA: + keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA; + break; + case LIBSSH2_HOSTKEY_TYPE_DSS: + keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS; + break; +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256 + case LIBSSH2_HOSTKEY_TYPE_ECDSA_256: + keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256; + break; +#endif +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384 + case LIBSSH2_HOSTKEY_TYPE_ECDSA_384: + keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384; + break; +#endif +#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521 + case LIBSSH2_HOSTKEY_TYPE_ECDSA_521: + keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521; + break; +#endif +#ifdef LIBSSH2_HOSTKEY_TYPE_ED25519 + case LIBSSH2_HOSTKEY_TYPE_ED25519: + keybit = LIBSSH2_KNOWNHOST_KEY_ED25519; + break; +#endif + default: + infof(data, "unsupported key type, can't check knownhosts!\n"); + keybit = 0; + break; + } + if(!keybit) + /* no check means failure! */ + rc = CURLKHSTAT_REJECT; + else { #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP - keycheck = libssh2_knownhost_checkp(sshc->kh, - conn->host.name, - (conn->remote_port != PORT_SSH)? - conn->remote_port:-1, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, - &host); + keycheck = libssh2_knownhost_checkp(sshc->kh, + conn->host.name, + (conn->remote_port != PORT_SSH)? + conn->remote_port:-1, + remotekey, keylen, + LIBSSH2_KNOWNHOST_TYPE_PLAIN| + LIBSSH2_KNOWNHOST_KEYENC_RAW| + keybit, + &host); #else - keycheck = libssh2_knownhost_check(sshc->kh, - conn->host.name, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, - &host); + keycheck = libssh2_knownhost_check(sshc->kh, + conn->host.name, + remotekey, keylen, + LIBSSH2_KNOWNHOST_TYPE_PLAIN| + LIBSSH2_KNOWNHOST_KEYENC_RAW| + keybit, + &host); #endif - infof(data, "SSH host check: %d, key: %s\n", keycheck, - (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? - host->key:"<none>"); + infof(data, "SSH host check: %d, key: %s\n", keycheck, + (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? + host->key:"<none>"); + + /* setup 'knownkey' */ + if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { + knownkey.key = host->key; + knownkey.len = 0; + knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? + CURLKHTYPE_RSA : CURLKHTYPE_DSS; + knownkeyp = &knownkey; + } - /* setup 'knownkey' */ - if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { - knownkey.key = host->key; - knownkey.len = 0; - knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? + /* setup 'foundkey' */ + foundkey.key = remotekey; + foundkey.len = keylen; + foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? CURLKHTYPE_RSA : CURLKHTYPE_DSS; - knownkeyp = &knownkey; - } - /* setup 'foundkey' */ - foundkey.key = remotekey; - foundkey.len = keylen; - foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? - CURLKHTYPE_RSA : CURLKHTYPE_DSS; + /* + * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the + * curl_khmatch enum are ever modified, we need to introduce a + * translation table here! + */ + keymatch = (enum curl_khmatch)keycheck; - /* - * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the - * curl_khmatch enum are ever modified, we need to introduce a - * translation table here! - */ - keymatch = (enum curl_khmatch)keycheck; - - /* Ask the callback how to behave */ - Curl_set_in_callback(data, true); - rc = func(data, knownkeyp, /* from the knownhosts file */ - &foundkey, /* from the remote host */ - keymatch, data->set.ssh_keyfunc_userp); - Curl_set_in_callback(data, false); + /* Ask the callback how to behave */ + Curl_set_in_callback(data, true); + rc = func(data, knownkeyp, /* from the knownhosts file */ + &foundkey, /* from the remote host */ + keymatch, data->set.ssh_keyfunc_userp); + Curl_set_in_callback(data, false); + } } else /* no remotekey means failure! */ diff --git a/libs/libcurl/src/ssh.h b/libs/libcurl/src/vssh/ssh.h index 3213c5a52e..3213c5a52e 100644 --- a/libs/libcurl/src/ssh.h +++ b/libs/libcurl/src/vssh/ssh.h diff --git a/libs/libcurl/src/vtls/bearssl.c b/libs/libcurl/src/vtls/bearssl.c new file mode 100644 index 0000000000..67f945831c --- /dev/null +++ b/libs/libcurl/src/vtls/bearssl.c @@ -0,0 +1,866 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019, Michael Forney, <mforney@mforney.org> + * + * 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.haxx.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_BEARSSL + +#include <bearssl.h> + +#include "bearssl.h" +#include "urldata.h" +#include "sendf.h" +#include "inet_pton.h" +#include "vtls.h" +#include "connect.h" +#include "select.h" +#include "multiif.h" +#include "curl_printf.h" +#include "curl_memory.h" + +struct x509_context { + const br_x509_class *vtable; + br_x509_minimal_context minimal; + bool verifyhost; + bool verifypeer; +}; + +struct ssl_backend_data { + br_ssl_client_context ctx; + struct x509_context x509; + unsigned char buf[BR_SSL_BUFSIZE_BIDI]; + br_x509_trust_anchor *anchors; + size_t anchors_len; + const char *protocols[2]; + /* SSL client context is active */ + bool active; + /* size of pending write, yet to be flushed */ + size_t pending_write; +}; + +#define BACKEND connssl->backend + +struct cafile_parser { + CURLcode err; + bool in_cert; + br_x509_decoder_context xc; + /* array of trust anchors loaded from CAfile */ + br_x509_trust_anchor *anchors; + size_t anchors_len; + /* buffer for DN data */ + unsigned char dn[1024]; + size_t dn_len; +}; + +static void append_dn(void *ctx, const void *buf, size_t len) +{ + struct cafile_parser *ca = ctx; + + if(ca->err != CURLE_OK || !ca->in_cert) + return; + if(sizeof(ca->dn) - ca->dn_len < len) { + ca->err = CURLE_FAILED_INIT; + return; + } + memcpy(ca->dn + ca->dn_len, buf, len); + ca->dn_len += len; +} + +static void x509_push(void *ctx, const void *buf, size_t len) +{ + struct cafile_parser *ca = ctx; + + if(ca->in_cert) + br_x509_decoder_push(&ca->xc, buf, len); +} + +static CURLcode load_cafile(const char *path, br_x509_trust_anchor **anchors, + size_t *anchors_len) +{ + struct cafile_parser ca; + br_pem_decoder_context pc; + br_x509_trust_anchor *ta; + size_t ta_size; + br_x509_trust_anchor *new_anchors; + size_t new_anchors_len; + br_x509_pkey *pkey; + FILE *fp; + unsigned char buf[BUFSIZ], *p; + const char *name; + size_t n, i, pushed; + + fp = fopen(path, "rb"); + if(!fp) + return CURLE_SSL_CACERT_BADFILE; + + ca.err = CURLE_OK; + ca.in_cert = FALSE; + ca.anchors = NULL; + ca.anchors_len = 0; + br_pem_decoder_init(&pc); + br_pem_decoder_setdest(&pc, x509_push, &ca); + for(;;) { + n = fread(buf, 1, sizeof(buf), fp); + if(n == 0) + break; + p = buf; + while(n) { + pushed = br_pem_decoder_push(&pc, p, n); + if(ca.err) + goto fail; + p += pushed; + n -= pushed; + + switch(br_pem_decoder_event(&pc)) { + case 0: + break; + case BR_PEM_BEGIN_OBJ: + name = br_pem_decoder_name(&pc); + if(strcmp(name, "CERTIFICATE") && strcmp(name, "X509 CERTIFICATE")) + break; + br_x509_decoder_init(&ca.xc, append_dn, &ca); + if(ca.anchors_len == SIZE_MAX / sizeof(ca.anchors[0])) { + ca.err = CURLE_OUT_OF_MEMORY; + goto fail; + } + new_anchors_len = ca.anchors_len + 1; + new_anchors = realloc(ca.anchors, + new_anchors_len * sizeof(ca.anchors[0])); + if(!new_anchors) { + ca.err = CURLE_OUT_OF_MEMORY; + goto fail; + } + ca.anchors = new_anchors; + ca.anchors_len = new_anchors_len; + ca.in_cert = TRUE; + ca.dn_len = 0; + ta = &ca.anchors[ca.anchors_len - 1]; + ta->dn.data = NULL; + break; + case BR_PEM_END_OBJ: + if(!ca.in_cert) + break; + ca.in_cert = FALSE; + if(br_x509_decoder_last_error(&ca.xc)) { + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + ta->flags = 0; + if(br_x509_decoder_isCA(&ca.xc)) + ta->flags |= BR_X509_TA_CA; + pkey = br_x509_decoder_get_pkey(&ca.xc); + if(!pkey) { + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + ta->pkey = *pkey; + + /* calculate space needed for trust anchor data */ + ta_size = ca.dn_len; + switch(pkey->key_type) { + case BR_KEYTYPE_RSA: + ta_size += pkey->key.rsa.nlen + pkey->key.rsa.elen; + break; + case BR_KEYTYPE_EC: + ta_size += pkey->key.ec.qlen; + break; + default: + ca.err = CURLE_FAILED_INIT; + goto fail; + } + + /* fill in trust anchor DN and public key data */ + ta->dn.data = malloc(ta_size); + if(!ta->dn.data) { + ca.err = CURLE_OUT_OF_MEMORY; + goto fail; + } + memcpy(ta->dn.data, ca.dn, ca.dn_len); + ta->dn.len = ca.dn_len; + switch(pkey->key_type) { + case BR_KEYTYPE_RSA: + ta->pkey.key.rsa.n = ta->dn.data + ta->dn.len; + memcpy(ta->pkey.key.rsa.n, pkey->key.rsa.n, pkey->key.rsa.nlen); + ta->pkey.key.rsa.e = ta->pkey.key.rsa.n + ta->pkey.key.rsa.nlen; + memcpy(ta->pkey.key.rsa.e, pkey->key.rsa.e, pkey->key.rsa.elen); + break; + case BR_KEYTYPE_EC: + ta->pkey.key.ec.q = ta->dn.data + ta->dn.len; + memcpy(ta->pkey.key.ec.q, pkey->key.ec.q, pkey->key.ec.qlen); + break; + } + break; + default: + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + } + } + if(ferror(fp)) + ca.err = CURLE_READ_ERROR; + +fail: + fclose(fp); + if(ca.err == CURLE_OK) { + *anchors = ca.anchors; + *anchors_len = ca.anchors_len; + } + else { + for(i = 0; i < ca.anchors_len; ++i) + free(ca.anchors[i].dn.data); + free(ca.anchors); + } + + return ca.err; +} + +static void x509_start_chain(const br_x509_class **ctx, + const char *server_name) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + if(!x509->verifyhost) + server_name = NULL; + x509->minimal.vtable->start_chain(&x509->minimal.vtable, server_name); +} + +static void x509_start_cert(const br_x509_class **ctx, uint32_t length) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + x509->minimal.vtable->start_cert(&x509->minimal.vtable, length); +} + +static void x509_append(const br_x509_class **ctx, const unsigned char *buf, + size_t len) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + x509->minimal.vtable->append(&x509->minimal.vtable, buf, len); +} + +static void x509_end_cert(const br_x509_class **ctx) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + x509->minimal.vtable->end_cert(&x509->minimal.vtable); +} + +static unsigned x509_end_chain(const br_x509_class **ctx) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + unsigned err; + + err = x509->minimal.vtable->end_chain(&x509->minimal.vtable); + if(err && !x509->verifypeer) { + /* ignore any X.509 errors */ + err = BR_ERR_OK; + } + + return err; +} + +static const br_x509_pkey *x509_get_pkey(const br_x509_class *const *ctx, + unsigned *usages) +{ + struct x509_context *x509 = (struct x509_context *)ctx; + + return x509->minimal.vtable->get_pkey(&x509->minimal.vtable, usages); +} + +static const br_x509_class x509_vtable = { + sizeof(struct x509_context), + x509_start_chain, + x509_start_cert, + x509_append, + x509_end_cert, + x509_end_chain, + x509_get_pkey +}; + +static CURLcode bearssl_connect_step1(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); + const char *hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : + conn->host.name; + const bool verifypeer = SSL_CONN_CONFIG(verifypeer); + const bool verifyhost = SSL_CONN_CONFIG(verifyhost); + CURLcode ret; + unsigned version_min, version_max; +#ifdef ENABLE_IPV6 + struct in6_addr addr; +#else + struct in_addr addr; +#endif + + switch(SSL_CONN_CONFIG(version)) { + case CURL_SSLVERSION_SSLv2: + failf(data, "BearSSL does not support SSLv2"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_SSLv3: + failf(data, "BearSSL does not support SSLv3"); + return CURLE_SSL_CONNECT_ERROR; + case CURL_SSLVERSION_TLSv1_0: + version_min = BR_TLS10; + version_max = BR_TLS10; + break; + case CURL_SSLVERSION_TLSv1_1: + version_min = BR_TLS11; + version_max = BR_TLS11; + break; + case CURL_SSLVERSION_TLSv1_2: + version_min = BR_TLS12; + version_max = BR_TLS12; + break; + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + version_min = BR_TLS10; + version_max = BR_TLS12; + break; + default: + failf(data, "BearSSL: unknown CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(ssl_cafile) { + ret = load_cafile(ssl_cafile, &BACKEND->anchors, &BACKEND->anchors_len); + if(ret != CURLE_OK) { + if(verifypeer) { + failf(data, "error setting certificate verify locations:\n" + " CAfile: %s\n", ssl_cafile); + return ret; + } + infof(data, "error setting certificate verify locations," + " continuing anyway:\n"); + } + } + + /* initialize SSL context */ + br_ssl_client_init_full(&BACKEND->ctx, &BACKEND->x509.minimal, + BACKEND->anchors, BACKEND->anchors_len); + br_ssl_engine_set_versions(&BACKEND->ctx.eng, version_min, version_max); + br_ssl_engine_set_buffer(&BACKEND->ctx.eng, BACKEND->buf, + sizeof(BACKEND->buf), 1); + + /* initialize X.509 context */ + BACKEND->x509.vtable = &x509_vtable; + BACKEND->x509.verifypeer = verifypeer; + BACKEND->x509.verifyhost = verifyhost; + br_ssl_engine_set_x509(&BACKEND->ctx.eng, &BACKEND->x509.vtable); + + if(SSL_SET_OPTION(primary.sessionid)) { + void *session; + + Curl_ssl_sessionid_lock(conn); + if(!Curl_ssl_getsessionid(conn, &session, NULL, sockindex)) { + br_ssl_engine_set_session_parameters(&BACKEND->ctx.eng, session); + infof(data, "BearSSL: re-using session ID\n"); + } + Curl_ssl_sessionid_unlock(conn); + } + + if(conn->bits.tls_enable_alpn) { + int cur = 0; + + /* NOTE: when adding more protocols here, increase the size of the + * protocols array in `struct ssl_backend_data`. + */ + +#ifdef USE_NGHTTP2 + if(data->set.httpversion >= CURL_HTTP_VERSION_2 && + (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) { + BACKEND->protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; + infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); + } +#endif + + BACKEND->protocols[cur++] = ALPN_HTTP_1_1; + infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + + br_ssl_engine_set_protocol_names(&BACKEND->ctx.eng, + BACKEND->protocols, cur); + } + + if((1 == Curl_inet_pton(AF_INET, hostname, &addr)) +#ifdef ENABLE_IPV6 + || (1 == Curl_inet_pton(AF_INET6, hostname, &addr)) +#endif + ) { + if(verifyhost) { + failf(data, "BearSSL: " + "host verification of IP address is not supported"); + return CURLE_PEER_FAILED_VERIFICATION; + } + hostname = NULL; + } + + if(!br_ssl_client_reset(&BACKEND->ctx, hostname, 0)) + return CURLE_FAILED_INIT; + BACKEND->active = TRUE; + + connssl->connecting_state = ssl_connect_2; + + return CURLE_OK; +} + +static CURLcode bearssl_run_until(struct connectdata *conn, int sockindex, + unsigned target) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + unsigned state; + unsigned char *buf; + size_t len; + ssize_t ret; + int err; + + for(;;) { + state = br_ssl_engine_current_state(&BACKEND->ctx.eng); + if(state & BR_SSL_CLOSED) { + err = br_ssl_engine_last_error(&BACKEND->ctx.eng); + switch(err) { + case BR_ERR_OK: + /* TLS close notify */ + if(connssl->state != ssl_connection_complete) { + failf(data, "SSL: connection closed during handshake"); + return CURLE_SSL_CONNECT_ERROR; + } + return CURLE_OK; + case BR_ERR_X509_EXPIRED: + failf(data, "SSL: X.509 verification: " + "certificate is expired or not yet valid"); + return CURLE_PEER_FAILED_VERIFICATION; + case BR_ERR_X509_BAD_SERVER_NAME: + failf(data, "SSL: X.509 verification: " + "expected server name was not found in the chain"); + return CURLE_PEER_FAILED_VERIFICATION; + case BR_ERR_X509_NOT_TRUSTED: + failf(data, "SSL: X.509 verification: " + "chain could not be linked to a trust anchor"); + return CURLE_PEER_FAILED_VERIFICATION; + } + /* X.509 errors are documented to have the range 32..63 */ + if(err >= 32 && err < 64) + return CURLE_PEER_FAILED_VERIFICATION; + return CURLE_SSL_CONNECT_ERROR; + } + if(state & target) + return CURLE_OK; + if(state & BR_SSL_SENDREC) { + buf = br_ssl_engine_sendrec_buf(&BACKEND->ctx.eng, &len); + ret = swrite(sockfd, buf, len); + if(ret == -1) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(connssl->state != ssl_connection_complete) + connssl->connecting_state = ssl_connect_2_writing; + return CURLE_AGAIN; + } + return CURLE_WRITE_ERROR; + } + br_ssl_engine_sendrec_ack(&BACKEND->ctx.eng, ret); + } + else if(state & BR_SSL_RECVREC) { + buf = br_ssl_engine_recvrec_buf(&BACKEND->ctx.eng, &len); + ret = sread(sockfd, buf, len); + if(ret == 0) { + failf(data, "SSL: EOF without close notify"); + return CURLE_READ_ERROR; + } + if(ret == -1) { + if(SOCKERRNO == EAGAIN || SOCKERRNO == EWOULDBLOCK) { + if(connssl->state != ssl_connection_complete) + connssl->connecting_state = ssl_connect_2_reading; + return CURLE_AGAIN; + } + return CURLE_READ_ERROR; + } + br_ssl_engine_recvrec_ack(&BACKEND->ctx.eng, ret); + } + } +} + +static CURLcode bearssl_connect_step2(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CURLcode ret; + + ret = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP | BR_SSL_RECVAPP); + if(ret == CURLE_AGAIN) + return CURLE_OK; + if(ret == CURLE_OK) { + if(br_ssl_engine_current_state(&BACKEND->ctx.eng) == BR_SSL_CLOSED) { + failf(data, "SSL: connection closed during handshake"); + return CURLE_SSL_CONNECT_ERROR; + } + connssl->connecting_state = ssl_connect_3; + } + return ret; +} + +static CURLcode bearssl_connect_step3(struct connectdata *conn, int sockindex) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + CURLcode ret; + + DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); + + if(conn->bits.tls_enable_alpn) { + const char *protocol; + + protocol = br_ssl_engine_get_selected_protocol(&BACKEND->ctx.eng); + if(protocol) { + infof(data, "ALPN, server accepted to use %s\n", protocol); + +#ifdef USE_NGHTTP2 + if(!strcmp(protocol, NGHTTP2_PROTO_VERSION_ID)) + conn->negnpn = CURL_HTTP_VERSION_2; + else +#endif + if(!strcmp(protocol, ALPN_HTTP_1_1)) + conn->negnpn = CURL_HTTP_VERSION_1_1; + else + infof(data, "ALPN, unrecognized protocol %s\n", protocol); + Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); + } + else + infof(data, "ALPN, server did not agree to a protocol\n"); + } + + if(SSL_SET_OPTION(primary.sessionid)) { + bool incache; + void *oldsession; + br_ssl_session_parameters *session; + + session = malloc(sizeof(*session)); + if(!session) + return CURLE_OUT_OF_MEMORY; + br_ssl_engine_get_session_parameters(&BACKEND->ctx.eng, session); + Curl_ssl_sessionid_lock(conn); + incache = !(Curl_ssl_getsessionid(conn, &oldsession, NULL, sockindex)); + if(incache) + Curl_ssl_delsessionid(conn, oldsession); + ret = Curl_ssl_addsessionid(conn, session, 0, sockindex); + Curl_ssl_sessionid_unlock(conn); + if(ret) { + free(session); + return CURLE_OUT_OF_MEMORY; + } + } + + connssl->connecting_state = ssl_connect_done; + + return CURLE_OK; +} + +static ssize_t bearssl_send(struct connectdata *conn, int sockindex, + const void *buf, size_t len, CURLcode *err) +{ + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned char *app; + size_t applen; + + for(;;) { + *err = bearssl_run_until(conn, sockindex, BR_SSL_SENDAPP); + if (*err != CURLE_OK) + return -1; + app = br_ssl_engine_sendapp_buf(&BACKEND->ctx.eng, &applen); + if(!app) { + failf(data, "SSL: connection closed during write"); + *err = CURLE_SEND_ERROR; + return -1; + } + if(BACKEND->pending_write) { + applen = BACKEND->pending_write; + BACKEND->pending_write = 0; + return applen; + } + if(applen > len) + applen = len; + memcpy(app, buf, applen); + br_ssl_engine_sendapp_ack(&BACKEND->ctx.eng, applen); + br_ssl_engine_flush(&BACKEND->ctx.eng, 0); + BACKEND->pending_write = applen; + } +} + +static ssize_t bearssl_recv(struct connectdata *conn, int sockindex, + char *buf, size_t len, CURLcode *err) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + unsigned char *app; + size_t applen; + + *err = bearssl_run_until(conn, sockindex, BR_SSL_RECVAPP); + if(*err != CURLE_OK) + return -1; + app = br_ssl_engine_recvapp_buf(&BACKEND->ctx.eng, &applen); + if(!app) + return 0; + if(applen > len) + applen = len; + memcpy(buf, app, applen); + br_ssl_engine_recvapp_ack(&BACKEND->ctx.eng, applen); + + return applen; +} + +static CURLcode bearssl_connect_common(struct connectdata *conn, + int sockindex, + bool nonblocking, + bool *done) +{ + CURLcode ret; + struct Curl_easy *data = conn->data; + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + curl_socket_t sockfd = conn->sock[sockindex]; + time_t timeout_ms; + int what; + + /* check if the connection has already been established */ + if(ssl_connection_complete == connssl->state) { + *done = TRUE; + return CURLE_OK; + } + + if(ssl_connect_1 == connssl->connecting_state) { + ret = bearssl_connect_step1(conn, sockindex); + if(ret) + return ret; + } + + while(ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + /* check allowed time left */ + timeout_ms = Curl_timeleft(data, NULL, TRUE); + + if(timeout_ms < 0) { + /* no need to continue if time already is up */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + + /* if ssl is expecting something, check if it's available. */ + if(ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state) { + + curl_socket_t writefd = ssl_connect_2_writing == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + curl_socket_t readfd = ssl_connect_2_reading == + connssl->connecting_state?sockfd:CURL_SOCKET_BAD; + + what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd, + nonblocking?0:timeout_ms); + if(what < 0) { + /* fatal error */ + failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); + return CURLE_SSL_CONNECT_ERROR; + } + else if(0 == what) { + if(nonblocking) { + *done = FALSE; + return CURLE_OK; + } + else { + /* timeout */ + failf(data, "SSL connection timeout"); + return CURLE_OPERATION_TIMEDOUT; + } + } + /* socket is readable or writable */ + } + + /* Run transaction, and return to the caller if it failed or if this + * connection is done nonblocking and this loop would execute again. This + * permits the owner of a multi handle to abort a connection attempt + * before step2 has completed while ensuring that a client using select() + * or epoll() will always have a valid fdset to wait on. + */ + ret = bearssl_connect_step2(conn, sockindex); + if(ret || (nonblocking && + (ssl_connect_2 == connssl->connecting_state || + ssl_connect_2_reading == connssl->connecting_state || + ssl_connect_2_writing == connssl->connecting_state))) + return ret; + } + + if(ssl_connect_3 == connssl->connecting_state) { + ret = bearssl_connect_step3(conn, sockindex); + if(ret) + return ret; + } + + if(ssl_connect_done == connssl->connecting_state) { + connssl->state = ssl_connection_complete; + conn->recv[sockindex] = bearssl_recv; + conn->send[sockindex] = bearssl_send; + *done = TRUE; + } + else + *done = FALSE; + + /* Reset our connect state machine */ + connssl->connecting_state = ssl_connect_1; + + return CURLE_OK; +} + +static size_t Curl_bearssl_version(char *buffer, size_t size) +{ + return msnprintf(buffer, size, "BearSSL"); +} + +static bool Curl_bearssl_data_pending(const struct connectdata *conn, + int connindex) +{ + const struct ssl_connect_data *connssl = &conn->ssl[connindex]; + + return br_ssl_engine_current_state(&BACKEND->ctx.eng) & BR_SSL_RECVAPP; +} + +static CURLcode Curl_bearssl_random(struct Curl_easy *data UNUSED_PARAM, + unsigned char *entropy, size_t length) +{ + static br_hmac_drbg_context ctx; + static bool seeded = FALSE; + + if(!seeded) { + br_prng_seeder seeder; + + br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0); + seeder = br_prng_seeder_system(NULL); + if(!seeder || !seeder(&ctx.vtable)) + return CURLE_FAILED_INIT; + seeded = TRUE; + } + br_hmac_drbg_generate(&ctx, entropy, length); + + return CURLE_OK; +} + +static CURLcode Curl_bearssl_connect(struct connectdata *conn, int sockindex) +{ + CURLcode ret; + bool done = FALSE; + + ret = bearssl_connect_common(conn, sockindex, FALSE, &done); + if(ret) + return ret; + + DEBUGASSERT(done); + + return CURLE_OK; +} + +static CURLcode Curl_bearssl_connect_nonblocking(struct connectdata *conn, + int sockindex, bool *done) +{ + return bearssl_connect_common(conn, sockindex, TRUE, done); +} + +static void *Curl_bearssl_get_internals(struct ssl_connect_data *connssl, + CURLINFO info UNUSED_PARAM) +{ + return &BACKEND->ctx; +} + +static void Curl_bearssl_close(struct connectdata *conn, int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + size_t i; + + if(BACKEND->active) { + br_ssl_engine_close(&BACKEND->ctx.eng); + (void)bearssl_run_until(conn, sockindex, BR_SSL_CLOSED); + } + for(i = 0; i < BACKEND->anchors_len; ++i) + free(BACKEND->anchors[i].dn.data); + free(BACKEND->anchors); +} + +static void Curl_bearssl_session_free(void *ptr) +{ + free(ptr); +} + +static CURLcode Curl_bearssl_md5sum(unsigned char *input, + size_t inputlen, + unsigned char *md5sum, + size_t md5len UNUSED_PARAM) +{ + br_md5_context ctx; + + br_md5_init(&ctx); + br_md5_update(&ctx, input, inputlen); + br_md5_out(&ctx, md5sum); + return CURLE_OK; +} + +static CURLcode Curl_bearssl_sha256sum(const unsigned char *input, + size_t inputlen, + unsigned char *sha256sum, + size_t sha256len UNUSED_PARAM) +{ + br_sha256_context ctx; + + br_sha256_init(&ctx); + br_sha256_update(&ctx, input, inputlen); + br_sha256_out(&ctx, sha256sum); + return CURLE_OK; +} + +const struct Curl_ssl Curl_ssl_bearssl = { + { CURLSSLBACKEND_BEARSSL, "bearssl" }, + + 0, + + sizeof(struct ssl_backend_data), + + Curl_none_init, + Curl_none_cleanup, + Curl_bearssl_version, + Curl_none_check_cxn, + Curl_none_shutdown, + Curl_bearssl_data_pending, + Curl_bearssl_random, + Curl_none_cert_status_request, + Curl_bearssl_connect, + Curl_bearssl_connect_nonblocking, + Curl_bearssl_get_internals, + Curl_bearssl_close, + Curl_none_close_all, + Curl_bearssl_session_free, + Curl_none_set_engine, + Curl_none_set_engine_default, + Curl_none_engines_list, + Curl_none_false_start, + Curl_bearssl_md5sum, + Curl_bearssl_sha256sum +}; + +#endif /* USE_BEARSSL */ diff --git a/libs/libcurl/src/vtls/bearssl.h b/libs/libcurl/src/vtls/bearssl.h new file mode 100644 index 0000000000..5f94922b92 --- /dev/null +++ b/libs/libcurl/src/vtls/bearssl.h @@ -0,0 +1,32 @@ +#ifndef HEADER_CURL_BEARSSL_H +#define HEADER_CURL_BEARSSL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2019, Michael Forney, <mforney@mforney.org> + * + * 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.haxx.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_BEARSSL + +extern const struct Curl_ssl Curl_ssl_bearssl; + +#endif /* USE_BEARSSL */ +#endif /* HEADER_CURL_BEARSSL_H */ diff --git a/libs/libcurl/src/vtls/gskit.h b/libs/libcurl/src/vtls/gskit.h index 466ee4d9de..b06b5e17d3 100644 --- a/libs/libcurl/src/vtls/gskit.h +++ b/libs/libcurl/src/vtls/gskit.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2019, 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 diff --git a/libs/libcurl/src/vtls/mbedtls.h b/libs/libcurl/src/vtls/mbedtls.h index 4a938605bd..0cc64b3991 100644 --- a/libs/libcurl/src/vtls/mbedtls.h +++ b/libs/libcurl/src/vtls/mbedtls.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com> * * This software is licensed as described in the file COPYING, which diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c index a375f00da2..ef51b0d912 100644 --- a/libs/libcurl/src/vtls/nss.c +++ b/libs/libcurl/src/vtls/nss.c @@ -113,7 +113,7 @@ typedef struct { ptr->type = (_type); \ ptr->pValue = (_val); \ ptr->ulValueLen = (_len); \ -} WHILE_FALSE +} while(0) #define CERT_NewTempCertificate __CERT_NewTempCertificate diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c index 760758d234..726ff6e7ca 100644 --- a/libs/libcurl/src/vtls/openssl.c +++ b/libs/libcurl/src/vtls/openssl.c @@ -142,10 +142,6 @@ #endif #endif -#ifdef LIBRESSL_VERSION_NUMBER -#define OpenSSL_version_num() LIBRESSL_VERSION_NUMBER -#endif - #if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \ !(defined(LIBRESSL_VERSION_NUMBER) && \ LIBRESSL_VERSION_NUMBER < 0x20700000L) @@ -392,11 +388,20 @@ static const char *SSL_ERROR_to_str(int err) */ static char *ossl_strerror(unsigned long error, char *buf, size_t size) { + if(size) + *buf = '\0'; + #ifdef OPENSSL_IS_BORINGSSL ERR_error_string_n((uint32_t)error, buf, size); #else ERR_error_string_n(error, buf, size); #endif + + if(size > 1 && !*buf) { + strncpy(buf, (error ? "Unknown error" : "No error"), size); + buf[size - 1] = '\0'; + } + return buf; } @@ -2768,19 +2773,29 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) infof(data, " CRLfile: %s\n", ssl_crlfile); } - /* Try building a chain using issuers in the trusted store first to avoid - problems with server-sent legacy intermediates. Newer versions of - OpenSSL do alternate chain checking by default which gives us the same - fix without as much of a performance hit (slight), so we prefer that if - available. - https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest - */ -#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) if(verifypeer) { + /* Try building a chain using issuers in the trusted store first to avoid + problems with server-sent legacy intermediates. Newer versions of + OpenSSL do alternate chain checking by default which gives us the same + fix without as much of a performance hit (slight), so we prefer that if + available. + https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest + */ +#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), X509_V_FLAG_TRUSTED_FIRST); - } #endif +#ifdef X509_V_FLAG_PARTIAL_CHAIN + if(!SSL_SET_OPTION(no_partialchain)) { + /* Have intermediate certificates in the trust store be treated as + trust-anchors, in the same way as self-signed root CA certificates + are. This allows users to verify servers using the intermediate cert + only, instead of needing the whole chain. */ + X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx), + X509_V_FLAG_PARTIAL_CHAIN); + } +#endif + } /* SSL always tries to verify the peer, this only says whether it should * fail to connect if the verification fails, or if it should continue @@ -2806,8 +2821,10 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) /* give application a chance to interfere with SSL set up. */ if(data->set.ssl.fsslctx) { + Curl_set_in_callback(data, true); result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx, data->set.ssl.fsslctxp); + Curl_set_in_callback(data, false); if(result) { failf(data, "error signaled by ssl ctx callback"); return result; @@ -2988,8 +3005,13 @@ static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name : conn->host.name; const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port; + char extramsg[80]=""; + int sockerr = SOCKERRNO; + if(sockerr && detail == SSL_ERROR_SYSCALL) + Curl_strerror(sockerr, extramsg, sizeof(extramsg)); failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ", - SSL_ERROR_to_str(detail), hostname, port); + extramsg[0] ? extramsg : SSL_ERROR_to_str(detail), + hostname, port); return result; } @@ -3065,7 +3087,7 @@ do { \ Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \ if(1 != BIO_reset(mem)) \ break; \ -} WHILE_FALSE +} while(0) static void pubkey_show(struct Curl_easy *data, BIO *mem, @@ -3097,7 +3119,7 @@ do { \ if(_type->_name) { \ pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \ } \ -} WHILE_FALSE +} while(0) #endif static int X509V3_ext(struct Curl_easy *data, @@ -3826,10 +3848,22 @@ static ssize_t ossl_send(struct connectdata *conn, *curlcode = CURLE_AGAIN; return -1; case SSL_ERROR_SYSCALL: - Curl_strerror(SOCKERRNO, error_buffer, sizeof(error_buffer)); - failf(conn->data, OSSL_PACKAGE " SSL_write: %s", error_buffer); - *curlcode = CURLE_SEND_ERROR; - return -1; + { + int sockerr = SOCKERRNO; + sslerror = ERR_get_error(); + if(sslerror) + ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); + else if(sockerr) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); + error_buffer[sizeof(error_buffer) - 1] = '\0'; + } + failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d", + error_buffer, sockerr); + *curlcode = CURLE_SEND_ERROR; + return -1; + } case SSL_ERROR_SSL: /* A failure in the SSL library occurred, usually a protocol error. The OpenSSL error queue contains more information on the error. */ @@ -3894,11 +3928,6 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ /* there's data pending, re-invoke SSL_read() */ *curlcode = CURLE_AGAIN; return -1; - case SSL_ERROR_SYSCALL: - Curl_strerror(SOCKERRNO, error_buffer, sizeof(error_buffer)); - failf(conn->data, OSSL_PACKAGE " SSL_read: %s", error_buffer); - *curlcode = CURLE_RECV_ERROR; - return -1; default: /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return value/errno" */ @@ -3907,14 +3936,44 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ if((nread < 0) || sslerror) { /* If the return code was negative or there actually is an error in the queue */ + int sockerr = SOCKERRNO; + if(sslerror) + ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)); + else if(sockerr && err == SSL_ERROR_SYSCALL) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + strncpy(error_buffer, SSL_ERROR_to_str(err), sizeof(error_buffer)); + error_buffer[sizeof(error_buffer) - 1] = '\0'; + } failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d", - (sslerror ? - ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)) : - SSL_ERROR_to_str(err)), - SOCKERRNO); + error_buffer, sockerr); *curlcode = CURLE_RECV_ERROR; return -1; } + /* For debug builds be a little stricter and error on any + SSL_ERROR_SYSCALL. For example a server may have closed the connection + abruptly without a close_notify alert. For compatibility with older + peers we don't do this by default. #4624 + + We can use this to gauge how many users may be affected, and + if it goes ok eventually transition to allow in dev and release with + the newest OpenSSL: #if (OPENSSL_VERSION_NUMBER >= 0x10101000L) */ +#ifdef DEBUGBUILD + if(err == SSL_ERROR_SYSCALL) { + int sockerr = SOCKERRNO; + if(sockerr) + Curl_strerror(sockerr, error_buffer, sizeof(error_buffer)); + else { + msnprintf(error_buffer, sizeof(error_buffer), + "Connection closed abruptly"); + } + failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d" + " (Fatal because this is a curl debug build)", + error_buffer, sockerr); + *curlcode = CURLE_RECV_ERROR; + return -1; + } +#endif } } return nread; @@ -3922,13 +3981,35 @@ static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ static size_t Curl_ossl_version(char *buffer, size_t size) { -#ifdef OPENSSL_IS_BORINGSSL +#ifdef LIBRESSL_VERSION_NUMBER +#if LIBRESSL_VERSION_NUMBER < 0x2070100fL + return msnprintf(buffer, size, "%s/%lx.%lx.%lx", + OSSL_PACKAGE, + (LIBRESSL_VERSION_NUMBER>>28)&0xf, + (LIBRESSL_VERSION_NUMBER>>20)&0xff, + (LIBRESSL_VERSION_NUMBER>>12)&0xff); +#else /* OpenSSL_version() first appeared in LibreSSL 2.7.1 */ + char *p; + int count; + const char *ver = OpenSSL_version(OPENSSL_VERSION); + const char expected[] = OSSL_PACKAGE " "; /* ie "LibreSSL " */ + if(Curl_strncasecompare(ver, expected, sizeof(expected) - 1)) { + ver += sizeof(expected) - 1; + } + count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); + for(p = buffer; *p; ++p) { + if(ISSPACE(*p)) + *p = '_'; + } + return count; +#endif +#elif defined(OPENSSL_IS_BORINGSSL) return msnprintf(buffer, size, OSSL_PACKAGE); #elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING) return msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); #else - /* not BoringSSL and not using OpenSSL_version */ + /* not LibreSSL, BoringSSL and not using OpenSSL_version */ char sub[3]; unsigned long ssleay_value; diff --git a/libs/libcurl/src/vtls/polarssl.h b/libs/libcurl/src/vtls/polarssl.h index 23c3636ee6..f36f24f8df 100644 --- a/libs/libcurl/src/vtls/polarssl.h +++ b/libs/libcurl/src/vtls/polarssl.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com> * * This software is licensed as described in the file COPYING, which diff --git a/libs/libcurl/src/vtls/polarssl_threadlock.c b/libs/libcurl/src/vtls/polarssl_threadlock.c index 27c94b11e2..4e269c8e6a 100644 --- a/libs/libcurl/src/vtls/polarssl_threadlock.c +++ b/libs/libcurl/src/vtls/polarssl_threadlock.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2013-2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2013 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com> * * This software is licensed as described in the file COPYING, which diff --git a/libs/libcurl/src/vtls/polarssl_threadlock.h b/libs/libcurl/src/vtls/polarssl_threadlock.h index 122647528d..c1900bfe81 100644 --- a/libs/libcurl/src/vtls/polarssl_threadlock.h +++ b/libs/libcurl/src/vtls/polarssl_threadlock.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2013 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com> * * This software is licensed as described in the file COPYING, which diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index bbd2fe921c..dc58ed0d3b 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.c @@ -7,7 +7,7 @@ * * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de> * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com> - * Copyright (C) 2012 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2020, 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 @@ -554,10 +554,6 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) switch(conn->ssl_config.version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT | - SP_PROT_TLS1_1_CLIENT | - SP_PROT_TLS1_2_CLIENT; - break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: case CURL_SSLVERSION_TLSv1_2: @@ -1859,7 +1855,9 @@ schannel_recv(struct connectdata *conn, int sockindex, goto cleanup; } else { +#ifndef CURL_DISABLE_VERBOSE_STRINGS char buffer[STRERROR_LEN]; +#endif *err = CURLE_RECV_ERROR; infof(data, "schannel: failed to read data from server: %s\n", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); diff --git a/libs/libcurl/src/vtls/schannel_verify.c b/libs/libcurl/src/vtls/schannel_verify.c index 1bdf50a55c..3a668adc76 100644 --- a/libs/libcurl/src/vtls/schannel_verify.c +++ b/libs/libcurl/src/vtls/schannel_verify.c @@ -99,7 +99,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: invalid path name for CA file '%s': %s", - ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -120,7 +121,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: failed to open CA file '%s': %s", - ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -129,7 +131,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: failed to determine size of CA file '%s': %s", - ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -159,7 +162,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, char buffer[STRERROR_LEN]; failf(data, "schannel: failed to read from CA file '%s': %s", - ca_file, Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + ca_file, + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; goto cleanup; } @@ -223,7 +227,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, "schannel: failed to extract certificate from CA file " "'%s': %s", ca_file, - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -252,7 +256,8 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store, "schannel: failed to add certificate from CA file '%s' " "to certificate store: %s", ca_file, - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, + sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; more_certs = 0; } @@ -460,7 +465,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) if(!trust_store) { char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate store: %s", - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } else { @@ -489,7 +494,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) char buffer[STRERROR_LEN]; failf(data, "schannel: failed to create certificate chain engine: %s", - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); result = CURLE_SSL_CACERT_BADFILE; } } @@ -512,7 +517,7 @@ CURLcode Curl_verify_certificate(struct connectdata *conn, int sockindex) &pChainContext)) { char buffer[STRERROR_LEN]; failf(data, "schannel: CertGetCertificateChain failed: %s", - Curl_strerror(GetLastError(), buffer, sizeof(buffer))); + Curl_winapi_strerror(GetLastError(), buffer, sizeof(buffer))); pChainContext = NULL; result = CURLE_PEER_FAILED_VERIFICATION; } diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c index e6d7562254..c493b15169 100644 --- a/libs/libcurl/src/vtls/vtls.c +++ b/libs/libcurl/src/vtls/vtls.c @@ -517,7 +517,7 @@ void Curl_ssl_close_all(struct Curl_easy *data) #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ defined(USE_SECTRANSP) || defined(USE_POLARSSL) || defined(USE_NSS) || \ - defined(USE_MBEDTLS) || defined(USE_WOLFSSL) + 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]; @@ -1189,6 +1189,8 @@ const struct Curl_ssl *Curl_ssl = &Curl_ssl_schannel; #elif defined(USE_MESALINK) &Curl_ssl_mesalink; +#elif defined(USE_BEARSSL) + &Curl_ssl_bearssl; #else #error "Missing struct Curl_ssl for selected SSL backend" #endif @@ -1224,6 +1226,9 @@ static const struct Curl_ssl *available_backends[] = { #if defined(USE_MESALINK) &Curl_ssl_mesalink, #endif +#if defined(USE_BEARSSL) + &Curl_ssl_bearssl, +#endif NULL }; diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index 61d8416c29..976cc43601 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -108,6 +108,7 @@ CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen, #include "sectransp.h" /* SecureTransport (Darwin) version */ #include "mbedtls.h" /* mbedTLS versions */ #include "mesalink.h" /* MesaLink versions */ +#include "bearssl.h" /* BearSSL versions */ #ifndef MAX_PINNED_PUBKEY_SIZE #define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */ |