diff options
29 files changed, 861 insertions, 1783 deletions
diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES index 68ebc8265b..2862b0eeb9 100644 --- a/libs/libcurl/docs/CHANGES +++ b/libs/libcurl/docs/CHANGES @@ -6,6 +6,358 @@ Changelog +Version 7.69.1 (11 Mar 2020) + +Daniel Stenberg (11 Mar 2020) +- RELEASE-NOTES: 7.69.1 + +- THANKS: from the 7.69.1 release + +- [Marc Hoersken brought this change] + + test1129: fix invalid case of closing XML-tag and Content-Length + + Fixes #5070 + Closes #5072 + +Marc Hoersken (10 Mar 2020) +- tests/data: fix static ip instead of dynamic value being used + + Follow up to 94ced8e + +- tests/data: fix static ip:port instead of dynamic values being used + + Closes #5065 + +- tests/server: fix missing use of exe_ext helper function + + Follow up to 9819984 and 3dce984 + Reviewed-By: Daniel Stenberg + Closes #5064 + +- runtests: log minimal and maximal used port numbers + +Daniel Stenberg (9 Mar 2020) +- [Jim Fuller brought this change] + + sftp: fix segfault regression introduced by #4747 + + This fix adds a defensive check for the case where the char *name in + struct libssh2_knownhost is NULL + + Fixes #5041 + Closes #5062 + +- RELEASE-NOTES: synced + +- socks4: fix host resolve regression + + 1. The socks4 state machine was broken in the host resolving phase + + 2. The code now insists on IPv4-only when using SOCKS4 as the protocol + only supports that. + + Regression from #4907 and 4a4b63d, shipped in 7.69.0 + + Reported-by: amishmm on github + Bug: https://github.com/curl/curl/issues/5053#issuecomment-596191594 + Closes #5061 + +- [Patrick Monnerat brought this change] + + silly web server: silent a compilation warning + + Recent gcc warns when byte count of strncpy() equals the destination + buffer size. Since the destination buffer is previously cleared and + the source string is always shorter, reducing the byte count by one + silents the warning without affecting the result. + + Closes #5059 + +- [Patrick Monnerat brought this change] + + cookie: get_top_domain() sets zero length for null domains + + This silents a compilation warning with gcc -O3. + +- [Patrick Monnerat brought this change] + + test 1560: avoid valgrind false positives + + When using maximum code optimization level (-O3), valgrind wrongly + detects uses of uninitialized values in strcmp(). + + Preset buffers with all zeroes to avoid that. + +Steve Holme (8 Mar 2020) +- sha256: Added WinCrypt implementation + + Closed #5030 + +- sha256: Added SecureTransport implementation + +Daniel Stenberg (7 Mar 2020) +- lib1564: reduce number of mid-wait wakeup calls + + This test does A LOT of *wakeup() calls and then calls curl_multi_poll() + twice. The first *poll() is then expected to return early and the second + not - as the first is supposed to drain the socketpair pipe. + + It turns out however that when given "excessive" amounts of writes to + the pipe, some operating systems (the Solaris based are known) will + return EAGAIN before the pipe is drained, which in our test case causes + the second *poll() call to also abort early. + + This change attempts to avoid the OS-specific behaviors in the test by + reducing the amount of wakeup calls from 1234567 to 10. + + Reported-by: Andy Fiddaman + Fixes #5037 + Closes #5058 + +- [Patrick Monnerat brought this change] + + mime: fix the binary encoder to handle large data properly + + New test 666 checks this is effective. + As upload buffer size is significant in this kind of tests, shorten it + in similar test 652. + + Fixes #4860 + Closes #4833 + Reported-by: RuurdBeerstra on github + +- [Patrick Monnerat brought this change] + + mime: do not perform more than one read in a row + + Input buffer filling may delay the data sending if data reads are slow. + To overcome this problem, file and callback data reads do not accumulate + in buffer anymore. All other data (memory data and mime framing) are + considered as fast and still concatenated in buffer. + As this may highly impact performance in terms of data overhead, an early + end of part data check is added to spare a read call. + When encoding a part's data, an encoder may require more bytes than made + available by a single read. In this case, the above rule does not apply + and reads are performed until the encoder is able to deliver some data. + + Tests 643, 644, 645, 650 and 654 have been adapted to the output data + changes, with test data size reduced to avoid the boredom of long lists of + 1-byte chunks in verification data. + New test 667 checks mimepost using single-byte read callback with encoder. + New test 668 checks the end of part data early detection. + + Fixes #4826 + Reported-by: MrdUkk on github + +- [Patrick Monnerat brought this change] + + mime: latch last read callback status. + + In case a read callback returns a status (pause, abort, eof, + error) instead of a byte count, drain the bytes read so far but + remember this status for further processing. + Takes care of not losing data when pausing, and properly resume a + paused mime structure when requested. + New tests 670-673 check unpausing cases, with easy or multi + interface and mime or form api. + + Fixes #4813 + Reported-by: MrdUkk on github + +Marc Hoersken (7 Mar 2020) +- runtests: fix missing use of exe_ext helper function + +Daniel Stenberg (7 Mar 2020) +- [Ernst Sjöstrand brought this change] + + ares: store dns parameters for duphandle + + With c-ares the dns parameters lives in ares_channel. Store them in the + curl handle and set them again in easy_duphandle. + + Regression introduced in #3228 (6765e6d), shipped in curl 7.63.0. + + Fixes #4893 + Closes #5020 + Signed-off-by: Ernst Sjöstrand <ernst.sjostrand@verisure.com> + +- version: make curl_version* thread-safe without using global context + + Closes #5010 + +- RELEASE-NOTES: synced + +Marc Hoersken (7 Mar 2020) +- tests: use native Sleep function as fallback on Windows + + Reviewed-By: Daniel Stenberg + Closes #5054 + +- perl: align order and completeness of Windows OS checks + +Daniel Stenberg (7 Mar 2020) +- tool_cb_see: set correct copyright year range + + Follow-up to a39e5bfb9 + +Marc Hoersken (7 Mar 2020) +- seek: fix fallback for missing ftruncate on Windows + + This fixes test 198 on versions of MinGW-w64 without ftruncate + + Reviewed-By: Daniel Stenberg + Reviewed-By: Marcel Raad + Closes #5055 + +- config-win32: Windows does not have ftruncate + +Daniel Stenberg (7 Mar 2020) +- pause: force a connection (re-)check after unpausing + + There might be data available that was already read off the socket, for + example in the TLS layer. + + Reported-by: Anders Berg + Fixes #4966 + Closes #5049 + +- socks5: switch state properly when the resolve is done + + Regression from 4a4b63d (and #4907) + Reported-by: vitaha85 on github + Fixes #5053 + Closes #5056 + +Jay Satiro (7 Mar 2020) +- libssh: Fix matching user-specified MD5 hex key + + Prior to this change a match would never be successful because it + was mistakenly coded to compare binary data from libssh to a + user-specified hex string (ie CURLOPT_SSH_HOST_PUBLIC_KEY_MD5). + + Reported-by: fds242@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/4971 + Closes https://github.com/curl/curl/pull/4974 + +Daniel Stenberg (6 Mar 2020) +- pause: bail out on bad input + + A NULL easy handle or an easy handle without an associated connection + cannot be paused or unpaused. + + Closes #5050 + +Steve Holme (6 Mar 2020) +- unit1612: fixed the inclusion and compilation of the HMAC unit test + + Follow up to 3f74e5e6 to fix: + + - A typo in Makefile.inc where unit1611 was used instead + - Some compilation issues in unit1612.c + + Closes #5024 + +Daniel Stenberg (6 Mar 2020) +- pause: return early for calls that don't change pause state + + Reviewed-by: Patrick Monnerat + Ref: #4833 + Closes #5026 + +Jay Satiro (6 Mar 2020) +- curl_share_setopt.3: Note sharing cookies doesn't enable the engine + + Follow-up to d0a7ee3 which fixed a bug in 7.66.0 that caused + CURL_LOCK_DATA_COOKIE to enable the easy handle's cookie engine. + + Bug: https://curl.haxx.se/mail/lib-2020-03/0019.html + Reported-by: Felipe Gasper + + Closes https://github.com/curl/curl/pull/5048 + +- multi: skip EINTR check on wakeup socket if it was closed + + - Don't check errno on wakeup socket if sread returned 0 since sread + doesn't set errno in that case. + + This is a follow-up to cf7760a from several days ago which fixed + Curl_multi_wait to stop busy looping sread on the non-blocking wakeup + socket if it was closed (ie sread returns 0). Due to a logic error it + was still possible to busy loop in that case if errno == EINTR. + + Closes https://github.com/curl/curl/pull/5047 + +Daniel Stenberg (6 Mar 2020) +- transfer: set correct copyright year range + +- urldata: remove the 'stream_was_rewound' connectdata struct member + + ... as it is never set anywhere. + + Follow-up to 2f44e94ef + Closes #5046 + +- Revert "pause: force-drain the transfer on unpause" + + This reverts commit fa0216b294af4c7113a9040ca65eefc7fc18ac1c (from #5000) + + Clearly that didn't solve the problem correctly. + + Reported-by: Christopher Reid + Reopens #4966 + Fixes #5044 + +- RELEASE-NOTES: synced + + and bumped curlver.h + +- MANUAL: update a dict-using command line + + The 'web1913' database is now invalid, use 'gcide' instead. + +- KNOWN_BUGS: configure --with-gssapi with Heimdal is ignored on macOS + + Closes #3841 + +- polarssl: remove more references and mentions + + Assisted-by: Jay Satiro + Follow-up to 6357a19ff29dac04 + Closes #5036 + +Marc Hoersken (4 Mar 2020) +- tests: wrap ignored test failures in braces + +- tests: align some Windows sleep defines with each other + +- tests: try to make sleeping portable by avoiding select + + select does not support just waiting on Windows: + https://perldoc.perl.org/perlport.html#select + + Reviewed-By: Daniel Stenberg + Closes #5035 + +Daniel Stenberg (4 Mar 2020) +- runtests.1: rephrase how to specify what tests to run + + Also mention the new tilde-prefixed way to ignore test results. + + Reviewed-By: Marc Hoersken + Closes #5033 + +- cirrus-ci: disable the FreeBSD 13 builds + + FreeBSD 13.0 is apparently close to a year away from a stable release + and has proven to cause intermittent builds failures recently. + + Assisted-by: Dan Fandrich + Assisted-by: Fedor Korotkov + Fixes #5028 + Closes #5029 + Version 7.69.0 (4 Mar 2020) Daniel Stenberg (4 Mar 2020) @@ -6849,391 +7201,3 @@ Daniel Stenberg (11 Jun 2019) - wolfssl: fix key pinning build error follow-up from deb9462ff2de8 - -- CURLMOPT_SOCKETFUNCTION.3: clarified - - Moved away the callback explanation from curl_multi_socket_action.3 and - expanded it somewhat. - - Closes #4006 - -- wolfssl: fixup for SNI use - - follow-up from deb9462ff2de8 - - Closes #4007 - -- CURLOPT_CAINFO.3: polished wording - - Clarify the functionality when built to use Schannel and Secure - Transport and stop calling it the "recommended" or "preferred" way and - instead rather call it the default. - - Removed the reference to the ssl comparison table as it isn't necessary. - - Reported-by: Richard Alcock - Bug: https://curl.haxx.se/mail/lib-2019-06/0019.html - Closes #4005 - -GitHub (10 Jun 2019) -- [Daniel Stenberg brought this change] - - SECURITY.md: created - - Brief security policy description for use/display on github. - -Daniel Gustafsson (10 Jun 2019) -- tool_cb_prg: Fix integer overflow in progress bar - - Commit 61faa0b420c236480bc9ef6fd52b4ecc1e0f8d17 fixed the progress bar - width calculation to avoid integer overflow, but failed to account for - the fact that initial_size is initialized to -1 when the file size is - retrieved from the remote on an upload, causing another signed integer - overflow. Fix by separately checking for this case before the width - calculation. - - Closes #3984 - Reported-by: Brian Carpenter (Geeknik Labs) - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - -Daniel Stenberg (10 Jun 2019) -- wolfssl: refer to it as wolfSSL only - - Remove support for, references to and use of "cyaSSL" from the source - and docs. wolfSSL is the current name and there's no point in keeping - references to ancient history. - - Assisted-by: Daniel Gustafsson - - Closes #3903 - -- RELEASE-NOTES: synced - -- bindlocal: detect and avoid IP version mismatches in bind() - - Reported-by: Alex Grebenschikov - Fixes #3993 - Closes #4002 - -- multi: make sure 'data' can present in several sockhash entries - - Since more than one socket can be used by each transfer at a given time, - each sockhash entry how has its own hash table with transfers using that - socket. - - In addition, the sockhash entry can now be marked 'blocked = TRUE'" - which then makes the delete function just set 'removed = TRUE' instead - of removing it "for real", as a way to not rip out the carpet under the - feet of a parent function that iterates over the transfers of that same - sockhash entry. - - Reported-by: Tom van der Woerdt - Fixes #3961 - Fixes #3986 - Fixes #3995 - Fixes #4004 - Closes #3997 - -- [Sorcus brought this change] - - libcurl-tutorial.3: Fix small typo (mutipart -> multipart) - - Fixed-by: MrSorcus on github - Closes #4000 - -- unpause: trigger a timeout for event-based transfers - - ... so that timeouts or other state machine actions get going again - after a changing pause state. For example, if the last delivery was - paused there's no pending socket activity. - - Reported-by: sstruchtrup on github - Fixes #3994 - Closes #4001 - -Marcel Raad (9 Jun 2019) -- travis: use xenial LLVM package for scan-build - - I missed that in commit 99a49d6. - -- travis: update scan-build job to xenial - - Closes https://github.com/curl/curl/pull/3999 - -Daniel Stenberg (8 Jun 2019) -- bump: start working on 7.65.2 - -Marcel Raad (5 Jun 2019) -- examples/htmltitle: use C++ casts between pointer types - - Compilers and static analyzers warn about using C-style casts here. - - Closes https://github.com/curl/curl/pull/3975 - -- examples/fopen: fix comparison - - As want is size_t, (file->buffer_pos - want) is unsigned, so checking - if it's less than zero makes no sense. - Check if file->buffer_pos is less than want instead to avoid the - unsigned integer wraparound. - - Closes https://github.com/curl/curl/pull/3975 - -- build: fix Codacy warnings - - Reduce variable scopes and remove redundant variable stores. - - Closes https://github.com/curl/curl/pull/3975 - -- sws: remove unused variables - - Unused since commit 2f44e94. - - Closes https://github.com/curl/curl/pull/3975 - -Version 7.65.1 (4 Jun 2019) - -Daniel Stenberg (4 Jun 2019) -- RELEASE-NOTES: 7.65.1 - -- THANKS: new contributors from 7.65.1 - -Steve Holme (4 Jun 2019) -- [Frank Gevaerts brought this change] - - ssl: Update outdated "openssl-only" comments for supported backends - - These are for features that used to be openssl-only but were expanded - over time to support other SSL backends. - - Closes #3985 - -Daniel Stenberg (4 Jun 2019) -- curl_share_setopt.3: improve wording [ci ship] - - Reported-by: Carlos ORyan - -Steve Holme (4 Jun 2019) -- tool_parsecfg: Use correct return type for GetModuleFileName() - - GetModuleFileName() returns a DWORD which is a typedef of an unsigned - long and not an int. - - Closes #3980 - -Daniel Stenberg (3 Jun 2019) -- TODO: "at least N milliseconds between requests" [ci skip] - - Suggested-by: dkwolfe4 on github - Closes #3920 - -Steve Holme (2 Jun 2019) -- tests/server/.gitignore: Add socksd to the ignore list - - Missed in 04fd6755. - - Closes #3978 - -- tool_parsecfg: Fix control flow issue (DEADCODE) - - Follow-up to 8144ba38. - - Detected by Coverity CID 1445663 - Closes #3976 - -Daniel Stenberg (2 Jun 2019) -- [Sergey Ogryzkov brought this change] - - NTLM: reset proxy "multipass" state when CONNECT request is done - - Closes #3972 - -- test334: verify HTTP 204 response with chunked coding header - - Verifies that a bodyless response don't parse this content-related - header. - -- [Michael Kaufmann brought this change] - - http: don't parse body-related headers bodyless responses - - Responses with status codes 1xx, 204 or 304 don't have a response body. For - these, don't parse these headers: - - - Content-Encoding - - Content-Length - - Content-Range - - Last-Modified - - Transfer-Encoding - - This change ensures that HTTP/2 upgrades work even if a - "Content-Length: 0" or a "Transfer-Encoding: chunked" header is present. - - Co-authored-by: Daniel Stenberg - Closes #3702 - Fixes #3968 - Closes #3977 - -- tls13-docs: mention it is only for OpenSSL >= 1.1.1 - - Reported-by: Jay Satiro - Co-authored-by: Jay Satiro - Fixes #3938 - Closes #3946 - -- dump-header.d: spell out that no headers == empty file [ci skip] - - Reported-by: wesinator at github - Fixes #3964 - Closes #3974 - -- singlesocket: use separate variable for inner loop - - An inner loop within the singlesocket() function wrongly re-used the - variable for the outer loop which then could cause an infinite - loop. Change to using a separate variable! - - Reported-by: Eric Wu - Fixes #3970 - Closes #3973 - -- RELEASE-NOTES: synced - -- [Josie Huddleston brought this change] - - http2: Stop drain from being permanently set on - - Various functions called within Curl_http2_done() can have the - side-effect of setting the Easy connection into drain mode (by calling - drain_this()). However, the last time we unset this for a transfer (by - calling drained_transfer()) is at the beginning of Curl_http2_done(). - If the Curl_easy is reused for another transfer, it is then stuck in - drain mode permanently, which in practice makes it unable to write any - data in the new transfer. - - This fix moves the last call to drained_transfer() to later in - Curl_http2_done(), after the functions that could potentially call for a - drain. - - Fixes #3966 - Closes #3967 - Reported-by: Josie-H - -Steve Holme (29 May 2019) -- conncache: Remove the DEBUGASSERT on length check - - We trust the calling code as this is an internal function. - - Closes #3962 - -Jay Satiro (29 May 2019) -- [Gisle Vanem brought this change] - - system_win32: fix function prototype - - - Change if_nametoindex parameter type from char * to const char *. - - Follow-up to 09eef8af from this morning. - - Bug: https://github.com/curl/curl/commit/09eef8af#r33716067 - -Marcel Raad (29 May 2019) -- appveyor: add Visual Studio solution build - - Closes https://github.com/curl/curl/pull/3941 - -- appveyor: add support for other build systems - - Introduce BUILD_SYSTEM variable, which is currently always CMake. - - Closes https://github.com/curl/curl/pull/3941 - -Steve Holme (29 May 2019) -- url: Load if_nametoindex() dynamically from iphlpapi.dll on Windows - - This fixes the static dependency on iphlpapi.lib and allows curl to - build for targets prior to Windows Vista. - - This partially reverts 170bd047. - - Fixes #3960 - Closes #3958 - -Daniel Stenberg (29 May 2019) -- http: fix "error: equality comparison with extraneous parentheses" - -- parse_proxy: make sure portptr is initialized - - Reported-by: Benbuck Nason - - fixes #3959 - -- url: default conn->port to the same as conn->remote_port - - ... so that it has a sensible value when ConnectionExists() is called which - needs it set to differentiate host "bundles" correctly on port number! - - Also, make conncache:hashkey() use correct port for bundles that are proxy vs - host connections. - - Probably a regression from 7.62.0 - - Reported-by: Tom van der Woerdt - Fixes #3956 - Closes #3957 - -- conncache: make "bundles" per host name when doing proxy tunnels - - Only HTTP proxy use where multiple host names can be used over the same - connection should use the proxy host name for bundles. - - Reported-by: Tom van der Woerdt - Fixes #3951 - Closes #3955 - -- multi: track users of a socket better - - They need to be removed from the socket hash linked list with more care. - - When sh_delentry() is called to remove a sockethash entry, remove all - individual transfers from the list first. To enable this, each Curl_easy struct - now stores a pointer to the sockethash entry to know how to remove itself. - - Reported-by: Tom van der Woerdt and Kunal Ekawde - - Fixes #3952 - Fixes #3904 - Closes #3953 - -Steve Holme (28 May 2019) -- curl-win32.h: Enable Unix Domain Sockets based on the Windows SDK version - - Microsoft added support for Unix Domain Sockets in Windows 10 1803 - (RS4). Rather than expect the user to enable Unix Domain Sockets by - uncommenting the #define that was added in 0fd6221f we use the RS4 - pre-processor variable that is present in newer versions of the - Windows SDK. - - Closes #3939 - -Daniel Stenberg (28 May 2019) -- [Jonas Vautherin brought this change] - - cmake: support CMAKE_OSX_ARCHITECTURES when detecting SIZEOF variables - - Closes #3945 - -Marcel Raad (27 May 2019) -- HAProxy tests: add keywords - - Add the proxy and haproxy keywords in order to be able to exclude or - run these specific tests. - - Closes https://github.com/curl/curl/pull/3949 - -Daniel Stenberg (27 May 2019) -- [Maksim Stsepanenka brought this change] - - tests: make test 1420 and 1406 work with rtsp-disabled libcurl - - Closes #3948 diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS index 82d7d8f1dc..53735cb6f5 100644 --- a/libs/libcurl/docs/THANKS +++ b/libs/libcurl/docs/THANKS @@ -91,6 +91,7 @@ Alfonso Martone Alfred Gebert Allen Pulsifer Alona Rossen +amishmm on github Amit Katyal Amol Pattekar Amr Shahin @@ -147,6 +148,7 @@ Andrii Moiseiev Andrius Merkys Andrés García Andy Cedilnik +Andy Fiddaman Andy Serpa Andy Tsouladze Angus Mackay @@ -636,9 +638,12 @@ Fabrice Fontaine Fabrizio Ammollo Fahim Chandurwala Faizur Rahman +fds242 on github Federico Bianchi Fedor Karpelevitch +Fedor Korotkov Feist Josselin +Felipe Gasper Felix Hädicke Felix Kaiser Felix von Leitner @@ -2049,6 +2054,7 @@ Vincent Le Normand Vincent Penquerc'h Vincent Sanders Vincent Torri +vitaha85 on github Vlad Grachov Vlad Ureche Vladimir Grishchenko diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h index 5264f19865..5fc49d4188 100644 --- a/libs/libcurl/include/curl/curlver.h +++ b/libs/libcurl/include/curl/curlver.h @@ -30,13 +30,13 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.69.0" +#define LIBCURL_VERSION "7.69.1" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 #define LIBCURL_VERSION_MINOR 69 -#define LIBCURL_VERSION_PATCH 0 +#define LIBCURL_VERSION_PATCH 1 /* This is the numeric version of the libcurl version number, meant for easier parsing and comparions by programs. The LIBCURL_VERSION_NUM define will @@ -57,7 +57,7 @@ CURL_VERSION_BITS() macro since curl's own configure script greps for it and needs it to contain the full number. */ -#define LIBCURL_VERSION_NUM 0x074500 +#define LIBCURL_VERSION_NUM 0x074501 /* * This is the date and time when the full source package was created. The @@ -68,7 +68,7 @@ * * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "2020-03-04" +#define LIBCURL_TIMESTAMP "2020-03-11" #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/src/checksrc.pl b/libs/libcurl/src/checksrc.pl index 8343645610..e1bb1a6339 100644 --- a/libs/libcurl/src/checksrc.pl +++ b/libs/libcurl/src/checksrc.pl @@ -36,7 +36,7 @@ my $file; my $dir="."; my $wlist=""; my @alist; -my $windows_os = $^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'cygwin'; +my $windows_os = $^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys'; my $verbose; my %whitelist; diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index da385c2ac7..d19665d71a 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -183,7 +183,7 @@ /* #define HAVE_DOPRNT 1 */ /* Define if you have the ftruncate function. */ -#define HAVE_FTRUNCATE 1 +/* #define HAVE_FTRUNCATE 1 */ /* Define to 1 if you have the `getpeername' function. */ #define HAVE_GETPEERNAME 1 @@ -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 */ @@ -717,9 +713,6 @@ Vista # define CURL_DISABLE_LDAP 1 #endif -/* if SSL is enabled */ -#define USE_OPENSSL 1 - /* Define to use the Windows crypto library. */ #if !defined(CURL_WINDOWS_APP) #define USE_WIN32_CRYPTO diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c index 69bc04260a..68054e1c4c 100644 --- a/libs/libcurl/src/cookie.c +++ b/libs/libcurl/src/cookie.c @@ -245,18 +245,17 @@ pathmatched: */ static const char *get_top_domain(const char * const domain, size_t *outlen) { - size_t len; + size_t len = 0; const char *first = NULL, *last; - if(!domain) - return NULL; - - len = strlen(domain); - last = memrchr(domain, '.', len); - if(last) { - first = memrchr(domain, '.', (last - domain)); - if(first) - len -= (++first - domain); + if(domain) { + len = strlen(domain); + last = memrchr(domain, '.', len); + if(last) { + first = memrchr(domain, '.', (last - domain)); + if(first) + len -= (++first - domain); + } } if(outlen) diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c index 1a6912748e..b648e80c14 100644 --- a/libs/libcurl/src/easy.c +++ b/libs/libcurl/src/easy.c @@ -83,8 +83,6 @@ #include "curl_memory.h" #include "memdebug.h" -void Curl_version_init(void); - /* true globals -- for curl_global_init() and curl_global_cleanup() */ static unsigned int initialized; static long init_flags; @@ -201,8 +199,6 @@ static CURLcode global_init(long flags, bool memoryfuncs) init_flags = flags; - Curl_version_init(); - return CURLE_OK; fail: @@ -887,6 +883,17 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) data->state.resolver)) goto fail; +#ifdef USE_ARES + if(Curl_set_dns_servers(outcurl, data->set.str[STRING_DNS_SERVERS])) + goto fail; + if(Curl_set_dns_interface(outcurl, data->set.str[STRING_DNS_INTERFACE])) + goto fail; + if(Curl_set_dns_local_ip4(outcurl, data->set.str[STRING_DNS_LOCAL_IP4])) + goto fail; + if(Curl_set_dns_local_ip6(outcurl, data->set.str[STRING_DNS_LOCAL_IP6])) + goto fail; +#endif /* USE_ARES */ + Curl_convert_setup(outcurl); Curl_initinfo(outcurl); @@ -973,16 +980,37 @@ void curl_easy_reset(struct Curl_easy *data) */ CURLcode curl_easy_pause(struct Curl_easy *data, int action) { - struct SingleRequest *k = &data->req; + struct SingleRequest *k; CURLcode result = CURLE_OK; + int oldstate; + int newstate; - /* first switch off both pause bits */ - int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE); + if(!GOOD_EASY_HANDLE(data) || !data->conn) + /* crazy input, don't continue */ + return CURLE_BAD_FUNCTION_ARGUMENT; - /* set the new desired pause bits */ - newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) | + k = &data->req; + oldstate = k->keepon & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE); + + /* first switch off both pause bits then set the new pause bits */ + newstate = (k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) | + ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) | ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0); + if((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) == oldstate) { + /* Not changing any pause state, return */ + DEBUGF(infof(data, "pause: no change, early return\n")); + return CURLE_OK; + } + + /* Unpause parts in active mime tree. */ + if((k->keepon & ~newstate & KEEP_SEND_PAUSE) && + (data->mstate == CURLM_STATE_PERFORM || + data->mstate == CURLM_STATE_TOOFAST) && + data->state.fread_func == (curl_read_callback) Curl_mime_read) { + Curl_mime_unpause(data->state.in); + } + /* put it back in the keepon */ k->keepon = newstate; @@ -1033,8 +1061,11 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) to have this handle checked soon */ if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) != (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) { - data->state.drain++; Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */ + + /* force a recv/send check of this connection, as the data might've been + read off the socket already */ + data->conn->cselect_bits = CURL_CSELECT_IN | CURL_CSELECT_OUT; if(data->multi) Curl_update_timer(data->multi); } diff --git a/libs/libcurl/src/formdata.c b/libs/libcurl/src/formdata.c index 50a37e0e74..57ec6ad254 100644 --- a/libs/libcurl/src/formdata.c +++ b/libs/libcurl/src/formdata.c @@ -728,14 +728,10 @@ int curl_formget(struct curl_httppost *form, void *arg, if(!nread) break; - switch(nread) { - default: - if(append(arg, buffer, nread) != nread) - result = CURLE_READ_ERROR; - break; - case CURL_READFUNC_ABORT: - case CURL_READFUNC_PAUSE: - break; + if(nread > sizeof(buffer) || append(arg, buffer, nread) != nread) { + result = CURLE_READ_ERROR; + if(nread == CURL_READFUNC_ABORT) + result = CURLE_ABORTED_BY_CALLBACK; } } diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index 72b38a3f66..41d8db6856 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -333,7 +333,7 @@ static const struct Curl_handler Curl_handler_http2_ssl = { int Curl_http2_ver(char *p, size_t len) { nghttp2_info *h2 = nghttp2_version(0); - return msnprintf(p, len, " nghttp2/%s", h2->version_str); + return msnprintf(p, len, "nghttp2/%s", h2->version_str); } /* diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index f0001fee06..0b521b0f86 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.69.0</string> + <string>7.69.1</string> <key>CFBundleName</key> <string>libcurl</string> @@ -27,9 +27,9 @@ <string>????</string> <key>CFBundleShortVersionString</key> - <string>libcurl 7.69.0</string> + <string>libcurl 7.69.1</string> <key>CFBundleGetInfoString</key> - <string>libcurl.plist 7.69.0</string> + <string>libcurl.plist 7.69.1</string> </dict> </plist> diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c index 2571287c6a..b72732310d 100644 --- a/libs/libcurl/src/mime.c +++ b/libs/libcurl/src/mime.c @@ -26,6 +26,7 @@ #include "mime.h" #include "non-ascii.h" +#include "warnless.h" #include "urldata.h" #include "sendf.h" @@ -52,6 +53,10 @@ #define READ_ERROR ((size_t) -1) +#define STOP_FILLING ((size_t) -2) + +static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, + void *instream, bool *hasread); /* Encoders. */ static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, @@ -354,10 +359,15 @@ static size_t encoder_nop_read(char *buffer, size_t size, bool ateof, (void) ateof; + if(!size) + return STOP_FILLING; + if(size > insize) size = insize; + if(size) - memcpy(buffer, st->buf, size); + memcpy(buffer, st->buf + st->bufbeg, size); + st->bufbeg += size; return size; } @@ -377,6 +387,9 @@ static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof, (void) ateof; + if(!size) + return STOP_FILLING; + if(size > cursize) size = cursize; @@ -404,8 +417,11 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, /* Line full ? */ if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) { /* Yes, we need 2 characters for CRLF. */ - if(size < 2) + if(size < 2) { + if(!cursize) + return STOP_FILLING; break; + } *ptr++ = '\r'; *ptr++ = '\n'; st->pos = 0; @@ -414,7 +430,12 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, } /* Be sure there is enough space and input data for a base64 group. */ - if(size < 4 || st->bufend - st->bufbeg < 3) + if(size < 4) { + if(!cursize) + return STOP_FILLING; + break; + } + if(st->bufend - st->bufbeg < 3) break; /* Encode three bytes as four characters. */ @@ -431,25 +452,31 @@ static size_t encoder_base64_read(char *buffer, size_t size, bool ateof, } /* If at eof, we have to flush the buffered data. */ - if(ateof && size >= 4) { - /* Buffered data size can only be 0, 1 or 2. */ - ptr[2] = ptr[3] = '='; - i = 0; - switch(st->bufend - st->bufbeg) { - case 2: - i = (st->buf[st->bufbeg + 1] & 0xFF) << 8; - /* FALLTHROUGH */ - case 1: - i |= (st->buf[st->bufbeg] & 0xFF) << 16; - ptr[0] = base64[(i >> 18) & 0x3F]; - ptr[1] = base64[(i >> 12) & 0x3F]; - if(++st->bufbeg != st->bufend) { - ptr[2] = base64[(i >> 6) & 0x3F]; - st->bufbeg++; + if(ateof) { + if(size < 4) { + if(!cursize) + return STOP_FILLING; + } + else { + /* Buffered data size can only be 0, 1 or 2. */ + ptr[2] = ptr[3] = '='; + i = 0; + switch(st->bufend - st->bufbeg) { + case 2: + i = (st->buf[st->bufbeg + 1] & 0xFF) << 8; + /* FALLTHROUGH */ + case 1: + i |= (st->buf[st->bufbeg] & 0xFF) << 16; + ptr[0] = base64[(i >> 18) & 0x3F]; + ptr[1] = base64[(i >> 12) & 0x3F]; + if(++st->bufbeg != st->bufend) { + ptr[2] = base64[(i >> 6) & 0x3F]; + st->bufbeg++; + } + cursize += 4; + st->pos += 4; + break; } - cursize += 4; - st->pos += 4; - break; } } @@ -581,8 +608,11 @@ static size_t encoder_qp_read(char *buffer, size_t size, bool ateof, } /* If the output buffer would overflow, do not store. */ - if(len > size) + if(len > size) { + if(!cursize) + return STOP_FILLING; break; + } /* Append to output buffer. */ memcpy(ptr, buf, len); @@ -612,16 +642,18 @@ static size_t mime_mem_read(char *buffer, size_t size, size_t nitems, void *instream) { curl_mimepart *part = (curl_mimepart *) instream; - size_t sz = (size_t) part->datasize - part->state.offset; + size_t sz = curlx_sotouz(part->datasize - part->state.offset); (void) size; /* Always 1.*/ + if(!nitems) + return STOP_FILLING; + if(sz > nitems) sz = nitems; if(sz) - memcpy(buffer, (char *) &part->data[part->state.offset], sz); + memcpy(buffer, part->data + curlx_sotouz(part->state.offset), sz); - part->state.offset += sz; return sz; } @@ -641,7 +673,7 @@ static int mime_mem_seek(void *instream, curl_off_t offset, int whence) if(offset < 0 || offset > part->datasize) return CURL_SEEKFUNC_FAIL; - part->state.offset = (size_t) offset; + part->state.offset = offset; return CURL_SEEKFUNC_OK; } @@ -668,6 +700,9 @@ static size_t mime_file_read(char *buffer, size_t size, size_t nitems, { curl_mimepart *part = (curl_mimepart *) instream; + if(!nitems) + return STOP_FILLING; + if(mime_open_file(part)) return READ_ERROR; @@ -711,15 +746,16 @@ static size_t readback_bytes(mime_state *state, const char *trail) { size_t sz; + size_t offset = curlx_sotouz(state->offset); - if(numbytes > state->offset) { - sz = numbytes - state->offset; - bytes += state->offset; + if(numbytes > offset) { + sz = numbytes - offset; + bytes += offset; } else { size_t tsz = strlen(trail); - sz = state->offset - numbytes; + sz = offset - numbytes; if(sz >= tsz) return 0; bytes = trail + sz; @@ -736,25 +772,79 @@ static size_t readback_bytes(mime_state *state, /* Read a non-encoded part content. */ static size_t read_part_content(curl_mimepart *part, - char *buffer, size_t bufsize) + char *buffer, size_t bufsize, bool *hasread) { size_t sz = 0; - if(part->readfunc) - sz = part->readfunc(buffer, 1, bufsize, part->arg); + switch(part->lastreadstatus) { + case 0: + case CURL_READFUNC_ABORT: + case CURL_READFUNC_PAUSE: + case READ_ERROR: + return part->lastreadstatus; + default: + break; + } + + /* If we can determine we are at end of part data, spare a read. */ + if(part->datasize != (curl_off_t) -1 && + part->state.offset >= part->datasize) { + /* sz is already zero. */ + } + else { + switch(part->kind) { + case MIMEKIND_MULTIPART: + /* + * Cannot be processed as other kinds since read function requires + * an additional parameter and is highly recursive. + */ + sz = mime_subparts_read(buffer, 1, bufsize, part->arg, hasread); + break; + case MIMEKIND_FILE: + if(part->fp && feof(part->fp)) + break; /* At EOF. */ + /* FALLTHROUGH */ + default: + if(part->readfunc) { + if(!(part->flags & MIME_FAST_READ)) { + if(*hasread) + return STOP_FILLING; + *hasread = TRUE; + } + sz = part->readfunc(buffer, 1, bufsize, part->arg); + } + break; + } + } + + switch(sz) { + case STOP_FILLING: + break; + case 0: + case CURL_READFUNC_ABORT: + case CURL_READFUNC_PAUSE: + case READ_ERROR: + part->lastreadstatus = sz; + break; + default: + part->state.offset += sz; + part->lastreadstatus = sz; + break; + } + return sz; } /* Read and encode part content. */ -static size_t read_encoded_part_content(curl_mimepart *part, - char *buffer, size_t bufsize) +static size_t read_encoded_part_content(curl_mimepart *part, char *buffer, + size_t bufsize, bool *hasread) { mime_encoder_state *st = &part->encstate; size_t cursize = 0; size_t sz; bool ateof = FALSE; - while(bufsize) { + for(;;) { if(st->bufbeg < st->bufend || ateof) { /* Encode buffered data. */ sz = part->encoder->encodefunc(buffer, bufsize, ateof, part); @@ -763,9 +853,8 @@ static size_t read_encoded_part_content(curl_mimepart *part, if(ateof) return cursize; break; - case CURL_READFUNC_ABORT: - case CURL_READFUNC_PAUSE: case READ_ERROR: + case STOP_FILLING: return cursize? cursize: sz; default: cursize += sz; @@ -787,7 +876,7 @@ static size_t read_encoded_part_content(curl_mimepart *part, if(st->bufend >= sizeof(st->buf)) return cursize? cursize: READ_ERROR; /* Buffer full. */ sz = read_part_content(part, st->buf + st->bufend, - sizeof(st->buf) - st->bufend); + sizeof(st->buf) - st->bufend, hasread); switch(sz) { case 0: ateof = TRUE; @@ -795,6 +884,7 @@ static size_t read_encoded_part_content(curl_mimepart *part, case CURL_READFUNC_ABORT: case CURL_READFUNC_PAUSE: case READ_ERROR: + case STOP_FILLING: return cursize? cursize: sz; default: st->bufend += sz; @@ -802,12 +892,12 @@ static size_t read_encoded_part_content(curl_mimepart *part, } } - return cursize; + /* NOTREACHED */ } /* Readback a mime part. */ static size_t readback_part(curl_mimepart *part, - char *buffer, size_t bufsize) + char *buffer, size_t bufsize, bool *hasread) { size_t cursize = 0; #ifdef CURL_DOES_CONVERSIONS @@ -866,9 +956,9 @@ static size_t readback_part(curl_mimepart *part, break; case MIMESTATE_CONTENT: if(part->encoder) - sz = read_encoded_part_content(part, buffer, bufsize); + sz = read_encoded_part_content(part, buffer, bufsize, hasread); else - sz = read_part_content(part, buffer, bufsize); + sz = read_part_content(part, buffer, bufsize, hasread); switch(sz) { case 0: mimesetstate(&part->state, MIMESTATE_END, NULL); @@ -881,6 +971,7 @@ static size_t readback_part(curl_mimepart *part, case CURL_READFUNC_ABORT: case CURL_READFUNC_PAUSE: case READ_ERROR: + case STOP_FILLING: return cursize? cursize: sz; } break; @@ -909,9 +1000,9 @@ static size_t readback_part(curl_mimepart *part, return cursize; } -/* Readback from mime. */ +/* Readback from mime. Warning: not a read callback function. */ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, - void *instream) + void *instream, bool *hasread) { curl_mime *mime = (curl_mime *) instream; size_t cursize = 0; @@ -932,7 +1023,7 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, #endif mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart); /* The first boundary always follows the header termination empty line, - so is always preceded by a CRLK. We can then spare 2 characters + so is always preceded by a CRLF. We can then spare 2 characters by skipping the leading CRLF in boundary. */ mime->state.offset += 2; break; @@ -962,11 +1053,12 @@ static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems, mimesetstate(&mime->state, MIMESTATE_END, NULL); break; } - sz = readback_part(part, buffer, nitems); + sz = readback_part(part, buffer, nitems, hasread); switch(sz) { case CURL_READFUNC_ABORT: case CURL_READFUNC_PAUSE: case READ_ERROR: + case STOP_FILLING: return cursize? cursize: sz; case 0: #ifdef CURL_DOES_CONVERSIONS @@ -1031,6 +1123,7 @@ static int mime_part_rewind(curl_mimepart *part) if(res == CURL_SEEKFUNC_OK) mimesetstate(&part->state, targetstate, NULL); + part->lastreadstatus = 1; /* Successful read status. */ return res; } @@ -1073,6 +1166,8 @@ static void cleanup_part_content(curl_mimepart *part) part->datasize = (curl_off_t) 0; /* No size yet. */ cleanup_encoder_state(&part->encstate); part->kind = MIMEKIND_NONE; + part->flags &= ~MIME_FAST_READ; + part->lastreadstatus = 1; /* Successful read status. */ } static void mime_subparts_free(void *ptr) @@ -1238,6 +1333,7 @@ void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy) { memset((char *) part, 0, sizeof(*part)); part->easy = easy; + part->lastreadstatus = 1; /* Successful read status. */ mimesetstate(&part->state, MIMESTATE_BEGIN, NULL); } @@ -1328,6 +1424,7 @@ CURLcode curl_mime_data(curl_mimepart *part, part->readfunc = mime_mem_read; part->seekfunc = mime_mem_seek; part->freefunc = mime_mem_free; + part->flags |= MIME_FAST_READ; part->kind = MIMEKIND_DATA; } @@ -1502,7 +1599,7 @@ CURLcode Curl_mime_set_subparts(curl_mimepart *part, } subparts->parent = part; - part->readfunc = mime_subparts_read; + /* Subparts are processed internally: no read callback. */ part->seekfunc = mime_subparts_seek; part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind; part->arg = subparts; @@ -1524,9 +1621,23 @@ CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts) size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream) { curl_mimepart *part = (curl_mimepart *) instream; + size_t ret; + bool hasread; (void) size; /* Always 1. */ - return readback_part(part, buffer, nitems); + + do { + hasread = FALSE; + ret = readback_part(part, buffer, nitems, &hasread); + /* + * If this is not possible to get some data without calling more than + * one read callback (probably because a content encoder is not able to + * deliver a new bunch for the few data accumulated so far), force another + * read until we get enough data or a special exit code. + */ + } while(ret == STOP_FILLING); + + return ret; } /* Rewind mime stream. */ @@ -1805,6 +1916,26 @@ CURLcode Curl_mime_prepare_headers(curl_mimepart *part, return ret; } +/* Recursively reset paused status in the given part. */ +void Curl_mime_unpause(curl_mimepart *part) +{ + if(part) { + if(part->lastreadstatus == CURL_READFUNC_PAUSE) + part->lastreadstatus = 1; /* Successful read status. */ + if(part->kind == MIMEKIND_MULTIPART) { + curl_mime *mime = (curl_mime *) part->arg; + + if(mime) { + curl_mimepart *subpart; + + for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) + Curl_mime_unpause(subpart); + } + } + } +} + + #else /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */ /* Mime not compiled in: define stubs for externally-referenced functions. */ diff --git a/libs/libcurl/src/mime.h b/libs/libcurl/src/mime.h index 4312125796..d7f25132e3 100644 --- a/libs/libcurl/src/mime.h +++ b/libs/libcurl/src/mime.h @@ -31,6 +31,7 @@ /* Part flags. */ #define MIME_USERHEADERS_OWNER (1 << 0) #define MIME_BODY_ONLY (1 << 1) +#define MIME_FAST_READ (1 << 2) #define FILE_CONTENTTYPE_DEFAULT "application/octet-stream" #define MULTIPART_CONTENTTYPE_DEFAULT "multipart/mixed" @@ -87,7 +88,7 @@ typedef struct { typedef struct { enum mimestate state; /* Current state token. */ void *ptr; /* State-dependent pointer. */ - size_t offset; /* State-dependent offset. */ + curl_off_t offset; /* State-dependent offset. */ } mime_state; /* minimum buffer size for the boundary string */ @@ -125,6 +126,7 @@ struct curl_mimepart_s { mime_state state; /* Current readback state. */ const mime_encoder *encoder; /* Content data encoder. */ mime_encoder_state encstate; /* Data encoder state. */ + size_t lastreadstatus; /* Last read callback returned status. */ }; CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...); @@ -147,6 +149,7 @@ size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream); CURLcode Curl_mime_rewind(curl_mimepart *part); const char *Curl_mime_contenttype(const char *filename); +void Curl_mime_unpause(curl_mimepart *part); #else /* if disabled */ @@ -158,6 +161,7 @@ const char *Curl_mime_contenttype(const char *filename); #define Curl_mime_size(x) (curl_off_t) -1 #define Curl_mime_read NULL #define Curl_mime_rewind(x) ((void)x, CURLE_NOT_BUILT_IN) +#define Curl_mime_unpause(x) #endif diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index cef2805c8e..e10e752931 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -1194,14 +1194,16 @@ static CURLMcode Curl_multi_wait(struct Curl_multi *multi, if(use_wakeup && multi->wakeup_pair[0] != CURL_SOCKET_BAD) { if(ufds[curlfds + extra_nfds].revents & POLLIN) { char buf[64]; + ssize_t nread; 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) { + nread = sread(multi->wakeup_pair[0], buf, sizeof(buf)); + if(nread <= 0) { #ifndef USE_WINSOCK - if(EINTR == SOCKERRNO) + if(nread < 0 && EINTR == SOCKERRNO) continue; #endif break; diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index 2e494a6df9..4648c872b4 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -2583,16 +2583,32 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif #ifdef USE_ARES case CURLOPT_DNS_SERVERS: - result = Curl_set_dns_servers(data, va_arg(param, char *)); + result = Curl_setstropt(&data->set.str[STRING_DNS_SERVERS], + va_arg(param, char *)); + if(result) + return result; + result = Curl_set_dns_servers(data, data->set.str[STRING_DNS_SERVERS]); break; case CURLOPT_DNS_INTERFACE: - result = Curl_set_dns_interface(data, va_arg(param, char *)); + result = Curl_setstropt(&data->set.str[STRING_DNS_INTERFACE], + va_arg(param, char *)); + if(result) + return result; + result = Curl_set_dns_interface(data, data->set.str[STRING_DNS_INTERFACE]); break; case CURLOPT_DNS_LOCAL_IP4: - result = Curl_set_dns_local_ip4(data, va_arg(param, char *)); + result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP4], + va_arg(param, char *)); + if(result) + return result; + result = Curl_set_dns_local_ip4(data, data->set.str[STRING_DNS_LOCAL_IP4]); break; case CURLOPT_DNS_LOCAL_IP6: - result = Curl_set_dns_local_ip6(data, va_arg(param, char *)); + result = Curl_setstropt(&data->set.str[STRING_DNS_LOCAL_IP6], + va_arg(param, char *)); + if(result) + return result; + result = Curl_set_dns_local_ip6(data, data->set.str[STRING_DNS_LOCAL_IP6]); break; #endif case CURLOPT_TCP_KEEPALIVE: diff --git a/libs/libcurl/src/sha256.c b/libs/libcurl/src/sha256.c index 97214182be..352d577e8d 100644 --- a/libs/libcurl/src/sha256.c +++ b/libs/libcurl/src/sha256.c @@ -161,6 +161,80 @@ static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) #endif } +#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ + (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \ + (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ + (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000)) + +#include <CommonCrypto/CommonDigest.h> + +#include "curl_memory.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +typedef CC_SHA256_CTX SHA256_CTX; + +static void SHA256_Init(SHA256_CTX *ctx) +{ + (void) CC_SHA256_Init(ctx); +} + +static void SHA256_Update(SHA256_CTX *ctx, + const unsigned char *data, + unsigned int length) +{ + (void) CC_SHA256_Update(ctx, data, length); +} + +static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) +{ + (void) CC_SHA256_Final(digest, ctx); +} + +#elif defined(USE_WIN32_CRYPTO) + +#include <wincrypt.h> + +typedef struct { + HCRYPTPROV hCryptProv; + HCRYPTHASH hHash; +} SHA256_CTX; + +#if !defined(CALG_SHA_256) +#define CALG_SHA_256 0x0000800c +#endif + +static void SHA256_Init(SHA256_CTX *ctx) +{ + if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, + PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { + CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash); + } +} + +static void SHA256_Update(SHA256_CTX *ctx, + const unsigned char *data, + unsigned int length) +{ + CryptHashData(ctx->hHash, (unsigned char *) data, length, 0); +} + +static void SHA256_Final(unsigned char *digest, SHA256_CTX *ctx) +{ + unsigned long length; + + CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); + if(length == SHA256_DIGEST_LENGTH) + CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); + + if(ctx->hHash) + CryptDestroyHash(ctx->hHash); + + if(ctx->hCryptProv) + CryptReleaseContext(ctx->hCryptProv, 0); +} + #else /* When no other crypto library is available we use this code segment */ diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c index 0fb97e1e5d..37099130e5 100644 --- a/libs/libcurl/src/socks.c +++ b/libs/libcurl/src/socks.c @@ -205,6 +205,8 @@ CURLcode Curl_SOCKS4(const char *proxy_user, switch(sx->state) { case CONNECT_SOCKS_INIT: + /* SOCKS4 can only do IPv4, insist! */ + conn->ip_version = CURL_IPRESOLVE_V4; if(conn->bits.httpproxy) infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n", protocol4a ? "a" : "", hostname, remote_port); @@ -261,8 +263,8 @@ CURLcode Curl_SOCKS4(const char *proxy_user, } else { result = Curl_resolv_check(data->conn, &dns); - /* stay in the state or error out */ - return result; + if(!dns) + return result; } /* FALLTHROUGH */ CONNECT_RESOLVED: @@ -763,8 +765,8 @@ CURLcode Curl_SOCKS5(const char *proxy_user, if(!dns) { result = Curl_resolv_check(data->conn, &dns); - /* stay in the state or error out */ - return result; + if(!dns) + return result; } /* FALLTHROUGH */ CONNECT_RESOLVED: diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index 827076183f..e76834eb34 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -890,7 +890,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, } /* if(!header and data to read) */ - if(conn->handler->readwrite && excess && !conn->bits.stream_was_rewound) { + if(conn->handler->readwrite && excess) { /* Parse the excess data */ k->str += nread; @@ -1217,8 +1217,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, else fd_write = CURL_SOCKET_BAD; - if(data->state.drain) { - data->state.drain--; + if(conn->data->state.drain) { select_res |= CURL_CSELECT_IN; DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n")); } @@ -1235,9 +1234,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, /* We go ahead and do a read if we have a readable socket or if the stream was rewound (in which case we have data in a buffer) */ - if((k->keepon & KEEP_RECV) && - ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) { - + if((k->keepon & KEEP_RECV) && (select_res & CURL_CSELECT_IN)) { result = readwrite_data(data, conn, k, &didwhat, done, comeback); if(result || *done) return result; diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index e1348cf29b..fbb8b645ec 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -464,8 +464,6 @@ struct ConnectBits { #endif BIT(netrc); /* name+password provided by netrc */ BIT(userpwd_in_url); /* name+password found in url */ - BIT(stream_was_rewound); /* The stream was rewound after a request read - past the end of its response byte boundary */ BIT(proxy_connect_closed); /* TRUE if a proxy disconnected the connection in a CONNECT request with auth, so that libcurl should reconnect and continue. */ @@ -1579,6 +1577,11 @@ enum dupstring { STRING_TEMP_URL, /* temp URL storage for proxy use */ + STRING_DNS_SERVERS, + STRING_DNS_INTERFACE, + STRING_DNS_LOCAL_IP4, + STRING_DNS_LOCAL_IP6, + /* -- end of zero-terminated strings -- */ STRING_LASTZEROTERMINATED, @@ -1587,6 +1590,7 @@ enum dupstring { STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */ + STRING_LAST /* not used, just an end-of-list marker */ }; diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c index 77aca7cbe8..8170106eea 100644 --- a/libs/libcurl/src/version.c +++ b/libs/libcurl/src/version.c @@ -66,16 +66,6 @@ #include <brotli/decode.h> #endif -void Curl_version_init(void); - -/* For thread safety purposes this function is called by global_init so that - the static data in both version functions is initialized. */ -void Curl_version_init(void) -{ - curl_version(); - curl_version_info(CURLVERSION_NOW); -} - #ifdef HAVE_BROTLI static size_t brotli_version(char *buf, size_t bufsz) { @@ -88,95 +78,108 @@ static size_t brotli_version(char *buf, size_t bufsz) } #endif +/* + * curl_version() returns a pointer to a static buffer. + * + * It is implemented to work multi-threaded by making sure repeated invokes + * generate the exact same string and never write any temporary data like + * zeros in the data. + */ char *curl_version(void) { - static bool initialized; - static char version[250]; - char *ptr = version; - size_t len; - size_t left = sizeof(version); - - if(initialized) - return version; - - strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION); - len = strlen(ptr); - left -= len; - ptr += len; - - len = Curl_ssl_version(ptr + 1, left - 1); - - if(len > 0) { - *ptr = ' '; - left -= ++len; - ptr += len; - } + static char out[250]; + char *outp; + size_t outlen; + const char *src[14]; +#ifdef USE_SSL + char ssl_version[40]; +#endif +#ifdef HAVE_LIBZ + char z_version[40]; +#endif +#ifdef HAVE_BROTLI + char br_version[40] = "brotli/"; +#endif +#ifdef USE_ARES + char cares_version[40]; +#endif +#if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) + char idn_version[40]; +#endif +#ifdef USE_LIBPSL + char psl_version[40]; +#endif +#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) + char iconv_version[40]="iconv"; +#endif +#ifdef USE_SSH + char ssh_version[40]; +#endif +#ifdef USE_NGHTTP2 + char h2_version[40]; +#endif +#ifdef ENABLE_QUIC + char h3_version[40]; +#endif +#ifdef USE_LIBRTMP + char rtmp_version[40]; +#endif + int i = 0; + int j; + src[i++] = LIBCURL_NAME "/" LIBCURL_VERSION; +#ifdef USE_SSL + Curl_ssl_version(ssl_version, sizeof(ssl_version)); + src[i++] = ssl_version; +#endif #ifdef HAVE_LIBZ - len = msnprintf(ptr, left, " zlib/%s", zlibVersion()); - left -= len; - ptr += len; + msnprintf(z_version, sizeof(z_version), "zlib/%s", zlibVersion()); + src[i++] = z_version; #endif #ifdef HAVE_BROTLI - len = msnprintf(ptr, left, "%s", " brotli/"); - left -= len; - ptr += len; - len = brotli_version(ptr, left); - left -= len; - ptr += len; + brotli_version(&br_version[7], sizeof(br_version) - 7); + src[i++] = br_version; #endif #ifdef USE_ARES - /* this function is only present in c-ares, not in the original ares */ - len = msnprintf(ptr, left, " c-ares/%s", ares_version(NULL)); - left -= len; - ptr += len; + msnprintf(cares_version, sizeof(cares_version), + "c-ares/%s", ares_version(NULL)); + src[i++] = cares_version; #endif #ifdef USE_LIBIDN2 if(idn2_check_version(IDN2_VERSION)) { - len = msnprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL)); - left -= len; - ptr += len; + msnprintf(idn_version, sizeof(idn_version), + "libidn2/%s", idn2_check_version(NULL)); + src[i++] = idn_version; } +#elif defined(USE_WIN32_IDN) + msnprintf(idn_version, sizeof(idn_version), "WinIDN"); + src[i++] = idn_version; #endif + #ifdef USE_LIBPSL - len = msnprintf(ptr, left, " libpsl/%s", psl_get_version()); - left -= len; - ptr += len; -#endif -#ifdef USE_WIN32_IDN - len = msnprintf(ptr, left, " WinIDN"); - left -= len; - ptr += len; + msnprintf(psl_version, sizeof(psl_version), "libpsl/%s", psl_get_version()); + src[i++] = psl_version; #endif #if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) #ifdef _LIBICONV_VERSION - len = msnprintf(ptr, left, " iconv/%d.%d", - _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255); + msnprintf(iconv_version, sizeof(iconv_version), "iconv/%d.%d", + _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255); #else - /* version unknown */ - len = msnprintf(ptr, left, " iconv"); + /* version unknown, let the default stand */ #endif /* _LIBICONV_VERSION */ - left -= len; - ptr += len; + src[i++] = iconv_version; #endif #ifdef USE_SSH - if(left) { - *ptr++=' '; - left--; - } - len = Curl_ssh_version(ptr, left); - left -= len; - ptr += len; + Curl_ssh_version(ssh_version, sizeof(ssh_version)); + src[i++] = ssh_version; #endif #ifdef USE_NGHTTP2 - len = Curl_http2_ver(ptr, left); - left -= len; - ptr += len; + Curl_http2_ver(h2_version, sizeof(h2_version)); + src[i++] = h2_version; #endif #ifdef ENABLE_QUIC - len = Curl_quic_ver(ptr, left); - left -= len; - ptr += len; + Curl_quic_ver(h3_version, sizeof(h3_version)); + src[i++] = h3_version; #endif #ifdef USE_LIBRTMP { @@ -188,27 +191,32 @@ char *curl_version(void) else suff[0] = '\0'; - msnprintf(ptr, left, " librtmp/%d.%d%s", + msnprintf(rtmp_version, sizeof(rtmp_version), "librtmp/%d.%d%s", RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff, suff); -/* - If another lib version is added below this one, this code would - also have to do: - - len = what msnprintf() returned - - left -= len; - ptr += len; -*/ + src[i++] = rtmp_version; } #endif - /* Silent scan-build even if librtmp is not enabled. */ - (void) left; - (void) ptr; + outp = &out[0]; + outlen = sizeof(out); + for(j = 0; j < i; j++) { + size_t n = strlen(src[j]); + /* we need room for a space, the string and the final zero */ + if(outlen <= (n + 2)) + break; + if(j) { + /* prepend a space if not the first */ + *outp++ = ' '; + outlen--; + } + memcpy(outp, src[j], n); + outp += n; + outlen -= n; + } + *outp = 0; - initialized = true; - return version; + return out; } /* data for curl_version_info @@ -391,7 +399,6 @@ static curl_version_info_data version_info = { curl_version_info_data *curl_version_info(CURLversion stamp) { - static bool initialized; #if defined(USE_SSH) static char ssh_buffer[80]; #endif @@ -406,9 +413,6 @@ curl_version_info_data *curl_version_info(CURLversion stamp) static char brotli_buffer[80]; #endif - if(initialized) - return &version_info; - #ifdef USE_SSL Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer)); version_info.ssl_version = ssl_buffer; @@ -476,7 +480,5 @@ curl_version_info_data *curl_version_info(CURLversion stamp) #endif (void)stamp; /* avoid compiler warnings, we don't use this */ - - initialized = true; return &version_info; } diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c index 0788404c02..2f6ee8bdf9 100644 --- a/libs/libcurl/src/vquic/ngtcp2.c +++ b/libs/libcurl/src/vquic/ngtcp2.c @@ -641,7 +641,7 @@ int Curl_quic_ver(char *p, size_t len) { ngtcp2_info *ng2 = ngtcp2_version(0); nghttp3_info *ht3 = nghttp3_version(0); - return msnprintf(p, len, " ngtcp2/%s nghttp3/%s", + return msnprintf(p, len, "ngtcp2/%s nghttp3/%s", ng2->version_str, ht3->version_str); } diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c index d09ba7038a..c40e5e937c 100644 --- a/libs/libcurl/src/vquic/quiche.c +++ b/libs/libcurl/src/vquic/quiche.c @@ -532,7 +532,7 @@ static ssize_t h3_stream_send(struct connectdata *conn, */ int Curl_quic_ver(char *p, size_t len) { - return msnprintf(p, len, " quiche/%s", quiche_version()); + return msnprintf(p, len, "quiche/%s", quiche_version()); } /* Index where :authority header field will appear in request header diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c index 647b4d4913..08d9f9e0fb 100644 --- a/libs/libcurl/src/vssh/libssh.c +++ b/libs/libcurl/src/vssh/libssh.c @@ -345,13 +345,27 @@ static int myssh_is_known(struct connectdata *conn) return rc; if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) { + int i; + char md5buffer[33]; + const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; + rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, &hash, &hlen); - if(rc != SSH_OK) + if(rc != SSH_OK || hlen != 16) { + failf(data, + "Denied establishing ssh session: md5 fingerprint not available"); goto cleanup; + } + + for(i = 0; i < 16; i++) + msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char)hash[i]); + + infof(data, "SSH MD5 fingerprint: %s\n", md5buffer); - if(hlen != strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) || - memcmp(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], hash, hlen)) { + if(!strcasecompare(md5buffer, pubkey_md5)) { + failf(data, + "Denied establishing ssh session: mismatch md5 fingerprint. " + "Remote %s is not equal to %s", md5buffer, pubkey_md5); rc = SSH_ERROR; goto cleanup; } diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c index 8e043747e7..c487ccabb5 100644 --- a/libs/libcurl/src/vssh/libssh2.c +++ b/libs/libcurl/src/vssh/libssh2.c @@ -694,31 +694,40 @@ static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn) while(!libssh2_knownhost_get(sshc->kh, &store, store)) { /* For non-standard ports, the name will be enclosed in */ /* square brackets, followed by a colon and the port */ - if(store->name[0] == '[') { - kh_name_end = strstr(store->name, "]:"); - if(!kh_name_end) { - infof(data, "Invalid host pattern %s in %s\n", - store->name, data->set.str[STRING_SSH_KNOWNHOSTS]); - continue; - } - port = atoi(kh_name_end + 2); - if(kh_name_end && (port == conn->remote_port)) { - kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end); - if(strncmp(store->name + 1, conn->host.name, kh_name_size) == 0) { + if(store) { + if(store->name) { + if(store->name[0] == '[') { + kh_name_end = strstr(store->name, "]:"); + if(!kh_name_end) { + infof(data, "Invalid host pattern %s in %s\n", + store->name, data->set.str[STRING_SSH_KNOWNHOSTS]); + continue; + } + port = atoi(kh_name_end + 2); + if(kh_name_end && (port == conn->remote_port)) { + kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end); + if(strncmp(store->name + 1, + conn->host.name, kh_name_size) == 0) { + found = true; + break; + } + } + } + else if(strcmp(store->name, conn->host.name) == 0) { found = true; break; } } - } - else if(strcmp(store->name, conn->host.name) == 0) { - found = true; - break; + else { + found = true; + break; + } } } if(found) { infof(data, "Found host %s in %s\n", - store->name, data->set.str[STRING_SSH_KNOWNHOSTS]); + conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]); switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) { #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519 diff --git a/libs/libcurl/src/vtls/polarssl.c b/libs/libcurl/src/vtls/polarssl.c deleted file mode 100644 index 9e7dd90437..0000000000 --- a/libs/libcurl/src/vtls/polarssl.c +++ /dev/null @@ -1,931 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 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 - * 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. - * - ***************************************************************************/ - -/* - * Source file for all PolarSSL-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - */ - -#include "curl_setup.h" - -#ifdef USE_POLARSSL -#include <polarssl/net.h> -#include <polarssl/ssl.h> -#include <polarssl/certs.h> -#include <polarssl/x509.h> -#include <polarssl/version.h> -#include <polarssl/sha256.h> - -#if POLARSSL_VERSION_NUMBER < 0x01030000 -#error too old PolarSSL -#endif - -#include <polarssl/error.h> -#include <polarssl/entropy.h> -#include <polarssl/ctr_drbg.h> - -#include "urldata.h" -#include "sendf.h" -#include "inet_pton.h" -#include "polarssl.h" -#include "vtls.h" -#include "parsedate.h" -#include "connect.h" /* for the connect timeout */ -#include "select.h" -#include "strcase.h" -#include "polarssl_threadlock.h" -#include "multiif.h" -#include "curl_printf.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* See https://tls.mbed.org/discussions/generic/ - howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der -*/ -#define RSA_PUB_DER_MAX_BYTES (38 + 2 * POLARSSL_MPI_MAX_SIZE) -#define ECP_PUB_DER_MAX_BYTES (30 + 2 * POLARSSL_ECP_MAX_BYTES) - -#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ - RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) - -struct ssl_backend_data { - ctr_drbg_context ctr_drbg; - entropy_context entropy; - ssl_context ssl; - int server_fd; - x509_crt cacert; - x509_crt clicert; - x509_crl crl; - rsa_context rsa; -}; - -#define BACKEND connssl->backend - -/* apply threading? */ -#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) -#define THREADING_SUPPORT -#endif - -#ifndef POLARSSL_ERROR_C -#define error_strerror(x,y,z) -#endif /* POLARSSL_ERROR_C */ - - -#if defined(THREADING_SUPPORT) -static entropy_context entropy; - -static int entropy_init_initialized = 0; - -/* start of entropy_init_mutex() */ -static void entropy_init_mutex(entropy_context *ctx) -{ - /* lock 0 = entropy_init_mutex() */ - Curl_polarsslthreadlock_lock_function(0); - if(entropy_init_initialized == 0) { - entropy_init(ctx); - entropy_init_initialized = 1; - } - Curl_polarsslthreadlock_unlock_function(0); -} -/* end of entropy_init_mutex() */ - -/* start of entropy_func_mutex() */ -static int entropy_func_mutex(void *data, unsigned char *output, size_t len) -{ - int ret; - /* lock 1 = entropy_func_mutex() */ - Curl_polarsslthreadlock_lock_function(1); - ret = entropy_func(data, output, len); - Curl_polarsslthreadlock_unlock_function(1); - - return ret; -} -/* end of entropy_func_mutex() */ - -#endif /* THREADING_SUPPORT */ - -/* Define this to enable lots of debugging for PolarSSL */ -#undef POLARSSL_DEBUG - -#ifdef POLARSSL_DEBUG -static void polarssl_debug(void *context, int level, const char *line) -{ - struct Curl_easy *data = NULL; - - if(!context) - return; - - data = (struct Curl_easy *)context; - - infof(data, "%s", line); - (void) level; -} -#else -#endif - -/* ALPN for http2? */ -#ifdef POLARSSL_SSL_ALPN -# define HAS_ALPN -#endif - -static Curl_recv polarssl_recv; -static Curl_send polarssl_send; - -static CURLcode polarssl_version_from_curl(int *polarver, long ssl_version) -{ - switch(ssl_version) { - case CURL_SSLVERSION_TLSv1_0: - *polarver = SSL_MINOR_VERSION_1; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1: - *polarver = SSL_MINOR_VERSION_2; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_2: - *polarver = SSL_MINOR_VERSION_3; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3: - break; - } - return CURLE_SSL_CONNECT_ERROR; -} - -static CURLcode -set_ssl_version_min_max(struct connectdata *conn, int sockindex) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data* connssl = &conn->ssl[sockindex]; - long ssl_version = SSL_CONN_CONFIG(version); - long ssl_version_max = SSL_CONN_CONFIG(version_max); - int ssl_min_ver = SSL_MINOR_VERSION_1; - int ssl_max_ver = SSL_MINOR_VERSION_1; - CURLcode result = CURLE_OK; - - switch(ssl_version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - ssl_version = CURL_SSLVERSION_TLSv1_0; - break; - } - - switch(ssl_version_max) { - case CURL_SSLVERSION_MAX_NONE: - case CURL_SSLVERSION_MAX_DEFAULT: - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; - break; - } - - result = polarssl_version_from_curl(&ssl_min_ver, ssl_version); - if(result) { - failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); - return result; - } - result = polarssl_version_from_curl(&ssl_max_ver, ssl_version_max >> 16); - if(result) { - failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); - return result; - } - - ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver); - ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver); - - return result; -} - -static CURLcode -polarssl_connect_step1(struct connectdata *conn, - int sockindex) -{ - struct Curl_easy *data = conn->data; - struct ssl_connect_data* connssl = &conn->ssl[sockindex]; - const char *capath = SSL_CONN_CONFIG(CApath); - 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; - int ret = -1; - char errorbuf[128]; - errorbuf[0] = 0; - - /* PolarSSL only supports SSLv3 and TLSv1 */ - if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) { - failf(data, "PolarSSL does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef THREADING_SUPPORT - entropy_init_mutex(&entropy); - - if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy, - NULL, 0)) != 0) { - error_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", - -ret, errorbuf); - } -#else - entropy_init(&BACKEND->entropy); - - if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy, - NULL, 0)) != 0) { - error_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", - -ret, errorbuf); - } -#endif /* THREADING_SUPPORT */ - - /* Load the trusted CA */ - memset(&BACKEND->cacert, 0, sizeof(x509_crt)); - - if(SSL_CONN_CONFIG(CAfile)) { - ret = x509_crt_parse_file(&BACKEND->cacert, - SSL_CONN_CONFIG(CAfile)); - - if(ret<0) { - error_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s", - SSL_CONN_CONFIG(CAfile), -ret, errorbuf); - - if(SSL_CONN_CONFIG(verifypeer)) - return CURLE_SSL_CACERT_BADFILE; - } - } - - if(capath) { - ret = x509_crt_parse_path(&BACKEND->cacert, capath); - - if(ret<0) { - error_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s", - capath, -ret, errorbuf); - - if(SSL_CONN_CONFIG(verifypeer)) - return CURLE_SSL_CACERT_BADFILE; - } - } - - /* Load the client certificate */ - memset(&BACKEND->clicert, 0, sizeof(x509_crt)); - - if(SSL_SET_OPTION(cert)) { - ret = x509_crt_parse_file(&BACKEND->clicert, - SSL_SET_OPTION(cert)); - - if(ret) { - error_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s", - SSL_SET_OPTION(cert), -ret, errorbuf); - - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Load the client private key */ - if(SSL_SET_OPTION(key)) { - pk_context pk; - pk_init(&pk); - ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key), - SSL_SET_OPTION(key_passwd)); - if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA)) - ret = POLARSSL_ERR_PK_TYPE_MISMATCH; - if(ret == 0) - rsa_copy(&BACKEND->rsa, pk_rsa(pk)); - else - rsa_free(&BACKEND->rsa); - pk_free(&pk); - - if(ret) { - error_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s", - SSL_SET_OPTION(key), -ret, errorbuf); - - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Load the CRL */ - memset(&BACKEND->crl, 0, sizeof(x509_crl)); - - if(SSL_SET_OPTION(CRLfile)) { - ret = x509_crl_parse_file(&BACKEND->crl, - SSL_SET_OPTION(CRLfile)); - - if(ret) { - error_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s", - SSL_SET_OPTION(CRLfile), -ret, errorbuf); - - return CURLE_SSL_CRL_BADFILE; - } - } - - infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port); - - if(ssl_init(&BACKEND->ssl)) { - failf(data, "PolarSSL: ssl_init failed"); - return CURLE_SSL_CONNECT_ERROR; - } - - switch(SSL_CONN_CONFIG(version)) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_1); - break; - case CURL_SSLVERSION_SSLv3: - ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_0); - ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_0); - infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n"); - break; - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - { - CURLcode result = set_ssl_version_min_max(conn, sockindex); - if(result != CURLE_OK) - return result; - break; - } - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - - ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT); - ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL); - - ssl_set_rng(&BACKEND->ssl, ctr_drbg_random, - &BACKEND->ctr_drbg); - ssl_set_bio(&BACKEND->ssl, - net_recv, &conn->sock[sockindex], - net_send, &conn->sock[sockindex]); - - ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites()); - - /* Check if there's a cached ID we can/should use here! */ - if(SSL_SET_OPTION(primary.sessionid)) { - void *old_session = NULL; - - Curl_ssl_sessionid_lock(conn); - if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) { - ret = ssl_set_session(&BACKEND->ssl, old_session); - if(ret) { - Curl_ssl_sessionid_unlock(conn); - failf(data, "ssl_set_session returned -0x%x", -ret); - return CURLE_SSL_CONNECT_ERROR; - } - infof(data, "PolarSSL re-using session\n"); - } - Curl_ssl_sessionid_unlock(conn); - } - - ssl_set_ca_chain(&BACKEND->ssl, - &BACKEND->cacert, - &BACKEND->crl, - hostname); - - ssl_set_own_cert_rsa(&BACKEND->ssl, - &BACKEND->clicert, &BACKEND->rsa); - - if(ssl_set_hostname(&BACKEND->ssl, hostname)) { - /* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name - to set in the SNI extension. So even if curl connects to a host - specified as an IP address, this function must be used. */ - failf(data, "couldn't set hostname in PolarSSL"); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - static const char *protocols[3]; - int cur = 0; - -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { - protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); - } -#endif - - protocols[cur++] = ALPN_HTTP_1_1; - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - - protocols[cur] = NULL; - - ssl_set_alpn_protocols(&BACKEND->ssl, protocols); - } -#endif - -#ifdef POLARSSL_DEBUG - ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data); -#endif - - connssl->connecting_state = ssl_connect_2; - - return CURLE_OK; -} - -static CURLcode -polarssl_connect_step2(struct connectdata *conn, - int sockindex) -{ - int ret; - struct Curl_easy *data = conn->data; - struct ssl_connect_data* connssl = &conn->ssl[sockindex]; - char buffer[1024]; - const char * const pinnedpubkey = SSL_IS_PROXY() ? - data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] : - data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; - - - char errorbuf[128]; - errorbuf[0] = 0; - - conn->recv[sockindex] = polarssl_recv; - conn->send[sockindex] = polarssl_send; - - ret = ssl_handshake(&BACKEND->ssl); - - switch(ret) { - case 0: - break; - - case POLARSSL_ERR_NET_WANT_READ: - connssl->connecting_state = ssl_connect_2_reading; - return CURLE_OK; - - case POLARSSL_ERR_NET_WANT_WRITE: - connssl->connecting_state = ssl_connect_2_writing; - return CURLE_OK; - - default: - error_strerror(ret, errorbuf, sizeof(errorbuf)); - failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s", - -ret, errorbuf); - return CURLE_SSL_CONNECT_ERROR; - } - - infof(data, "PolarSSL: Handshake complete, cipher is %s\n", - ssl_get_ciphersuite(&BACKEND->ssl) ); - - ret = ssl_get_verify_result(&BACKEND->ssl); - - if(ret && SSL_CONN_CONFIG(verifypeer)) { - if(ret & BADCERT_EXPIRED) - failf(data, "Cert verify failed: BADCERT_EXPIRED"); - - if(ret & BADCERT_REVOKED) { - failf(data, "Cert verify failed: BADCERT_REVOKED"); - return CURLE_PEER_FAILED_VERIFICATION; - } - - if(ret & BADCERT_CN_MISMATCH) - failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); - - if(ret & BADCERT_NOT_TRUSTED) - failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); - - return CURLE_PEER_FAILED_VERIFICATION; - } - - if(ssl_get_peer_cert(&(BACKEND->ssl))) { - /* If the session was resumed, there will be no peer certs */ - memset(buffer, 0, sizeof(buffer)); - - if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ", - ssl_get_peer_cert(&(BACKEND->ssl))) != -1) - infof(data, "Dumping cert info:\n%s\n", buffer); - } - - /* adapted from mbedtls.c */ - if(pinnedpubkey) { - int size; - CURLcode result; - x509_crt *p; - unsigned char pubkey[PUB_DER_MAX_BYTES]; - const x509_crt *peercert; - - peercert = ssl_get_peer_cert(&BACKEND->ssl); - - if(!peercert || !peercert->raw.p || !peercert->raw.len) { - failf(data, "Failed due to missing peer certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - p = calloc(1, sizeof(*p)); - - if(!p) - return CURLE_OUT_OF_MEMORY; - - x509_crt_init(p); - - /* Make a copy of our const peercert because pk_write_pubkey_der - needs a non-const key, for now. - https://github.com/ARMmbed/mbedtls/issues/396 */ - if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { - failf(data, "Failed copying peer certificate"); - x509_crt_free(p); - free(p); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); - - if(size <= 0) { - failf(data, "Failed copying public key from peer certificate"); - x509_crt_free(p); - free(p); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - /* pk_write_pubkey_der writes data at the end of the buffer. */ - result = Curl_pin_peer_pubkey(data, - pinnedpubkey, - &pubkey[PUB_DER_MAX_BYTES - size], size); - if(result) { - x509_crt_free(p); - free(p); - return result; - } - - x509_crt_free(p); - free(p); - } - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - const char *next_protocol = ssl_get_alpn_protocol(&BACKEND->ssl); - - if(next_protocol != NULL) { - infof(data, "ALPN, server accepted to use %s\n", next_protocol); - -#ifdef USE_NGHTTP2 - if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN)) { - conn->negnpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; - } - } - else - infof(data, "ALPN, server did not agree to a protocol\n"); - Curl_multiuse_state(conn, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); - } -#endif - - connssl->connecting_state = ssl_connect_3; - infof(data, "SSL connected\n"); - - return CURLE_OK; -} - -static CURLcode -polarssl_connect_step3(struct connectdata *conn, - int sockindex) -{ - CURLcode retcode = CURLE_OK; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct Curl_easy *data = conn->data; - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - - if(SSL_SET_OPTION(primary.sessionid)) { - int ret; - ssl_session *our_ssl_sessionid; - void *old_ssl_sessionid = NULL; - - our_ssl_sessionid = calloc(1, sizeof(ssl_session)); - if(!our_ssl_sessionid) - return CURLE_OUT_OF_MEMORY; - - ret = ssl_get_session(&BACKEND->ssl, our_ssl_sessionid); - if(ret) { - failf(data, "ssl_get_session returned -0x%x", -ret); - return CURLE_SSL_CONNECT_ERROR; - } - - /* If there's already a matching session in the cache, delete it */ - Curl_ssl_sessionid_lock(conn); - if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex)) - Curl_ssl_delsessionid(conn, old_ssl_sessionid); - - retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex); - Curl_ssl_sessionid_unlock(conn); - if(retcode) { - free(our_ssl_sessionid); - failf(data, "failed to store ssl session"); - return retcode; - } - } - - connssl->connecting_state = ssl_connect_done; - - return CURLE_OK; -} - -static ssize_t polarssl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - int ret = -1; - - ret = ssl_write(&BACKEND->ssl, - (unsigned char *)mem, len); - - if(ret < 0) { - *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ? - CURLE_AGAIN : CURLE_SEND_ERROR; - ret = -1; - } - - return ret; -} - -static void Curl_polarssl_close(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - rsa_free(&BACKEND->rsa); - x509_crt_free(&BACKEND->clicert); - x509_crt_free(&BACKEND->cacert); - x509_crl_free(&BACKEND->crl); - ssl_free(&BACKEND->ssl); -} - -static ssize_t polarssl_recv(struct connectdata *conn, - int num, - char *buf, - size_t buffersize, - CURLcode *curlcode) -{ - struct ssl_connect_data *connssl = &conn->ssl[num]; - int ret = -1; - ssize_t len = -1; - - memset(buf, 0, buffersize); - ret = ssl_read(&BACKEND->ssl, (unsigned char *)buf, buffersize); - - if(ret <= 0) { - if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) - return 0; - - *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ? - CURLE_AGAIN : CURLE_RECV_ERROR; - return -1; - } - - len = ret; - - return len; -} - -static void Curl_polarssl_session_free(void *ptr) -{ - ssl_session_free(ptr); - free(ptr); -} - -/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and - higher) will be mbed TLS branded.. */ - -static size_t Curl_polarssl_version(char *buffer, size_t size) -{ - unsigned int version = version_get_number(); - return msnprintf(buffer, size, "%s/%d.%d.%d", - version >= 0x01030A00?"mbedTLS":"PolarSSL", - version>>24, (version>>16)&0xff, (version>>8)&0xff); -} - -static CURLcode -polarssl_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - CURLcode result; - struct Curl_easy *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - timediff_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) { - /* Find out how much more time we're allowed */ - 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; - } - - result = polarssl_connect_step1(conn, sockindex); - if(result) - return result; - } - - 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(connssl->connecting_state == ssl_connect_2_reading || - connssl->connecting_state == ssl_connect_2_writing) { - - 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:(time_t)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 part of a multi handle 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. - */ - result = polarssl_connect_step2(conn, sockindex); - if(result || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return result; - - } /* repeat step2 until all transactions are done. */ - - if(ssl_connect_3 == connssl->connecting_state) { - result = polarssl_connect_step3(conn, sockindex); - if(result) - return result; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = polarssl_recv; - conn->send[sockindex] = polarssl_send; - *done = TRUE; - } - else - *done = FALSE; - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - -static CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn, - int sockindex, bool *done) -{ - return polarssl_connect_common(conn, sockindex, TRUE, done); -} - - -static CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex) -{ - CURLcode result; - bool done = FALSE; - - result = polarssl_connect_common(conn, sockindex, FALSE, &done); - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -/* - * return 0 error initializing SSL - * return 1 SSL initialized successfully - */ -static int Curl_polarssl_init(void) -{ - return Curl_polarsslthreadlock_thread_setup(); -} - -static void Curl_polarssl_cleanup(void) -{ - (void)Curl_polarsslthreadlock_thread_cleanup(); -} - -static bool Curl_polarssl_data_pending(const struct connectdata *conn, - int sockindex) -{ - const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - return ssl_get_bytes_avail(&BACKEND->ssl) != 0; -} - -static CURLcode Curl_polarssl_sha256sum(const unsigned char *input, - size_t inputlen, - unsigned char *sha256sum, - size_t sha256len UNUSED_PARAM) -{ - (void)sha256len; - sha256(input, inputlen, sha256sum, 0); - return CURLE_OK; -} - -static void *Curl_polarssl_get_internals(struct ssl_connect_data *connssl, - CURLINFO info UNUSED_PARAM) -{ - (void)info; - return &BACKEND->ssl; -} - -const struct Curl_ssl Curl_ssl_polarssl = { - { CURLSSLBACKEND_POLARSSL, "polarssl" }, /* info */ - - SSLSUPP_CA_PATH | - SSLSUPP_PINNEDPUBKEY, - - sizeof(struct ssl_backend_data), - - Curl_polarssl_init, /* init */ - Curl_polarssl_cleanup, /* cleanup */ - Curl_polarssl_version, /* version */ - Curl_none_check_cxn, /* check_cxn */ - Curl_none_shutdown, /* shutdown */ - Curl_polarssl_data_pending, /* data_pending */ - /* This might cause libcurl to use a weeker random! */ - Curl_none_random, /* random */ - Curl_none_cert_status_request, /* cert_status_request */ - Curl_polarssl_connect, /* connect */ - Curl_polarssl_connect_nonblocking, /* connect_nonblocking */ - Curl_polarssl_get_internals, /* get_internals */ - Curl_polarssl_close, /* close_one */ - Curl_none_close_all, /* close_all */ - Curl_polarssl_session_free, /* session_free */ - Curl_none_set_engine, /* set_engine */ - Curl_none_set_engine_default, /* set_engine_default */ - Curl_none_engines_list, /* engines_list */ - Curl_none_false_start, /* false_start */ - Curl_none_md5sum, /* md5sum */ - Curl_polarssl_sha256sum /* sha256sum */ -}; - -#endif /* USE_POLARSSL */ diff --git a/libs/libcurl/src/vtls/polarssl.h b/libs/libcurl/src/vtls/polarssl.h deleted file mode 100644 index f36f24f8df..0000000000 --- a/libs/libcurl/src/vtls/polarssl.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef HEADER_CURL_POLARSSL_H -#define HEADER_CURL_POLARSSL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * 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 - * 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_POLARSSL - -extern const struct Curl_ssl Curl_ssl_polarssl; - -#endif /* USE_POLARSSL */ -#endif /* HEADER_CURL_POLARSSL_H */ diff --git a/libs/libcurl/src/vtls/polarssl_threadlock.c b/libs/libcurl/src/vtls/polarssl_threadlock.c deleted file mode 100644 index 4e269c8e6a..0000000000 --- a/libs/libcurl/src/vtls/polarssl_threadlock.c +++ /dev/null @@ -1,144 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * 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 - * 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" - -#if (defined(USE_POLARSSL) || defined(USE_MBEDTLS)) && \ - ((defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \ - (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H))) - -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) -# include <pthread.h> -# define POLARSSL_MUTEX_T pthread_mutex_t -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) -# include <process.h> -# define POLARSSL_MUTEX_T HANDLE -#endif - -#include "polarssl_threadlock.h" -#include "curl_printf.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* number of thread locks */ -#define NUMT 2 - -/* This array will store all of the mutexes available to PolarSSL. */ -static POLARSSL_MUTEX_T *mutex_buf = NULL; - -int Curl_polarsslthreadlock_thread_setup(void) -{ - int i; - - mutex_buf = calloc(NUMT * sizeof(POLARSSL_MUTEX_T), 1); - if(!mutex_buf) - return 0; /* error, no number of threads defined */ - - for(i = 0; i < NUMT; i++) { - int ret; -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) - ret = pthread_mutex_init(&mutex_buf[i], NULL); - if(ret) - return 0; /* pthread_mutex_init failed */ -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) - mutex_buf[i] = CreateMutex(0, FALSE, 0); - if(mutex_buf[i] == 0) - return 0; /* CreateMutex failed */ -#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ - } - - return 1; /* OK */ -} - -int Curl_polarsslthreadlock_thread_cleanup(void) -{ - int i; - - if(!mutex_buf) - return 0; /* error, no threads locks defined */ - - for(i = 0; i < NUMT; i++) { - int ret; -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) - ret = pthread_mutex_destroy(&mutex_buf[i]); - if(ret) - return 0; /* pthread_mutex_destroy failed */ -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) - ret = CloseHandle(mutex_buf[i]); - if(!ret) - return 0; /* CloseHandle failed */ -#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ - } - free(mutex_buf); - mutex_buf = NULL; - - return 1; /* OK */ -} - -int Curl_polarsslthreadlock_lock_function(int n) -{ - if(n < NUMT) { - int ret; -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) - ret = pthread_mutex_lock(&mutex_buf[n]); - if(ret) { - DEBUGF(fprintf(stderr, - "Error: polarsslthreadlock_lock_function failed\n")); - return 0; /* pthread_mutex_lock failed */ - } -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) - ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0); - if(ret) { - DEBUGF(fprintf(stderr, - "Error: polarsslthreadlock_lock_function failed\n")); - return 0; /* pthread_mutex_lock failed */ - } -#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ - } - return 1; /* OK */ -} - -int Curl_polarsslthreadlock_unlock_function(int n) -{ - if(n < NUMT) { - int ret; -#if defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H) - ret = pthread_mutex_unlock(&mutex_buf[n]); - if(ret) { - DEBUGF(fprintf(stderr, - "Error: polarsslthreadlock_unlock_function failed\n")); - return 0; /* pthread_mutex_unlock failed */ - } -#elif defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H) - ret = ReleaseMutex(mutex_buf[n]); - if(!ret) { - DEBUGF(fprintf(stderr, - "Error: polarsslthreadlock_unlock_function failed\n")); - return 0; /* pthread_mutex_lock failed */ - } -#endif /* USE_THREADS_POSIX && HAVE_PTHREAD_H */ - } - return 1; /* OK */ -} - -#endif /* USE_POLARSSL || USE_MBEDTLS */ diff --git a/libs/libcurl/src/vtls/polarssl_threadlock.h b/libs/libcurl/src/vtls/polarssl_threadlock.h deleted file mode 100644 index c1900bfe81..0000000000 --- a/libs/libcurl/src/vtls/polarssl_threadlock.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef HEADER_CURL_POLARSSL_THREADLOCK_H -#define HEADER_CURL_POLARSSL_THREADLOCK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * 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 - * 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" - -#if (defined USE_POLARSSL) || (defined USE_MBEDTLS) - -#if (defined(USE_THREADS_POSIX) && defined(HAVE_PTHREAD_H)) || \ - (defined(USE_THREADS_WIN32) && defined(HAVE_PROCESS_H)) - -int Curl_polarsslthreadlock_thread_setup(void); -int Curl_polarsslthreadlock_thread_cleanup(void); -int Curl_polarsslthreadlock_lock_function(int n); -int Curl_polarsslthreadlock_unlock_function(int n); - -#else - -#define Curl_polarsslthreadlock_thread_setup() 1 -#define Curl_polarsslthreadlock_thread_cleanup() 1 -#define Curl_polarsslthreadlock_lock_function(x) 1 -#define Curl_polarsslthreadlock_unlock_function(x) 1 - -#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */ - -#endif /* USE_POLARSSL */ - -#endif /* HEADER_CURL_POLARSSL_THREADLOCK_H */ diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index 0818d947a4..f665ee3404 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.c @@ -27,16 +27,6 @@ * but vtls.c should ever call or use these functions. */ -/* - * Based upon the PolarSSL implementation in polarssl.c and polarssl.h: - * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com> - * - * Based upon the CyaSSL implementation in cyassl.c and cyassl.h: - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * Thanks for code and inspiration! - */ - #include "curl_setup.h" #ifdef USE_SCHANNEL diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index f58adee6e8..a81b2f22d1 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -262,7 +262,6 @@ bool Curl_ssl_false_start(void); #define Curl_ssl_send(a,b,c,d,e) -1 #define Curl_ssl_recv(a,b,c,d,e) -1 #define Curl_ssl_initsessions(x,y) CURLE_OK -#define Curl_ssl_version(x,y) 0 #define Curl_ssl_data_pending(x,y) 0 #define Curl_ssl_check_cxn(x) 0 #define Curl_ssl_free_certinfo(x) Curl_nop_stmt |