diff options
Diffstat (limited to 'libs')
168 files changed, 11445 insertions, 8210 deletions
diff --git a/libs/libcurl/docs/CHANGES b/libs/libcurl/docs/CHANGES index 1653a55c98..d48ababb4f 100644 --- a/libs/libcurl/docs/CHANGES +++ b/libs/libcurl/docs/CHANGES @@ -6,6 +6,5379 @@ Changelog +Version 7.86.0 (26 Oct 2022) + +Daniel Stenberg (26 Oct 2022) +- RELEASE: synced + + The 7.86.0 release + +- THANKS: added from the 7.86.0 release + +Viktor Szakats (25 Oct 2022) +- noproxy: include netinet/in.h for htonl() + + Solve the Amiga build warning by including `netinet/in.h`. + + `krb5.c` and `socketpair.c` are using `htonl()` too. This header is + already included in those sources. + + Regression from 1e9a538e05c0107c54ef81d9de7cd0b27cd13309 + + Reviewed-by: Daniel Stenberg + Closes #9787 + +Marc Hoersken (24 Oct 2022) +- CI: fix AppVeyor status failing for starting jobs + +Daniel Stenberg (24 Oct 2022) +- test445: verifies the protocols-over-http-proxy flaw and fix + +- http_proxy: restore the protocol pointer on error + + Reported-by: Trail of Bits + + Closes #9790 + +- multi: remove duplicate include of connect.h + + Reported-by: Martin Strunz + Fixes #9794 + Closes #9795 + +Daniel Gustafsson (24 Oct 2022) +- idn: fix typo in test description + + s/enabked/enabled/i + +Daniel Stenberg (24 Oct 2022) +- url: use IDN decoded names for HSTS checks + + Reported-by: Hiroki Kurosawa + + Closes #9791 + +- unit1614: fix disabled-proxy build + + Follow-up to 1e9a538e05c01 + + Closes #9792 + +Daniel Gustafsson (24 Oct 2022) +- cookies: optimize control character check + + When checking for invalid octets the strcspn() call will return the + position of the first found invalid char or the first NULL byte. + This means that we can check the indicated position in the search- + string saving a strlen() call. + + Closes: #9736 + Reviewed-by: Jay Satiro <raysatiro@yahoo.com> + +Daniel Stenberg (24 Oct 2022) +- netrc: replace fgets with Curl_get_line + + Make the parser only accept complete lines and avoid problems with + overly long lines. + + Reported-by: Hiroki Kurosawa + + Closes #9789 + +- RELEASE-NOTES: add "Planned upcoming removals include" + + URL: https://curl.se/mail/archive-2022-10/0001.html + + Suggested-by: Dan Fandrich + +Viktor Szakats (23 Oct 2022) +- ci: bump to gcc-11 for macos + + Ref: https://github.blog/changelog/2022-10-03-github-actions-jobs-running-on-macos-latest-are-now-running-on-macos-12/ + Ref: https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md + + Reviewed-by: Max Dymond + Closes #9785 + +- Makefile.m32: reintroduce CROSSPREFIX and -W -Wall [ci skip] + + - Reintroduce `CROSSPREFIX`: + + If set, we add it to the `CC` and `AR` values, and to the _default_ + value of `RC`, which is `windres`. This allows to control each of + these individidually, while also allowing to simplify configuration + via `CROSSPREFIX`. + + This variable worked differently earlier. Hopefully this new solution + hits a better compromise in usefulness/complexity/flexibility. + + Follow-up to: aa970c4c08775afcd0c2853be89b0a6f02582d50 + + - Enable warnings again: + + This time with an option to override it via `CFLAGS`. Warnings are + also enabled by default in CMake, `makefile.dj` and `makefile.amiga` + builds (not in autotools though). + + Follow-up to 10fbd8b4e3f83b967fd9ad9a41ab484c0e7e7ca3 + + Closes #9784 + +- noproxy: silence unused variable warnings with no ipv6 + + Follow-up to 36474f1050c7f4117e3c8de6cc9217cfebfc717d + + Reviewed-by: Daniel Stenberg + Closes #9782 + +Daniel Stenberg (22 Oct 2022) +- test644: verify --xattr (with redirect) + +- tool_xattr: save the original URL, not the final redirected one + + Adjusted test 1621 accordingly. + + Reported-by: Viktor Szakats + Fixes #9766 + Closes #9768 + +- docs: make sure libcurl opts examples pass in long arguments + + Reported-by: Sergey + Fixes #9779 + Closes #9780 + +Marc Hoersken (21 Oct 2022) +- CI: fix AppVeyor job links only working for most recent build + + Ref: https://github.com/curl/curl/pull/9768#issuecomment-1286675916 + Reported-by: Daniel Stenberg + + Follow up to #9769 + +Viktor Szakats (21 Oct 2022) +- noproxy: fix builds without AF_INET6 + + Regression from 1e9a538e05c0107c54ef81d9de7cd0b27cd13309 + + Reviewed-by: Daniel Stenberg + + Closes #9778 + +Daniel Stenberg (21 Oct 2022) +- noproxy: support proxies specified using cidr notation + + For both IPv4 and IPv6 addresses. Now also checks IPv6 addresses "correctly" + and not with string comparisons. + + Split out the noproxy checks and functionality into noproxy.c + + Added unit test 1614 to verify checking functions. + + Reported-by: Mathieu Carbonneaux + + Fixes #9773 + Fixes #5745 + Closes #9775 + +- urlapi: remove two variable assigns + + To please scan-build: + + urlapi.c:1163:9: warning: Value stored to 'qlen' is never read + qlen = Curl_dyn_len(&enc); + ^ ~~~~~~~~~~~~~~~~~~ + urlapi.c:1164:9: warning: Value stored to 'query' is never read + query = u->query = Curl_dyn_ptr(&enc); + ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Follow-up to 7d6cf06f571d57 + + Closes #9777 + +- [Jeremy Maitin-Shepard brought this change] + + cmake: improve usability of CMake build as a sub-project + + - Renames `uninstall` -> `curl_uninstall` + - Ensures all export rules are guarded by CURL_ENABLE_EXPORT_TARGET + + Closes #9638 + +- [Don J Olmstead brought this change] + + easy_lock: check for HAVE_STDATOMIC_H as well + + The check for `HAVE_STDATOMIC_H` looks to see if the `stdatomic.h` + header is present. + + Closes #9755 + +- RELEASE-NOTES: synced + +- [Brad Harder brought this change] + + CURLMOPT_PIPELINING.3: dedup manpage xref + + Closes #9776 + +Marc Hoersken (20 Oct 2022) +- CI: report AppVeyor build status for each job + + Also give each job on AppVeyor CI a human-readable name. + + This aims to make job and therefore build failures more visible. + + Reviewed-by: Marcel Raad + Closes #9769 + +Viktor Szakats (20 Oct 2022) +- amiga: set SIZEOF_CURL_OFF_T=8 by default [ci skip] + + Reviewed-by: Daniel Stenberg + + Closes #9771 + +- connect: fix builds without AF_INET6 + + Regression from 2b309560c1e5d6ed5c0e542e6fdffa968b0521c9 + + Reviewed-by: Daniel Stenberg + Reviewed-by: Jay Satiro + + Closes #9770 + +Daniel Stenberg (20 Oct 2022) +- test1105: adjust <data> to work with a hyper build + + Closes #9767 + +- urlapi: fix parsing URL without slash with CURLU_URLENCODE + + When CURLU_URLENCODE is set, the parser would mistreat the path + component if the URL was specified without a slash like in + http://local.test:80?-123 + + Extended test 1560 to reproduce and verify the fix. + + Reported-by: Trail of Bits + + Closes #9763 + +Marc Hoersken (19 Oct 2022) +- tests: avoid CreateThread if _beginthreadex is available + + CreateThread is not threadsafe if mixed with CRT calls. + _beginthreadex on the other hand can be mixed with CRT. + + Reviewed-by: Marcel Raad + Closes #9705 + +Jay Satiro (19 Oct 2022) +- [Joel Depooter brought this change] + + schannel: Don't reset recv/send function pointers on renegotiation + + These function pointers will have been set when the initial TLS + handshake was completed. If they are unchanged, there is no need to set + them again. If they have been changed, as is the case with HTTP/2, we + don't want to override that change. That would result in the + http22_recv/send functions being completely bypassed. + + Prior to this change a connection that uses Schannel with HTTP/2 would + fail on renegotiation with error "Received HTTP/0.9 when not allowed". + + Fixes https://github.com/curl/curl/issues/9451 + Closes https://github.com/curl/curl/pull/9756 + +Viktor Szakats (18 Oct 2022) +- hostip: guard PF_INET6 use + + Some platforms (e.g. Amiga OS) do not have `PF_INET6`. Adjust the code + for these. + + ``` + hostip.c: In function 'fetch_addr': + hostip.c:308:12: error: 'PF_INET6' undeclared (first use in this function) + pf = PF_INET6; + ^~~~~~~~ + ``` + + Regression from 1902e8fc511078fb5e26fc2b907b4cce77e1240d + + Reviewed-by: Daniel Stenberg + + Closes #9760 + +- amiga: do not hardcode openssl/zlib into the os config [ci skip] + + Enable them in `lib/makefile.amiga` and `src/makefile.amiga` instead. + + This allows builds without openssl and/or zlib. E.g. with the + <https://github.com/bebbo/amiga-gcc> cross-compiler. + + Reviewed-by: Daniel Stenberg + + Closes #9762 + +- amigaos: add missing curl header [ci skip] + + Without it, `CURLcode` and `CURLE_*` are undefined. `lib/hostip.h` and + conditional local code need them. + + Reviewed-by: Daniel Stenberg + + Closes #9761 + +Daniel Stenberg (18 Oct 2022) +- cmdline/docs: add a required 'multi' keyword for each option + + The keyword specifies how option works when specified multiple times: + + - single: the last provided value replaces the earlier ones + - append: it supports being provided multiple times + - boolean: on/off values + - mutex: flag-like option that disable anoter flag + + The 'gen.pl' script then outputs the proper and unified language for + each option's multi-use behavior in the generated man page. + + The multi: header is requires in each .d file and will cause build error + if missing or set to an unknown value. + + Closes #9759 + +- CURLOPT_AUTOREFERER.3: highlight the privacy leak risk + + Closes #9757 + +- mprintf: reject two kinds of precision for the same argument + + An input like "%.*1$.9999d" would first use the precision taken as an + argument *and* then the precision specified in the string, which is + confusing and wrong. pass1 will now instead return error on this double + use. + + Adjusted unit test 1398 to verify + + Reported-by: Peter Goodman + + Closes #9754 + +- ftp: remove redundant if + + Reported-by: Trail of Bits + + Closes #9753 + +- tool_operate: more transfer cleanup after parallel transfer fail + + In some circumstances when doing parallel transfers, the + single_transfer_cleanup() would not be called and then 'inglob' could + leak. + + Test 496 verifies + + Reported-by: Trail of Bits + Closes #9749 + +- mqtt: spell out CONNECT in comments + + Instead of calling it 'CONN' in several comments, use the full and + correct protocol packet name. + + Suggested by Trail of Bits + + Closes #9751 + +- CURLOPT_POSTFIELDS.3: refer to CURLOPT_MIMEPOST + + Not the deprecated CURLOPT_HTTPPOST option. + + Also added two see-alsos. + + Reported-by: Trail of Bits + Closes #9752 + +- RELEASE-NOTES: synced + +Jay Satiro (17 Oct 2022) +- ngtcp2: Fix build errors due to changes in ngtcp2 library + + ngtcp2/ngtcp2@b0d86f60 changed: + + - ngtcp2_conn_get_max_udp_payload_size => + ngtcp2_conn_get_max_tx_udp_payload_size + + - ngtcp2_conn_get_path_max_udp_payload_size => + ngtcp2_conn_get_path_max_tx_udp_payload_size + + ngtcp2/ngtcp2@ec59b873 changed: + + - 'early_data_rejected' member added to ng_callbacks. + + Assisted-by: Daniel Stenberg + Reported-by: jurisuk@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/9747 + Closes https://github.com/curl/curl/pull/9748 + +Daniel Stenberg (16 Oct 2022) +- curl_path: return error if given a NULL homedir + + Closes #9740 + +- libssh: if sftp_init fails, don't get the sftp error code + + This flow extracted the wrong code (sftp code instead of ssh code), and + the code is sometimes (erroneously) returned as zero anyway, so skip + getting it and set a generic error. + + Reported-by: David McLaughlin + Fixes #9737 + Closes #9740 + +- mqtt: return error for too long topic + + Closes #9744 + +- [Rickard Hallerbäck brought this change] + + tool_paramhlp: make the max argument a 'double' + + To fix compiler warnings "Implicit conversion from 'long' to 'double' + may lose precision" + + Closes #9700 + +Marc Hoersken (15 Oct 2022) +- [Philip Heiduck brought this change] + + cirrus-ci: add more macOS builds with m1 based on x86_64 builds + + Also refactor macOS builds to use task matrix. + + Assisted-by: Marc Hörsken + Closes #9565 + +Viktor Szakats (14 Oct 2022) +- cmake: set HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID on Windows + + `lib/config-win32.h` enables this configuration option unconditionally. + Make it apply to CMake builds as well. + + While here, delete a broken check for + `HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID` from `CMakeLists.txt`. This came with + the initial commit [1], but did not include the actual verification code + inside `CMake/CurlTests.c`, so it always failed. A later commit [2] + added a second test, for non-Windows platforms. + + Enabling this flag causes test 1056 to fail with CMake builds, as they + do with autotools builds. Let's apply the same solution and ignore the + results here as well. + + [1] 4c5307b45655ba75ab066564afdc0c111a8b9291 + [2] aec7c5a87c8482b6ddffa352d7d220698652262e + + Reviewed-by: Daniel Stenberg + Assisted-by: Marcel Raad + + Closes #9726 + +- cmake: set HAVE_GETADDRINFO_THREADSAFE on Windows + + autotools enables this configuration option unconditionally for Windows + [^1]. Do the same in CMake. + + The above will make this work for all reasonably recent environments. + The logic present in `lib/config-win32.h` [^2] has the following + exceptions which we did not cover in this CMake update: + + - Builds targeting Windows 2000 and earlier + - MS Visual C++ 5.0 (1997) and earlier + + Also make sure to disable this feature when `HAVE_GETADDRINFO` isn't + set, to avoid a broken build. We might want to handle that in the C + sources in a future commit. + + [^1]: https://github.com/curl/curl/blob/68fa9bf3f5d7b4fcbb57619f70cb4aabb79a51f6/m4/curl-functions.m4#L2067-L2070 + + [^2]: https://github.com/curl/curl/blob/68fa9bf3f5d7b4fcbb57619f70cb4aabb79a51f6/lib/config-win32.h#L511-L528 + + Closes #9727 + +- cmake: sync HAVE_SIGNAL detection with autotools + + `HAVE_SIGNAL` means the availability of the `signal()` function in + autotools, while in CMake it meant the availability of that function + _and_ the symbol `SIGALRM`. + + The latter is not available on Windows, but the function is, which means + on Windows, autotools did define `HAVE_SIGNAL`, but CMake did not, + introducing a slight difference into the binaries. + + This patch syncs CMake behaviour with autotools to look for the function + only. + + The logic came with the initial commit adding CMake support to curl, so + the commit history doesn't reveal the reason behind it. In any case, + it's best to check the existence of `SIGALRM` directly in the source + before use. For now, curl builds fine with `HAVE_SIGNAL` enabled and + `SIGALRM` missing. + + Follow-up to 68fa9bf3f5d7b4fcbb57619f70cb4aabb79a51f6 + + Closes #9725 + +- cmake: delete duplicate HAVE_GETADDRINFO test + + A custom `HAVE_GETADDRINFO` check came with the initial CMake commit + [1]. A later commit [2] added a standard check for it as well. The + standard check run before the custom one, so CMake ignored the latter. + + The custom check was also non-portable, so this patch deletes it in + favor of the standard check. + + [1] 4c5307b45655ba75ab066564afdc0c111a8b9291 + [2] aec7c5a87c8482b6ddffa352d7d220698652262e + + Closes #9731 + +Daniel Stenberg (14 Oct 2022) +- tool_formparse: unroll the NULL_CHECK and CONST_FREE macros + + To make the code read more obvious + + Assisted-by: Jay Satiro + + Closes #9710 + +- [Christopher Sauer brought this change] + + docs/INSTALL: update Android Instructions for newer NDKs + + Closes #9732 + +- markdown-uppercase: ignore quoted sections + + Sections within the markdown ~~~ or ``` are now ignored. + + Closes #9733 + +- RELEASE-NOTES: synced + +- test8: update as cookies no longer can have "embedded" TABs in content + +- test1105: extend to verify TAB in name/content discarding cookies + +- cookie: reject cookie names or content with TAB characters + + TABs in name and content seem allowed by RFC 6265: "the algorithm strips + leading and trailing whitespace from the cookie name and value (but + maintains internal whitespace)" + + Cookies with TABs in the names are rejected by Firefox and Chrome. + + TABs in content are stripped out by Firefox, while Chrome discards the + whole cookie. + + TABs in cookies also cause issues in saved netscape cookie files. + + Reported-by: Trail of Bits + + URL: https://curl.se/mail/lib-2022-10/0032.html + URL: https://github.com/httpwg/http-extensions/issues/2262 + + Closes #9659 + +- curl/add_parallel_transfers: better error handling + + 1 - consider the transfer handled at once when in the function, to avoid + the same list entry to get added more than once in rare error + situations + + 2 - set the ERRORBUFFER for the handle first after it has been added + successfully + + Reported-by: Trail of Bits + + Closes #9729 + +- netrc: remove the two 'changed' arguments + + As no user of these functions used the returned content. + +- test495: verify URL encoded user name + netrc-optional + + Reproduced issue #9709 + +- netrc: use the URL-decoded user + + When the user name is provided in the URL it is URL encoded there, but + when used for authentication the encoded version should be used. + + Regression introduced after 7.83.0 + + Reported-by: Jonas Haag + Fixes #9709 + Closes #9715 + +- [Shaun Mirani brought this change] + + url: allow non-HTTPS HSTS-matching for debug builds + + Closes #9728 + +- test1275: remove the check of stderr + + To avoid the mysterious test failures on Windows, instead rely on the + error code returned on failure. + + Fixes #9716 + Closes #9723 + +Viktor Szakats (13 Oct 2022) +- lib: set more flags in config-win32.h + + The goal is to add any flag that affect the created binary, to get in + sync with the ones built with CMake and autotools. + + I took these flags from curl-for-win [0], where they've been tested with + mingw-w64 and proven to work well. + + This patch brings them to curl as follows: + + - Enable unconditionally those force-enabled via + `CMake/WindowsCache.cmake`: + + - `HAVE_SETJMP_H` + - `HAVE_STRING_H` + - `HAVE_SIGNAL` (CMake equivalent is `HAVE_SIGNAL_FUNC`) + + - Expand existing guards with mingw-w64: + + - `HAVE_STDBOOL_H` + - `HAVE_BOOL_T` + + - Enable Win32 API functions for Windows Vista and later: + + - `HAVE_INET_NTOP` + - `HAVE_INET_PTON` + + - Set sizes, if not already set: + + - `SIZEOF_OFF_T = 8` + - `_FILE_OFFSET_BITS = 64` when `USE_WIN32_LARGE_FILES` is set, + and using mingw-w64. + + - Add the remaining for mingw-w64 only. Feel free to expand as desired: + + - `HAVE_LIBGEN_H` + - `HAVE_FTRUNCATE` + - `HAVE_BASENAME` + - `HAVE_STRTOK_R` + + Future TODO: + + - `HAVE_SIGNAL` has a different meaning in CMake. It's enabled when both + the `signal()` function and the `SIGALRM` macro are found. In + autotools and this header, it means the function only. For the + function alone, CMake uses `HAVE_SIGNAL_FUNC`. + + [0] https://github.com/curl/curl-for-win/blob/c9b9a5f273c94c73d2b565ee892c4dff0ca97a8c/curl-m32.sh#L53-L58 + + Reviewed-by: Daniel Stenberg + + Closes #9712 + +Daniel Stenberg (13 Oct 2022) +- tests: add tests/markdown-uppercase.pl to dist tarball + + Follow-up to aafb06c5928183d + + Closes #9722 + +- tool_paramhelp: asserts verify maximum sizes for string loading + + The two defines MAX_FILE2MEMORY and MAX_FILE2STRING define the largest + strings accepted when loading files into memory, but as the size is + later used as input to functions that take the size as 'int' as + argument, the sizes must not be larger than INT_MAX. + + These two new assert()s make the code error out if someone would bump + the sizes without this consideration. + + Reported-by Trail of Bits + + Closes #9719 + +- http: try parsing Retry-After: as a number first + + Since the date parser allows YYYYMMDD as a date format (due to it being + a bit too generic for parsing this particular header), a large integer + number could wrongly match that pattern and cause the parser to generate + a wrong value. + + No date format accepted for this header starts with a decimal number, so + by reversing the check and trying a number first we can deduct that if + that works, it was not a date. + + Reported-by Trail of Bits + + Closes #9718 + +- [Patrick Monnerat brought this change] + + doc: fix deprecation versions inconsistencies + + Ref: https://curl.se/mail/lib-2022-10/0026.html + + Closes #9711 + +- http_aws_sigv4: fix strlen() check + + The check was off-by-one leading to buffer overflow. + + Follow-up to 29c4aa00a16872 + + Detected by OSS-Fuzz + + Closes #9714 + +- curl/main_checkfds: check the fcntl return code better + + fcntl() can (in theory) return a non-zero number for success, so a + better test for error is checking for -1 explicitly. + + Follow-up to 41e1b30ea1b77e9ff + + Mentioned-by: Dominik Klemba + + Closes #9708 + +Viktor Szakats (12 Oct 2022) +- tidy-up: delete unused HAVE_STRUCT_POLLFD + + It was only defined in `lib/config-win32.h`, when building for Vista. + + It was only used in `select.h`, in a condition that also included a + check for `POLLIN` which is a superior choice for this detection and + which was already used by cmake and autotools builds. + + Delete both instances of this macro. + + Closes #9707 + +Daniel Stenberg (12 Oct 2022) +- test1275: verify upercase after period in markdown + + Script based on the #9474 pull-request logic, but implemented in perl. + + Updated docs/URL-SYNTAX.md accordingly. + + Suggested-by: Dan Fandrich + + Closes #9697 + +- [12932 brought this change] + + misc: nitpick grammar in comments/docs + + because the 'u' in URL is actually a consonant *sound* it is only + correct to write "a URL" + + sorry this is a bit nitpicky :P + + https://english.stackexchange.com/questions/152/when-should-i-use-a-vs-an + https://www.techtarget.com/whatis/feature/Which-is-correct-a-URL-or-an-URL + + Closes #9699 + +Viktor Szakats (11 Oct 2022) +- Makefile.m32: drop CROSSPREFIX and our CC/AR defaults [ci skip] + + This patch aimed to fix a regression [0], where `CC` initialization + moved beyond its first use. But, on closer inspection it turned out that + the `CC` initialization does not work as expected due to GNU Make + filling it with `cc` by default. So unless implicit values were + explicitly disabled via a GNU Make option, the default value of + `$CROSSPREFIX` + `gcc` was never used. At the same time the implicit + value `cc` maps to `gcc` in (most/all?) MinGW envs. + + `AR` has the same issue, with a default value of `ar`. + + We could reintroduce a separate variable to fix this without ill + effects, but for simplicity and flexibility, it seems better to drop + support for `CROSSPREFIX`, along with our own `CC`/`AR` init logic, and + require the caller to initialize `CC`, `AR` and `RC` to the full + (prefixed if necessary) names of these tools, as desired. + + We keep `RC ?= windres` because `RC` is empty by default. + + Also fix grammar in a comment. + + [0] 10fbd8b4e3f83b967fd9ad9a41ab484c0e7e7ca3 + + Closes #9698 + +- smb: replace CURL_WIN32 with WIN32 + + PR #9255 aimed to fix a Cygwin/MSYS issue (#8220). It used the + `CURL_WIN32` macro, but that one is not defined here, while compiling + curl itself. This patch changes this to `WIN32`, assuming this was the + original intent. + + Regression from 1c52e8a3795ccdf8ec9c308f4f8f19cf10ea1f1a + + Reviewed-by: Marcel Raad + + Closes #9701 + +Daniel Stenberg (11 Oct 2022) +- [Matthias Gatto brought this change] + + aws_sigv4: fix header computation + + Handle canonical headers and signed headers creation as explained here: + https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html + + The algo tells that signed and canonical must contain at last host and + x-amz-date. + + So we check whatever thoses are present in the curl http headers list. + If they are, we use the one enter by curl user, otherwise we generate + them. then we to lower, and remove space from each http headers plus + host and x-amz-date, then sort them all by alphabetical order. + + This patch also fix a bug with host header, which was ignoring the port. + + Closes #7966 + +Jay Satiro (11 Oct 2022) +- [Aftab Alam brought this change] + + README.md: link the curl logo to the website + + - Link the curl:// image to https://curl.se/ + + Closes https://github.com/curl/curl/pull/9675 + +- [Dustin Howett brought this change] + + schannel: when importing PFX, disable key persistence + + By default, the PFXImportCertStore API persists the key in the user's + key store (as though the certificate was being imported for permanent, + ongoing use.) + + The documentation specifies that keys that are not to be persisted + should be imported with the flag PKCS12_NO_PERSIST_KEY. + NOTE: this flag is only supported on versions of Windows newer than XP + and Server 2003. + + -- + + This is take 2 of the original fix. It extends the lifetime of the + client certificate store to that of the credential handle. The original + fix which landed in 70d010d and was later reverted in aec8d30 failed to + work properly because it did not do that. + + Minor changes were made to the schannel credential context to support + closing the client certificate store handle at the end of an SSL session. + + -- + + Reported-by: ShadowZzj@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/9300 + Supersedes https://github.com/curl/curl/pull/9363 + Closes https://github.com/curl/curl/pull/9460 + +Viktor Szakats (11 Oct 2022) +- Makefile.m32: support more options [ci skip] + + - Add support for these options: + `-wolfssl`, `-wolfssh`, `-mbedtls`, `-libssh`, `-psl` + + Caveats: + - `-wolfssh` requires `-wolfssl`. + - `-wolfssl` cannot be used with OpenSSL backends in parallel. + - `-libssh` has build issues with BoringSSL and LibreSSL, and also + what looks like a world-writable-config vulnerability on Windows. + Consider it experimental. + - `-psl` requires `-idn2` and extra libs passed via + `LIBS=-liconv -lunistring`. + + - Detect BoringSSL/wolfSSL and set ngtcp2 crypto lib accordingly. + - Generalize MultiSSL detection. + - Use else-if syntax. Requires GNU Make 3.81 (2006-04-01). + - Document more customization options. + + This brings over some configuration logic from `curl-for-win`. + + Closes #9680 + +- cmake: enable more detection on Windows + + Enable `HAVE_UNISTD_H`, `HAVE_STRTOK_R` and `HAVE_STRCASECMP` detection + on Windows, instead of having predefined values. + + With these features detected correctly, CMake Windows builds get closer + to the autotools and `config-win32.h` ones. + + This also fixes detecting `HAVE_FTRUNCATE` correctly, which required + `unistd.h`. + + Fixing `ftruncate()` in turn causes a build warning/error with legacy + MinGW/MSYS1 due to an offset type size mismatch. This env misses to + detect `HAVE_FILE_OFFSET_BITS`, which may be a reason. This patch + force-disables `HAVE_FTRUNCATE` for this platform. + + Reviewed-by: Daniel Stenberg + + Closes #9687 + +- autotools: allow unix sockets on Windows + + Fixes: https://github.com/curl/curl-for-win/blob/73a070d96fd906fdee929e2f1f00a9149fb39239/curl-autotools.sh#L44-L47 + + On Windows this feature is present, but not the header used in the + detection logic. It also requires an elaborate enabler logic + (as seen in `lib/curl_setup.h`). Let's always allow it and let the + lib code deal with the details. + + Closes #9688 + +- cmake: add missing inet_ntop check + + This adds the missing half of the check, next to the other half + already present in `lib/curl_config.h.cmake`. + + Force disable `HAVE_INET_NTOP` for old MSVC where it caused compiler + warnings. + + Reviewed-by: Daniel Stenberg + + Closes #9689 + +Daniel Stenberg (11 Oct 2022) +- RELEASE-NOTES: synced + +- [bsergean on github brought this change] + + asyn-ares: set hint flags when calling ares_getaddrinfo + + The hint flag is ARES_AI_NUMERICSERV, and it will save a call to + getservbyname or getservbyname_r to set it. + + Closes #9694 + +- header.d: add category smtp and imap + + They were previously (erroneously) added manually to tool_listhelp.c + which would make them get removed again when the file is updated next + time, unless added correctly here in header.d + + Follow-up to 2437fac01 + + Closes #9690 + +- curl/get_url_file_name: use libcurl URL parser + + To avoid URL tricks, use the URL parser for this. + + This update changes curl's behavior slightly in that it will ignore the + possible query part from the URL and only use the file name from the + actual path from the URL. I consider it a bugfix. + + "curl -O localhost/name?giveme-giveme" will now save the output in the + local file named 'name' + + Updated test 1210 to verify + + Assisted-by: Jay Satiro + + Closes #9684 + +- [Martin Ågren brought this change] + + docs: fix grammar around needing pass phrase + + "You never needed a pass phrase" reads like it's about to be followed by + something like "until version so-and-so", but that is not what is + intended. Change to "You never need a pass phrase". There are two + instances of this text, so make sure to update both. + +- [Xiang Xiao brought this change] + + cmake: add the check of HAVE_SOCKETPAIR + + which is used by Curl_socketpair + + Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com> + + Closes #9686 + +- curl/add_file_name_to_url: use the libcurl URL parser + + instead of the custom error-prone parser, to extract and update the path + of the given URL + + Closes #9683 + +- single_transfer: use the libcurl URL parser when appending query parts + + Instead of doing "manual" error-prone parsing in another place. + + Used when --data contents is added to the URL query when -G is provided. + + Closes #9681 + +- ws: fix buffer pointer use in the callback loop + + Closes #9678 + +- [Petr Štetiar brought this change] + + curl-wolfssl.m4: error out if wolfSSL is not usable + + When I explicitly declare, that I would like to have curl built with + wolfSSL support using `--with-wolfssl` configure option, then I would + expect, that either I endup with curl having that support, for example + in form of https support or it wouldn't be available at all. + + Downstream projects like for example OpenWrt build curl wolfSSL variant + with `--with-wolfssl` already, but in certain corner cases it does fail: + + configure:25299: checking for wolfSSL_Init in -lwolfssl + configure:25321: x86_64-openwrt-linux-musl-gcc -o conftest [snip] + In file included from target-x86_64_musl/usr/include/wolfssl/wolfcrypt/dsa.h:33, + from target-x86_64_musl/usr/include/wolfssl/wolfcrypt/asn_public.h:35, + from target-x86_64_musl/usr/include/wolfssl/ssl.h:35, + from conftest.c:47: + target-x86_64_musl/usr/include/wolfssl/wolfcrypt/integer.h:37:14: fatal error: wolfssl/wolfcrypt/sp_int.h: No such file or directory + #include <wolfssl/wolfcrypt/sp_int.h> + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ + compilation terminated. + + and in the end thus produces curl without https support: + + curl: (1) Protocol "https" not supported or disabled in libcurl + + So fix it, by making the working wolfSSL mandatory and error out in + configure step when that's not the case: + + checking for wolfSSL_Init in -lwolfssl... no + configure: error: --with-wolfssl but wolfSSL was not found or doesn't work + + References: https://github.com/openwrt/packages/issues/19005 + References: https://github.com/openwrt/packages/issues/19547 + Signed-off-by: Petr Štetiar <ynezz@true.cz> + + Closes #9682 + +- tool_getparam: pass in the snprintf("%.*s") string length as 'int' + + Reported by Coverity CID 1515928 + + Closes #9679 + +- [Paul Seligman brought this change] + + ws: minor fixes for web sockets without the CONNECT_ONLY flag + + - Fixed an issue where is_in_callback was getting cleared when using web + sockets with debug logging enabled + - Ensure the handle is is_in_callback when calling out to fwrite_func + - Change the write vs. send_data decision to whether or not the handle + is in CONNECT_ONLY mode. + - Account for buflen not including the header length in curl_ws_send + + Closes #9665 + +Marc Hoersken (8 Oct 2022) +- CI/cirrus: merge existing macOS jobs into a job matrix + + Ref: #9627 + Reviewed-by: Philip H. + + Closes #9672 + +Daniel Stenberg (8 Oct 2022) +- strcase: add and use Curl_timestrcmp + + This is a strcmp() alternative function for comparing "secrets", + designed to take the same time no matter the content to not leak + match/non-match info to observers based on how fast it is. + + The time this function takes is only a function of the shortest input + string. + + Reported-by: Trail of Bits + + Closes #9658 + +- tool_getparam: split out data_urlencode() into its own function + + Closes #9673 + +- connect: fix Curl_updateconninfo for TRNSPRT_UNIX + + Reported-by: Vasiliy Ulyanov + Fixes #9664 + Closes #9670 + +- ws: fix Coverity complaints + + Coverity pointed out several flaws where variables remained + uninitialized after forks. + + Follow-up to e3f335148adc6742728f + + Closes #9666 + +Marc Hoersken (7 Oct 2022) +- CI/GHA: merge msh3 and openssl3 builds into linux workflow + + Continue work on merging all Linux workflows into one file. + + Follow up to #9501 + Closes #9646 + +Daniel Stenberg (7 Oct 2022) +- curl_ws_send.3: call the argument 'fragsize' + + Since WebSocket works with "fragments" not "frames" + + Closes #9668 + +- easy: avoid Intel error #2312: pointer cast involving 64-bit pointed-to type + + Follow-up to e3f335148adc6742728ff8 + + Closes #9669 + +- tool_main: exit at once if out of file descriptors + + If the main_checkfds function cannot create new file descriptors in an + attempt to detect of stdin, stdout or stderr are closed. + + Also changed the check to use fcntl() to check if the descriptors are + open, which avoids superfluously calling pipe() if they all already are. + + Follow-up to facfa19cdd4d0094 + + Reported-by: Trail of Bits + + Closes #9663 + +- websockets: remodeled API to support 63 bit frame sizes + + curl_ws_recv() now receives data to fill up the provided buffer, but can + return a partial fragment. The function now also get a pointer to a + curl_ws_frame struct with metadata that also mentions the offset and + total size of the fragment (of which you might be receiving a smaller + piece). This way, large incoming fragments will be "streamed" to the + application. When the curl_ws_frame struct field 'bytesleft' is 0, the + final fragment piece has been delivered. + + curl_ws_recv() was also adjusted to work with a buffer size smaller than + the fragment size. (Possibly needless to say as the fragment size can + now be 63 bit large). + + curl_ws_send() now supports sending a piece of a fragment, in a + streaming manner, in addition to sending the entire fragment in a single + call if it is small enough. To send a huge fragment, curl_ws_send() can + be used to send it in many small calls by first telling libcurl about + the total expected fragment size, and then send the payload in N number + of separate invokes and libcurl will stream those over the wire. + + The struct curl_ws_meta() returns is now called 'curl_ws_frame' and it + has been extended with two new fields: *offset* and *bytesleft*. To help + describe the passed on data chunk when a fragment is delivered in many + smaller pieces. + + The documentation has been updated accordingly. + + Closes #9636 + +- [Patrick Monnerat brought this change] + + docs/examples: avoid deprecated options in examples where possible + + Example programs targeting a deprecated feature/option are commented with + a warning about it. + Other examples are adapted to not use deprecated options. + + Closes #9661 + +Viktor Szakats (6 Oct 2022) +- cmake: fix enabling websocket support + + Follow-up from 664249d095275ec532f55dd1752d80c8c1093a77 + + Closes #9660 + +- tidy-up: delete parallel/unused feature flags + + Detecting headers and lib separately makes sense when headers come in + variations or with extra ones, but this wasn't the case here. These were + duplicate/parallel macros that we had to keep in sync with each other + for a working build. This patch leaves a single macro for each of these + dependencies: + + - Rely on `HAVE_LIBZ`, delete parallel `HAVE_ZLIB_H`. + + Also delete CMake logic making sure these two were in sync, along with + a toggle to turn off that logic, called `CURL_SPECIAL_LIBZ`. + + Also delete stray `HAVE_ZLIB` defines. + + There is also a `USE_ZLIB` variant in `lib/config-dos.h`. This patch + retains it for compatibility and deprecates it. + + - Rely on `USE_LIBSSH2`, delete parallel `HAVE_LIBSSH2_H`. + + Also delete `LIBSSH2_WIN32`, `LIBSSH2_LIBRARY` from + `winbuild/MakefileBuild.vc`, these have a role when building libssh2 + itself. And `CURL_USE_LIBSSH`, which had no use at all. + + Also delete stray `HAVE_LIBSSH2` defines. + + - Rely on `USE_LIBSSH`, delete parallel `HAVE_LIBSSH_LIBSSH_H`. + + Also delete `LIBSSH_WIN32`, `LIBSSH_LIBRARY` and `HAVE_LIBSSH` from + `winbuild/MakefileBuild.vc`, these were the result of copy-pasting the + libssh2 line, and were not having any use. + + - Delete unused `HAVE_LIBPSL_H` and `HAVE_LIBPSL`. + + Reviewed-by: Daniel Stenberg + + Closes #9652 + +Daniel Stenberg (6 Oct 2022) +- netrc: compare user name case sensitively + + User name comparisions in netrc need to match the case. + + Closes #9657 + +- CURLOPT_COOKIEFILE: insist on "" for enable-without-file + + The former way that also suggested using a non-existing file to just + enable the cookie engine could lead to developers maybe a bit carelessly + guessing a file name that will not exist, and then in a future due to + circumstances, such a file could be made to exist and then accidentally + libcurl would read cookies not actually meant to. + + Reported-by: Trail of bits + + Closes #9654 + +- tests/Makefile: remove run time stats from ci-test + + The ci-test is the normal makefile target invoked in CI jobs. This has + been using the -r option to runtests.pl since a long time, but I find + that it mostly just adds many lines to the test output report without + anyone caring much about those stats. + + Remove it. + + Closes #9656 + +- [Patrick Monnerat brought this change] + + tool: reorganize function c_escape around a dynbuf + + This is a bit shorter and a lot safer. + + Substrings of unescaped characters are added by a single call to reduce + overhead. + + Extend test 1465 to handle more kind of escapes. + + Closes #9653 + +Jay Satiro (5 Oct 2022) +- CURLOPT_HTTPPOST.3: bolden the deprecation notice + + Ref: https://github.com/curl/curl/pull/9621 + + Closes https://github.com/curl/curl/pull/9637 + +Daniel Stenberg (5 Oct 2022) +- [John Bampton brought this change] + + misc: fix spelling in docs and comments + + also: remove outdated sentence + + Closes #9644 + +- [Patrick Monnerat brought this change] + + tool: avoid generating ambiguous escaped characters in --libcurl + + C string hexadecimal-escaped characters may have more than 2 digits. + This results in a wrong C compiler interpretation of a 2-digit escaped + character when followed by an hex digit character. + + The solution retained here is to represent such characters as 3-digit + octal escapes. + + Adjust and extend test 1465 for this case. + + Closes #9643 + +- configure: the ngtcp2 option should default to 'no' + + While still experimental. + + Bug: https://curl.se/mail/lib-2022-10/0007.html + Reported-by: Daniel Hallberg + + Closes #9650 + +- CURLOPT_MIMEPOST.3: add an (inline) example + + Reported-by: Jay Satiro + Bug: https://github.com/curl/curl/pull/9637#issuecomment-1268070723 + + Closes #9649 + +Viktor Szakats (5 Oct 2022) +- Makefile.m32: exclude libs & libpaths for shared mode exes [ci skip] + + Exclude linker flags specifying depedency libs and libpaths, when + building against `libcurl.dll`. In such case these options are not + necessary (but may cause errors if not/wrongly configured.) + + Also move and reword a comment on `CPPFLAGS` to not apply to + `UNICODE` options. These are necessary for all build targets. + + Closes #9651 + +Jay Satiro (5 Oct 2022) +- runtests: fix uninitialized value on ignored tests + + - Don't show TESTFAIL message (ie tests failed which aren't ignored) if + only ignored tests failed. + + Before: + IGNORED: failed tests: 571 612 1056 + TESTDONE: 1214 tests out of 1217 reported OK: 99% + Use of uninitialized value $failed in concatenation (.) or string at + ./runtests.pl line 6290. + TESTFAIL: These test cases failed: + + After: + IGNORED: failed tests: 571 612 1056 + TESTDONE: 1214 tests out of 1217 reported OK: 99% + + Closes https://github.com/curl/curl/pull/9648 + +- cirrus: use make LDFLAGS=-all-static instead of curl_LDFLAGS + + - Correct the use of -all-static for static Windows CI builds. + + curl_LDFLAGS was removed from the makefile when metalink support was + removed. LDFLAGS=-all-static is passed to make only, because it is not a + valid option for configure compilation tests. + + Closes https://github.com/curl/curl/pull/9633 + +Viktor Szakats (4 Oct 2022) +- Makefile.m32: fix regression with tool_hugehelp [ci skip] + + In a recent commit I mistakenly deleted this logic, after seeing a + reference to a filename ending with `.cvs` and thinking it must have + been long gone. Turns out this is an existing file. Restore the rule + and the necessary `COPY` definitions with it. + + The restored logic is required for a successful build on a bare source + tree (as opposed to a source release tarball). + + Also shorten an existing condition similar to the one added in this + patch. + + Regression since 07a0047882dd3f1fbf73486c5dd9c15370877ad6 + + Closes #9645 + +- Makefile.m32: deduplicate build rules [ci skip] + + After this patch, we reduce the three copies of most `Makefile.m32` + logic to one. This now resides in `lib/Makefile.m32`. It makes future + updates easier, the code shorter, with a small amount of added + complexity. + + `Makefile.m32` reduction: + + | | bytes | LOC total | blank | comment | code | + |-------------------|-------:|----------:|-------:|---------:|------:| + | 7.85.0 | 34772 | 1337 | 79 | 192 | 1066 | + | before this patch | 17601 | 625 | 62 | 106 | 457 | + | after this patch | 11680 | 392 | 52 | 104 | 236 | + + Details: + + - Change rules to create objects for the `v*` subdirs in the `lib` dir. + This allows to use a shared compile rule and assumes that filenames + are not (and will not be) colliding across these directories. + `Makefile.m32` now also stores a list of these subdirs. They are + changing rarely though. + + - Sync as much as possible between the three `Makefile.m32` scripts' + rules and their source/target sections. + + - After this patch `CPPFLAGS` are all applied to the `src` sources once + again. This matches the behaviour of cmake/autotools. Only zlib ones + are actually required there. + + - Use `.rc` names from `Makefile.inc` instead of keeping a duplicate. + + - Change examples to link `libcurl.dll` by default. This makes building + trivial, even as a cross-build: + `CC=x86_64-w64-mingw32-gcc make -f Makefile.m32` + To run them, you need to move/copy or add-to-path `libcurl.dll`. + You can select static mode via `CFG=-static`. + + - List more of the `Makefile.m32` config variables. + + - Drop `.rc` support from examples. It made it fragile without much + benefit. + + - Include a necessary system lib for the `externalsocket.c` example. + + - Exclude unnecessary systems libs when building in `-dyn` mode. + + Closes #9642 + +Daniel Stenberg (4 Oct 2022) +- RELEASE-NOTES: synced + +- CURLOPT_COOKIELIST.3: fix formatting mistake + + Also, updated manpage-syntax.pl to make it detect this error in test + 1173. + + Reported-by: ProceduralMan on github + Fixes #9639 + Closes #9640 + +- [Jay Satiro brought this change] + + connect: change verbose IPv6 address:port to [address]:port + + - Use brackets for the IPv6 address shown in verbose message when the + format is address:port so that it is less confusing. + + Before: Trying 2606:4700:4700::1111:443... + After: Trying [2606:4700:4700::1111]:443... + + Bug: https://curl.se/mail/archive-2022-02/0041.html + Reported-by: David Hu + + Closes #9635 + +Viktor Szakats (3 Oct 2022) +- Makefile.m32: major rework [ci skip] + + This patch overhauls `Makefile.m32` scripts, fixing a list of quirks, + making its behaviour and customization envvars align better with other + build systems, aiming for less code, that is easier to read, use and + maintain. + + Details: + - Rename customization envvars: + `CURL_CC` -> `CC` + `CURL_RC` -> `RC` + `CURL_AR` -> `AR` + `CURL_LDFLAG_EXTRAS_DLL` -> `CURL_LDFLAGS_LIB` + `CURL_LDFLAG_EXTRAS_EXE` -> `CURL_LDFLAGS_BIN` + - Drop `CURL_STRIP` and `CURL_RANLIB`. These tools are no longer used. + - Accept `CFLAGS`, `CPPFLAGS`, `RCFLAGS`, `LDFLAGS` and `LIBS` envvars. + - Drop `CURL_CFLAG_EXTRAS`, `CURL_LDFLAG_EXTRAS`, `CURL_RCFLAG_EXTRAS` in + favor of the above. + - Do not automatically enable `zlib` with `libssh2`. `zlib` is optional + with `libssh2`. + - Omit unnecessary `CPPFLAGS` options when building `curl.exe` and + examples. + - Drop support for deprecated `-winssl` `CFG` option. Use `-schannel` + instead. + - Avoid late evaluation where not necessary (`=` -> `:=`). + - Drop support for `CURL_DLL_A_SUFFIX` to override the implib suffix. + Instead, use the standard naming scheme by default: `libcurl.dll.a`. + The toolchain recognizes the name, and selects it automatically when + asking for a `-shared` vs. `-static` build. + - Stop applying `strip` to `libcurl.a`. Follow-up from + 16a58e9f93c7e89e1f87720199388bcfcfa148a4. There was no debug info to + strip since then. + - Stop setting `-O3`, `-W`, `-Wall` options. You can add these to + `CFLAGS` as desired. + - Always enable `-DCURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG` with OpenSSL, + to avoid that vulnerability on Windows. + - Add `-lbrotlicommon` to `LIBS` when using `brotli`. + - Do not enable `-nghttp3` without `-ngtcp2`. + - `-ssh2` and `-rtmp` options no longer try to auto-select a TLS-backend. + You need to set the backend explicitly. This scales better and avoids + issues with certain combinations (e.g. `libssh2` + `wolfssl` with no + `schannel`). + - Default to OpenSSL TLS-backend with `ngtcp2`. Possible to override via + `NGTCP2_LIBS`. + - Old, alternate method of enabling components (e.g. `SSH2=1`) no longer + supported. + - Delete `SPNEGO` references. They were no-ops. + - Drop support for Win9x environments. + - Allow setting `OPENSSL_LIBS` independently from `OPENSSL_LIBPATH`. + - Support autotools/CMake `libssh2` builds by default. + - Respect `CURL_DLL_SUFFIX` in `-dyn` mode when building `curl.exe` and + examples. + - Assume standard directory layout with `LIBCARES_PATH`. (Instead of the + long gone embedded one.) + - Stop static linking with c-ares by default. Add + `CPPFLAGS=-DCARES_STATICLIB` to enable it. + - Reorganize internal layout to avoid redundancy and emit clean diffs + between src/lib and example make files. + - Delete unused variables. + - Code cleanups/rework. + - Comment and indentation fixes. + + Closes #9632 + +- scripts/release-notes.pl: strip ci skip tag [ci skip] + + Ref: https://github.com/curl/curl/commit/e604a82cae922bf86403a94f5803ac5e4303ae97#commitcomment-85637701 + + Reviewed-by: Daniel Stenberg + + Closes #9634 + +- Makefile.m32: delete legacy component bits [ci skip] + + - Drop auto-detection of OpenSSL 1.0.2 and earlier. Now always defaulting + to OpenSSL 1.1.0 and later, LibreSSL and BoringSSL. + + - Drop `Invalid path to OpenSSL package` detection. OpenSSL has been + using a standard file layout since 1.1.0, so this seems unnecessary + now. + + - Drop special logic to enable Novell LDAP SDK support. + + - Drop special logic to enable OpenLDAP LDAP SDK support. This seems + to be distinct from native OpenLDAP, with support implemented inside + `lib/ldap.c` (vs. `lib/openldap.c`) back when the latter did not exist + yet in curl. + + - Add `-lwldap32` only if there is no other LDAP library (either native + OpenLDAP, or SDKs above) present. + + - Update `doc/INSTALL.md` accordingly. + + After this patch, it's necessary to make configration changes when using + OpenSSL 1.0.2 or earlier, or the two LDAP SDKs. + + OpenSSL 1.0.2 and earlier: + ``` + export OPENSSL_INCLUDE = <path-to-openssl>/outinc + export OPENSSL_LIBPATH = <path-to-openssl>/out + export OPENSSL_LIBS = -lssl32 -leay32 -lgdi32 + ``` + + Novell LDAP SDK, previously enabled via `USE_LDAP_NOVELL=1`: + ``` + export CURL_CFLAG_EXTRAS = -I<path-to-sdk>/inc -DCURL_HAS_NOVELL_LDAPSDK + export CURL_LDFLAG_EXTRAS = -L<path-to-sdk>/lib/mscvc -lldapsdk -lldapssl -lldapx + ``` + + OpenLDAP LDAP SDK, previously enabled via `USE_LDAP_OPENLDAP=1`: + ``` + export CURL_CFLAG_EXTRAS = -I<path-to-sdk>/include -DCURL_HAS_OPENLDAP_LDAPSDK + export CURL_LDFLAG_EXTRAS = -L<path-to-sdk>/lib -lldap -llber + ``` + + I haven't tested these scenarios, and in general we recommend using + a recent OpenSSL release. Also, WinLDAP (the Windows default) and + OpenLDAP (via `-DUSE_OPENLDAP`) are the LDAP options actively worked on + in curl. + + Closes #9631 + +Daniel Stenberg (2 Oct 2022) +- vauth/ntlm.h: make line shorter than 80 columns + + Follow-up from 265fbd937 + +Viktor Szakats (1 Oct 2022) +- docs: update sourceforge project links [ci skip] + + SourceForge projects can now choose between two hostnames, with .io and + .net ending. Both support HTTPS by default now. Opening the other variant + will perm-redirected to the one chosen by the project. + + The .io -> .net redirection is done insecurely. + + Let's update the URLs to point to the current canonical endpoints to + avoid any redirects. + + Closes #9630 + +Daniel Stenberg (1 Oct 2022) +- curl_url_set.3: document CURLU_APPENDQUERY proper + + Listed among the other supported flags. + + Reported-by: Robby Simpson + Fixes #9628 + Closes #9629 + +Viktor Szakats (1 Oct 2022) +- Makefile.m32: cleanups and fixes [ci skip] + + - Add `-lcrypt32` once, and add it always for simplicity. + - Delete broken link and reference to the pre-Vista WinIDN add-on. + MS no longer distribute it. + - Delete related `WINIDN_PATH` option. IDN is a system lib since Vista. + - Sync `LIBCARES_PATH` default with the rest of dependencies. + - Delete version numbers from dependency path defaults. + - `libgsasl` package is now called `gsasl`. + - Delete `libexpat` and `libxml2` references. No longer used by curl. + - Delete `Edit the path below...` comments. We recommend to predefine + those envvars instead. + - `libcares.a` is not an internal dependency anymore. Stop using it as + such. + - `windres` `--include-dir` -> `-I`, `-F` -> `--target=` for readability. + - Delete `STRIP`, `CURL_STRIP`, `AR` references from `src/Makefile.m32`. + They were never used. + - Stop to `clean` some objects twice in `src/Makefile.m32`. + - Delete cvs-specific leftovers. + - Finish resource support in examples make file. + - Delete `-I<root>/lib` from examples make file. + - Fix copyright start year in examples make file. + - Delete duplicate `ftpuploadresume` input in examples make file. + - Sync OpenSSL lib order, `SYNC` support, `PROOT` use, dependency path + defaults, variables names and other internal bits between the three + make files. + - `lib/Makefile.m32` accepted custom options via `DLL_LIBS` envvar. This + was lib-specific and possibly accidental. Use `CURL_LDFLAG_EXTRAS_DLL` + envvar for the same effect. + - Fix linking `curl.exe` and examples to wrong static libs with + auto-detected OpenSSL 1.0.2 or earlier. + - Add `-lgdi32` for OpenSSL 1.0.2 and earlier only. + - Add link to Novell LDAP SDK and use a relative default path. Latest + version is from 2016, linked to an outdated OpenSSL 1.0.1. + - Whitespace and comment cleanups. + + TODO in a next commit: + + Delete built-in detection/logic for OpenSSL 1.0.2 and earlier, the Novell + LDAP SDK and the other LDAP SDK (which is _not_ OpenLDAP). Write up the + necessary custom envvars to configure them. + + Closes #9616 + +Daniel Stenberg (30 Sep 2022) +- RELEASE-NOTES: synced + +- [Matt Holt brought this change] + + HTTP3.md: update Caddy example + + Closes #9623 + +- easy: fix the altsvc init for curl_easy_duphandle + + It was using the old #ifdef which nothing sets anymore + + Closes #9624 + +- GHA: build tests in a separate step from the running of them + + ... to make the output smaller for when you want to look at test + failures. + + Removed the examples build from msh3 + + Closes #9619 + +Viktor Szakats (29 Sep 2022) +- ldap: delete stray CURL_HAS_MOZILLA_LDAP reference + + Added in 68b215157fdf69612edebdb220b3804822277822, while adding openldap + support. This is also the single mention of this constant in the source + tree and also in that commit. Based on these, it seems like an accident. + + Delete this reference. + + Reviewed-by: Daniel Stenberg + + Closes #9625 + +- docs: spelling nits + + - MingW -> MinGW (Minimalist GNU for Windows) + - f.e. -> e.g. + - some whitespace and punctuation. + + Reviewed-by: Daniel Stenberg + + Closes #9622 + +Daniel Stenberg (29 Sep 2022) +- [Philip Heiduck brought this change] + + cirrus-ci: add macOS build with m1 + + Signed-off-by: Philip H <47042125+pheiduck@users.noreply.github.com> + + Closes #9565 + +- [Patrick Monnerat brought this change] + + lib: sanitize conditional exclusion around MIME + + The introduction of CURL_DISABLE_MIME came with some additional bugs: + - Disabled MIME is compiled-in anyway if SMTP and/or IMAP is enabled. + - CURLOPT_MIMEPOST, CURLOPT_MIME_OPTIONS and CURLOPT_HTTPHEADER are + conditioned on HTTP, although also needed for SMTP and IMAP MIME mail + uploads. + + In addition, the CURLOPT_HTTPHEADER and --header documentation does not + mention their use for MIME mail. + + This commit fixes the problems above. + + Closes #9610 + +- [Thiago Suchorski brought this change] + + docs: minor grammar fixes + + Closes #9609 + +- CURLSHOPT_UNLOCKFUNC.3: the callback as no 'access' argument + + Probably a copy and paste error from the lock function man page. + + Reported-by: Robby Simpson + Fixes #9612 + Closes #9613 + +- CURLOPT_ACCEPT_ENCODING.3: remove "four" as they are five + + ... instead just list the supported encodings. + + Reported-by: ProceduralMan on github + Fixes #9614 + Closes #9615 + +Dan Fandrich (28 Sep 2022) +- tests: Remove a duplicated keyword + +- docs: document more server names for test files + +Daniel Stenberg (28 Sep 2022) +- altsvc: reject bad port numbers + + The existing code tried but did not properly reject alternative services + using negative or too large port numbers. + + With this fix, the logic now also flushes the old entries immediately + before adding a new one, making a following header with an illegal entry + not flush the already stored entry. + + Report from the ongoing source code audit by Trail of Bits. + + Adjusted test 356 to verify. + + Closes #9607 + +- functypes: provide the recv and send arg and return types + + This header is for providing the argument types for recv() and send() + when built to not use a dedicated config-[platfor].h file. + + Remove the slow brute-force checks from configure and cmake. + + This change also removes the use of the types for select, as they were + not used in code. + + Closes #9592 + +- urlapi: reject more bad characters from the host name field + + Extended test 1560 to verify + + Report from the ongoing source code audit by Trail of Bits. + + Closes #9608 + +- configure: deprecate builds with small curl_off_t + + If curl_off_t turns out to be smaller than 8 bytes, + --with-n64-deprecated needs to be used to allow the build to + continue. This is to highlight the fact that support for such builds is + going away next year. + + Also mentioned in DEPRECATED.md + + Closes #9605 + +- [Patrick Monnerat brought this change] + + http, vauth: always provide Curl_allow_auth_to_host() functionality + + This function is currently located in the lib/http.c module and is + therefore disabled by the CURL_DISABLE_HTTP conditional token. + + As it may be called by TLS backends, disabling HTTP results in an + undefined reference error at link time. + + Move this function to vauth/vauth.c to always provide it and rename it + as Curl_auth_allowed_to_host() to respect the vauth module naming + convention. + + Closes #9600 + +- ngtcp2: fix C89 compliance nit + +- openssl: make certinfo available for QUIC + + Curl_ossl_certchain() is now an exported function in lib/vtls/openssl.c that + can also be used from quiche.c and ngtcp2.c to get the cert chain for QUIC + connections as well. + + The *certchain function was moved to the top of the file for this reason. + + Reported-by: Eloy Degen + Fixes #9584 + Closes #9597 + +- RELEASE-NOTES: synced + +- DEPRECATE.md: Support for systems without 64 bit data types + + Closes #9604 + +- [Patrick Monnerat brought this change] + + tests: skip mime/form tests when mime is not built-in + + Closes #9596 + +- url: rename function due to name-clash in Watt-32 + + Follow-up to 2481dbe5f4f58 and applies the change the way it was + intended. + +Viktor Szakats (26 Sep 2022) +- windows: adjust name of two internal public functions + + According to `docs/INTERNALS.md`, internal function names spanning source + files start with uppercase `Curl_`. Bring these two functions in + alignment with this. + + This also stops exporting them from `libcurl.dll` in autotools builds. + + Reviewed-by: Daniel Stenberg + + Closes #9598 + +Daniel Stenberg (26 Sep 2022) +- [Gisle Vanem brought this change] + + url: rename function due to name-clash in Watt-32 + + Since the commit 764c958c52edb427f39, there was a new function called + resolve_ip(). This clashes with an internal function in Watt-32. + + Closes #9585 + +Jay Satiro (26 Sep 2022) +- schannel: ban server ALPN change during recv renegotiation + + By the time schannel_recv is renegotiating the connection, libcurl has + already decided on a protocol and it is too late for the server to + select a protocol via ALPN except for the originally selected protocol. + + Ref: https://github.com/curl/curl/issues/9451 + + Closes https://github.com/curl/curl/pull/9463 + +Daniel Stenberg (26 Sep 2022) +- url: a zero-length userinfo part in the URL is still a (blank) user + + Adjusted test 1560 to verify + + Reported-by: Jay Satiro + + Fixes #9088 + Closes #9590 + +Viktor Szakats (25 Sep 2022) +- autotools: allow --enable-symbol-hiding with windows + + This local autotools logic was put in place in + 9e24b9c7afbcb81120af4cf3f6cdee49a06d8224 (in 2012) which disabled it for + Windows unconditionally. Testing reveals that it actually works with + tested toolchains (mingw-w64 and CI ones), so let's allow this build + feature on that platform. Bringing this in sync with CMake, which already + supported this. + + Reviewed-by: Jay Satiro + + Closes #9586 + +- autotools: reduce brute-force when detecting recv/send arg list + + autotools uses brute-force to detect `recv`/`send`/`select` argument + lists, by interating through _all_ argument type combinations on each + `./configure` run. This logic exists since + 01fa02d0b545e1433dced2430561f8c0c72b74a9 (from 2006) and was a bit later + extended with Windows support. + + This results in a worst-case number of compile + link cycles as below: + - `recv`: 96 + - `send`: 192 + - `select`: 60 + Total: 348 (the number of curl C source files is 195, for comparison) + + Notice that e.g. curl-for-win autotools builds require two `./configure` + invocations, doubling these numbers. + + `recv` on Windows was especially unlucky because `SOCKET` (the correct + choice there) was listed _last_ in one of the outer trial loops. This + resulted in lengthy waits while autotools was trying all invalid + combinations first, wasting cycles, disk writes and slowing down + iteration. + + This patch reduces the amount of idle work by reordering the tests in + a way to succeed first on a well-known platform such as Windows, and + also on non-Windows by testing for POSIX prototypes first, on the + assumption that these are the most likely candidates these days. (We do + not touch `select`, where the order was already optimal for these + platforms.) + + For non-Windows, this means to try a return value of `ssize_t` first, + then `int`, reordering the buffer argument type to try `void *` first, + then `byte *`, and prefer the `const` flavor with `send`. If we are + here, also stop testing for `SOCKET` type in non-Windows builds. + + After the patch, detection on Windows is instantaneous. It should also be + faster on popular platforms such as Linux and BSD-based ones. + + If there are known-good variations for other platforms, they can also be + fast-tracked like above, given a way to check for that platform inside + the autotools logic. + + Reviewed-by: Daniel Stenberg + + Closes #9591 + +Daniel Stenberg (23 Sep 2022) +- TODO: Provide the error body from a CONNECT response + + Spellchecked-by: Jay Satiro + + Closes #9513 + Closes #9581 + +Viktor Szakats (23 Sep 2022) +- windows: autotools .rc warnings fixup + + Move `LT_LANG([Windows Resource])` after `XC_LIBTOOL`, fixing: + + - Warnings when running `autoreconf -fi`. + + - Warning when compiling .rc files: + libtool: compile: unable to infer tagged configuration + libtool: error: specify a tag with '--tag' + + Follow up to 6de7322c03d5b4d91576a7d9fc893e03cc9d1057 + Ref: https://github.com/curl/curl/pull/9521#issuecomment-1256291156 + + Suggested-by: Patrick Monnerat + Closes #9582 + +Daniel Stenberg (23 Sep 2022) +- [Randall S. Becker brought this change] + + curl_setup: disable use of FLOSS for 64-bit NonStop builds + + Older 32-bit builds currently need FLOSS. This dependency may be removed + in future OS releases. + + Signed-off-by: Randall S. Becker <randall.becker@nexbridge.ca> + + Closes #9575 + +- [Patrick Monnerat brought this change] + + tool: remove dead code + + Add a debug assertion to verify protocols included/excluded in a set + are always tokenized. + + Follow-up to commit 677266c. + + Closes #9576 + +- [Patrick Monnerat brought this change] + + lib: prepare the incoming of additional protocols + + Move the curl_prot_t to its own conditional block. Introduce symbol + PROTO_TYPE_SMALL to control it. + + Fix a cast in a curl_prot_t assignment. + Remove an outdated comment. + + Follow-up to cd5ca80. + + Closes #9534 + +- msh3: change the static_assert to make the code C89 + +- bearssl: make it proper C89 compliant + +- curl-compilers.m4: for gcc + want warnings, set gnu89 standard + + To better verify that the code is C89 + + Closes #9542 + +- [Patrick Monnerat brought this change] + + lib517: fix C89 constant signedness + + In C89, positive integer literals that overflow an int but not an + unsigned int may be understood as a negative int. + + lib517.c:129:3: warning: this decimal constant is unsigned only in ISO C90 + {"Sun, 06 Nov 2044 08:49:37 GMT", 2362034977 }, + ^ + + Closes #9572 + +- mprintf: use snprintf if available + + This is the single place in libcurl code where it uses the "native" + s(n)printf() function. Used for writing floats. The use has been + reviewed and vetted and uses a HUGE target buffer, but switching to + snprintf() still makes this safer and removes build-time warnings. + + Reported-by: Philip Heiduck + + Fixes #9569 + Closes #9570 + +- docs: tag curl options better in man pages + + As it makes them links in the HTML versions. + + Verified by the extended test 1176 + +- symbols-in-versions: CURLOPT_ENCODING is deprecated since 7.21.6 + +- manpage-syntax.pl: all libcurl option symbols should be \fI-tagged + + ... as that makes them links to their corresponding man page. + + This script is used for test 1173. + + Closes #9574 + +- RELEASE-NOTES: synced + +- [Patrick Monnerat brought this change] + + tool: remove protocol count limitation + + Replace bit mask protocol sets by null-terminated arrays of protocol + tokens. These are the addresses of the protocol names returned by + curl_version_info(). + + Protocol names are sorted case-insensitively before output to satisfy CI + tests matches consistency. + + The protocol list returned by curl_version_info() is augmented with all + RTMP protocol variants. + + Test 1401 adjusted for new alpha ordered output. + + Closes #9546 + +- test972: verify the output without using external tool + + It seems too restrictive to assume and use an external tool to verify + the JSON. This now verifies the outut byte per byte. We could consider + building a local "JSON verifyer" in a future. + + Remove 'jsonlint' from the CI job. + + Reported-by: Marcel Raad + Fixes #9563 + Closes #9564 + +- hostip: lazily wait to figure out if IPv6 works until needed + + The check may take many milliseconds, so now it is performed once the + value is first needed. Also, this change makes sure that the value is + not used if the resolve is set to be IPv4-only. + + Closes #9553 + +- curl.h: fix mention of wrong error code in comment + + The same error and comment were also used and is now corrected in + CURLOPT_SSH_KEYFUNCTION.3 + +- symbol-scan.pl: scan and verify .3 man pages + + This script now also finds all .3 man pages in docs/include and + docs/include/opts, extracts all uses of CURL* symbols and verifies that all + symbols mentioned in docs are defined in public headers. + + A "global symbol" is one of those matching a known prefix and the script makes + an attempt to check all/most of them. Just using *all* symbols that match + CURL* proved matching a little too many other references as well and turned + difficult turning into something useful. + + Closes #9544 + +- symbols-in-versions: add missing LIBCURL* symbols + +- symbol-scan.pl: also check for LIBCURL* symbols + + Closes #9544 + +- docs/libcurl/symbols-in-versions: add several missing symbols + +- test1119: scan all public headers + + Previously this test only scanned a subset of the headers, which made us + accidentally miss symbols that were provided in the others. Now, the script + iterates over all headers present in include/curl. + + Closes #9544 + +- [Patrick Monnerat brought this change] + + examples/chkspeed: improve portability + + The example program chkspeed uses strncasecmp() which is not portable + across systems. Replace calls to this function by tests on characters. + + Closes #9562 + +- easy: fix the #include order + + The mentioned "last 3 includes" order should be respected. easy_lock.h should + be included before those three. + + Reported-by: Yuriy Chernyshov + Fixes #9560 + Closes #9561 + +- docs: spellfixes + + Pointed by the new CI job + +- GHA: spellcheck + + This spellchecker checks markdown files. For this reason this job + converts all man pages in the repository to markdown with pandoc before + the check runs. + + The perl script 'cleanspell' filters out details from the man page in + the process, to avoid the spellchecker trying to spellcheck things it + can't. Like curl specific symbols and the SYNOPSIS and EXAMPLE sections + of libcurl man pages. + + The spell checker does not check words in sections that are within pre, + strong and em tags. + + 'spellcheck.words' is a custom word list with additional accepted words. + + Closes #9523 + +- connect: fix the wrong error message on connect failures + + The "Failed to connect to" message after a connection failure would + include the strerror message based on the presumed previous socket + error, but in times it seems that error number is not set when reaching + this code and therefore it would include the wrong error message. + + The strerror message is now removed from here and the curl_easy_strerror + error is used instead. + + Reported-by: Edoardo Lolletti + Fixes #9549 + Closes #9554 + +- httpput-postfields.c: shorten string for C89 compliance + + httpput-postfields.c:41:3: error: string length ‘522’ is greater than the length ‘509’ ISO C90 compilers are required to support [-Woverlength-strings] + 41 | "this chapter."; + | ^~~~~~~~~~~~~~~ + + Closes #9555 + +- ws: fix a C89 compliance nit + + Closes #9541 + +- [Patrick Monnerat brought this change] + + unit test 1655: make it C89-compliant + + Initializations performed in unit test 1655 use automatic variables in + aggregates and thus can only be computed at run-time. Using gcc in C89 + dialect mode produces warning messages like: + + unit1655.c:96:7: warning: initializer element is not computable at load time [-Wpedantic] + 96 | { toolong, DOH_DNS_NAME_TOO_LONG }, /* expect early failure */ + | ^~~~~~~ + + Fix the problem by converting these automatic pointer variables to + static arrays. + + Closes #9551 + +- [Tobias Schaefer brought this change] + + curl_strequal.3: fix typo + + Closes #9548 + +- [Dmitry Karpov brought this change] + + resolve: make forced IPv4 resolve only use A queries + + This protects IPv4-only transfers from undesired bad IPv6-related side + effects and make IPv4 transfers in dual-stack libcurl behave the same + way as in IPv4 single-stack libcurl. + + Closes #9540 + +- RELEASE-NOTES: synced + +- winbuild/MakefileBuild.vc: handle spaces in libssh(2) include paths + + Patched-by: Mark Itzcovitz + Bug: https://curl.se/mail/lib-2022-09/0038.html + + Closes #9536 + +- TODO: Reduce CA certificate bundle reparsing + + By adding some sort of cache. + + Reported-by: Michael Drake + Closes #9379 + Closes #9538 + +Marc Hoersken (19 Sep 2022) +- CI/GHA: cancel outdated CI runs on new PR changes + + Avoid letting outdated CI runs continue if a PR receives + new changes. Outside a PR we let them continue running + by tying the concurrency to the commit hash instead. + + Also only let one CodeQL or Hacktoberfest job run at a time. + + Other CI platforms we use have this build in, but GitHub + unfortunately neither by default nor with a simple option. + + This saves CI resources and therefore a little energy. + + Approved-by: Daniel Stenberg + Approved-by: Max Dymond + Closes #9533 + +Daniel Stenberg (19 Sep 2022) +- docs: fix proselint complaints + +- GHA: run proselint on markdown files + + Co-authored-by: Marc Hörsken + + Closes #9520 + +- lib: the number four in a sequence is the "fourth" + + Spelling is hard + + Closes #9535 + +- [John Bampton brought this change] + + misc: fix spelling in two source files + + Closes #9529 + +Viktor Szakats (18 Sep 2022) +- windows: add .rc support to autotools builds + + After this update autotools builds will compile and link `.rc` resources + to Windows executables. Bringing this feature on par with CMake and + Makefile.m32 builds. And also making it unnecessary to improvise these + steps manually, while monkey patching build files, e.g. [0]. + + You can customize the resource compiler via the `RC` envvar, and its + options via `RCFLAGS`. + + This harmless warning may appear throughout the build, even though the + autotools manual documents [1] `RC` as a valid tag, and it fails when + omitting one: + `libtool: error: ignoring unknown tag RC` + + [0] https://github.com/curl/curl-for-win/blob/535f19060d4b708f72e75dd849409ce50baa1b84/curl-autotools.sh#L376-L382 + [1] https://www.gnu.org/software/libtool/manual/html_node/Tags.html + + Closes #9521 + +Marc Hoersken (18 Sep 2022) +- CI/linkcheck: only run if a Markdown file is changed + + This saves CI resources and therefore a little energy. + + Reviewed-by: Max Dymond + Closes #9531 + +- README.md: add GHA status badges for Linux and macOS builds + + This makes sense now that Linux builds are being consolidated. + + Approved-by: Daniel Stenberg + Closes #9530 + + [skip ci] + +Daniel Stenberg (17 Sep 2022) +- misc: null-terminate + + Make use of this term consistently. + + Closes #9527 + +Marc Hoersken (17 Sep 2022) +- CI/GHA: merge intel CC and more TLS libs into linux workflow + + Continue work on merging all Linux workflows into one file. + + Reviewed-by: Max Dymond + Follow up to #9501 + Closes #9514 + +Daniel Stenberg (17 Sep 2022) +- [Patrick Monnerat brought this change] + + lib1597: make it C89-compliant again + + Automatic variable addresses cannot be used in an initialisation + aggregate. + + Follow-up to 9d51329 + + Reported-by: Daniel Stenberg + Fixes: #9524 + Closes #9525 + +- tool_libinfo: silence "different 'const' qualifiers" in qsort() + + MSVC 15.0.30729.1 warned about it + + Follow-up to dd2a024323dcc + + Closes #9522 + +- [Patrick Monnerat brought this change] + + docs: tell about disabled protocols in CURLOPT_*PROTOCOLS_STR. + + Disabled protocols are now handled as if they were unknown. + Also update the possible protocol list. + +- [Patrick Monnerat brought this change] + + cli tool: do not use disabled protocols + + As they are now rejected by the library, take care of not passing + disabled protocol names to CURLOPT_PROTOCOLS_STR and + CURLOPT_REDIR_PROTOCOLS_STR. + + Rather than using the CURLPROTO_* constants, dynamically assign protocol + numbers based on the order they are listed by curl_version_info(). + + New type proto_set_t implements prototype bit masks: it should therefore + be large enough to accomodate all library-enabled protocols. If not, + protocol numbers beyond the bit count of proto_set_t are recognized but + "inaccessible": when used, a warning is displayed and the value is + ignored. Should proto_set_t overflows, enabled protocols are reordered to + force those having a public CURLPROTO_* representation to be accessible. + + Code has been added to subordinate RTMP?* protocols to the presence of + RTMP in the enabled protocol list, being returned by curl_version_info() + or not. + +- [Patrick Monnerat brought this change] + + setopt: use the handler table for protocol name to number conversions + + This also returns error CURLE_UNSUPPORTED_PROTOCOL rather than + CURLE_BAD_FUNCTION_ARGUMENT when a listed protocol name is not found. + + A new schemelen parameter is added to Curl_builtin_scheme() to support + this extended use. + + Note that disabled protocols are not recognized anymore. + + Tests adapted accordingly. + + Closes #9472 + +- altsvc: use 'h3' for h3 + + Since the official and real version has been out for a while now and servers + are deployed out there using it, there is no point in sticking to h3-29. + + Reported-by: ウさん + Fixes #9515 + Closes #9516 + +Jay Satiro (16 Sep 2022) +- [chemodax brought this change] + + winbuild: Use NMake batch-rules for compilation + + - Invoke cl compiler once for each group of .c files. + + This is significantly improves compilation time. For example in my + environment: 40 s --> 20 s. + + Prior to this change cl was invoked per .c file. + + Closes https://github.com/curl/curl/pull/9512 + +Daniel Stenberg (16 Sep 2022) +- ws: the infof() flags should be %zu + + Follow-up to e5e9e0c5e49ae0 + + Closes #9518 + +- curl: warn for --ssl use, considered insecure + + Closes #9519 + +- [Sergey Bronnikov brought this change] + + curl_escape.3: fix typo + + lengthf -> length + + Closes #9517 + +- mailmap: merge Philip Heiduck's two addresses into one + +- test1948: verify PUT + POST reusing the same handle + + Reproduced #9507, verifies the fix + +- setopt: when POST is set, reset the 'upload' field + + Reported-by: RobBotic1 on github + Fixes #9507 + Closes #9511 + +Marc Hoersken (15 Sep 2022) +- github: initial CODEOWNERS setup for CI configuration + + Reviewed-by: Daniel Stenberg + Reviewed-by: Marcel Raad + Reviewed-by: Max Dymond + + Closes #9505 + + [skip ci] + +- [Philip Heiduck brought this change] + + CI: optimize some more dependencies install + + Signed-off-by: Philip Heiduck <pheiduck@Philips-MBP.lan> + + Closes #9500 + +- CI/GHA: merge event-based and NSS into new linux workflow + + Continue work on merging all Linux workflows into one file. + + Follow up to #9501 + Closes #9506 + +Daniel Stenberg (15 Sep 2022) +- include/curl/websockets.h: add extern "C" for C++ + + Reported-by: n0name321 on github + Fixes #9509 + Closes #9510 + +- lib1560: extended to verify detect/reject of unknown schemes + + ... when no guessing is allowed. + +- urlapi: detect scheme better when not guessing + + When the parser is not allowed to guess scheme, it should consider the + word ending at the first colon to be the scheme, independently of number + of slashes. + + The parser now checks that the scheme is known before it counts slashes, + to improve the error messge for URLs with unknown schemes and maybe no + slashes. + + When following redirects, no scheme guessing is allowed and therefore + this change effectively prevents redirects to unknown schemes such as + "data". + + Fixes #9503 + +- strerror: improve two URL API error messages + +Marc Hoersken (14 Sep 2022) +- CI/GHA: merge bearssl and hyper into initial linux workflow + + Begin work on merging all Linux workflows into one file. + + Closes #9501 + +Daniel Stenberg (14 Sep 2022) +- RELEASE-NOTES: synced + +- cmake: define BUILDING_LIBCURL in lib/CMakeLists, not config.h + + Since the config file might also get included by the tool code at times. + This syncs with how other builds do it. + + Closes #9498 + +- tool_hugehelp: make hugehelp a blank macro when disabled + + Closes #9485 + +- getparameter: return PARAM_MANUAL_REQUESTED for -M even when disabled + + ... to improve the output in this situation. Now it doesn't say "option + unknown" anymore. + + Closes #9485 + +- setopt: fix compiler warning + + Follow-up to cd5ca80f00d2 + + closes #9502 + +- [Philip Heiduck brought this change] + + CI: skip make, do make install at once for dependencies + + Signed-off-by: Philip Heiduck <pheiduck@Philips-MBP.lan> + + Closes #9477 + +- formdata: typecast the va_arg return value + + To avoid "enumerated type mixed with another type" warnings + + Follow-up from 0f52dd5fd5aa3592691a + + Closes #9499 + +- RELEASE-PROCEDURE.md: mention patch releases + + - When to make them and how to argue for them + - Refreshed the release date list + + Closes #9495 + +- urldata: use a curl_prot_t type for storing protocol bits + + This internal-use-only storage type can be bumped to a curl_off_t once + we need to use bit 32 as the previous 'unsigned int' can no longer hold + them all then. + + The websocket protocols take bit 30 and 31 so they are the last ones + that fit within 32 bits - but cannot properly be exported through APIs + since those use *signed* 32 bit types (long) in places. + + Closes #9481 + +- [zhanghu on xiaomi brought this change] + + formdata: fix warning: 'CURLformoption' is promoted to 'int' + + curl/lib/formdata.c: In function 'FormAdd': + curl/lib/formdata.c:249:31: warning: 'CURLformoption' is promoted to 'int' when passed through '...' + 249 | option = va_arg(params, CURLformoption); + | ^ + curl/lib/formdata.c:249:31: note: (so you should pass 'int' not 'CURLformoption' to 'va_arg') + curl/lib/formdata.c:249:31: note: if this code is reached, the program will abort + + Closes #9484 + +- CURLOPT_CONNECT_ONLY.3: for ws(s) as well + + and correct the version number for when that support comes. Even if it + is still experimental for WebSocket. + + Closes #9487 + +- tool_operate: avoid a few #ifdefs for disabled-libcurl builds + + By providing empty macros in the header file instead, the code gets + easier to read and yet is disabled on demand. + + Closes #9486 + +- [a1346054 on github brought this change] + + scripts: use `grep -E` instead of `egrep` + + egrep is deprecated + + Closes #9491 + +- [Hayden Roche brought this change] + + wolfSSL: fix session management bug. + + Prior to this commit, non-persistent pointers were being used to store + sessions. When a WOLFSSL object was then freed, that freed the session + it owned, and thus invalidated the pointer held in curl's cache. This + commit makes it so we get a persistent (deep copied) session pointer + that we then add to the cache. Accordingly, wolfssl_session_free, which + was previously a no-op, now needs to actually call SSL_SESSION_free. + + This bug was discovered by a wolfSSL customer. + + Closes #9492 + +- docs: use "WebSocket" in singular + + This is how the RFC calls the protocol. Also rename the file in docs/ to + WEBSOCKET.md in uppercase to match how we have done it for many other + protocol docs in similar fashion. + + Add the WebSocket docs to the tarball. + + Closes #9496 + +Marcel Raad (12 Sep 2022) +- ws: fix build without `USE_WEBSOCKETS` + + The curl.h include is required unconditionally. + +- ws: add missing curl.h include + + A conflict between commits 664249d0952 and e5839f4ee70 broke the build. + +Daniel Stenberg (12 Sep 2022) +- ws: fix an infof() call to use %uz for size_t output + + Detected by Coverity, CID 1514665. + + Closes #9480 + +Marcel Raad (12 Sep 2022) +- curl_setup: include only system.h instead of curl.h + + As done before commit 9506d01ee50. + + Ref: https://github.com/curl/curl/pull/9375#discussion_r957010158 + Closes https://github.com/curl/curl/pull/9453 + +- lib: add missing limits.h includes + + Closes https://github.com/curl/curl/pull/9453 + +- lib and tests: add missing curl.h includes + + Closes https://github.com/curl/curl/pull/9453 + +- curl_setup: include curl.h after platform setup headers + + The platform setup headers might set definitions required for the + includes in curl.h. + + Ref: https://github.com/curl/curl/pull/9375#discussion_r956998269 + Closes https://github.com/curl/curl/pull/9453 + +Daniel Stenberg (12 Sep 2022) +- [Benjamin Loison brought this change] + + docs: correct missing uppercase in Markdown files + + To detect these typos I used: + + ``` + clear && grep -rn '\. [a-z]' . | uniq | grep -v '\. lib' | grep -v '[0-9]\. [a-z]' | grep -v '\.\. [a-z]' | grep -v '\. curl' | grep -v 'e.g. [a-z]' | grep -v 'eg. [a-z]' | grep -v '\etc. [a-z]' | grep -v 'i.e\. [a-z]' | grep --color=always '\. [a-z]' | grep '\.md' + ``` + + Closes #9474 + +- tool_setopt: use better English in --libcurl source comments + + Like this: + + XYZ was set to an object pointer + ABC was set to a function pointer + + Closes #9475 + +- setopt: make protocol2num use a curl_off_t for the protocol bit + + ... since WSS does not fit within 32 bit. + + Bug: https://github.com/curl/curl/pull/9467#issuecomment-1243014887 + Closes #9476 + +- RELEASE-NOTES: synced + +- configure: polish the grep -E message a bit further + + Suggested-by: Emanuele Torre + Closes #9473 + +- GHA: add a gcc-11 -O3 build using OpenSSL + + Since -O3 might trigger other warnings + + Closes #9454 + +- [Patrick Monnerat brought this change] + + content_encoding: use writer struct subclasses for different encodings + + The variable-sized encoding-specific storage of a struct contenc_writer + currently relies on void * alignment that may be insufficient with + regards to the specific storage fields, although having not caused any + problems yet. + + In addition, gcc 11.3 issues a warning on access to fields of partially + allocated structures that can occur when the specific storage size is 0: + + content_encoding.c: In function ‘Curl_build_unencoding_stack’: + content_encoding.c:980:21: warning: array subscript ‘struct contenc_writer[0]’ is partly outside array bounds of ‘unsigned char[16]’ [-Warray-bounds] + 980 | writer->handler = handler; + | ~~~~~~~~~~~~~~~~^~~~~~~~~ + In file included from content_encoding.c:49: + memdebug.h:115:29: note: referencing an object of size 16 allocated by ‘curl_dbg_calloc’ + 115 | #define calloc(nbelem,size) curl_dbg_calloc(nbelem, size, __LINE__, __FILE__) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + content_encoding.c:977:60: note: in expansion of macro ‘calloc’ + 977 | struct contenc_writer *writer = (struct contenc_writer *)calloc(1, sz); + + To solve both these problems, the current commit replaces the + contenc_writer/params structure pairs by "subclasses" of struct + contenc_writer. These are structures that contain a contenc_writer at + offset 0. Proper field alignment is therefore handled by the compiler and + full structure allocation is performed, silencing the warnings. + + Closes #9455 + +- configure: correct the wording when checking grep -E + + The check first checks that grep -E works, and only as a fallback tries + to find and use egrep. egrep is deprecated. + + This change only corrects the output wording, not the checks themselves. + + Closes #9471 + +Viktor Szakats (10 Sep 2022) +- websockets: sync prototypes in docs with implementation [ci skip] + + Docs for the new send/recv functions synced with the committed versions + of these. + + Closes #9470 + +Daniel Stenberg (10 Sep 2022) +- setopt: make protocols2num() work with websockets + + So that CURLOPT_PROTOCOLS_STR and CURLOPT_REDIR_PROTOCOLS_STR can + specify those as well. + + Reported-by: Patrick Monnerat + Bug: https://curl.se/mail/lib-2022-09/0016.html + Closes #9467 + +- curl/websockets.h: remove leftover bad typedef + + Just a leftover trace of a development thing that did not stay like + that. + + Reported-by: Marc Hörsken + Fixes #9465 + Cloes #9466 + +Marcel Raad (10 Sep 2022) +- [Orgad Shaneh brought this change] + + fix Cygwin/MSYS compilation + + _getpid is Windows API. On Cygwin variants it should remain getpid. + + Fixes #8220 + Closes #9255 + +Marc Hoersken (10 Sep 2022) +- GHA: prepare workflow merge by aligning structure again + + Closes #9413 + +Daniel Stenberg (9 Sep 2022) +- docs: the websockets symbols are added in 7.86.0 + + Nothing else + + Closes #9459 + +- tests/libtest/Makefile.inc: fixup merge conflict mistake + +- EXPERIMENTAL.md: add WebSockets + +- appveyor: enable websockets + +- cirrus: enable websockets in the windows builds + +- GHA: add websockets to macos, openssl3 and hyper builds + +- tests: add websockets tests + + - add websockets support to sws + - 2300: first very basic websockets test + - 2301: first libcurl test for ws (not working yet) + - 2302: use the ws callback + - 2303: test refused upgrade + +- curl_ws_meta: initial implementation + +- curl_ws_meta.3: added docs + +- ws: initial websockets support + + Closes #8995 + +- version: add ws + wss + +- libtest/lib1560: test basic websocket URL parsing + +- configure: add --enable-websockets + +- docs/WebSockets.md: docs + +- test415: verify Content-Length parser with control code + negative value + +- strtoofft: after space, there cannot be a control code + + With the change from ISSPACE() to ISBLANK() this function no longer + deals with (ignores) control codes the same way, which could lead to + this function returning unexpected values like in the case of + "Content-Length: \r-12354". + + Follow-up to 6f9fb7ec2d7cb389a0da5 + + Detected by OSS-fuzz + Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=51140 + Assisted-by: Max Dymond + Closes #9458 + +- headers: reset the requests counter at transfer start + + If not, reusing an easy handle to do a subsequent transfer would + continue the counter from the previous invoke, which then would make use + of the header API difficult/impossible as the request counter + mismatched. + + Add libtest 1947 to verify. + + Reported-by: Andrew Lambert + Fixes #9424 + Closes #9447 + +Jay Satiro (8 Sep 2022) +- header: define public API functions as extern c + + Prior to this change linker errors would occur if curl_easy_header or + curl_easy_nextheader was called from a C++ unit. + + Bug: https://github.com/curl/curl/issues/9424#issuecomment-1238818007 + Reported-by: Andrew Lambert + + Closes https://github.com/curl/curl/pull/9446 + +Daniel Stenberg (8 Sep 2022) +- http2: make nghttp2 less picky about field whitespace + + In nghttp2 1.49.0 it returns error on leading and trailing whitespace in + header fields according to language in the recently shipped RFC 9113. + + nghttp2 1.50.0 introduces an option to switch off this strict check and + this change enables this option by default which should make curl behave + more similar to how it did with nghttp2 1.48.0 and earlier. + + We might want to consider making this an option in the future. + + Closes #9448 + +- RELEASE-NOTES: synced + + And bump to 7.86.0 for the pending next release + +- [Michael Heimpold brought this change] + + ftp: ignore a 550 response to MDTM + + The 550 is overused as a return code for multiple error case, e.g. + file not found and/or insufficient permissions to access the file. + + So we cannot fail hard in this case. + + Adjust test 511 since we now fail later. + Add new test 3027 which check that when MDTM failed, but the file could + actually be retrieved, that in this case no filetime is provided. + + Reported-by: Michael Heimpold + Fixes #9357 + Closes #9387 + +- urlapi: leaner with fewer allocs + + Slightly faster with more robust code. Uses fewer and smaller mallocs. + + - remove two fields from the URL handle struct + - reduce copies and allocs + - use dynbuf buffers more instead of custom malloc + copies + - uses dynbuf to build the host name in reduces serial alloc+free within + the same function. + - move dedotdotify into urlapi.c and make it static, not strdup the input + and optimize it by checking for . and / before using strncmp + - remove a few strlen() calls + - add Curl_dyn_setlen() that can "trim" an existing dynbuf + + Closes #9408 + +Jay Satiro (7 Sep 2022) +- setup-win32: no longer define UNICODE/_UNICODE implicitly + + - If UNICODE or _UNICODE is defined but the other isn't then error + instead of implicitly defining it. + + As Marcel pointed out it is too late at this point to make such a define + because Windows headers may already be included, so likely it never + worked. We never noticed because build systems that can make Windows + Unicode builds always define both. If one is defined but not the other + then something went wrong during the build configuration. + + Bug: https://github.com/curl/curl/pull/9375#discussion_r956545272 + Reported-by: Marcel Raad + + Closes https://github.com/curl/curl/pull/9384 + +Dan Fandrich (6 Sep 2022) +- tests: fix tag syntax errors in test files + +Marc Hoersken (6 Sep 2022) +- lib: add required Win32 setup definitions in setup-win32.h + + Assisted-by: Jay Satiro + Reviewed-by: Marcel Raad + + Follow up to #9312 + Closes #9375 + +Daniel Stenberg (6 Sep 2022) +- pingpong: extend the response reading error with errno + + To help diagnosing the cause of the problem. + + See #9380 + Closes #9443 + +- curl-compilers.m4: use -O2 as default optimize for clang + + Not -Os + + Closes #9444 + +- tool_operate: fix msnprintfing the error message + + Follow-up to 7be53774c41c59b47075fba + + Coverity CID 1513717 pointed out that we cannot use sizeof() on the + error buffer anymore. + + Closes #9440 + +- [Emanuele Torre brought this change] + + curl_ctype: add space around <= operator in ISSPACE macro + + Follow-up to f65f750 + + Closes #9441 + +- CURLOPT_PROXY_SSLCERT_BLOB.3: this is for HTTPS proxies + + The 'protocols' listed were previously wrong. + + Reported-by: ProceduralMan on github + Fixes #9434 + Closes #9435 + +- curl_ctype: convert to macros-only + + This no longer provide functions, only macros. Runs faster and produces + smaller output. + + The biggest precaution this change brings: + + DO NOT use post/pre-increments when passing arguments to the macros. + + Closes #9429 + +- misc: ISSPACE() => ISBLANK() + + Instances of ISSPACE() use that should rather use ISBLANK(). I think + somewhat carelessly used because it sounds as if it checks for space or + whitespace, but also includes %0a to %0d. + + For parsing purposes, we should only accept what we must and not be + overly liberal. It leads to surprises and surprises lead to bad things. + + Closes #9432 + +- ctype: remove all use of <ctype.h>, use our own versions + + Except in the test servers. + + Closes #9433 + +Marc Hoersken (5 Sep 2022) +- cmake: skip superfluous hex2dec conversion using math expr + + CMake seems to be able to compare two hex values just fine. + Also make sure CURL_TARGET_WINDOWS_VERSION is respected. + + Assisted-by: Marcel Raad + Reviewed-by: Viktor Szakats + Reported-by: Keitagit-kun on github + + Follow up to #9312 + Fixes #9406 + Closes #9411 + +Daniel Stenberg (5 Sep 2022) +- curl_easy_pause.3: unpausing is as fast as possible + + Reported-by: ssdbest on github + Fixes #9410 + Closes #9430 + +- CURLOPT_DNS_INTERFACE.3: mention it works for almost all protocols + + Except file. + + Reported-by: ProceduralMan on github + Fixes #9427 + Closes #9428 + +- NPN: remove support for and use of + + Next Protocol Negotiation is a TLS extension that was created and used + for agreeing to use the SPDY protocol (the precursor to HTTP/2) for + HTTPS. In the early days of HTTP/2, before the spec was finalized and + shipped, the protocol could be enabled using this extension with some + servers. + + curl supports the NPN extension with some TLS backends since then, with + a command line option `--npn` and in libcurl with + `CURLOPT_SSL_ENABLE_NPN`. + + HTTP/2 proper is made to use the ALPN (Application-Layer Protocol + Negotiation) extension and the NPN extension has no purposes + anymore. The HTTP/2 spec was published in May 2015. + + Today, use of NPN in the wild should be extremely rare and most likely + totally extinct. Chrome removed NPN support in Chrome 51, shipped in + June 2016. Removed in Firefox 53, April 2017. + + Closes #9307 + +- RELEASE-NOTES: synced + + and bump the tentative next release version to 7.85.1 + +- [Samuel Henrique brought this change] + + configure: fail if '--without-ssl' + explicit parameter for an ssl lib + + A side effect of a previous change to configure (576e507c78bdd2ec88) + exposed a non-critical issue that can happen if configure is called with + both '--without-ssl' and some parameter setting the use of a ssl library + (e.g. --with-gnutls). The configure script would end up assuming this is + a MultiSSL build, due to the way the case statement is written. + + I have changed the order of the variables in the string concatenation + for the case statement and also tweaked the options so that + --without-ssl never turns the build into a MultiSSL one and also clearly + stating that there are conflicting parameters if the user sets it like + described above. + + Closes #9414 + +- tests/certs/scripts: insert standard curl source headers + + ... including the SPDX-License-Identifier. + + These omissions were not detected by the RUEUSE CI job nor the copyright.pl + scanners because we have a general wildcard in .reuse/dep5 for + "tests/certs/*". + + Reported-by: Samuel Henrique + Fixes #9417 + Closes #9420 + +- [Samuel Henrique brought this change] + + docs: remove mentions of deprecated '--without-openssl' config parameter + + Closes #9415 + +- [Samuel Henrique brought this change] + + manpages: Fix spelling of "allows to" -> "allows one to" + + References: + https://salsa.debian.org/lintian/lintian/-/blob/master/tags/t/typo-in-manual-page.tag + https://english.stackexchange.com/questions/60271/grammatical-complements-for-allow/60285#60285 + + Closes #9419 + +- [Samuel Henrique brought this change] + + CURLOPT_WILDCARDMATCH.3: Fix backslash escaping under single quotes + + Lintian (on Debian) has been complaining about this for a while but + I didn't bother initially as the groff parser that we use is not + affected by this. + + But I have now noticed that the online manpage is affected by it: + https://curl.se/libcurl/c/CURLOPT_WILDCARDMATCH.html + + (I'm using double quotes for quoting-only down below) + + The section that should be parsed as "'\'" ends up being parsed as + "'´". + + This is due to roffit not parsing "'\\'" correctly, which is fine + as the "correct" way of writing "'\'" is "'\e'" instead. + + Note that this fix is not enough to fix the online manpage at + curl's website, as roffit seems to parse it wrongly either way. + + My intent is to at least fix the manpage so that roffit can + be changed to parse "'\e'" correctly (although I suggest making + roffit parse both ways correctly, since that's what groff does). + + More details at: + https://bugs.debian.org/966803 + https://salsa.debian.org/lintian/lintian/-/blob/930b18e4b28b7540253f458ef42a884cca7965c3/tags/a/acute-accent-in-manual-page.tag + + Closes #9418 + +- tool_operate: reduce errorbuffer allocs + + - parallel transfers: only alloc and keep errorbuffers in memory for + actual "live" transfers and not for the ones in the pending queue + + - serial transfers: reuse the same fixed buffer for all transfers, not + allocated at all. + + Closes #9394 + +Viktor Szakats (31 Aug 2022) +- misc: spelling fixes + + Found using codespell 2.2.1. + + Also delete the redundant protocol designator from an archive.org URL. + + Reviewed-by: Daniel Stenberg + Closes #9403 + +Daniel Stenberg (31 Aug 2022) +- tool_progress: remove 'Qd' from the parallel progress bar + + The "queued" value is no longer showing anything useful to the user. It + is an internal number of transfers waiting at that moment. + + Closes #9389 + +- tool_operate: prevent over-queuing in parallel mode + + When doing a huge amount of parallel transfers, we must not add them to + the per_transfer list frivolously since they all use memory after all. + This was previous done without really considering millions or billions + of transfers. Massive parallelism would use a lot of memory for no good + purpose. + + The queue is now limited to twice the paralleism number. + + This makes the 'Qd' value in the parallel progress meter mostly useless + for users, but works for now for us as a debug display. + + Reported-by: justchen1369 on github + Fixes #8933 + Closes #9389 + +Viktor Szakats (31 Aug 2022) +- cmake: fix original MinGW builds + + 1. Re-enable `HAVE_GETADDRINFO` detection on Windows + + Commit d08ee3c83d6bd416aef62ff844c98e47c4682429 (in 2013) added logic + that automatically assumed `getaddrinfo()` to be present for builds + with IPv6 enabled. As it turns out, certain toolchains (e.g. original + MinGW) by default target older Windows versions, and thus do not + support `getaddrinfo()` out of the box. The issue was masked for + a while by CMake builds forcing a newer Windows version, but that + logic got deleted in commit 8ba22ffb2030ed91312fc8634e29516cdf0a9761. + Since then, some CI builds started failing due to IPv6 enabled, + `HAVE_GETADDRINFO` set, but `getaddrinfo()` in fact missing. + + It also turns out that IPv6 works without `getaddrinfo()` since commit + 67a08dca27a6a07b36c7f97252e284ca957ff1a5 (from 2019, via #4662). So, + to resolve all this, we can now revert the initial commit, thus + restoring `getaddrinfo()` detection and support IPv6 regardless of its + outcome. + + Reported-by: Daniel Stenberg + + 2. Omit `bcrypt` with original MinGW + + Original (aka legacy/old) MinGW versions do not support `bcrypt` + (introduced with Vista). We already have logic to handle that in + `lib/rand.c` and autotools builds, where we do not call the + unsupported API and do not link `bcrypt`, respectively, when using + original MinGW. + + This patch ports that logic to CMake, fixing the link error: + `c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: cannot find -lbcrypt` + + Ref: https://ci.appveyor.com/project/curlorg/curl/builds/44624888/job/40vle84cn4vle7s0#L508 + Regression since 76172511e7adcf720f4c77bd91f49278300ec97e + + Fixes #9214 + Fixes #9393 + Fixes #9395 + Closes #9396 + +Version 7.85.0 (31 Aug 2022) + +Daniel Stenberg (31 Aug 2022) +- RELEASE-NOTES: synced + + curl 7.85.0 release + +- THANKS: add contributors from the 7.85.0 release + +- getparam: correctly clean args + + Follow-up to bf7e887b2442783ab52 + + The previous fix for #9128 was incomplete and caused #9397. + + Fixes #9397 + Closes #9399 + +- zuul: remove the clang-tidy job + + Turns out we don't see the warnings, but the warnings right now are + plain ridiculous and unhelpful so we can just as well just kill this + job. + + Closes #9390 + +- cmake: set feature PSL if present + + ... make test 1014 pass when libpsl is used. + + Closes #9391 + +- lib530: simplify realloc failure exit path + + To make code analyzers happier + + Closes #9392 + +- [Orgad Shaneh brought this change] + + tests: add tests for netrc login/password combinations + + Covers the following PRs: + + - #9066 + - #9247 + - #9248 + + Closes #9256 + +- [Orgad Shaneh brought this change] + + url: really use the user provided in the url when netrc entry exists + + If the user is specified as part of the URL, and the same user exists + in .netrc, Authorization header was not sent at all. + + The user and password fields were assigned in conn->user and password + but the user was not assigned to data->state.aptr, which is the field + that is used in output_auth_headers and friends. + + Fix by assigning the user also to aptr. + + Amends commit d1237ac906ae7e3cd7a22c3a2d3a135a97edfbf5. + + Fixes #9243 + +- [Orgad Shaneh brought this change] + + netrc: Use the password from lines without login + + If netrc entry has password with empty login, use it for any username. + + Example: + .netrc: + machine example.com password 123456 + + curl -vn http://user@example.com/ + + Fix it by initializing state_our_login to TRUE, and reset it only when + finding an entry with the same host and different login. + + Closes #9248 + +- [Jay Satiro brought this change] + + url: treat missing usernames in netrc as empty + + - If, after parsing netrc, there is a password with no username then + set a blank username. + + This used to be the case prior to 7d600ad (precedes 7.82). Note + parseurlandfillconn already does the same thing for URLs. + + Reported-by: Raivis <standsed@users.noreply.github.com> + Testing-by: Domen Kožar + + Fixes https://github.com/curl/curl/issues/8653 + Closes #9334 + Closes #9066 + +- test8: verify that "ctrl-byte cookies" are ignored + +- cookie: reject cookies with "control bytes" + + Rejects 0x01 - 0x1f (except 0x09) plus 0x7f + + Reported-by: Axel Chong + + Bug: https://curl.se/docs/CVE-2022-35252.html + + CVE-2022-35252 + + Closes #9381 + +- libssh: ignore deprecation warnings + + libssh 0.10.0 marks all SCP functions as "deprecated" which causes + compiler warnings and errors in our CI jobs and elsewhere. Ignore + deprecation warnings if 0.10.0 or later is found in the build. + + If they actually remove the functions at a later point, then someone can + deal with that pain and functionality break then. + + Fixes #9382 + Closes #9383 + +- Revert "schannel: when importing PFX, disable key persistence" + + This reverts commit 70d010d285315e5f1cad6bdb4953e167b069b692. + + Due to further reports in #9300 that indicate this commit might + introduce problems. + +- multi: use larger dns hash table for multi interface + + Have curl_multi_init() use a much larger DNS hash table than used for + the easy interface to scale and perform better when used with _many_ + host names. + + curl_share_init() sets an in-between size. + + Inspired-by: Ivan Tsybulin + See #9340 + Closes #9376 + +Marc Hoersken (28 Aug 2022) +- CI/runtests.pl: add param for dedicated curl to talk to APIs + + This should make it possible to also report test failures + if our freshly build curl binary is not fully functional. + + Reviewed-by: Daniel Stenberg + Closes #9360 + +Daniel Stenberg (27 Aug 2022) +- [Jacob Tolar brought this change] + + openssl: add cert path in error message + + Closes #9349 + +- [Jacob Tolar brought this change] + + cert.d: clarify that escape character works for file paths + + Closes #9349 + +- gha: move over ngtcp2-gnutls CI job from zuul + + Closes #9331 + +Marc Hoersken (26 Aug 2022) +- cmake: add detection of threadsafe feature + + Avoids failing test 1014 by replicating configure checks + for HAVE_ATOMIC and _WIN32_WINNT with custom CMake tests. + + Reviewed-by: Marcel Raad + + Follow up to #8680 + Closes #9312 + +Daniel Stenberg (26 Aug 2022) +- RELEASE-NOTES: synced + +Marc Hoersken (26 Aug 2022) +- CI/azure: align torture shallowness with GHA + + There 25 is used with FTP tests skipped, and 20 for FTP tests. + This should make torture tests stay within the 60min timeout. + + Reviewed-by: Daniel Stenberg + Closes #9371 + +- multi_wait: fix and improve Curl_poll error handling on Windows + + First check for errors and return CURLM_UNRECOVERABLE_POLL + before moving forward and waiting on socket readiness events. + + Reviewed-by: Jay Satiro + Reviewed-by: Marcel Raad + + Reported-by: Daniel Stenberg + Ref: #9361 + + Follow up to #8961 + Closes #9372 + +- multi_wait: fix skipping to populate revents for extra_fds + + On Windows revents was not populated for extra_fds if + multi_wait had to wait due to the Curl_poll pre-check + not signalling any readiness. This commit fixes that. + + Reviewed-by: Marcel Raad + Reviewed-by: Jay Satiro + + Closes #9361 + +- CI/appveyor: disable TLS in msys2-native autotools builds + + Schannel cannot be used from msys2-native Linux-emulated builds. + + Reviewed-by: Marcel Raad + Reviewed-by: Daniel Stenberg + + Follow up to #9367 + Closes #9370 + +Jay Satiro (25 Aug 2022) +- tests: fix http2 tests to use CRLF headers + + Prior to this change some tests that rely on nghttpx proxy did not use + CRLF headers everywhere. A recent change in nghttp2, which updated its + version of llhttp (HTTP parser), requires curl's HTTP/1.1 test server to + use CRLF headers. + + Ref: https://github.com/nghttp2/nghttp2/commit/9d389e8 + + Fixes https://github.com/curl/curl/issues/9364 + Closes https://github.com/curl/curl/pull/9365 + +Daniel Stenberg (25 Aug 2022) +- [rcombs brought this change] + + multi: use a pipe instead of a socketpair on apple platforms + + Sockets may be shut down by the kernel when the app is moved to the + background, but pipes are not. + + Removed from KNOWN_BUGS + + Fixes #6132 + Closes #9368 + +- [Somnath Kundu brought this change] + + libssh2: provide symlink name in SFTP dir listing + + When reading the symbolic link name for a file, we need to add the file + name to base path name. + + Closes #9369 + +- configure: if asked to use TLS, fail if no TLS lib was detected + + Previously the configure script would just warn about this fact and + continue with TLS disabled build which is not always helpful. TLS should + be explicitly disabled if that is what the user wants. + + Closes #9367 + +- [Dustin Howett brought this change] + + schannel: when importing PFX, disable key persistence + + By default, the PFXImportCertStore API persists the key in the user's + key store (as though the certificate was being imported for permanent, + ongoing use.) + + The documentation specifies that keys that are not to be persisted + should be imported with the flag `PKCS12_NO_PERSIST_KEY`. + NOTE: this flag is only supported on versions of Windows newer than XP + and Server 2003. + + Fixes #9300 + Closes #9363 + +- unit1303: four tests should have TRUE for 'connecting' + + To match the comments. + + Reported-by: Wu Zheng + + See #9355 + Closes #9356 + +- CURLOPT_BUFFERSIZE.3: add upload buffersize to see also + + Closes #9354 + +- [Fabian Fischer brought this change] + + HTTP3.md: add missing autoreconf command for building with wolfssl + + Closes #9353 + +- RELEASE-NOTES: synced + +- multi: have curl_multi_remove_handle close CONNECT_ONLY transfer + + Ẃhen it has been used in the multi interface, it is otherwise left in + the connection cache, can't be reused and nothing will close them since + the easy handle loses the association with the multi handle and thus the + connection cache - until the multi handle is closed or it gets pruned + because the cache is full. + + Reported-by: Dominik Thalhammer + Fixes #9335 + Closes #9342 + +- docs/cmdline-opts: remove \& escapes from all .d files + + gen.pl escapes them itself now + +- docs/cmdline-opts/gen.pl: encode leading single and double quotes + + As "(aq" and "(dq" to prevent them from implying a meaning in the nroff + output. This removes the need for using \& escapes in the .d files' + description parts. + + Closes #9352 + +Marc Hoersken (23 Aug 2022) +- tests/server/sockfilt.c: avoid race condition without a mutex + + Avoid loosing any triggered handles by first aborting and joining + the waiting threads before evaluating the individual signal state. + + This removes the race condition and therefore need for a mutex. + + Closes #9023 + +Daniel Stenberg (22 Aug 2022) +- [Emil Engler brought this change] + + url: output the maximum when rejecting a url + + This commit changes the failf message to output the maximum length, when + curl refuses to process a URL because it is too long. + + See: #9317 + Closes: #9327 + +- [Chris Paulson-Ellis brought this change] + + configure: fix broken m4 syntax in TLS options + + Commit b589696f added lines to some shell within AC_ARG_WITH macros, but + inadvertently failed to move the final closing ). + + Quote the script section using braces. + + So, if these problems have been around for a while, how did I find them? + Only because I did a configure including these options: + + $ ./configure --with-openssl --without-rustls + SSL: enabled (OpenSSL) + + Closes #9344 + +- tests/data/CMakeLists: remove making the 'show' makefile target + + It is not used by runtests since 3c0f462 + + Closes #9333 + +- tests/data/Makefile: remove 'filecheck' target + + No practical use anymore since 3c0f4622cdfd6 + + Closes #9332 + +- libssh2: make atime/mtime date overflow return error + + Closes #9328 + +- libssh: make atime/mtime date overflow return error + + Closes #9328 + +- examples/curlx.c: remove + + This example is a bit convoluted to use as an example, combined with the + special license for it makes it unsuitable. + + Closes #9330 + +- [Tobias Nygren brought this change] + + curl.h: include <sys/select.h> on SunOS + + It is needed for fd_set to be visible to downstream consumers that use + <curl/multi.h>. Header is known to exist at least as far back as Solaris + 2.6. + + Closes #9329 + +- DEPRECATE.md: push the NSS deprecation date forward one year to 2023 + + URL: https://curl.se/mail/lib-2022-08/0016.html + +- libssh2: setting atime or mtime >32bit on 4-bytes-long systems + + Since the libssh2 API uses 'long' to store the timestamp, it cannot + transfer >32bit times on Windows and 32bit architecture builds. + + Avoid nasty surprises by instead not setting such time. + + Spotted by Coverity + + Closes #9325 + +- libssh: setting atime or mtime > 32bit is now just skipped + + The libssh API used caps the time to an unsigned 32bit variable. Avoid + nasty surprises by instead not setting such time. + + Spotted by Coverity. + + Closes #9324 + +Jay Satiro (16 Aug 2022) +- KNOWN_BUGS: Windows Unicode builds use homedir in current locale + + Bug: https://github.com/curl/curl/pull/7252 + Reported-by: dEajL3kA@users.noreply.github.com + + Ref: https://github.com/curl/curl/pull/7281 + + Closes https://github.com/curl/curl/pull/9305 + +Daniel Stenberg (16 Aug 2022) +- test399: switch it to use a config file instead + + ... as using a 65535 bytes host name in a URL does not fit on the + command line on some systems - like Windows. + + Reported-by: Marcel Raad + Fixes #9321 + Closes #9322 + +- RELEASE-NOTES: synced + +- asyn-ares: make a single alloc out of hostname + async data + + This saves one alloc per name resolve and simplifies the exit path. + + Closes #9310 + +- Curl_close: call Curl_resolver_cancel to avoid memory-leak + + There might be a pending (c-ares) resolve that isn't free'd up yet. + + Closes #9310 + +- asyn-thread: fix socket leak on OOM + + Closes #9310 + +- GHA: mv CI torture test from Zuul + + Closes #9310 + +- ngtcp2-wolfssl.yml: add GHA to build ngtcp2 + wolfSSL + + Closes #9318 + +- test399: verify check of too long host name + +- url: reject URLs with hostnames longer than 65535 bytes + + It *probably* causes other problems too since DNS can't resolve such + long names, but the SNI field in TLS is limited to 16 bits length. + + Closes #9317 + +- curl_multi_perform.3: minor language fix + + Closes #9316 + +- ngtcp2: fix picky compiler warnings with wolfSSL for QUIC + + Follow-up to 8a13be227eede2 + + Closes #9315 + +- ngtcp2: remove leftover variable + + Mistake leftover from my edit before push. + + Follow-up from 8a13be227eede2601c2b3b + Reported-by: Viktor Szakats + Bug: https://github.com/curl/curl/pull/9290#issuecomment-1214569167 + +Viktor Szakats (15 Aug 2022) +- Makefile.m32: allow -nghttp3/-ngtcp2 without -ssl [ci skip] + + Before this patch `-nghttp3`/`-ngtcp2` had an effect only when `-ssl` + was also enabled. `-ssl` meaning OpenSSL (and its forks). After + 8a13be227eede2601c2b3b1c63e08b3dc9b35dd5 nghttp3/ngtcp2 can also be + used together with wolfSSL. This patch adds the ability to enable + `-nghttp3`/`-ngtcp2` independently from `-ssl` (OpenSSL), allowing to + use it with wolfSSL or other, future TLS backends. + + Before this patch, it was fine to enable `-nghttp3`/`-ngtcp2` + unconditionally. After this patch, this is no longer the case, and now + it's the user's responsibility to enable `-nghttp3`/`-ngtcp2` only + together with a compatible TLS backend. + + When using a TLS backend other than OpenSSL, the TLS-specific ngtcp2 + library must be configured manually, e.g.: + `export CURL_LDFLAG_EXTRAS=-lngtcp2_crypto_wolfssl` + + (or via `NGTCP2_LIBS`) + + Closes #9314 + +Daniel Stenberg (15 Aug 2022) +- [Stefan Eissing brought this change] + + quic: add support via wolfSSL + + - based on ngtcp2 PR https://github.com/ngtcp2/ngtcp2/pull/505 + - configure adapted to build against ngtcp2 wolfssl crypto lib + - quic code added for creation of WOLFSSL* instances + + Closes #9290 + +Marcel Raad (14 Aug 2022) +- [David Carlier brought this change] + + memdebug: add annotation attributes + + memory debug tracking annotates whether the returned pointer does not + `alias`, hints where the size required is, for Windows to be better + debugged via Visual Studio. + + Closes https://github.com/curl/curl/pull/9306 + +Daniel Stenberg (14 Aug 2022) +- GHA: move libressl CI from zuul to GitHub + + Closes #9309 + +- KNOWN_BUGS: FTPS directory listing hangs on Windows with Schannel + + Closes #9161 + +- KNOWN_BUGS: CURLOPT_CERTINFO results in CURLE_OUT_OF_MEMORY with Schannel + + Closes #8741 + +- KNOWN_BUGS: libssh blocking and infinite loop problem + + Closes #8632 + +- RELEASE-NOTES: synced + +- msh3: fix the QUIC disconnect function + + And free request related memory better in 'done'. Fixes a memory-leak. + + Reported-by: Gisle Vanem + Fixes #8915 + Closes #9304 + +- connect: close the happy eyeballs loser connection when using QUIC + + Reviewed-by: Nick Banks + + Closes #9303 + +- [Emil Engler brought this change] + + refactor: split resolve_server() into functions + + This commit splits the branch-heavy resolve_server() function into + various sub-functions, in order to reduce the amount of nested + if/else-statements. + + Beside this, it also removes many else-sequences, by returning in the + previous if-statement. + + Closes #9283 + +- schannel: re-indent to use curl style better + + Only white space changes + + Closes #9301 + +- [Emanuele Torre brought this change] + + docs/cmdline-opts: fix example and categories for --form-escape + + The example was missing a "--form" argument + I also replaced "--form" with "-F" to shorten the line a bit since it + was already very long. + + And I also moved --form-escape from the "post" category to the "upload" + category (this is what I originally wanted to fix, before also noticing + the mistake in the example). + + Closes #9298 + +- [Nick Banks brought this change] + + HTTP3.md: update to msh3 v0.4.0 + + Closes #9297 + +- hostip: resolve *.localhost to 127.0.0.1/::1 + + Following the footsteps of other clients like Firefox/Chrome. RFC 6761 + says clients SHOULD do this. + + Add test 389 to verify. + + Reported-by: TheKnarf on github + Fixes #9192 + Closes #9296 + +Jay Satiro (11 Aug 2022) +- KNOWN_BUGS: long paths are not fully supported on Windows + + Bug: https://github.com/curl/curl/issues/8361 + Reported-by: Gisle Vanem + + Closes https://github.com/curl/curl/pull/9288 + +Daniel Stenberg (11 Aug 2022) +- config: remove the check for and use of SIZEOF_SHORT + + shorts are 2 bytes on all platforms curl runs and have ever run on. + + Closes #9291 + +- configure: introduce CURL_SIZEOF + + This is a rewrite of the previously used GPLv3+exception licensed + file. With this change, there is no more reference to GPL so we can + remove that from LICENSES/. + + Ref: #9220 + Closes #9291 + +- [Sean McArthur brought this change] + + hyper: customize test1274 to how hyper unfolds headers + + Closes #9217 + +- [Orgad Shaneh brought this change] + + curl-config: quote directories with potential space + + On Windows (at least with CMake), the default prefix is + C:/Program Files (x86)/CURL. + + Closes #9253 + +- [Oliver Roberts brought this change] + + amigaos: fix threaded resolver on AmigaOS 4.x + + Replace ip4 resolution function on AmigaOS 4.x, as it requires runtime + feature detection and extra code to make it thread safe. + + Closes #9265 + +- [Emil Engler brought this change] + + imap: use ISALNUM() for alphanumeric checks + + This commit replaces a self-made character check for alphanumeric + characters within imap_is_bchar() with the ISALNUM() macro, as it is + reduces the size of the code and makes the performance better, due to + ASCII arithmetic. + + Closes #9289 + +- RELEASE-NOTES: synced + +- [Cering on github brought this change] + + connect: add quic connection information + + Fixes #9286 + Closes #9287 + +- [Philip Heiduck brought this change] + + cirrus/freebsd-ci: bootstrap the pip installer + + Signed-off-by: Philip H <47042125+pheiduck@users.noreply.github.com> + + Closes #9213 + +- urldata: move smaller fields down in connectdata struct + + By (almost) sorting the struct fields in connectdata in a decending size + order, having the single char ones last, we reduce the number of holes + in the struct and thus the amount of storage needed. + + Closes #9280 + +- ldap: adapt to conn->port now being an 'int' + + Remove typecasts. Fix printf() formats. + + Follow-up from 764c6bd3bf. + Pointed out by Coverity CID 1507858. + + Closes #9281 + +- KNOWN_BUGS: Negotiate authentication against Hadoop HDFS + + Closes #8264 + +- [Oliver Roberts brought this change] + + file: add handling of native AmigaOS paths + + On AmigaOS 4.x, handle native absolute paths, whilst blocking relative + paths. Also allow unix style paths if feature enabled at link time. + + Inspiration-from: Michael Trebilcock + + Closes #9259 + +- KNOWN_BUGS: cmake build is not thread-safe + + The cmake build does not check for and verify presence of a working + Atomic type, which then makes curl_global_init() to not build + thread-safe on non-Windows platforms. + + Closes https://github.com/curl/curl/issues/8973 + Closes https://github.com/curl/curl/pull/8982 + +- [Oliver Roberts brought this change] + + configure: fixup bsdsocket detection code for AmigaOS 4.x + + The code that detects bsdsocket.library for AmigaOS did not work + for AmigaOS 4.x. This has been fixed and also cleaned up a little + to reduce duplication. Wasn't technically necessary before, but is + required when building with AmiSSL instead of OpenSSL. + + Closes #9268 + +- [Oliver Roberts brought this change] + + tool: reintroduce set file comment code for AmigaOS + + Amiga specific code which put the URL in the file comment was perhaps + accidentally removed in b88940850002a3f1c25bc6488b95ad30eb80d696 having + originally been added in 5c215bdbdfde8b2350cdcbac82aae0c914da5314. + Reworked to fit the code changes and added it back in. + + Reported-by: Michael Trebilcock + Originally-added-by: Chris Young + + Closes #9258 + +- urldata: make 'negnpn' use less storage + + The connectdata struct field 'negnpn' never holds a value larger than + 30, so an unsigned char saves 3 bytes struct space. + + Closes #9279 + +- urldata: make three *_proto struct fields smaller + + Use 'unsigned char' for storage instead of the enum, for three GSSAPI + related fields in the connectdata struct. + + Closes #9278 + +- connect: set socktype/protocol correctly + + So that an address used from the DNS cache that was previously used for + QUIC can be reused for TCP and vice versa. + + To make this possible, set conn->transport to "unix" for unix domain + connections ... and store the transport struct field in an unsigned char + to use less space. + + Reported-by: ウさん + Fixes #9274 + Closes #9276 + +- [Oliver Roberts brought this change] + + amissl: allow AmiSSL to be used with AmigaOS 4.x builds + + Enable AmiSSL to be used instead of static OpenSSL link libraries. + for AmigaOS 4.x, as it already is in the AmigaOS 3.x build. + + Closes #9269 + +- [opensignature on github brought this change] + + openssl: add details to "unable to set client certificate" error + + from: "curl: (58) unable to set client certificate" + + to: curl: (58) unable to set client certificate [error:0A00018F:SSL + routines::ee key too small] + + Closes #9228 + +- [Oliver Roberts brought this change] + + amissl: make AmiSSL v5 a minimum requirement + + AmiSSL v5 is the latest version, featuring a port of OpenSSL 3.0. + Support for previous OpenSSL 1.1.x versions has been dropped, so + makes sense to enforce v5 as the minimum requirement. This also + allows all the AmiSSL stub workarounds to be removed as they are + now provided in a link library in the AmiSSL SDK. + + Closes #9267 + +- [Oliver Roberts brought this change] + + configure: -pthread not available on AmigaOS 4.x + + The most recent GCC builds for AmigaOS 4.x do not allow -pthread and + exit with an error. Instead, need to explictly specify -lpthread. + + Closes #9266 + +- digest: pass over leading spaces in qop values + + When parsing the "qop=" parameter of the digest authentication, and the + value is provided within quotes, the list of values can have leading + white space which the parser previously did not handle correctly. + + Add test case 388 to verify. + + Reported-by: vlubart on github + Fixes #9264 + Closes #9270 + +- [Evgeny Grin (Karlson2k) brought this change] + + digest: reject broken header with session protocol but without qop + + Closes #9077 + +- CURLINFO_SPEED_UPLOAD/DOWNLOAD.3: fix examples + + Reported-by: jvvprasad78 on github + Assisted-by: Jay Satiro + Fixes #9239 + Closes #9241 + +- [Fabian Keil brought this change] + + test44[2-4]: add '--resolve' to the keywords + + ... so the tests can be automatically skipped when + using an external proxy like Privoxy. + + Closes #9250 + +- RELEASE-NOTES: synced + +- CURLOPT_CONNECT_ONLY.3: clarify multi API use + + Reported-by: Maxim Ivanov + Fixes #9244 + Closes #9262 + +- [Andrew Lambert brought this change] + + curl_easy_header: Add CURLH_PSEUDO to sanity check + + Fixes #9235 + Closes #9236 + +- [Emil Engler brought this change] + + docs: add dns category to --resolve + + This commit adds the dns category to the --resolve command line option, + because it can be interpreted as both: a low-level connection option and + an option related to the resolving of a hostname. + + It is also not common for dns options to belong to the connection + category and vice versa. --ipv4 and --ipv6 are both good examples. + + Closes #9229 + +Jay Satiro (2 Aug 2022) +- [Wyatt O'Day brought this change] + + schannel: Add TLS 1.3 support + + - Support TLS 1.3 as the default max TLS version for Windows Server 2022 + and Windows 11. + + - Support specifying TLS 1.3 ciphers via existing option + CURLOPT_TLS13_CIPHERS (tool: --tls13-ciphers). + + Closes https://github.com/curl/curl/pull/8419 + +Daniel Stenberg (2 Aug 2022) +- [Emil Engler brought this change] + + cmdline-opts/gen.pl: improve performance + + On some systems, the gen.pl script takes nearly two minutes for the + generation of the main-page, which is a completely unacceptable time. + + The slow performance has two causes: + 1. Use of a regex locale operator + 2. Useless invokations of loops + + The commit addresses the first issue by replacing the "\W" wiht + [^a-zA-Z0-9_], which is, according to regex101.com, functionally + equivalent to the previous operation, except that it is obviously + limited to ASCII only, which is fine, as the curl project is + English-only anyway. + + The second issue is being addressed by only running the loop if the line + contains a "--" in it. The loop may be completeley removed in the + future. + + Co-authored-by: Emanuele Torre <torreemanuele6@gmail.com> + + See #8299 + Fixes #9230 + Closes #9232 + +- docs/cmdline: mark fail and fail-with-body as mutually exclusive + + Reported-by: Andreas Sommer + Fixes #9221 + Closes #9222 + +- [Nao Yonashiro brought this change] + + quiche: fix build failure + + Reviewed-by: Alessandro Ghedini + Closes #9223 + +Viktor Szakats (2 Aug 2022) +- configure.ac: drop references to deleted functions + + follow-up from 4d73854462f30948acab12984b611e9e33ee41e6 + + Reported-by: Oliver Roberts + Fixes #9238 + Closes #9240 + +Daniel Stenberg (28 Jul 2022) +- [Sean McArthur brought this change] + + hyper: enable obs-folded multiline headers + + Closes #9216 + +- connect: revert the use of IP*_RECVERR + + The options were added in #6341 and d13179d, but cause problems: Lots of + POLLIN event occurs but recvfrom read nothing. + + Reported-by: Tatsuhiro Tsujikawa + Fixes #9209 + Closes #9215 + +- [Marco Kamner brought this change] + + docs: remove him/her/he/she from documentation + + Closes #9208 + +- RELEASE-NOTES: synced + +- tool_getparam: make --doh-url "" switch it off + + A possible future addition could be to parse the URL first too to verify + that it is valid before trying to use it. + + Assisted-by: Jay Satiro + Closes #9207 + +- mailmap: add rzrymiak on github + +Jay Satiro (26 Jul 2022) +- ngtcp2: Fix build error due to change in nghttp3 prototypes + + ngtcp2/nghttp3@4a066b2 changed nghttp3_conn_block_stream and + nghttp3_conn_shutdown_stream_write return from int to void. + + Reported-by: jurisuk@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/9204 + Closes https://github.com/curl/curl/pull/9200 + +Daniel Stenberg (26 Jul 2022) +- [rzrymiak on github brought this change] + + BUGS.md: improve language + + Closes #9205 + +- [Philip Heiduck brought this change] + + cirrus.yml: replace py38-pip with py39-pip + + Reported-by: Jay Satiro + Fixes #9201 + Closes #9202 + +- tool_getparam: fix cleanarg() for unicode builds + + Use the correct type, and make cleanarg an empty macro if the cleaning + ability is absent. + + Fixes #9195 + Closes #9196 + + Reviewed-by: Jay Satiro + Reviewed-by: Marcel Raad + +Marc Hoersken (25 Jul 2022) +- test3026: add support for Windows using native Win32 threads + + Reviewed-by: Viktor Szakats + Reviewed-by: Jay Satiro + Reviewed-by: Daniel Stenberg + + Follow up to 7ade9c50b35d95d47a43880c3097bebab7a7e690 + Closes #9012 + +Jay Satiro (25 Jul 2022) +- [Evgeny Grin (Karlson2k) brought this change] + + digest: fix memory leak, fix not quoted 'opaque' + + Fix leak regression introduced by 3a6fe0c. + + Closes https://github.com/curl/curl/pull/9199 + +Daniel Stenberg (23 Jul 2022) +- tests: several enumerated type cleanups + + To please icc + + Closes #9179 + +- tool_paramhlp: fix "enumerated type mixed with another type" + + Warning by icc + + Closes #9179 + +- tool_writeout: fix enumerated type mixed with another type + + Closes #9179 + +- tool_cfgable: make 'synthetic_error' a plain bool + + The specific reason was not used. + + Closes #9179 + +- tool_paramhlp: make check_protocol return ParameterError + + "enumerated type mixed with another type" + + Closes #9179 + +- tool_formparse: fix variable may be used before its value is set + + Warning by icc + + Closes #9179 + +- sendf: skip storing HTTP headers if HTTP disabled + + Closes #9179 + +- url: enumerated type mixed with another type + + Follow-up to 1c58e7ae99ce2030213f28b + + Closes #9179 + +- urldata: change second proxytype field to unsigned char to match + + To avoid "enumerated type mixed with another type" + + Closes #9179 + +- http: typecast the httpreq assignment to avoid icc compiler warning + + error #188: enumerated type mixed with another type + + Closes #9179 + +- urldata: make state.httpreq an unsigned char + + To match set.method used for the same purpose. + + Closes #9179 + +- splay: avoid using -1 in unsigned variable + + To fix icc compiler warning integer conversion resulted in a change of sign + + Closes #9179 + +- sendf: store the header type in an usigned char to avoid icc warnings + + Closes #9179 + +- multi: fix the return code from Curl_pgrsDone() + + It does not return a CURLcode. Detected by the icc compiler warning + "enumerated type mixed with another type" + + Closes #9179 + +- sendf: make Curl_debug a void function + + As virtually no called checked the return code, and those that did + wrongly treated it as a CURLcode. Detected by the icc compiler warning: + enumerated type mixed with another type + + Closes #9179 + +- http_chunks: remove an assign + typecast + + As it caused icc to complain: "pointer cast involving 64-bit pointed-to + type" + + Closes #9179 + +- vtls: make Curl_ssl_backend() return the enum type curl_sslbackend + + To fix the icc warning enumerated type mixed with another type + + Closes #9179 + +- curl-compilers.m4: make icc use -diag* options and disable two warnings + + -wd and -we are deprecated and are now -diag-disable and -diag-error + + Disable warning 1024 and 2259 + + Closes #9179 + +- [Matthew Thompson brought this change] + + GHA: add two Intel compiler CI jobs + + Closes #9179 + +- [Daniel Katz brought this change] + + curl-functions.m4: check whether atomics can link rather than just compile + + Some build toolchains support C11 atomics (i.e., _Atomic types), but + will not link the associated atomics runtime unless a flag is passed. In + such an environment, linking an application with libcurl.a can fail due + to undefined symbols for atomic load/store functions. + + I encountered this behavior when upgrading curl to 7.84.0 and attempting + to build with Solaris Studio 12.6. Solaris provides the flag + -xatomic=[gcc | studio], allowing users to link to one of two atomics + runtime implementations. However, if the user does not provide this + flag, then neither runtime is linked. This led to builds failing in CI. + + Closes #9190 + +- [Rosen Penev brought this change] + + curl-wolfssl.m4: add options header when building test code + + Needed for certain configurations of wolfSSL. Otherwise, missing header + error may occur. + + Tested with OpenWrt. + + Closes #9187 + +- ftp: use a correct expire ID for timer expiry + + This was an accurate error pointed out by the icc warning: enumerated + type mixed with another type + + Ref: #9179 + Closes #9184 + +- sendf: fix paused header writes since after the header API + + Regression since d1e4a67 + + Reported-by: Sergey Ogryzkov + Fixes #9180 + Closes #9182 + +- mprintf: fix *dyn_vprintf() when out-of-memory + + Follow-up to 0e48ac1f99a. Torture-testing 1455 would lead to a memory + leak otherwise. + + Closes #9185 + +- curl-confopts: remove leftover AC_REQUIREs + + configure.ac:3488: warning: CURL_CHECK_FUNC_IOCTL is m4_require'd but not m4_defun'd + configure.ac:3488: warning: CURL_CHECK_FUNC_SETSOCKOPT is m4_require'd but not m4_defun'd + + follow-up from 4d73854462f30 + + Closes #9183 + +- file: fix icc enumerated type mixed with another type warning + + Ref: #9179 + Closes #9181 + +Viktor Szakats (19 Jul 2022) +- tidy-up: delete unused build configuration macros + + Most of them feature guards: + + - `CURL_INCLUDES_SYS_UIO` [1] + - `HAVE_ALLOCA_H` [2] + - `HAVE_CRYPTO_CLEANUP_ALL_EX_DATA` (unused since de71e68000c8624ea13f90b136f8734dd0fb1bdc) + - `HAVE_DLFCN_H` + - `HAVE_DLOPEN` + - `HAVE_DOPRNT` + - `HAVE_FCNTL` + - `HAVE_GETHOSTBYNAME` [3] + - `HAVE_GETOPT_H` + - `HAVE_GETPASS` + - `HAVE_GETPROTOBYNAME` + - `HAVE_GETSERVBYNAME` + - `HAVE_IDN_FREE*` + - `HAVE_INET_ADDR` + - `HAVE_IOCTL` + - `HAVE_KRB4` + - `HAVE_KRB_GET_OUR_IP_FOR_REALM` + - `HAVE_KRB_H` + - `HAVE_LDAPSSL_H` + - `HAVE_LDAP_INIT_FD` + - `HAVE_LIBDL` + - `HAVE_LIBNSL` + - `HAVE_LIBRESOLV*` + - `HAVE_LIBUCB` + - `HAVE_LL` + - `HAVE_LOCALTIME_R` + - `HAVE_MALLOC_H` + - `HAVE_MEMCPY` + - `HAVE_MEMORY_H` + - `HAVE_NETINET_IF_ETHER_H` + - `HAVE_NI_WITHSCOPEID` + - `HAVE_OPENSSL_CRYPTO_H` + - `HAVE_OPENSSL_ERR_H` + - `HAVE_OPENSSL_PEM_H` + - `HAVE_OPENSSL_PKCS12_H` + - `HAVE_OPENSSL_RAND_H` + - `HAVE_OPENSSL_RSA_H` + - `HAVE_OPENSSL_SSL_H` + - `HAVE_OPENSSL_X509_H` + - `HAVE_PEM_H` + - `HAVE_POLL` + - `HAVE_RAND_SCREEN` + - `HAVE_RAND_STATUS` + - `HAVE_RECVFROM` + - `HAVE_SETSOCKOPT` + - `HAVE_SETVBUF` + - `HAVE_SIZEOF_LONG_DOUBLE` + - `HAVE_SOCKIO_H` + - `HAVE_SOCK_OPTS` + - `HAVE_STDIO_H` + - `HAVE_STRCASESTR` + - `HAVE_STRFTIME` + - `HAVE_STRLCAT` + - `HAVE_STRNCMPI` + - `HAVE_STRNICMP` + - `HAVE_STRSTR` + - `HAVE_STRUCT_IN6_ADDR` + - `HAVE_TLD_H` + - `HAVE_TLD_STRERROR` + - `HAVE_UNAME` + - `HAVE_USLEEP` + - `HAVE_WINBER_H` + - `HAVE_WRITEV` + - `HAVE_X509_H` + - `LT_OBJDIR` + - `NEED_BASENAME_PROTO` + - `NOT_NEED_LIBNSL` + - `OPENSSL_NO_KRB5` + - `RECVFROM_TYPE*` + - `SIZEOF_LONG_DOUBLE` + - `STRERROR_R_TYPE_ARG3` + - `USE_YASSLEMUL` + - `_USRDLL` (from CMake) [4] + + [1] Related parts in `m4/curl-functions.m4` and `configure.ac` might + also be deleted. + + [2] Related comment can possibly be deleted in + `packages/vms/generate_config_vms_h_curl.com`. + + [3] There are more instances of this in autotools, but I did not dare to + touch those. Looked like it's used to detect socket support. + + [4] This is necessary for MFC (Microsoft Foundation Class) DLLs to + force linking MFC components statically to the DLL. `libcurl.dll` + does not use MFC, so we can delete this define. + Ref: https://docs.microsoft.com/cpp/build/regular-dlls-statically-linked-to-mfc + + Script that can help finding unused settings like above: + ```shell + + autoheader configure.ac # generate lib/curl_config.h.in + + { + grep -o -E 'set\([A-Z][A-Z0-9_]{3,}' CMake/Platforms/WindowsCache.cmake | sed -E 's|set\(||g' + grep -o -E -h '#define +[A-Z][A-Z0-9_]{3,}' lib/config-*.h | sed -E 's|#define +||g' + grep -o -E '#cmakedefine +[A-Z][A-Z0-9_]{3,}' lib/curl_config.h.cmake | sed -E 's|#cmakedefine +||g' + grep -o -E '#undef +[A-Z][A-Z0-9_]{3,}' lib/curl_config.h.in | sed -E 's|#undef +||g' + } | sort -u | grep -v -F 'HEADER_CURL_' | while read -r def; do + c="$(git grep -w -F "${def}" | grep -v -E -c '(/libcurl\.tmpl|^lib/config-|^lib/curl_config\.h\.cmake|^CMakeLists\.txt|^CMake/Platforms/WindowsCache\.cmake|^packages/vms/config_h\.com|^m4/curl-functions\.m4|^acinclude\.m4|^configure\.ac)')" + if [ "${c}" = '0' ]; then + echo "${def}" + fi + done + ``` + + Reviewed-by: Daniel Stenberg + Closes #9044 + +Daniel Stenberg (19 Jul 2022) +- RELEASE-NOTES: synced + +- cookie: treat a blank domain in Set-Cookie: as non-existing + + This matches what RFC 6265 section 5.2.3 says. + + Extended test 31 to verify. + + Fixes #9164 + Reported-by: Gwen Shapira + Closes #9177 + +- [Patrick Monnerat brought this change] + + base64: base64url encoding has no padding + + See RFC4648 section 5 and RFC7540 section 3.2.1. + + Suppress generation of '=' padding of base64url encoding. This is + accomplished by considering the string beginning at offset 64 in the + character table as the padding: this is "=" for base64, "" for base64url. + + Also use strchr() to replace character search loops where possible. + + Suppress erroneous comments about empty encoding results. + + Adjust unit test 1302 to unpadded base64url encoding and add tests for + empty results. + + Closes #9139 + +- easyoptions: fix icc warning + + easyoptions.c(360): error #188: enumerated type mixed with another type + + Ref: #9156 + Reported-by: Matthew Thompson + Closes #9176 + +- [lwthiker brought this change] + + h2h3: fix overriding the 'TE: Trailers' header + + A 'TE: Trailers' header is explicitly replaced by 'te: trailers' + (lowercase) in Curl_pseudo_headers() when building the list of HTTP/2 or + HTTP/3 headers. However, this is then replaced again by the original + value due to a bug, resulting in the uppercased version being sent. Some + HTTP/2 servers reject the whole HTTP/2 stream when this is the case. + + Closes #9170 + +- lib3026: reduce the number of threads to 100 + + Down from 1000, to make it run and work in more systems. + + Fixes #9172 + Reported-by: Érico Nogueira Rolim + Closes #9173 + +- doh: move doh related struct definitions to doh.h + + and make 'dnstype' in 'struct dnsprobe' use the DNStype to fix the icc compiler warning: + + doh.c(924): error #188: enumerated type mixed with another type + + Reported-by: Matthew Thompson + Ref #9156 + Closes #9174 + +Viktor Szakats (17 Jul 2022) +- Makefile.m32: stop trying to build libcares.a [ci skip] + + Before this patch, `lib/Makefile.m32` had a rule to build `libcares.a` in + `-cares`-enabled builds, via c-ares's own `Makefile.m32`. Committed in + 2007 [1]. The commit message doesn't specifically address this particular + change. This logic comes from the times when c-ares was part of the curl + source tree, hence the special treatment. + + This feature creates problems when building c-ares first, using CMake + and pointing `LIBCARES_PATH` to its install prefix, where `Makefile.m32` + is missing in such case. A sub-build for c-ares is undesired also when + c-ares had already been build via its own `Makefile.m32`. + + To avoid the sub-build, this patch deletes its Makefile rule. After this + patch `libcares.a` needs to be manually built before using it in + `Makefile.m32`. Aligning it with the rest of dependencies. + + [1] 46c92c0b806da041d7a5c6fb64dbcdc474d99b31 + + Reviewed-by: Daniel Stenberg + Closes #9169 + +Daniel Stenberg (17 Jul 2022) +- curl: writeout: fix repeated header outputs + + The function stored a terminating zero into the buffer for convenience, + but when on repeated calls that would cause problems. Starting now, the + passed in buffer is not modified. + + Reported-by: highmtworks on github + Fixes #9150 + Closes #9152 + +- curl_multi_timeout.3: clarify usage + + Fixes #9155 + Closes #9157 + Reported-by: jvvprasad78 on github + +- mprintf: make dprintf_formatf never return negative + + This function no longer returns a negative value if the formatting + string is bad since the return value would sometimes be propagated as a + return code from the mprintf* functions and they are documented to + return the length of the output. Which cannot be negative. + + Fixes #9149 + Closes #9151 + Reported-by: yiyuaner on github + +Viktor Szakats (17 Jul 2022) +- trace: 0x7F character is non-printable + + `0x7F` is `DEL`, a non-printable symbol, so print it as + `UNPRINTABLE_CHAR`. + + Reported-by: MasterInQuestion on github + Fixes #9162 + Closes #9166 + +- doh: use https protocol by default + + The only allowed protocol is https, so it makes sense to use that + by default if not passed explicitly by the user. + + Reported-by: MasterInQuestion on github + Reviewed-by: Jay Satiro + Fixes #9163 + Closes #9165 + +- openssl: fix BoringSSL symbol conflicts with LDAP and Schannel + + Same issue as here [1], but this time when building curl with BoringSSL + for Windows with LDAP(S) or Schannel support enabled. + + Apply the same fix [2] for these source files as well. + + This can also be fixed by moving `#include "urldata.h"` _before_ + including `winldap.h` and `schnlsp.h` respectively. This seems like + a cleaner fix, though I'm not sure why it works and if it has any + downside. + + [1] https://github.com/curl/curl/issues/5669 + [2] https://github.com/curl/curl/commit/fbe07c6829ba8c5793c84c2856526e19e9029ab9 + + Co-authored-by: Jay Satiro + Closes #9110 + +Daniel Stenberg (13 Jul 2022) +- asyn-thread: make getaddrinfo_complete return CURLcode + + ... as the only caller that cares about what it returns assumes that + anyway. This caused icc to warn: + + asyn-thread.c(505): error #188: enumerated type mixed with another type + result = getaddrinfo_complete(data); + + Repoorted-by: Matthew Thompson + Bug: https://github.com/curl/curl/issues/9081#issuecomment-1182143076 + Closes #9146 + +- easy_lock: fix build with icc + + The Intel compiler tries to look like GCC *and* clang *and* it lies in + its __has_builtin() function (returns true when it should return false), + so override it. + + Reported-by: Matthew Thompson + Fixes #9081 + Closes #9144 + +- configure: fix --disable-headers-api + + Reported-by: Michał Antoniak + Fixes #9134 + Closes #9143 + +- test3026: require 'threadsafe' + + Reported-by: Sukanya Hanumanthu + Fixes #9141 + Closes #9142 + +- [Even Rouault brought this change] + + CMake: link curl to its dependencies with PRIVATE + + The current PUBLIC visibility causes issues for downstream users. + Cf https://github.com/OSGeo/PROJ/pull/3172#issuecomment-1157942986 + + Reviewed-by: Jakub Zakrzewski + Closes #9125 + +- [Even Rouault brought this change] + + CMake: remove APPEND in export(TARGETS) + + When running cmake several times, new content was appended to already + existing generated files, which is not appropriate + + Reviewed-by: Jakub Zakrzewski + Closes #9124 + +- [Tatsuhiro Tsujikawa brought this change] + + ngtcp2: implement cb_h3_stop_sending and cb_h3_reset_stream callbacks + + Closes #9135 + +- RELEASE-NOTES: synced + +Viktor Szakats (11 Jul 2022) +- build: improve OS string in CMake and `config-win32.h` + + This patch makes CMake fill the "OS string" with the value of + `CMAKE_C_COMPILER_TARGET`, if passed. This typically contains a triplet, + the same we can pass to `./configure` via `--host=`. + + For non-CMake, non-autotools, Windows builds, this patch adds the ability + to override the default `OS` value in `lib/config-win32.h`. + + With these its possible to get the same OS string across the three build + systems. + + This patch supersedes the earlier, partial, CMake-only solution: + 435f395f3f8c11eebfcc243ca55ebcc11a19b8b8, thus retiring the + `CURL_OS_SUFFIX` CMake option. + + Reviewed-by: Jay Satiro + Closes #9117 + +- Makefile.m32: add `CURL_RC` and `CURL_STRIP` variables [ci skip] + + They allow to override the hardcoded values for the `windres` and `strip` + tools, complementing the existing set of `CURL_{CC,AR,RANLIB}` variables. + + `CURL_RC` comes handy when using LLVM tools with `CROSSPREFIX=llvm-` and + `CURL_CC=clang` set on current latest debian:unstable or earlier, where + `llvm-windres` is missing, and a `CURL_RC=<triplet>-windres` fixes it. + Hopefully this will be fixed in the llvm package. FWIW `llvm-windres` + does exist in Homebrew llvm, MSYS2 llvm and llvm-mingw. + + Reviewed-by: Daniel Stenberg + Closes #9132 + +Daniel Stenberg (10 Jul 2022) +- [Tatsuhiro Tsujikawa brought this change] + + ngtcp2: fix stall or busy loop on STOP_SENDING with upload data + + Fixes #9122 + Closes #9123 + +- [Xiaoke Wang brought this change] + + tool_operate: better cleanup of easy handle in exit path + + Closes #9114 + +- [Xiaoke Wang brought this change] + + getinfo: return better error on NULL as first argument + + Closes #9114 + +- tool_getparam: repair cleanarg + + Regression since 9e5669f. + + Make sure the "cleaning" of command line arguments is done on the + original argv[] pointers. As a bonus, it also exits better on out of + memory error. + + Reported-by: Litter White + Fixes #9128 + Closes #9130 + +Jay Satiro (10 Jul 2022) +- docs: explain curl_easy_escape/unescape curl handle is ignored + + 26101421 (precedes 7.82.0) removed character conversion support used by + very old legacy operating systems and since then the curl handle passed + to curl_easy_escape/unescape is always ignored. + + Bug: https://github.com/curl/curl/discussions/9115 + Reported-by: Ted Lyngmo + + Closes https://github.com/curl/curl/pull/9121 + +Viktor Szakats (8 Jul 2022) +- openssl: add `CURL_BORINGSSL_VERSION` to identify BoringSSL + + BoringSSL doesn't keep a version number, and doesn't self-identify itself + via any other revision number via its own headers. We can identify + BoringSSL revisions by their commit hash. This hash is typically known by + the builder. This patch adds a way to pass this hash to libcurl, so that + it can display in the curl version string: + + For example: + + `CFLAGS=-DCURL_BORINGSSL_VERSION="c239ffd0"` + + ``` + curl 7.84.0 (x86_64-w64-mingw32) libcurl/7.84.0 BoringSSL/c239ffd0 (Schannel) zlib/1.2.12 [...] + Release-Date: 2022-06-27 + Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 [...] + Features: alt-svc AsynchDNS brotli gsasl HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos [...] + ``` + + The setting is optional, and if not passed, BoringSSL will appear without + a version number, like before this patch. + + Closes #9113 + +Jay Satiro (8 Jul 2022) +- escape: remove outdated comment + + Bug: https://github.com/curl/curl/discussions/9115 + Reported-by: Ted Lyngmo + +- [Tatsuhiro Tsujikawa brought this change] + + ngtcp2: Fix missing initialization of nghttp3_nv.flags + + Closes https://github.com/curl/curl/pull/9118 + +Daniel Stenberg (6 Jul 2022) +- [Brad Forschinger brought this change] + + netrc.d: remove spurious quote + + Closes #9111 + +Viktor Szakats (6 Jul 2022) +- Makefile.m32: add `NGTCP2_LIBS` option [ci skip] + + Makefile.m32's ngtcp2 has its two libs hardwired for OpenSSL. + Add `NGTCP2_LIBS` envvar to override them with a custom list, + making it possible to use BoringSSL, or any other backend. + + Closes #9109 + +Jay Satiro (6 Jul 2022) +- [Evgeny Grin (Karlson2k) brought this change] + + digest: fix missing increment of 'nc' value for auth-int + + - Increment nc regardless of qop type. + + Prior to this change nc was only incremented for qop type auth even + though libcurl sends nc with any qop. + + Closes https://github.com/curl/curl/pull/9090 + +Daniel Stenberg (5 Jul 2022) +- RELEASE-NOTES: synced + + Bumped to 7.85.0 + +- urldata: reduce size of four ftp related members + + ftp_filemethod, ftpsslauth and ftp_ccc are now uchars + + accepttimeout is now unsigned int - almost 50 days ought to be enough + for this value. + + Closes #9106 + +- urldata: reduce three type-members from int to uchar + + - timecondition + - proxytype + - method + + ... previously used their enum type in the struct, which made them + unnecesarily large. + + Closes #9105 + +- CURLOPT_SERVER_RESPONSE_TIMEOUT: the new name + + Starting now, CURLOPT_FTP_RESPONSE_TIMEOUT is the alias instead of the + other way around. + + Since 7.20.0, CURLOPT_SERVER_RESPONSE_TIMEOUT has existed as an alias + but since the option is for more protocols than FTP the more "correct" + version of the option is the "server" one so now we switch. + + Closes #9104 + +- urldata: make 'ftp_create_missing_dirs' a uchar + + It only ever holds the values 0-2. + + Closes #9103 + +- [Don J Olmstead brought this change] + + cmake: support ngtcp2 boringssl backend + + Update the ngtcp2 find module to detect the boringssl backend. Determine + if the underlying OpenSSL implementation is BoringSSL and if so use that + as the ngtcp2 backend. + + Reviewed-by: Jakub Zakrzewski + Closes #9065 + +- urldata: change 4 timeouts to unsigned int from long + + They're not used for that long times anyway, 32 bit milliseconds is long + enough. + + Closes #9101 + +- urldata: make 'use_netrc' a uchar + + Closes #9102 + +- urldata: make 'buffer_size' an unsigned int + + It is already capped at READBUFFER_MAX which fits easily in 32 bits. + + Closes #9098 + +- urldata: remove the unused 'rtspversion' struct member + + Closes #9100 + +- urldata: make 'use_port' an usigned short + + ... instead of a long. It is already enforced to not attempt to set any + value outside of 16 bits unsigned. + + Closes #9099 + +- urldata: store dns cache timeout in an int + + 68 years ought to be enough for most. + + Closes #9097 + +- curl: proto2num: make sure obuf is inited + + Detected by Coverity. CID 1507052. + + Closes #9096 + +- cookie: use %zu to infof() for size_t values + + Detected by Coverity. CID 1507051 + Closes #9095 + +Viktor Szakats (4 Jul 2022) +- makefile.m32: add support for custom ARCH [ci skip] + + When building curl for target platform other than x64 and x86, it is now + possible to pass `ARCH=custom`, that will omit all hardcoded logic for + setting up CFLAGS/LDFLAGS/RCFLAGS for these platforms, and let these be + customized via `CURL_CFLAG_EXTRAS`, `CURL_LDFLAG_EXTRAS`, and a newly + added one for the resource compiler: `CURL_RCFLAG_EXTRAS`. + + This makes it possible to use `makefile.m32` to build for ARM64 for + example. + + Reviewed-by: Daniel Stenberg + Closes #9092 + +- cmake: do not force Windows target versions + + The goal of this patch is to avoid CMake forcing specific Windows + versions and rely on toolchain defaults or manual selection instead. + This gives back control to the user. This also brings CMake closer to + how autotools and `Makefile.m32` behaves in this regard. + + - CMake had a setting `ENABLE_INET_PTON` defaulting to `ON`, which did + nothing else than fixing the Windows build target to Vista. This also + happened when the toolchain did not have Vista support (e.g. original + MinGW), breaking such builds. + + In other environments it did not make a user-facing difference, + because libcurl has its own pton() implementation, so it works well + with or without Vista's inet_pton(). + + This patch drops this setting. inet_pton() is now used whenever + building for Vista or newer, either when requested manually or by + default with modern toolchains (e.g. mingw-w64). Older envs will fall + back to curl's pton(). + + Ref: https://github.com/curl/curl/pull/9027#issuecomment-1164157604 + Ref: https://github.com/curl/curl/pull/8997#issuecomment-1164344155 + + - When the user did no select a Windows target version manually, stop + explicitly targeting Windows XP, and instead use the toolchain default. + + This may pose an issue with old toolchains defaulting to pre-XP + targets. In such case you must manually target Windows XP via: + `-DCURL_TARGET_WINDOWS_VERSION=0x0501` + or + `-DCMAKE_C_FLAGS=-D_WIN32_WINNT=0x0501` + + Reviewed-by: Jay Satiro + Reviewed-by: Marcel Raad + Closes #9046 + +- windows: improve random source + + - Use the Windows API to seed the fallback random generator. + + This ensures to always have a random seed, even when libcurl is built + with a vtls backend lacking a random generator API, such as rustls + (experimental), GSKit and certain mbedTLS builds, or, when libcurl is + built without a TLS backend. We reuse the Windows-specific random + function from the Schannel backend. + + - Implement support for `BCryptGenRandom()` [1] on Windows, as a + replacement for the deprecated `CryptGenRandom()` [2] function. + + It is used as the secure random generator for Schannel, and also to + provide entropy for libcurl's fallback random generator. The new + function is supported on Vista and newer via its `bcrypt.dll`. It is + used automatically when building for supported versions. It also works + in UWP apps (the old function did not). + + - Clear entropy buffer before calling the Windows random generator. + + This avoids using arbitrary application memory as entropy (with + `CryptGenRandom()`) and makes sure to return in a predictable state + when an API call fails. + + [1] https://docs.microsoft.com/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom + [2] https://docs.microsoft.com/windows/win32/api/wincrypt/nf-wincrypt-cryptgenrandom + + Closes #9027 + +Daniel Stenberg (4 Jul 2022) +- setopt: add CURLOPT_PROTOCOLS_STR and CURLOPT_REDIR_PROTOCOLS_STR + + ... as replacements for deprecated CURLOPT_PROTOCOLS and + CURLOPT_REDIR_PROTOCOLS as these new ones do not risk running into the + 32 bit limit the old ones are facing. + + CURLINFO_PROTCOOL is now deprecated. + + The curl tool is updated to use the new options. + + Added test 1597 to verify the libcurl protocol parser. + + Closes #8992 + +- digest: simplify a switch() to a simple if + +- digest: provide a special bit for "sess" algos + + Also shortened the names and moved them to the .c file since they are + private for this source file only. Also made them #defines instead of + enum. + + Closes #9079 + +Jay Satiro (4 Jul 2022) +- [Thomas Weißschuh brought this change] + + select: do not return fatal error on EINTR from poll() + + The same was done for select() in 5912da25 but poll() was missed. + + Bug: https://bugs.archlinux.org/task/75201 + Reported-by: Alexandre Bury (gyscos at archlinux) + + Ref: https://github.com/curl/curl/issues/8921 + Ref: https://github.com/curl/curl/pull/8961 + Ref: https://github.com/curl/curl/commit/5912da25#r77584294 + + Closes https://github.com/curl/curl/pull/9091 + +- [Kai Pastor brought this change] + + cmake: fix build for mingw cross compile + + - Change normaliz lib name to all lowercase. + + This is from a standing patch in vcpkg: + Mingw has libnormaliz.a. For case-sensitive file systems (e.g. cross + builds from Linux), the spelling must match exactly. + + Closes https://github.com/curl/curl/pull/9084 + +- easy_lock: fix build for mingw + + - Define SRWLOCK symbols missing in some mingw environments. + + Closes https://github.com/curl/curl/pull/8997 + +Daniel Stenberg (2 Jul 2022) +- tool_progress: avoid division by zero in parallel progress meter + + Reported-by: Brian Carpenter + Fixes #9082 + Closes #9083 + +- http_aws_sigv4.c: remove two unusued includes + + Closes #9080 + +- .mailmap: additional edit + + Follow-up to 861e2a8aca6c7 so that Evgeny appears with the same in git + logs even when using old email. + +- RELEASE-NOTES: synced + + bumped to 7.84.1 + +- [Evgeny Grin (Karlson2k) brought this change] + + .mailmap: updated + +- [Evgeny Grin (Karlson2k) brought this change] + + THANKS: merged two entries for Evgeny Grin + + Also updated THANKS-filter file + + Closes #9076 + +- [Jilayne Lovejoy brought this change] + + lib/curl_path.c: add ISC to license expression + + THe text of the ISC license is in this file, so the SPDX license + expression should be updated + + Closes #9073 + +- [Sean McArthur brought this change] + + hyper: use wakers for curl pause/resume + + Closes #9070 + +Viktor Szakats (30 Jun 2022) +- Makefile.m32: do not set the libcurl.rc debug flag [ci skip] + + Delete `-DDEBUGBUILD=0` windres option. This was likely meant to + disable VS_FF_DEBUG in FILEFLAGS, but any assigned value enabled + it instead. Delete this unnecessary option and thus sync up with + how CMake compiles libcurl.rc by default. + + Reviewed-by: Jay Satiro + Closes #9069 + +Daniel Stenberg (29 Jun 2022) +- curl.h: CURLE_CONV_FAILED is obsoleted + + The last use was removed in 7.82.0. Updated some docs too to reflect the + current error code situation. + + Closes #9067 + +- curl: output warning when a cookie is dropped due to size + + Dropped from the request, that is. + + Closes #9064 + +- curl_mime_data.3: polish the wording + + Closes #9063 + +- configure: check for the stdatomic.h header in configure + + ... and only set HAVE_ATOMIC if that header exists since we use + typedefes set in it. + + Reported-by: Ryan Schmidt + Fixes #9059 + Closes #9060 + +- easy_lock: fix the #ifdef conditional for ia32_pause + + To work better with new and old clang compilers. + + Reported-by: Ryan Schmidt + Assisted-by: Joshua Root + + Fixes #9058 + Closes #9062 + +- easy_lock: switch to using atomic_int instead of bool + + To work with more compilers without requiring separate libs to + link. Like with gcc-12 for RISC-V on Linux. + + Reported-by: Adam Sampson + Fixes #9055 + Closes #9061 + +- [vvb2060 brought this change] + + ngtcp2: fix incompatible function pointer types + + Closes #9056 + +- [vvb2060 brought this change] + + easy_lock.h: use __asm__ instead of asm to fix build + + Closes #9056 + +- [Samuel Henrique brought this change] + + libcurl-security.3: fix typo on macro "SH_" + + During the packaging of the latest curl release for Debian, Lintian + warned me about a typo which causes the section name "Secrets in memory" + to not be rendered in the manpage due to "SH_" not being recognized as a + header. + + Closes #9057 + +- easy_lock.h: include sched.h if available to fix build + + Patched-by: Harry Sintonen + + Closes #9054 + Version 7.84.0 (27 Jun 2022) Daniel Stenberg (27 Jun 2022) @@ -265,7 +5638,7 @@ Daniel Stenberg (20 Jun 2022) Closes #9028 -- [Philip H brought this change] +- [Philip Heiduck brought this change] CI: bump FreeBSD 13.0 to 13.1 @@ -748,7 +6121,7 @@ Daniel Stenberg (7 Jun 2022) Closes #8910 -- [Evgeny Grin brought this change] +- [Evgeny Grin (Karlson2k) brought this change] digest: tolerate missing "realm" @@ -757,7 +6130,7 @@ Daniel Stenberg (7 Jun 2022) Closes #8912 -- [Evgeny Grin brought this change] +- [Evgeny Grin (Karlson2k) brought this change] digest: added detection of more syntax error in server headers @@ -766,7 +6139,7 @@ Daniel Stenberg (7 Jun 2022) Closes #8912 -- [Evgeny Grin brought this change] +- [Evgeny Grin (Karlson2k) brought this change] digest: unquote realm and nonce before processing @@ -1924,7 +7297,7 @@ Daniel Gustafsson (5 May 2022) Daniel Stenberg (5 May 2022) - docs/THANKS: remove name duplicate -- [Philip H brought this change] +- [Philip Heiduck brought this change] .mailmap: update @@ -2014,7 +7387,7 @@ Daniel Gustafsson (2 May 2022) Reviewed-by: Daniel Stenberg <daniel@haxx.se> Daniel Stenberg (2 May 2022) -- [Philip H brought this change] +- [Philip Heiduck brought this change] misc: use "autoreconf -fi" instead buildconf @@ -2022,7 +7395,7 @@ Daniel Stenberg (2 May 2022) Closes #8777 Daniel Gustafsson (2 May 2022) -- [Philip H brought this change] +- [Philip Heiduck brought this change] cirrus: Use pip for Python packages on FreeBSD @@ -2032,7 +7405,7 @@ Daniel Gustafsson (2 May 2022) Closes: #8783 Reviewed-by: Daniel Gustafsson <daniel@yesql.se> -- [Philip H brought this change] +- [Philip Heiduck brought this change] cirrus: Update to FreeBSD 12.3 @@ -2314,7 +7687,7 @@ Daniel Stenberg (27 Apr 2022) Bug: https://hackerone.com/reports/1548535 Closes #8742 -- [Philip H brought this change] +- [Philip Heiduck brought this change] mlc: curl.zuul.vexxhost.dev is reachable again @@ -3024,7 +8397,7 @@ Marc Hoersken (23 Mar 2022) Closes #8594 Daniel Stenberg (22 Mar 2022) -- [Philip H brought this change] +- [Philip Heiduck brought this change] firefox-db2pem.sh: make the shell script safer @@ -3072,7 +8445,7 @@ Daniel Stenberg (22 Mar 2022) Closes #8623 -- [Philip H brought this change] +- [Philip Heiduck brought this change] ci/event-based.yml: improve impacket install @@ -3195,7 +8568,7 @@ Daniel Stenberg (22 Mar 2022) - scripts/copyright.pl: ignore the new mlc_config.json file -- [Philip H brought this change] +- [Philip Heiduck brought this change] mlc_config.json: add file to ignore known troublesome URLs @@ -3205,7 +8578,7 @@ Daniel Stenberg (22 Mar 2022) Closes #8597 -- [Philip H brought this change] +- [Philip Heiduck brought this change] winbuild/README.md: fixup dead link @@ -3273,7 +8646,7 @@ Daniel Stenberg (17 Mar 2022) Closes #8601 -- [Philip H brought this change] +- [Philip Heiduck brought this change] CI: Do not use buildconf. Instead, just use: autoreconf -fi @@ -3490,3966 +8863,3 @@ Daniel Stenberg (9 Mar 2022) connect: make Curl_getconnectinfo work with conn cache from share handle Closes #8524 - -- [lwthiker brought this change] - - openssl: enable CURLOPT_SSL_EC_CURVES with BoringSSL - - The CURLOPT_SSL_EC_CURVES option (used by the '--curves' flag) in - libcurl was ignored when compiling with BoringSSL because - HAVE_SSL_CTX_SET_EC_CURVES was explicitly disabled if BoringSSL was - detected. However, this feature is supported in BoringSSL since - 5fd1807d. This commit enables it, and also reduces the required minimal - OpenSSL version to 1.0.2 as per OpenSSL's official documentation. - - Fixes #8553 - Closes #8556 - -- [Samuel Henrique brought this change] - - json.d: fix typo (overriden -> overridden) - - Closes #8557 - -- wolfssl: fix compiler error without IPv6 - - Reported-by: Joseph Chen - Fixes #8550 - Closes #8552 - -- RELEASE-NOTES: synced - - and bump pending version to 7.82.1 - -- [Paul Howarth brought this change] - - runtests: make 'oldlibssh' be before 0.9.4 - - The 'oldlibssh' feature indicates that the error code returned by libssh - for a broken known_hosts file should be 67 rather than 60 (test1459). - This feature was added as part of #8444 with 'oldlibssh' mapping to - libssh versions prior to 0.9.6, and then refined as part of #8511 to map - to versions prior to 0.9.5. - - In Red Hat Enterprise Linux 8.5 there is a patched version of libssh - version 0.9.4 (https://git.centos.org/rpms/libssh/blob/c8/f/SOURCES) in - which test1459 fails because it returns the "new" value rather than the - "old" one. It's plausible that one of the patches is responsible for - this rather than the underlying code but I don't think so. - - This change therefore drops the 'oldlibssh' version check to map to - libssh versions older than 0.9.4, which fixes builds on RHEL-8. - - Closes #8548 - -- ipv4/6.d: clarify that they are about using IP addresses - - ... they may still *resolve* other families, but not use those - addresses. - - Ref: #8530 - Closes #8543 - -- [r-a-sattarov brought this change] - - curl/system.h: update ifdef condition for MCST-LCC compiler - - in mcst-lcc compiler => 1.25 added a new macro definition to determine - compiler - - Closes #8546 - -Marc Hoersken (6 Mar 2022) -- CI: install Python package impacket to run SMB test 1451 - - Install Python package impacket in relevant CI workflows. - - Follow up to #7935 - Supersedes #7940 - Closes #8544 - -Daniel Stenberg (5 Mar 2022) -- [Michał Antoniak brought this change] - - connect: use TCP_KEEPALIVE only if TCP_KEEPIDLE is not defined - - Closes #8539 - -- docs/HYPER.md: updated to reflect current hyper build needs - -- GHA: build hyper with nightly rustc - - Closes #8545 - -Version 7.82.0 (5 Mar 2022) - -Daniel Stenberg (5 Mar 2022) -- RELEASE-NOTES: synced - - The 7.82.0 release - -- THANKS: updates from the 7.82.0 release notes - -- misc: update copyright year ranges - -Jay Satiro (5 Mar 2022) -- unit1610: init SSL library before calling SHA256 functions - - The SSL library must be initialized (via global initialization) because - libcurl's SHA256 functions may call SHA256 functions in the SSL library. - - Reported-by: Gisle Vanem - - Fixes https://github.com/curl/curl/issues/8538 - Closes https://github.com/curl/curl/pull/8540 - -- examples/curlx: support building with OpenSSL 1.1.0+ - - - Access members of X509_STORE_CTX in OpenSSL 1.1.0+ by using API - functions. - - The X509_STORE_CTX struct has been opaque since OpenSSL 1.1.0. - - Ref: https://curl.se/mail/lib-2022-03/0004.html - - Closes https://github.com/curl/curl/pull/8529 - -- h2h3: fix typo - - Bug: https://github.com/curl/curl/issues/8381#issuecomment-1055440241 - Reported-by: Michael Kaufmann - -- [Farzin brought this change] - - CURLOPT_XFERINFOFUNCTION.3: fix example struct assignment - - Closes https://github.com/curl/curl/pull/8519 - -Daniel Stenberg (26 Feb 2022) -- azure-pipelines: add a build on Windows with libssh - - Closes #8511 - -- runtests: make 'oldlibssh' be before 0.9.5 - - Closes #8511 - -- libssh: fix include files and defines use for Windows builds - - Reported-by: 梦终无痕 - Bug: https://curl.se/mail/lib-2022-02/0131.html - Closes #8511 - -- RELEASE-NOTES: synced - -- [illusory-dream brought this change] - - winbuild: add parameter WITH_SSH - - For building with libssh - Closes #8514 - -- configure: change output for cross-compiled alt-svc support - - It said 'no', while it actually is 'yes' - - Closes #8512 - -- gha: add a macOS CI job with libssh - - Closes #8513 - -- TODO: remove "Bring back libssh tests on Travis" - - The job was added to Circle CI in d8ddd0e7536 - -- TODO: remove "better persistency for HTTP/1.0" - - Let's not bother. - -- TODO: remove "Option to ignore private IP" - - ... as curl ignores the IP entirely by default these days. - -- TODO: remove "hardcode the "localhost" addresses" - - This is implmented since 1a0ebf6632f88 - -- TODO: 1.24 was a dupe of 1.1 - -- TODO: remove "Typesafe curl_easy_setopt()" - - I don't consider this a serious TODO item - -- KNOWN_BUGS: remove "Uploading HTTP/3 files gets interrupted" - - This works now - -- KNOWN_BUGS: remove "HTTP/3 multipart POST with quiche fails" - - It works now - -- quiche: remove two leftover debug infof() outputs - -- [Tatsuhiro Tsujikawa brought this change] - - ngtcp2: Reset dynbuf when it is fully drained - - Reported-by: vl409 on github - Fixes #7351 - Closes #8504 - -- [Stewart Gebbie brought this change] - - hostip: avoid unused parameter error in Curl_resolv_check - - When built without DNS-over-HTTP and without asynchronous resolvers, - neither the dns nor the data parameters are used. - - That is Curl_resolv_check appears to call - Curl_resolver_is_resolved(data, dns). But, - with CURL_DISABLE_DOH without CURLRES_ASYNCH, the call is actually - elided via a macro definition. - - This fix resolves the resultant: "unused parameter 'data'" error. - - Closes #8505 - -- http2: move two infof calls to debug-h2-only - - and remove a superflous one - - Ref: https://github.com/curl/curl/discussions/8498 - Closes #8502 - -- [Jean-Philippe Menil brought this change] - - quiche: fix upload for bigger content-length - - Signed-off-by: Jean-Philippe Menil <jpmenil@gmail.com> - Closes #8421 - -Jay Satiro (23 Feb 2022) -- [Farzin brought this change] - - CURLOPT_PROGRESSFUNCTION.3: fix example struct assignment - - Closes https://github.com/curl/curl/pull/8500 - -Daniel Stenberg (22 Feb 2022) -- [Rob Boeckermann brought this change] - - OS400/README: clarify compilation steps - - Closes #8494 - -- [Rob Boeckermann brought this change] - - OS400: fix typos in rpg include file - - This resolves issues compiling rpg code that includes the curl header - file. - - Closes #8494 - -- [Michał Antoniak brought this change] - - vtls: fix socket check conditions - - fix condition to check the second socket during associate and - disassociate connection - - Closes #8493 - -- libssh2: don't typecast socket to int for libssh2_session_handshake - - Since libssh2_socket_t uses SOCKET on windows which can be larger than - int. - - Closes #8492 - -- RELEASE-NOTES: fix typo and make one desc shorter - -- RELEASE-NOTES: synced - -- CURLOPT_XFERINFOFUNCTION.3: fix typo in example - - Reported-by: coralw on github - Fixes #8487 - Closes #8488 - -- README: disable linkchecks for the sponsor links - - Closes #8489 - -Jay Satiro (21 Feb 2022) -- openssl: check if sessionid flag is enabled before retrieving session - - Ideally, Curl_ssl_getsessionid should not be called unless sessionid - caching is enabled. There is a debug assertion in the function to help - ensure that. Therefore, the pattern in all vtls is basically: - - if(primary.sessionid) {lock(); Curl_ssl_getsessionid(...); unlock();} - - There was one instance in openssl.c where sessionid was not checked - beforehand and this change fixes that. - - Prior to this change an assertion would occur in openssl debug builds - during connection stage if session caching was disabled. - - Reported-by: Jim Beveridge - - Fixes https://github.com/curl/curl/issues/8472 - Closes https://github.com/curl/curl/pull/8484 - -- multi: allow user callbacks to call curl_multi_assign - - Several years ago a change was made to block user callbacks from calling - back into the API when not supported (recursive calls). One of the calls - blocked was curl_multi_assign. Recently the blocking was extended to the - multi interface API, however curl_multi_assign may need to be called - from within those user callbacks (eg CURLMOPT_SOCKETFUNCTION). - - I can't think of any callback where it would be unsafe to call - curl_multi_assign so I removed the restriction entirely. - - Reported-by: Michael Wallner - - Ref: https://github.com/curl/curl/commit/b46cfbc - Ref: https://github.com/curl/curl/commit/340bb19 - - Fixes https://github.com/curl/curl/issues/8480 - Closes https://github.com/curl/curl/pull/8483 - -Daniel Stenberg (21 Feb 2022) -- [Michał Antoniak brought this change] - - ssl: reduce allocated space for ssl backend when FTP is disabled - - Add assert() for the backend pointer in many places - - Closes #8471 - -- [Michał Antoniak brought this change] - - checkprefix: remove strlen calls - - Closes #8481 - -Jay Satiro (20 Feb 2022) -- [1337vt brought this change] - - curl.h: fix typo - - Closes https://github.com/curl/curl/pull/8482 - -- [Jan Venekamp brought this change] - - sectransp: mark a 3DES cipher as weak - - - Change TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA strength to weak. - - All other 3DES ciphers are already marked as weak. - - Closes https://github.com/curl/curl/pull/8479 - -- [Jan Venekamp brought this change] - - bearssl: fix EXC_BAD_ACCESS on incomplete CA cert - - - Do not create trust anchor object for a CA certificate until after it - is processed. - - Prior to this change the object was created at state BR_PEM_BEGIN_OBJ - (certificate processing begin state). An incomplete certificate (for - example missing a newline at the end) never reaches BR_PEM_END_OBJ - (certificate processing end state) and therefore the trust anchor data - was not set in those objects, which caused EXC_BAD_ACCESS. - - Ref: https://github.com/curl/curl/pull/8106 - - Closes https://github.com/curl/curl/pull/8476 - -- [Jan Venekamp brought this change] - - bearssl: fix connect error on expired cert and no verify - - - When peer verification is disabled use the x509_decode engine instead - of the x509_minimal engine to parse and extract the public key from - the first cert of the chain. - - Prior to this change in such a case no key was extracted and that caused - CURLE_SSL_CONNECT_ERROR. The x509_minimal engine will stop parsing if - any validity check fails but the x509_decode won't. - - Ref: https://github.com/curl/curl/pull/8106 - - Closes https://github.com/curl/curl/pull/8475 - -- [Jan Venekamp brought this change] - - bearssl: fix session resumption (session id) - - Prior to this change br_ssl_client_reset was mistakenly called with - resume_session param set to 0, which disabled session resumption. - - Ref: https://github.com/curl/curl/pull/8106 - - Closes https://github.com/curl/curl/pull/8474 - -Daniel Stenberg (18 Feb 2022) -- [Michał Antoniak brought this change] - - openssl: fix build for version < 1.1.0 - - Closes #8470 - -- [Joel Depooter brought this change] - - schannel: move the algIds array out of schannel.h - - This array is only used by the SCHANNEL_CRED struct in the - schannel_acquire_credential_handle function. It can therefore be kept as - a local variable. This is a minor update to - bbb71507b7bab52002f9b1e0880bed6a32834511. - - This change also updates the NUM_CIPHERS value to accurately count the - number of ciphers options listed in schannel.c, which is 47 instead of - 45. It is unlikely that anyone tries to set all 47 values, but if they - had tried, the last two would not have been set. - - Closes #8469 - -- [Alejandro R. Sedeño brought this change] - - configure.ac: use user-specified gssapi dir when using pkg-config - - Using the system pkg-config path in the face of a user-specified - library path is asking to link the wrong library. - - Reported-by: Michael Kaufmann - Fixes #8289 - Closes #8456 - -- [Kevin Adler brought this change] - - os400: Add link to QADRT devkit to README.OS400 - - Closes #8455 - -- [Kevin Adler brought this change] - - os400: Add function wrapper for system command - - The wrapper will exit if the system command failed instead of blindly - continuing on. - - In addition, only copy docs which exist, since now the copy failure will - cause the build to stop. - - Closes #8455 - -- [Kevin Adler brought this change] - - os400: Default build to target current release - - V6R1M0 is not available as a target release since IBM i 7.2. To keep - from having to keep this up to date in git, default to the current - release. Users can configure this to whatever release they want to - actually build for. - - Closes #8455 - -- docs/INTERNALS.md: clean up, refer to the book - - The explanatory parts are now in the everything curl book (which can - also use images etc). This document now refers to that resource and only - leaves listings of supported versions of libs, tools and operating - systems. See https://everything.curl.dev/internals - - Closes #8467 - -Marcel Raad (17 Feb 2022) -- des: fix compile break for OpenSSL without DES - - When `USE_OPENSSL` was defined but OpenSSL had no DES support and a - different crypto library was used for that, `Curl_des_set_odd_parity` - was called but not defined. This could for example happen on Windows - and macOS when using OpenSSL v3 with deprecated features disabled. - - Use the same condition for the function definition as used at the - caller side, but leaving out the OpenSSL part to avoid including - OpenSSL headers. - - Closes https://github.com/curl/curl/pull/8459 - -Daniel Stenberg (17 Feb 2022) -- RELEASE-NOTES: synced - -- docs/DEPRECATE: remove NPN support in August 2022 - - Closes #8458 - -- ftp: provide error message for control bytes in path - - Closes #8460 - -- http: fix "unused parameter ‘conn’" warning - - Follow-up from 7d600ad1c395 - - Spotted on appveyor - - Closes #8465 - -Jay Satiro (17 Feb 2022) -- [Alejandro R. Sedeño brought this change] - - sha256: Fix minimum OpenSSL version - - - Change the minimum OpenSSL version for using their SHA256 - implementation from 0.9.7 to 0.9.8. - - EVP_sha256() does not appear in the OpenSSL source before 0.9.7h, and - does not get built by default until 0.9.8, so trying to use it for all - 0.9.7 is wrong, and before 0.9.8 is unreliable. - - Closes https://github.com/curl/curl/pull/8464 - -Daniel Stenberg (16 Feb 2022) -- KNOWN_BUGS: remove "slow connect to localhost on Windows" - - localhost is not resolved anymore since 1a0ebf6632f88 - -- KNOWN_BUGS: remove "HTTP/3 download is 5x times slower than HTTP/2" - - It's not actually a bug. More like room for improvement. - -- KNOWN_BUGS: remove "HTTP/3 download with quiche halts after a while" - - Follow-up to 96f85a0fef694 - -- KNOWN_BUGS: remove "pulseUI vpn" as a problem - - We haven't heard about this for a long time and rumours have it they - might have fixed it. - -- urldata: remove conn->bits.user_passwd - - The authentication status should be told by the transfer and not the - connection. - - Reported-by: John H. Ayad - Fixes #8449 - Closes #8451 - -- [Kevin Adler brought this change] - - gskit: Convert to using Curl_poll - - As mentioned in 32766cb, gskit was the last user of Curl_select which is - now gone. Convert to using Curl_poll to allow build to work on IBM i. - - Closes #8454 - -- [Kevin Adler brought this change] - - gskit: Fix initialization of Curl_ssl_gskit struct - - In c30bf22, Curl_ssl_getsock was factored out in to a member of - struct Curl_ssl but the gskit initialization was not updated to reflect - this new member. - - Closes #8454 - -- [Kevin Adler brought this change] - - gskit: Fix errors from Curl_strerror refactor - - 2f0bb864c1 replaced sterror with Curl_strerror, but the strerror buffer - shadows the set_buffer "buffer" parameter. To keep consistency with the - other functions that use Curl_strerror, rename the parameter. - - In addition, strerror.h is needed for the definition of STRERROR_LEN. - - Closes #8454 - -Marcel Raad (15 Feb 2022) -- ntlm: remove unused feature defines - - They're not used anymore and always supported. - - Closes https://github.com/curl/curl/pull/8453 - -Daniel Stenberg (15 Feb 2022) -- [Kantanat Wannapaka brought this change] - - README.md: fix link and layout - - replace <a></a> tags and <img></img> tags - - Closes #8448 - -- KNOWN_BUGS: fix typo "libpsl" - -Jay Satiro (14 Feb 2022) -- h2h3: fix compiler warning due to function prototype mismatch - - - Add missing const qualifier in Curl_pseudo_headers declaration. - -Daniel Stenberg (14 Feb 2022) -- [Stefan Eissing brought this change] - - urlapi: handle "redirects" smarter - - - avoid one malloc when setting a new url via curl_url_set() - and CURLUPART_URL. - - extract common pattern into a new static function. - - Closes #8450 - -- cijobs: pick up circleci configure lines better - -- circleci: add a job using wolfSSH - - Build only, no tests. - - Closes #8445 - -- scripts/ciconfig.pl: show used options not available - -- circleci: add a job using libssh - - Closes #8444 - -- runtests: set 'oldlibssh' for libssh versions before 0.9.6 - - ... and make test 1459 check for the different return code then. - - Closes #8444 - -Jay Satiro (13 Feb 2022) -- Makefile.am: Generate VS 2022 projects - - Follow-up to f13d4d0 which added VS 2022 project support. - - Ref: https://github.com/curl/curl/pull/8438 - -- [Daniel Stenberg brought this change] - - projects: remove support for MSVC before VC10 (Visual Studio 2010) - - - Remove Visual Studio project files for VC6, VC7, VC7.1, VC8 and VC9. - - Those versions are too old to be maintained any longer. - - Closes https://github.com/curl/curl/pull/8442 - -- [Stav Nir brought this change] - - projects: add support for Visual Studio 17 (2022) - - Closes https://github.com/curl/curl/pull/8438 - -Daniel Stenberg (13 Feb 2022) -- RELEASE-NOTES: synced - -- connect: follow-up fix the copyright year - -- [Michał Antoniak brought this change] - - misc: remove unused data when IPv6 is not supported - - Closes #8430 - -- scripts/ciconfig: show CI job config info - - Closes #8446 - -- quiche: handle stream reset - - A stream reset now causes a CURLE_PARTIAL_FILE error. I'm not convinced - this is the right action nor the right error code. - - Reported-by: Lucas Pardue - Fixes #8437 - Closes #8440 - -- mime: use a define instead of the magic number 24 - - MIME_BOUNDARY_DASHES is now the number of leading dashes in the - generated boundary string. - - Closes #8441 - -- [Henrik Holst brought this change] - - hostcheck: reduce strlen calls on chained certificates - - Closes #8428 - -- [Patrick Monnerat brought this change] - - mime: some more strlen() call removals. - - Closes #8423 - -- scripts/cijobs.pl: detect zuul cmake jobs better - -- url: exclude zonefrom_url when no ipv6 is available - - Closes #8439 - -- if2ip: make Curl_ipv6_scope a blank macro when IPv6-disabled - - Closes #8439 - -- [Henrik Holst brought this change] - - mprintf: remove strlen calls on empty strings in dprintf_formatf - - Turns out that in dprintf_formatf we did a strlen on empty strings, a - bit strange is how common this actually is, 24 alone when doing a simple - GET from https://curl.se - - Closes #8427 - -- wolfssl: return CURLE_AGAIN for the SSL_ERROR_NONE case - - Closes #8431 - -- wolfssl: when SSL_read() returns zero, check the error - - Returning zero indicates end of connection, so if there's no data read - but the connection is alive, it needs to return -1 with CURLE_AGAIN. - - Closes #8431 - -- quiche: after leaving h3_recving state, poll again - - This could otherwise easily leave libcurl "hanging" after the entire - transfer is done but without noticing the end-of-transfer signal. - - Assisted-by: Lucas Pardue - Closes #8436 - -- quiche: when *recv_body() returns data, drain it before polling again - - Assisted-by: Lucas Pardue - - Closes #8429 - -- [gaoxingwang on github brought this change] - - configure: fix '--enable-code-coverage' typo - - Fixes #8425 - Closes #8426 - -- lib/h2h3: #ifdef on ENABLE_QUIC, not the wrong define - - Otherwise the build fails when H3 is enabled but the build doesn't - include nghttp2. - - Closes #8424 - -- hostcheck: pass in pattern length too, to avoid a strlen call - - Removes one strlen() call per SAN name in a cert-check. - - Closes #8418 - -- [Henrik Holst brought this change] - - misc: remove strlen for Curl_checkheaders + Curl_checkProxyheaders - - Closes #8409 - -- configure: requires --with-nss-deprecated to build with NSS - - Add deprecation plans to docs/DEPRECATE.md - - Closes #8395 - -- mqtt: free 'sendleftovers' in disconnect - - Fix a memory-leak - - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43646 - Closes #8415 - -- [Patrick Monnerat brought this change] - - openldap: pass string length arguments to client_write() - - This uses the new STRCONST() macro and saves 2 strlen() calls on short - string constants per LDIF output line. - - Closes #8404 - -- [Henrik Holst brought this change] - - misc: reduce strlen() calls with Curl_dyn_add() - - Use STRCONST() to switch from Curl_dyn_add() to Curl_dyn_addn() for - string literals. - - Closes #8398 - -- http2: fix the array copy to nghttp2_nv - - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=44517 - Follow-up to 9f985a11e794 - Closes #8414 - -- RELEASE-NOTES: synced - -- scripts/cijobs.pl: output data about all currect CI jobs - - This script parses the config files for all the CI services currently in - use and output the information in a uniform way. The idea is that the - output from this script should be possible to massage into informational - tables or graphs to help us visualize what they are all testing and NOT - testing. - - Closes #8408 - -- maketgz: return error if 'make dist' fails - - To better detect this problem in CI jobs - - Reported-by: Marcel Raad - Bug: https://curl.se/mail/lib-2022-02/0070.html - Closes #8402 - -- h2h3: pass correct argument types to infof() - - Detected by Coverity. CID 1497993 - - Closes #8401 - -- lib/Makefile: remove config-tpf.h from the dist - - Follow-up from da15443dddea2bfb. Missed before because the 'distcheck' - CI job was not working as intended. - - Reported-by: Marcel Raad - Bug: https://curl.se/mail/lib-2022-02/0070.html - Closes #8403 - -- configure: remove support for "embedded ares" - - In March 2010 (commit 4259d2df7dd) we removed the embedded 'ares' - directory from the curl source tree but we have since supported - especially detecting and using that build directory. The time has come - to remove that kludge and ask users to specify the c-ares dir correctly - with --enable-ares. - - Closes #8397 - -- [Sebastian Sterk brought this change] - - github/workflows/mbedtls: fix indent & remove unnecessary line breaks - - Closes #8399 - -- CI: move the NSS job from zuul to GHA - - Closes #8396 - -- tests/unit/Makefile.am: add NSS_LIBS to build with NSS fine - - Closes #8396 - -Marcel Raad (7 Feb 2022) -- curl-openssl: fix SRP check for OpenSSL 3.0 - - When OpenSSL 3.0 is built with `--api=3.0` and `no-deprecated`, the SRP - functions exist in the library, but are disabled for user code. Check - if they are actually usable instead of only if they exist. Also, check - for the functions actually required for TLS-SRP. - - TLS-SRP support is still enabled if OpenSSL is configured with just - `--api=3.0` or with `--api=1.1.1 no-deprecated`. - - Closes https://github.com/curl/curl/pull/8394 - -Daniel Stenberg (7 Feb 2022) -- [Henrik Holst brought this change] - - http: make Curl_compareheader() take string length arguments too - - Also add STRCONST, a macro that returns a string literal and it's length - for functions that take "string,len" - - Removes unnecesary calls to strlen(). - - Closes #8391 - -- vquic/vquic.h: removed the unused H3 psuedo defines - -- ngtcp2: use Curl_pseudo_headers - -- quiche: use Curl_pseudo_headers - -- http2: use Curl_pseudo_headers - -- h2h3: added Curl_pseudo_headers() - - For use with both http2 and http3 requests. - -- ngtcp2/quiche: make :scheme possible to set - -- http2: allow CURLOPT_HTTPHEADER change ":scheme" - - The only h2 psuedo header that wasn't previously possible to change by a - user. This change also makes it impossible to send a HTTP/1 header that - starts with a colon, which I don't think anyone does anyway. - - The other pseudo headers are possible to change indirectly by doing the - rightly crafted request. - - Reported-by: siddharthchhabrap on github - Fixes #8381 - Closes #8393 - -- h2/h3: provide and refer to pseudo headers as defines - - ... and do sizeof() on the defines to use constants better. - - Closes #8389 - -- [Michał Antoniak brought this change] - - smb: passing a socket for writing and reading data instead of FIRSTSOCKET - - Closes #8383 - -- x509asn1: toggle off functions not needed for diff tls backends - - ... and clean the header file from private defines/structs (move to C - file) and unused function prototypes. - - Closes #8386 - -- lib: move hostcheck and x509sn1 sources to vtls/ - - ... since they are used strictly by TLS code. - - Closes #8386 - -Marcel Raad (4 Feb 2022) -- version_win32: fix warning for `CURL_WINDOWS_APP` - - The build version is not supported by the UWP code. - - Closes https://github.com/curl/curl/pull/8385 - -Daniel Stenberg (4 Feb 2022) -- tests/disable-scan.pl: properly detect multiple symbols per line - - Test 1165 would fail on some systems because it didn't detect - CURL_DISABLE_* symbols that were used to the right of another one on the - same line! The script would only detect and extract the first one. - - Reported-by: Marcel Raad - Fixes #8384 - Closes #8388 - -Jay Satiro (4 Feb 2022) -- config.d: Clarify _curlrc filename is still valid on Windows - - Recent changes added support for filename .curlrc on Windows, and - when it's not found curl falls back on the original Windows filename - _curlrc. _curlrc was removed from the doc, however it is still valid. - - Closes https://github.com/curl/curl/pull/8382 - -Daniel Stenberg (4 Feb 2022) -- lib: remove support for CURL_DOES_CONVERSIONS - - TPF was the only user and support for that was dropped. - - Closes #8378 - -- TPF: drop support - - There has been no TPF related changes done since September 2010 (commit - 7e1a45e224e57) and since this is a platform that is relatively different - than many others (== needs attention), I draw the conclusion that this - build is broken since a long time. - - Closes #8378 - -- scripts/delta: check the file delta for current branch - - ... also polish the output style a little bit - -Jay Satiro (3 Feb 2022) -- [Fabian Keil brought this change] - - runtests.pl: tolerate test directories without Makefile.inc - - Silences the following warnings when using a Makefile.inc-free - TESTDIR using the "-o" argument: - - readline() on closed filehandle D at ./runtests.pl line 592. - Use of uninitialized value $disttests in pattern match (m//) at - ./runtests.pl line 3602. - - Closes https://github.com/curl/curl/pull/8379 - -Daniel Stenberg (3 Feb 2022) -- [Henrik Holst brought this change] - - setopt: do bounds-check before strdup - - Curl_setstropt() allocated memory for the string before checking if the - string was within bounds. The bounds check should be done first. - - Closes #8377 - -- [Michał Antoniak brought this change] - - mbedtls: enable use of mbedtls without filesystem functions support - - Closes #8376 - -- [Bernhard Walle brought this change] - - configure: support specification of a nghttp2 library path - - This enables using --with-nghttp2=<dir> on systems without pkg-config. - - Closes #8375 - -- scripts/release-notes.pl: remove leftover debug output - -- RELEASE-NOTES: synced - -- scripts/release-notes.pl: fix number extraction for full URLs - -- [Leah Neukirchen brought this change] - - scripts/completion.pl: improve zsh completion - - - Detect all spellings of <file>, <file name> etc as well as <path>. - - Only complete directories for <dir>. - - Complete URLs for <URL>. - - Complete --request and --ftp-method. - - Closes #8363 - -- [Davide Cassioli brought this change] - - configure: use correct CFLAGS for threaded resolver with xlC on AIX - - Fixes #8276 - Closes #8374 - -- mailmap: Henrik Holst - -Jay Satiro (2 Feb 2022) -- build: fix ngtcp2 crypto library detection - - - Change library link check for ngtcp2_crypto_{gnutls,openssl} to - to use function ngtcp2_crypto_recv_client_initial_cb instead of - ngtcp2_crypto_ctx_initial. - - The latter function is no longer external since two days ago in - ngtcp2/ngtcp2@533451f. curl HTTP/3 CI builds have been failing since - then because they would not link to the ngtcp2 crypto library. - - Ref: https://github.com/ngtcp2/ngtcp2/pull/356 - - Closes https://github.com/curl/curl/pull/8372 - -- [Henrik Holst brought this change] - - urlapi: remove an unnecessary call to strlen - - - Use strcpy instead of strlen+memcpy to copy the url path. - - Ref: https://curl.se/mail/lib-2022-02/0006.html - - Closes https://github.com/curl/curl/pull/8370 - -Daniel Stenberg (1 Feb 2022) -- scripts/copyright.pl: fix for handling removed files better - -- vxworks: drop support - - No changes or fixes in vxworks related code since 2009 leads me to - believe that this doesn't work anymore. - - Closes #8362 - -- [Henrik Holst brought this change] - - base64: remove an unnecessary call to strlen - - Closes #8369 - -- tool_getparam: initial --json support - - Adds these test cases: - - 383 - simple single command line option - 384 - reading it from stdin - 385 - getting two --json options on command line - 386 - --next works after --json - - Closes #8314 - -- [Bjarni Ingi Gislason brought this change] - - curl_getdate.3: remove pointless .PP line - - mandoc: WARNING: skipping paragraph macro: PP empty - - Reported-by: Samuel Henrique - Closes #8365 - -- [Sebastian Sterk brought this change] - - multi: grammar fix in comment - - After 'must', the verb is used without 'to'. Correct: "must" or "have - to" - - Closes #8368 - -- openldap: fix compiler warning when built without SSL support - - openldap.c:841:52: error: unused parameter ‘data’ [-Werror=unused-parameter] - - Closes #8367 - -- [Samuel Henrique brought this change] - - CURLSHOPT_LOCKFUNC.3: fix typo "relased" -> "released" - - Found when packaging 7.81.0 for Debian. - - Closes #8364 - -- netware: remove support - - There are no current users and no Netware related changes done in the - code for over 13 years is a clear sign this is abandoned. - - Closes #8358 - -- CI: move two jobs from Zuul to Circle CI - - - openssl-no-verbose - - openssl-no-proxy - - Closes #8359 - -- cirlceci: also run a c-ares job on arm with debug enabled - - Closes #8357 - -- ci: move the OpenSSL + c-ares job from Zuul to Circle CI - - Closes #8357 - -- mailmap: Jan-Piet Mens - -- [luminixinc on github brought this change] - - multi: remember connection_id before returning connection to pool - - Fix a bug that does not require a new CVE as discussed on hackerone.com. - Previously `connection_id` was accessed after returning connection to - the shared pool. - - Bug: https://hackerone.com/reports/1463013 - Closes #8355 - -Jay Satiro (31 Jan 2022) -- write-out.d: Fix num_headers formatting - -- [Jan-Piet Mens brought this change] - - docs: capitalize the name 'Netscape' - - Closes https://github.com/curl/curl/pull/8354 - -Daniel Stenberg (30 Jan 2022) -- RELEASE-NOTES: synced - -- [Antoine Pietri brought this change] - - docs: grammar proofread, typo fixes - - (Partially automated) proofread of most of the documentation, leading to - various typo fixes. - - Closes #8353 - -- urldata: CONN_IS_PROXIED replaces bits.close when proxy can be disabled - - To remove run-time checks for such builds. - - Closes #8350 - -- setopt: fix the TLSAUTH #ifdefs for proxy-disabled builds - - Closes #8350 - -- conncache: make conncache_add_bundle return the pointer - - Simplifies the logic a little and avoids a ternary operator. - - Ref: #8346 - Closes #8349 - -- mailmap: neutric on github - -Jay Satiro (30 Jan 2022) -- [neutric on github brought this change] - - docs/TheArtOfHttpScripting: fix example POST URL - - Closes https://github.com/curl/curl/pull/8352 - -Daniel Stenberg (28 Jan 2022) -- nss: handshake callback during shutdown has no conn->bundle - - The callback gets called because of the call to PR_Recv() done to - attempt to avoid RST on the TCP connection. The conn->bundle pointer is - already cleared at this point so avoid dereferencing it. - - Reported-by: Eric Musser - Fixes #8341 - Closes #8342 - -- [Michał Antoniak brought this change] - - mbedtls: remove #include <mbedtls/certs.h> - - mbedtls/certs.h file contains only certificates example (all definitions - is beginning by mbedtls_test_*). None of them is used so we can avoid - include the file. - - Closes #8343 - -- [Michał Antoniak brought this change] - - mbedtls: enable use of mbedtls without CRL support - - Closes #8344 - -- [Bernhard Walle brought this change] - - configure: set CURL_LIBRARY_PATH for nghttp2 - - To execute the test program, we might need the library path so that the - lib is found at runtime. - - Closes #8340 - -Jay Satiro (28 Jan 2022) -- schannel: restore debug message in schannel_connect_step2 - - This is a follow-up to recent commit 2218c3a which removed the debug - message to avoid an unused variable warning. The message has been - reworked to avoid the warning. - - Ref: https://github.com/curl/curl/pull/8320#issuecomment-1022957904 - - Closes https://github.com/curl/curl/pull/8336 - -- test3021: disable all msys2 path transformation - - - Disable all MSYS2 path transformation in test3021 and test3022. - - Prior to this change path transformation in those tests was disabled - only for arguments that start with forward slashes. However arguments - that are in base64 contain forward slashes at any position and caused - unwanted translations. - - == Info: Denied establishing ssh session: mismatch sha256 fingerprint. - Remote +/EYG2YDzDGm6yiwepEMSuExgRRMoTi8Di1UN3kixZw= is not equal to - +C:/msys64/EYG2YDzDGm6yiwepEMSuExgRRMoTi8Di1UN3kixZw - - In the above example an argument containing a base64 sha256 fingerprint - was passed to curl after MSYS2 translated +/ into +C:/msys64/, and then - the fingerprint didn't match what was expected. - - Ref: https://www.msys2.org/wiki/Porting/ - - Fixes https://github.com/curl/curl/issues/8084 - Closes https://github.com/curl/curl/pull/8325 - -Daniel Stenberg (27 Jan 2022) -- CI: move scan-build job from Zuul to Azure Pipelines - - Closes #8338 - -Marcel Raad (27 Jan 2022) -- openssl: fix `ctx_option_t` for OpenSSL v3+ - - The options have been changed to `uint64_t` in - https://github.com/openssl/openssl/commit/56bd17830f2d5855b533d923d4e0649d3ed61d11. - - Closes https://github.com/curl/curl/pull/8331 - -Daniel Stenberg (27 Jan 2022) -- CI: move 'distcheck' job from zuul to azure pipelines - - Assisted-by: Kushal Das - - Closes #8334 - -- vtls: pass on the right SNI name - - The TLS backends convert the host name to SNI name and need to use that. - This involves cutting off any trailing dot and lowercasing. - - Co-authored-by: Jay Satiro - Closes #8320 - -- url: revert the removal of trailing dot from host name - - Reverts 5de8d84098db1bd24e (May 2014, shipped in 7.37.0) and the - follow-up changes done afterward. - - Keep the dot in names for everything except the SNI to make curl behave - more similar to current browsers. This means 'name' and 'name.' send the - same SNI for different 'Host:' headers. - - Updated test 1322 accordingly - - Fixes #8290 - Reported-by: Charles Cazabon - Closes #8320 - -- [neutric on github brought this change] - - docs/TheArtOfHttpScripting: fix capitalization - - Closes #8333 - -- tests/memanalyze.pl: also count and show "total allocations" - - This is the total number of bytes allocated, increasing for new - allocations and never reduced when freed. The existing "Maximum - allocated" is the high water mark. - - Closes #8330 - -- mailmap: spellfix githuh => github - -- RELEASE-NOTES: synced - -- hostcheck: fixed to not touch used input strings - - Avoids the need to clone the strings before check, thus avoiding - mallocs, which for cases where there are many SAN names in a cert could - end up numerous. - - Closes #8321 - -- ngtcp2: adapt to changed end of headers callback proto - - Closes #8322 - -- [Xiaoke Wang brought this change] - - openssl: check SSL_get_ex_data to prevent potential NULL dereference - - Closes #8268 - -Jay Satiro (23 Jan 2022) -- md5: check md5_init_func return value - - Prior to this change the md5_init_func (my_md5_init) return value was - ignored. - - Closes https://github.com/curl/curl/pull/8319 - -- md5: refactor for standard compliance - - - Wrap OpenSSL / wolfSSL MD5 functions instead of taking their function - addresses during static initialization. - - Depending on how curl was built the old way may have used a dllimport - function address during static initialization, which is not standard - compliant, resulting in Visual Studio warning C4232 (nonstandard - extension). Instead the function pointers now point to the wrappers - which call the MD5 functions. - - This change only affects OpenSSL and wolfSSL because calls to other SSL - libraries' md5 functions were already wrapped. Also sha256.c already - does this for all SSL libraries. - - Ref: https://github.com/curl/curl/pull/8298 - - Closes https://github.com/curl/curl/pull/8318 - -Daniel Stenberg (21 Jan 2022) -- [Lucas Pardue brought this change] - - docs: update IETF links to use datatracker - - The tools.ietf.org domain has been deprecated a while now, with the - links being redirected to datatracker.ietf.org. - - Rather than make people eat that redirect time, this change switches the - URL to a more canonical source. - - Closes #8317 - -- [Harry Sarson brought this change] - - CI: test building wolfssl with --enable-opensslextra - - Closes #8315 - -- [Harry Sarson brought this change] - - misc: allow curl to build with wolfssl --enable-opensslextra - - put all #include of openssl files behind wolfssl ifdefs so that we can - use the wolfssl/ prefixed include paths. Without these curl only builds - when wolfssl is built with enable-all. - - Fixes #8292 - Closes #8315 - -- [Lucas Pardue brought this change] - - quiche: change qlog file extension to `.sqlog` - - quiche has just switched it's qlog serialization format to JSON-SEQ by - default . The spec says this SHOULD use `.sqlog` extension. - - I believe ngtcp2 also supports JSON-SEQ by default as of - https://github.com/ngtcp2/ngtcp2/commit/9baf06fc3f352a1d062b6953ae1de22cae30639d - - Let's update curl so that tools know what format we are using! - - Closes #8316 - -Jay Satiro (21 Jan 2022) -- projects: Fix Visual Studio wolfSSL configurations - - - Change build-wolfssl.bat to disable SSLv3, enable TLSv1.3, enable - wolfSSL_DES_ecb_encrypt (needed by NTLM) and enable alt cert chains. - - - Disable warning C4214 'bit field types other than int'. - - - Add include directory wolfssl\wolfssl. - - wolfSSL offers OpenSSL API compatibility that libcurl uses, and some - recent change in libcurl included an include file for wolfSSL like - openssl/foo.h, which has a path like wolfssl\wolfssl\openssl\foo.h. - - The include directory issue was reported in #8292 but it's currently - unclear whether this type of change is needed for other build systems. - - Bug: https://github.com/curl/curl/issues/8292 - Reported-by: Harry Sarson - - Closes https://github.com/curl/curl/pull/8298 - -Daniel Stenberg (21 Jan 2022) -- openssl: return error if TLS 1.3 is requested when not supported - - Previously curl would just silently ignore it if the necessary defines - are not present at build-time. - - Reported-by: Stefan Eissing - Fixes #8309 - Closes #8310 - -- TODO: Passing NOTIFY option to CURLOPT_MAIL_RCPT - - Closes #8232 - -- [Philip H brought this change] - - workflows/wolfssl: install impacket - - needed Python Package for SMB tests - - Closes #8307 - -- url: make Curl_disconnect return void - - 1. The function would only ever return CURLE_OK anyway - 2. Only one caller actually used the return code - 3. Most callers did (void)Curl_disconnect() - - Closes #8303 - -- docs: document HTTP/2 not insisting on TLS 1.2 - - Both for --http2 and CURLOPT_HTTP_VERSION. - - Reported-by: jhoyla on github - Fixes #8235 - Closes #8300 - -- cmdline-opts/gen.pl: fix option matching to improve references - - Previously it could mistakenly match partial names when there are - options that start with the same prefix, leading to the wrong references - used. - - Closes #8299 - -- TODO: Less memory massaging with Schannel - -- [Patrick Monnerat brought this change] - - runtests.pl: disable debuginfod - - Valgrind and gdb implement this feature: as this highly slows down tests, - disable it. - - Closes #8291 - -- RELEASE-NOTES: synced - -- CURLMOPT_TIMERFUNCTION/DATA.3: fix the examples - - ... to not call libcurl recursively back. - - Closes #8286 - -- multi: set in_callback for multi interface callbacks - - This makes most libcurl functions return error if called from within a - callback using the same multi handle. For example timer or socket - callbacks calling curl_multi_socket_action. - - Reported-by: updatede on github - Fixes #8282 - Closes #8286 - -- docs/HISTORY.md: mention alt-svc and HSTS - -- misc: remove the final watcom references - - Follow-up to bbf8cae44dedc495e6 - - We removed support for the watcom builds files back in September - 2020. This removes all remaining watcom references and ifdefs. - - Closes #8287 - -- misc: remove BeOS code and references - - There has not been a mention of this OS in any commit since December - 2004 (58f4af7973e3d2). The OS is also long gone. - - Closes #8288 - -- tool_getparam: DNS options that need c-ares now fail without it - - Just silently accepting the options and then not having any effect is - not good. - - Ref: #8283 - Closes #8285 - -- curl: remove "separators" (when using globbed URLs) - - Unless muted (with -s) When doing globbing, curl would output mime-like - separators between the separate transfers. This is not documented - anywhere, surprises users and clobbers the output. Gone now. - - Updated test 18 and 1235 - - Reported-by: jonny112 on github - Bug: https://github.com/curl/curl/discussions/8257 - Closes #8278 - -Jay Satiro (15 Jan 2022) -- [Niels Martignène brought this change] - - mbedtls: fix CURLOPT_SSLCERT_BLOB (again) - - - Increase the buffer length passed to mbedtls_x509_crt_parse to account - for the null byte appended to the temporary blob. - - Follow-up to 867ad1c which uses a null terminated copy of the - certificate blob, because mbedtls_x509_crt_parse requires PEM data - to be null terminated. - - Ref: https://github.com/curl/curl/commit/867ad1c#r63439893 - Ref: https://github.com/curl/curl/pull/8146 - - Closes https://github.com/curl/curl/pull/8260 - -Daniel Stenberg (15 Jan 2022) -- [Alessandro Ghedini brought this change] - - quiche: verify the server cert on connect - - Similarly to c148f0f551f9bea0e3d0, make quiche correctly acknowledge - `CURLOPT_SSL_VERIFYPEER` and `CURLOPT_SSL_VERIFYHOST`. - - Fixes #8173 - Closes #8275 - -- [Ikko Ashimine brought this change] - - checksrc: fix typo in comment - - enfore -> enforce - - Closes #8281 - -- curl-openssl: remove the OpenSSL headers and library versions check - - It is more work to maintain that check than the (any?) benefit it - brings. - - Fixes #8279 - Reported-by: Satadru Pramanik - Closes #8280 - -- mqtt: free any leftover when done - - Oss-fuzz found an issue when the "sendleftovers" pointer could leak memory. - Fix this by always freeing it (if still assigned) in the done function. - - Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=43515 - Closes #8274 - -- formdata: avoid size_t => long typecast overflows - - Typically a problem for platforms with 32 bit long and 64 bit size_t - - Reported-by: Fabian Yamaguchi - Bug: https://hackerone.com/reports/1444539 - Closes #8272 - -- RELEASE-NOTES: synced - - bump next release to become 7.82.0 - -Marcel Raad (13 Jan 2022) -- build: enable -Warith-conversion - - This makes the behavior consistent between GCC 10 and earlier versions. - - Closes https://github.com/curl/curl/pull/8271 - -- build: fix -Wenum-conversion handling - - Don't enable that warning when warnings are disabled. - Also add it to CMake. - - Closes https://github.com/curl/curl/pull/8271 - -- appveyor: use VS 2017 image for the autotools builds - - The newer images don't have all required MSYS2 packages. - - Fixes https://github.com/curl/curl/issues/8248 - Closes https://github.com/curl/curl/pull/8265 - -- appveyor: update images from VS 2019 to 2022 - - Closes https://github.com/curl/curl/pull/8265 - -Daniel Stenberg (12 Jan 2022) -- [Michał Antoniak brought this change] - - mbedtls: return CURLcode result instead of a mbedtls error code - - ... when a certificate fails to be loaded from a blob - - Closes #8266 - -- curl_multi_socket.3: remove callback and typical usage descriptions - - 1. The callback is better described in the option for setting it. Having - it in a single place reduces the risk that one of them is wrong. - - 2. The "typical usage" is wrong since the functions described in this - man page are both deprecated so they cannot be used in any "typical" way - anymore. - - Closes #8262 - -- curl-functions.m4: revert DYLD_LIBRARY_PATH tricks in CURL_RUN_IFELSE - - Mostly reverts ba0657c343f, but now instead just run the plain macro on - darwin. The approach as used on other platforms is simply not necessary - on macOS. - - Fixes #8229 - Reported-by: Ryan Schmidt - Closes #8247 - -- [Patrick Monnerat brought this change] - - openldap: implement SASL authentication - - As credentials can be quite different depending on the mechanism used, - there are no default mechanisms for LDAP and simple bind with a DN is - then used. - - The caller has to provide mechanism(s) using CURLOPT_LOGIN_OPTIONS to - enable SASL authentication and disable simple bind. - - Closes #8152 - -Jay Satiro (10 Jan 2022) -- [Cameron Will brought this change] - - CURLOPT_RESOLVE.3: change example port to 443 - - 83cc966 changed documentation from using http to https. However, - CURLOPT_RESOLVE being set to port 80 in the documentation means that it - isn't valid for the new URL. Update to 443. - - Closes https://github.com/curl/curl/pull/8258 - -Daniel Stenberg (10 Jan 2022) -- [Fabian Keil brought this change] - - test374: gif data without new line at the end - - Closes #8239 - -- [Fabian Keil brought this change] - - runtests.pl: support the nonewline attribute for the data part - - Added to FILEFORMAT - - Closes #8239 - -- [Patrick Monnerat brought this change] - - curl tool: erase some more sensitive command line arguments - - As the ps command may reveal sensitive command line info, obfuscate - options --tlsuser, --tlspasswd, --proxy-tlsuser, --proxy-tlspassword and - --oauth2-bearer arguments. - - Reported-by: Stephen Boost <s.booth@epcc.ed.ac.uk> - - Closes #7964 - -- mesalink: remove support - - Mesalink has ceased development. We can no longer encourage use of it. - It seems to be continued under the name TabbySSL, but no attempts have - (yet) been to make curl support it. - - Fixes #8188 - Closes #8191 - -- ldap: return CURLE_URL_MALFORMAT for bad URL - - For consistency, use the same return code for URL malformats, - independently of what scheme that is used. Previously this would return - CURLE_LDAP_INVALID_URL, but starting now that error cannot be returned. - - Closes #8170 - -- docs/cmdline-opts: add "mutexed" options for more http versions - - Update four http version man page sections. - - Closes #8254 - -- [Stephen M. Coakley brought this change] - - rustls: add CURLOPT_CAINFO_BLOB support - - Add support for `CURLOPT_CAINFO_BLOB` `CURLOPT_PROXY_CAINFO_BLOB` to the - rustls TLS backend. Multiple certificates in a single PEM string are - supported just like OpenSSL does with this option. - - This is compatible at least with rustls-ffi 0.8+ which is our new - minimum version anyway. - - I was able to build and run this on Windows, pulling trusted certs from - the system and then add them to rustls by setting - `CURLOPT_CAINFO_BLOB`. Handy! - - Closes #8255 - -- scripts/copyright.pl: ignore missing files - -- RELEASE-NOTES: synced - -- data/DISABLED: disable test 313 for wolfssl builds - - It was previously disabled only in the CI jobs yaml - - Closes #8252 - -- runtests: make 'wolfssl' a testable feature - - Closes #8252 - -- GHA: install stunnel in the medbtls + wolfssl CI jobs - - Closes #8252 - -- CI: move the rustls CI job to GHA from Zuul - - Closes #8251 - -- DISABLE: disable a dozen tests in the rustls build - - Disables tests that don't yet work with the rustls backend. - - Fixes #8004 - Closes #8250 - -- runtests: make 'rustls' a testable feature - -- remote-header-name.d: clarify - - - it strips off the path from the server provided name - - it saves in current directory or --output-dir - - Ref: https://curl.se/mail/archive-2022-01/0032.html - Closes #8249 - -- url: given a user in the URL, find pwd for that user in netrc - - Add test 380 and 381 to verify, edited test 133 - - Reported-by: Manfred Schwarb - Fixes #8241 - Closes #8243 - -- [Niels Martignène brought this change] - - mbedtls: Fix ssl_init error with mbedTLS 3.1.0+ - - Since mbedTLS 3.1.0, mbedtls_ssl_setup() fails if the provided - config struct is not valid. - - mbedtls_ssl_config_defaults() needs to be called before the config - struct is passed to mbedtls_ssl_setup(). - - Closes #8238 - -- [Filip Lundgren brought this change] - - cmake: fix iOS CMake project generation error - - Closes #8244 - -- ngtcp2: fix declaration of ‘result’ shadows a previous local - - Follow-up to 8fbd6feddfa587cfd3 - - Closes #8245 - -- openssl.h: avoid including OpenSSL headers here - - ... by instead using the struct version of the typedef'ed pointer. To - fix build errors when both Schannel and OpenSSL are enabled. - - Fixes #8240 - Reported-by: Jan Ehrhardt - Closes #8246 - -- curl_url_set.3: mention when CURLU_ALLOW_SPACE was added - -- tool_findfile: free mem properly - - Follow-up to 764e4f066d5 - - Closes #8242 - -- tool_findfile: check ~/.config/curlrc too - - ... after the initial checks for .curlrc and if XDG_CONFIG_HOME is not - set, use $HOME and $CURL_HOME to check if ~/.config/curlrc is present. - - Add test 436 to verify - - Reported-by: Sandro Jaeckel - Fixes #8208 - Closes #8213 - -- runtests: allow client/file to specify multiple directories - - ... and make sure to mkdir them all - -- scripts/copyright.pl: support many provided file names on the cmdline - -- [Fabian Keil brought this change] - - tests/FILEFORMAT.md: fix typo - -- [Fabian Keil brought this change] - - Add test373: multiple chunks with binary zeros - -- [Fabian Keil brought this change] - - Add test372: binary zero in data element - -- [Fabian Keil brought this change] - - tests/server/getpart.c: properly deal with binary data containing NUL bytes - -- [Fabian Keil brought this change] - - runtests.pl: properly print the test if it contains binary zeros - -- mailmap: Xiaoke Wang - -- openssl: copyright year update - - Follow-up to 30aea2b1ede - -- scripts/copyright.pl: hush unless -v (for verbose) is used - -- [Xiaoke Wang brought this change] - - openssl: check the return value of BIO_new_mem_buf() - - Closes #8233 - -- examples/multi-app.c: call curl_multi_remove_handle as well - - Fixes #8234 - Reported-by: Melroy van den Berg - Closes #8236 - -- COPYING: bump copyright year range - -- RELEASE-NOTES: synced - - and bump curlver after release - -- docs: fix mandoc -T lint formatting complaints - - Closes #8228 - -- next.d. remove .fi/.nf as they are handled by gen.pl - - Closes #8228 - -- gen.pl: terminate "example" sections better - - If the example (section that is prefixed with spaces) ends the - description gen.pl would previously miss to output the terminating .fi - - Closes #8228 - -- [Satadru Pramanik brought this change] - - curl-functions.m4: fix LIBRARY_PATH adjustment to avoid eval - - $$ usage in a m4 file introduces the PID in linux. - Instead, just duplicate previous working code with a case switch. - - Fixes #8229 - Closes #8230 - -Version 7.81.0 (5 Jan 2022) - -Daniel Stenberg (5 Jan 2022) -- RELEASE-NOTES: synced - - curl 7.81.0 release - -- THANKS: add names from 7.81.0 release - -- curl_multi_init.3: fix the copyright year range - -- test719-721: require "proxy" feature present to run - - Bug: https://github.com/curl/curl/pull/8223#issuecomment-1005188696 - Reported-by: Marc Hörsken - - Closes #8226 - -- test719: require ipv6 support to run - - Follow-up to effd2bd7ba2a5fd244 - Reported-by: Marc Hörsken - Bug: https://github.com/curl/curl/pull/8217#issuecomment-1004681145 - - Closes #8223 - -- test719-721: verify SOCKS details - - Using the new verify/socks details - -- runtests: add verify/socks check - - If used, this data is compared with the data in log/socksd-request.log - which the socksd server logs. - - Added to FILEFORMAT.md - -- server/socksd: log atyp + address in a separate log - - To allow the test suite to verify that the right data arrived - -- socks5: use appropriate ATYP for numerical IP address host names - - When not resolving the address locallly (known as socks5h). - - Add test 719 and 720 to verify. - - Reported-by: Peter Piekarski - Fixes #8216 - Closes #8217 - -Jay Satiro (3 Jan 2022) -- curl_multi_init.3: fix EXAMPLE formatting - -Daniel Stenberg (3 Jan 2022) -- RELEASE-NOTES: synced - -- libtest: avoid "assignment within conditional expression" - - In lib530, lib540 and lib582 - - Closes #8218 - -- ftp: disable warning 4706 in MSVC - - Follow-up to 21248e052d - - Disabling "assignment within conditional expression" for MSVC needs to - be done before the function starts, for it to take effect. - - Closes #8218 - -- tool_operate: warn if too many output arguments were found - - More output instructions than URLs is likely a user error. - - Add test case 371 to verify - - Closes #8210 - -- .github/workflows/mbedtls.yml: bump to mbedtls 3.1.0 - - Closes #8215 - -- zuul: remove the mbedtls jobs - - Now running as github workflows - - Closes #8215 - -- github/workflows: add mbedtls and mbedtls-clang - - Closes #8215 - -- [Valentin Richter brought this change] - - mbedtls: fix private member designations for v3.1.0 - - "As a last resort, you can access the field foo of a structure bar by - writing bar.MBEDTLS_PRIVATE(foo). Note that you do so at your own risk, - since such code is likely to break in a future minor version of Mbed - TLS." - - https://github.com/ARMmbed/mbedtls/blob/f2d1199edc5834df4297f247f213e614f7782d1d/docs/3.0-migration-guide.md - - That future minor version is v3.1.0. I set the >= to == for the version - checks because v3.1.0 is a release, and I am not sure when the private - designation was reverted after v3.0.0. - - Closes #8214 - -- [Valentin Richter brought this change] - - cmake: prevent dev warning due to mismatched arg - - -- curl version=[7.81.0-DEV] - CMake Warning (dev) at /usr/share/cmake-3.22.1/Modules/FindPackageHandleStandardArgs.cmake:438 (message): - The package name passed to `find_package_handle_standard_args` (MBEDTLS) - does not match the name of the calling package (MbedTLS). This can lead to - problems in calling code that expects `find_package` result variables - (e.g., `_FOUND`) to follow a certain pattern. - Call Stack (most recent call first): - deps/curl/CMake/FindMbedTLS.cmake:31 (find_package_handle_standard_args) - deps/curl/CMakeLists.txt:473 (find_package) - This warning is for project developers. Use -Wno-dev to suppress it. - - Closes #8207 - -- urlapi: if possible, shorten given numerical IPv6 addresses - - Extended test 1560 to verify - - Closes #8206 - -- [Michał Antoniak brought this change] - - url: reduce ssl backend count for CURL_DISABLE_PROXY builds - - Closes #8212 - -- KNOWN_BUGS: "Trying local ports fails on Windows" - - Reported-by: gclinch on github - Closes #8112 - -- misc: update copyright year range - -- zuul: remove the wolfssl even more - - Follow-up to 1914465cf180d32b3d - -- examples/multi-single.c: remove WAITMS() - - As it isn't used. - - Reported-by: Melroy van den Berg - Fixes #8200 - Closes #8201 - -- gtls: add gnutls include for the session type - - Follow-up to 8fbd6feddfa5 to make it build more universally - -- m4/curl-compilers: tell clang -Wno-pointer-bool-conversion - - To hush compiler warnings we don't care for: error: address of function - 'X' will always evaluate to 'true' - - Fixes #8197 - Closes #8198 - -- http_proxy: don't close the socket (too early) - - ... and double-check in the OpenSSL shutdown that the socket is actually - still there before it is used. - - Fixes #8193 - Closes #8195 - - Reported-by: Leszek Kubik - -- ngtcp2: verify the server certificate for the gnutls case - - Closes #8178 - -- ngtcp2: verify the server cert on connect (quictls) - - Make ngtcp2+quictls correctly acknowledge `CURLOPT_SSL_VERIFYPEER` and - `CURLOPT_SSL_VERIFYHOST`. - - The name check now uses a function from lib/vtls/openssl.c which will - need attention for when TLS is not done by OpenSSL or is disabled while - QUIC is enabled. - - Possibly the servercert() function in openssl.c should be adjusted to be - able to use for both regular TLS and QUIC. - - Ref: #8173 - Closes #8178 - -- zuul: remove the wolfssl build - -- github workflow: add wolfssl - - Closes #8196 - -- [Nicolas Sterchele brought this change] - - zuul: fix quiche build pointing to wrong Cargo - - Fixes #8184 - Closes #8189 - -- checksrc: detect more kinds of NULL comparisons we avoid - - Co-authored-by: Jay Satiro - Closes #8180 - -- RELEASE-NOTES: synced - -- mesalink: remove the BACKEND define kludge - - Closes #8183 - -- schannel: remove the BACKEND define kludge - - Closes #8182 - -- gtls: check return code for gnutls_alpn_set_protocols - - Closes #8181 - -- [Stefan Huber brought this change] - - README: label the link to the support document - - Closes #8185 - -- docs/HTTP3: describe how to setup a h3 reverse-proxy for testing - - Assisted-by: Matt Holt - - Closes #8177 - -- libcurl-multi.3: "SOCKS proxy handshakes" are not blocking - - Since 4a4b63daaa0 - -- [Vladimir Panteleev brought this change] - - tests: Add test for CURLOPT_HTTP200ALIASES - -- [Vladimir Panteleev brought this change] - - http: Fix CURLOPT_HTTP200ALIASES - - The httpcode < 100 check was also triggered when none of the fields were - parsed, thus making the if(!nc) block unreachable. - - Closes #8171 - -- RELEASE-NOTES: synced - -- language: "email" - - Missed three occurrences. - - Follow-up to 7a92f86 - -- nss:set_cipher don't clobber the cipher list - - The string is set by the user and needs to remain intact for proper - connection reuse etc. - - Reported-by: Eric Musser - Fixes #8160 - Closes #8161 - -- misc: s/e-mail/email - - Consistency is king. Following the lead in everything curl. - - Closes #8159 - -- [Tobias Nießen brought this change] - - docs: fix typo in OpenSSL 3 build instructions - - Closes #8162 - -- linkcheck.yml: add CI job that checks markdown links - - Closes #8158 - -- RELEASE-PROCEDURE.md: remove ICAL link and old release dates - -- BINDINGS.md: "markdown-link-check-disable" - - It feels a bit unfortunate to litter an ugly tag for this functionality, - but if we get link scans of all markdown files, this might be worth the - price. - -- docs: fix dead links, remove ECH.md - -Jay Satiro (16 Dec 2021) -- openssl: define HAVE_OPENSSL_VERSION for OpenSSL 1.1.0+ - - Prior to this change OpenSSL_version was only detected in configure - builds. For other builds the old version parsing code was used which - would result in incorrect versioning for OpenSSL 3: - - Before: - - curl 7.80.0 (i386-pc-win32) libcurl/7.80.0 OpenSSL/3.0.0a zlib/1.2.11 - WinIDN libssh2/1.9.0 - - After: - - curl 7.80.0 (i386-pc-win32) libcurl/7.80.0 OpenSSL/3.0.1 zlib/1.2.11 - WinIDN libssh2/1.9.0 - - Reported-by: lllaffer@users.noreply.github.com - - Fixes https://github.com/curl/curl/issues/8154 - Closes https://github.com/curl/curl/pull/8155 - -Daniel Stenberg (16 Dec 2021) -- [James Fuller brought this change] - - docs: add known bugs list to HTTP3.md - - Closes #8156 - -Dan Fandrich (15 Dec 2021) -- BINDINGS: add one from Everything curl and update a link - -- libcurl-security.3: mention address and URL mitigations - - The new CURLOPT_PREREQFUNCTION callback is another way to sanitize - addresses. - Using the curl_url API is a way to mitigate against attacks relying on - URL parsing differences. - -Daniel Stenberg (15 Dec 2021) -- RELEASE-NOTES: synced - -- x509asn1: return early on errors - - Overhaul to make sure functions that detect errors bail out early with - error rather than trying to continue and risk hiding the problem. - - Closes #8147 - -- [Patrick Monnerat brought this change] - - openldap: several minor improvements - - - Early check proper LDAP URL syntax. Reject URLs with a userinfo part. - - Use dynamic memory for ldap_init_fd() URL rather than a - stack-allocated buffer. - - Never chase referrals: supporting it would require additional parallel - connections and alternate authentication credentials. - - Do not wait 1 microsecond while polling/reading query response data. - - Store last received server code for retrieval with CURLINFO_RESPONSE_CODE. - - Closes #8140 - -- [Michał Antoniak brought this change] - - misc: remove unused doh flags when CURL_DISABLE_DOH is defined - - Closes #8148 - -- mbedtls: fix CURLOPT_SSLCERT_BLOB - - The memory passed to mbedTLS for this needs to be null terminated. - - Reported-by: Florian Van Heghe - Closes #8146 - -- asyn-ares: ares_getaddrinfo needs no happy eyeballs timer - - Closes #8142 - -- mailmap: add Yongkang Huang - - From #8141 - -- [Yongkang Huang brought this change] - - check ssl_config when re-use proxy connection - -- mbedtls: do a separate malloc for ca_info_blob - - Since the mbedTLS API requires the data to the null terminated. - - Follow-up to 456c53730d21b1fad0c7f72c1817 - - Fixes #8139 - Closes #8145 - -Marc Hoersken (14 Dec 2021) -- CI: build examples for additional code verification - - Some CIs already build them, let's do it on more of them. - - Reviewed-by: Daniel Stenberg - - Follow up to #7690 and 77311f420a541a0de5b3014e0e40ff8b4205d4af - Replaces #7591 - Closes #7922 - -- docs/examples: workaround broken -Wno-pedantic-ms-format - - Avoid CURL_FORMAT_CURL_OFF_T by using unsigned long instead. - Improve size_t to long conversion in imap-append.c example. - - Ref: https://github.com/curl/curl/issues/6079 - Ref: https://github.com/curl/curl/pull/6082 - Assisted-by: Jay Satiro - Reviewed-by: Daniel Stenberg - - Preparation of #7922 - -- tests/data/test302[12]: fix MSYS2 path conversion of hostpubsha256 - - Ref: https://www.msys2.org/wiki/Porting/#filesystem-namespaces - - Reviewed-by: Marcel Raad - Reviewed-by: Jay Satiro - - Fixes #8084 - Closes #8138 - -Daniel Stenberg (13 Dec 2021) -- [Patrick Monnerat brought this change] - - openldap: simplify ldif generation code - - and take care of zero-length values, avoiding conversion to base64 - and/or trailing spaces. - - Closes #8136 - -- example/progressfunc: remove code for old libcurls - - 7.61.0 is over three years old now, remove all #ifdefs for handling - ancient libcurl versions so that the example gets easier to read and - understand - - Closes #8137 - -- [Xiaoke Wang brought this change] - - sha256/md5: return errors when init fails - - Closes #8133 - -- TODO: 13.3 Defeat TLS fingerprinting - - Closes #8119 - -- RELEASE-NOTES: synced - -- [Patrick Monnerat brought this change] - - openldap: process search query response messages one by one - - Upon receiving large result sets, this reduces memory consumption and - allows starting to output results while the transfer is still in - progress. - - Closes #8101 - -- hash: lazy-alloc the table in Curl_hash_add() - - This makes Curl_hash_init() infallible which saves error paths. - - Closes #8132 - -- multi: cleanup the socket hash when destroying it - - Since each socket hash entry may themselves have a hash table in them, - the destroying of the socket hash needs to make sure all the subhashes - are also correctly destroyed to avoid leaking memory. - - Fixes #8129 - Closes #8131 - -- test1156: fixup the stdout check for Windows - - It is not text mode. - - Follow-up to 6f73e68d182 - - Closes #8134 - -- test1528: enable for hyper - - Closes #8128 - -- test1527: enable for hyper - - Closes #8128 - -- test1526: enable for hyper - - Closes #8128 - -- test1525: slightly tweaked for hyper - - Closes #8128 - -- test1156: enable for hyper - - Minor reorg of the lib1156 code and it works fine for hyper. - - Closes #8127 - -- test661: enable for hyper - - Closes #8126 - -- docs: fix proselint nits - - - remove a lot of exclamation marks - - use consistent spaces (1, not 2) - - use better words at some places - - Closes #8123 - -- [RekGRpth brought this change] - - BINDINGS.md: add cURL client for PostgreSQL - - Closes #8125 - -- [RekGRpth brought this change] - - CURLSHOPT_USERDATA.3: fix copy-paste mistake - - Closes #8124 - -- docs: fix minor nroff format nits - - Repairs test 1140 - - Follow-up to 436cdf82041 - -- docs/URL-SYNTAX.md: space is not fine in a given URL - -- curl_multi_perform/socket_action.3: clarify what errors mean - - An error returned from one of these funtions mean that ALL still ongoing - transfers are to be considered failed. - - Ref: #8114 - Closes #8120 - -- libcurl-errors.3: add CURLM_ABORTED_BY_CALLBACK - - Follow-up to #8089 (2b3dd01) - - Closes #8116 - -- hash: add asserts to help detect bad usage - - For example trying to add entries after the hash has been "cleaned up" - - Closes #8115 - -- lib530: abort on curl_multi errors - - This makes torture tests run more proper. - - Also add an assert to trap situations where it would end up with no - sockets to wait for. - - Closes #8121 - -- FAQ: we never pronounced it "see URL", we say "kurl" - -- RELEASE-NOTES: synced - -- CURLOPT_RESOLVE.3: minor polish - - Minor rephrasing for some explanations. - - Put the format strings in stand-alone lines with .nf/.fi to be easier to spot. - - Move "added in" to AVAILABILITY - - Closed #8110 - -- test1556: adjust for hyper - - Closes #8105 - -- test1554: adjust for hyper - - Closes #8104 - -- retry-all-errors.d: make the example complete - - ... as it needs --retry too to work - -- TODO: 5.7 Require HTTP version X or higher - - Closes #7980 - -- CURLOPT_STDERR.3: does not work with libcurl as a win32 DLL - - This is the exact same limitation already documented for - CURLOPT_WRITEDATA but should be clarified here. It also has a different - work-around. - - Reported-by: Stephane Pellegrino - Bug: https://github.com/curl/curl/issues/8102 - Closes #8103 - -- multi: handle errors returned from socket/timer callbacks - - The callbacks were partially documented to support this. Now the - behavior is documented and returning error from either of these - callbacks will effectively kill all currently ongoing transfers. - - Added test 530 to verify - - Reported-by: Marcelo Juchem - Fixes #8083 - Closes #8089 - -- http2:set_transfer_url() return early on OOM - - If curl_url() returns NULL this should return early to avoid mistakes - - even if right now the subsequent function invokes are all OK. - - Coverity (wrongly) pointed out this as a NULL deref. - - Closes #8100 - -- tool_parsecfg: use correct free() call to free memory - - Detected by Coverity. CID 1494642. - Follow-up from 2be1aa619bca - - Closes #8099 - -- tool_operate: fix potential memory-leak - - A 'CURLU *' would leak if url_proto() is called with no URL. - - Detected by Coverity. CID 1494643. - Follow-up to 18270893abdb19 - Closes #8098 - -- [Patrick Monnerat brought this change] - - openldap: implement STARTTLS - - As this introduces use of CURLOPT_USE_SSL option for LDAP, also check - this option in ldap.c as it is not supported by this backend. - - Closes #8065 - -- [Jun Tseng brought this change] - - curl_easy_unescape.3: call curl_easy_cleanup in example - - Closes #8097 - -- [Jun Tseng brought this change] - - curl_easy_escape.3: call curl_easy_cleanup in example - - Closes #8097 - -- tool_listhelp: sync - - Follow-up to 172068b76f - -- [Damien Walsh brought this change] - - request.d: refer to 'method' rather than 'command' - - Closes #8094 - -- RELEASE-NOTES: synced - -- writeout: fix %{http_version} for HTTP/3 - - Output "3" properly when HTTP/3 was used. - - Reported-by: Bernat Mut - Fixes #8072 - Closes #8092 - -- urlapi: accept port number zero - - This is a regression since 7.62.0 (fb30ac5a2d). - - Updated test 1560 accordingly - - Reported-by: Brad Fitzpatrick - Fixes #8090 - Closes #8091 - -- [Mark Dodgson brought this change] - - lift: ignore is a deprecated config option, use ignoreRules - - Closes #8082 - -- [Alessandro Ghedini brought this change] - - HTTP3: update quiche build instructions - - The repo repo was re-organized a bit, so the build instructions need to - be updated. - - Closes #8076 - -- CURLMOPT_TIMERFUNCTION.3: call it expire time, not interval - - Since we say it is a non-repating timer - -- [Florian Van Heghe brought this change] - - mbedTLS: include NULL byte in blob data length for CURLOPT_CAINFO_BLOB - - Fixes #8079 - Closes #8081 - -Jay Satiro (2 Dec 2021) -- [Wyatt O'Day brought this change] - - version_win32: Check build number and platform id - - Prior to this change the build number was not checked during version - comparison, and the platform id was supposed to be checked but wasn't. - - Checking the build number is required for enabling "evergreen" - Windows 10/11 features (like TLS 1.3). - - Ref: https://github.com/curl/curl/pull/7784 - - Closes https://github.com/curl/curl/pull/7824 - Closes https://github.com/curl/curl/pull/7867 - -- libssh2: fix error message for sha256 mismatch - - - On mismatch error show sha256 fingerprint in base64 format. - - Prior to this change the fingerprint was mistakenly printed in binary. - -Daniel Stenberg (1 Dec 2021) -- [Xiaoke Wang brought this change] - - openssl: check the return value of BIO_new() - - Closes #8078 - -Dan Fandrich (30 Nov 2021) -- docs: Update the Reducing Size section - - Add many more options that can reduce the size of the binary that were - added since the last update. Update the sample minimal binary size for - version 7.80.0. - -- tests: Add some missing keywords to tests - - These are needed to skip some tests when configure options have disabled - certain features. - -Daniel Stenberg (30 Nov 2021) -- [Florian Van Heghe brought this change] - - mbedTLS: add support for CURLOPT_CAINFO_BLOB - - Closes #8071 - -- [Glenn Strauss brought this change] - - digest: compute user:realm:pass digest w/o userhash - - https://datatracker.ietf.org/doc/html/rfc7616#section-3.4.4 - ... the client MUST calculate a hash of the username after - any other hash calculation ... - - Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com> - Closes #8066 - -- config.d: update documentation to match the path search - - Assisted-by: Jay Satiro - -- tool_findfile: search for a file in the homedir - - The homedir() function is now renamed into findfile() and iterates over - all the environment variables trying to access the file in question - until it finds it. Last resort is then getpwuid() if - available. Previously it would first try to find a home directory and if - that was set, insist on checking only that directory for the file. This - now returns the full file name it finds. - - The Windows specific checks are now done differently too and in this - order: - - 1 - %USERPROFILE% - 2 - %APPDATA% - 3 - %USERPROFILE%\\Application Data - - The windows order is modified to match how the Windows 10 ssh tool works - when it searches for .ssh/known_hosts. - - Reported-by: jeffrson on github - Co-authored-by: Jay Satiro - Fixes #8033 - Closes #8035 - -- docs: consistent manpage SYNOPSIS - - Make all libcurl related options use .nf (no fill) for the SYNOPSIS - section - for consistent look. roffit then renders that section using - <pre> (monospace font) in html for the website. - - Extended manpage-syntax (test 1173) with a basic check for it. - - Closes #8062 - -- RELEASE-NOTES: synced - -- [Patrick Monnerat brought this change] - - openldap: handle connect phase with a state machine - - Closes #8054 - -- docs: address proselint nits - - - avoid exclamation marks - - use consistent number of spaces after periods: one - - avoid clichés - - avoid using 'very' - - Closes #8060 - -- [Bruno Baguette brought this change] - - FAQ: typo fix : "yout" ➤ "your" - - Closes #8059 - -- [Bruno Baguette brought this change] - - docs/INSTALL.md: typo fix : added missing "get" verb - - Closes #8058 - -- insecure.d: detail its use for SFTP and SCP as well - - Closes #8056 - -Viktor Szakats (25 Nov 2021) -- Makefile.m32: rename -winssl option to -schannel and tidy up - - - accept `-schannel` as an alternative to `CFG` option `-winssl` - (latter still accepted, but deprecated) - - rename internal variable `WINSSL` to `SCHANNEL` - - make the `CFG` option evaluation shorter, without repeating the option - name - - Reviewed-by: Marcel Raad - Reviewed-by: Daniel Stenberg - Closes #8053 - -Daniel Stenberg (25 Nov 2021) -- KNOWN_BUGS: 5.6 make distclean loops forever - - Reported-by: David Bohman - Closes #7716 - -- KNOWN_BUGS: add one, remove one - - - 5.10 SMB tests fail with Python 2 - - Just use python 3. - - + 5.10 curl hangs on SMB upload over stdin - - Closes #7896 - -- urlapi: provide more detailed return codes - - Previously, the return code CURLUE_MALFORMED_INPUT was used for almost - 30 different URL format violations. This made it hard for users to - understand why a particular URL was not acceptable. Since the API cannot - point out a specific position within the URL for the problem, this now - instead introduces a number of additional and more fine-grained error - codes to allow the API to return more exactly in what "part" or section - of the URL a problem was detected. - - Also bug-fixes curl_url_get() with CURLUPART_ZONEID, which previously - returned CURLUE_OK even if no zoneid existed. - - Test cases in 1560 have been adjusted and extended. Tests 1538 and 1559 - have been updated. - - Updated libcurl-errors.3 and curl_url_strerror() accordingly. - - Closes #8049 - -- urlapi: make Curl_is_absolute_url always use MAX_SCHEME_LEN - - Instad of having all callers pass in the maximum length, always use - it. The passed in length is instead used only as the length of the - target buffer for to storing the scheme name in, if used. - - Added the scheme max length restriction to the curl_url_set.3 man page. - - Follow-up to 45bcb2eaa78c79 - - Closes #8047 - -- [Jay Satiro brought this change] - - cmake: warn on use of the now deprecated symbols - - Follow-up to 9108da2c26d - - Closes #8052 - -- [Kevin Burke brought this change] - - tests/CI.md: add more information on CI environments - - Fixes #8012 - Closes #8022 - -- cmake: private identifiers use CURL_ instead of CMAKE_ prefix - - Since the 'CMAKE_' prefix is reserved for cmake's own private use. - Ref: https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html - - Reported-by: Boris Rasin - Fixes #7988 - Closes #8044 - -- urlapi: reject short file URLs - - file URLs that are 6 bytes or shorter are not complete. Return - CURLUE_MALFORMED_INPUT for those. Extended test 1560 to verify. - - Triggered by #8041 - Closes #8042 - -- curl: improve error message for --head with -J - - ... it now focuses on the "output of headers" combined with the - --remote-header-name option, as that is actually the problem. Both - --head and --include can output headers. - - Reported-by: nimaje on github - Fixes #7987 - Closes #8045 - -- RELEASE-NOTES: synced - -- [Stefan Eissing brought this change] - - urlapi: cleanup scheme parsing - - Makea Curl_is_absolute_url() always leave a defined 'buf' and avoids - copying on urls that do not start with a scheme. - - Closes #8043 - -- tool_operate: only set SSH related libcurl options for SSH URLs - - For example, this avoids trying to find and set the known_hosts file (or - warn for its absence) if SFTP or SCP are not used. - - Closes #8040 - -- [Jacob Hoffman-Andrews brought this change] - - rustls: remove comment about checking handshaking - - The comment is incorrect in two ways: - - It says the check needs to be last, but the check is actually first. - - is_handshaking actually starts out true. - - Closes #8038 - -Marcel Raad (20 Nov 2021) -- openssl: use non-deprecated API to read key parameters - - With OpenSSL 3.0, the parameters are read directly from the `EVP_PKEY` - using `EVP_PKEY_get_bn_param`. - - Closes https://github.com/curl/curl/pull/7893 - -- openssl: reduce code duplication - - `BN_print`'s `BIGNUM` parameter has been `const` since OpenSSL 0.9.4. - - Closes https://github.com/curl/curl/pull/7893 - -- openssl: remove `RSA_METHOD_FLAG_NO_CHECK` handling if unavailable - - The flag has been deprecated without replacement in OpenSSL 3.0. - - Closes https://github.com/curl/curl/pull/7893 - -- openssl: remove usage of deprecated `SSL_get_peer_certificate` - - The function name was changed to `SSL_get1_peer_certificate` in OpenSSL - 3.0. - - Closes https://github.com/curl/curl/pull/7893 - -Daniel Stenberg (19 Nov 2021) -- page-footer: fix typo - - Closes #8036 - -- http: enable haproxy support for hyper backend - - This is done by having native code do the haproxy header output before - hyper issues its request. The little downside with this approach is that - we need the entire Curl_buffer_send() function built, which is otherwise - not used for hyper builds. - - If hyper ends up getting native support for the haproxy protocols we can - backpedal on this. - - Enables test 1455 and 1456 - - Closes #8034 - -- [Bernhard Walle brought this change] - - configure: fix runtime-lib detection on macOS - - With a non-standard installation of openssl we get this error: - - checking run-time libs availability... failed - configure: error: one or more libs available at link-time are not available run-time. Libs used at link-time: -lnghttp2 -lssl -lcrypto -lssl -lcrypto -lz - - There's already code to set LD_LIBRARY_PATH on Linux, so set - DYLD_LIBRARY_PATH equivalent on macOS. - - Closes #8028 - -- [Don J Olmstead brought this change] - - cmake: don't set _USRDLL on a static Windows build - - Closes #8030 - -- page-footer: document more environment variables - - ... that curl might use. - - Closes #8027 - -- netrc.d: edit the .netrc example to look nicer - - Works nicely thanks to d1828b470f43d - - Closes #8025 - -- tftp: mark protocol as not possible to do over CONNECT - - ... and make connect_init() refusing trying to tunnel protocols marked - as not working. Avoids a double-free. - - Reported-by: Even Rouault - Fixes #8018 - Closes #8020 - -- docs/cmdline-opts: do not say "protocols: all" - - Remove the lines saying "protocols: all". It makes the output in the - manpage look funny, and the expectation is probably by default that if - not anything is mentioned about protocols the option apply to them all. - - Closes #8021 - -- curl.1: require "see also" for every documented option - - gen.pl now generates a warning if the "See Also" field is not filled in for a - command line option - - All command line options now provide one or more related options. 167 - "See alsos" added! - - Closes #8019 - -- insecure.d: expand and clarify - - Closes #8017 - -- gen.pl: improve example output format - - Treat consecutive lines that start with a space to be "examples". They - are output enclosed by .nf and .fi - - Updated form.d to use this new fanciness - - Closes #8016 - -- Revert "form-escape.d: double the back-slashes for proper man page output" - - This reverts commit a2d8eac04a4eb1d5a98cf24b4e5cec5cec565d27. - - silly me, it was intended to be one backslash! - -- form-escape.d: double the back-slashes for proper man page output - -- page-footer: add a mention of how to report bugs to the man page - -- RELEASE-NOTES: synced - - and bump to 7.81.0-DEV - -- [Patrick Monnerat brought this change] - - mime: use percent-escaping for multipart form field and file names - - Until now, form field and file names where escaped using the - backslash-escaping algorithm defined for multipart mails. This commit - replaces this with the percent-escaping method for URLs. - - As this may introduce incompatibilities with server-side applications, a - new libcurl option CURLOPT_MIME_OPTIONS with bitmask - CURLMIMEOPT_FORMESCAPE is introduced to revert to legacy use of - backslash-escaping. This is controlled by new cli tool option - --form-escape. - - New tests and documentation are provided for this feature. - - Reported by: Ryan Sleevi - Fixes #7789 - Closes #7805 - -- [Kevin Burke brought this change] - - zuul.d: update rustls-ffi to version 0.8.2 - - This version fixes errors with ALPN negotiation in rustls, which is - necessary for HTTP/2 support. For more information see the rustls-ffi - changelog. - - Closes #8013 - -- configure: better diagnostics if hyper is built wrong - - If hyper is indeed present in the specified directory but couldn't be - used to find the correct symbol, then offer a different error message to - better help the user understand the issue. - - Suggested-by: Jacob Hoffman-Andrews - Fixes #8001 - Closes #8005 - -- test1939: require proxy support to run - - Follow-up to f0b7099a10d1a - - Closes #8011 - -- test302[12]: run only with the libssh2 backend - - ... as the others don't support --hostpubsha256 - - Reported-by: Paul Howarth - Fixes #8009 - Closes #8010 - -- runtests: make the SSH library a testable feature - - libssh2, libssh and wolfssh - -- [Jacob Hoffman-Andrews brought this change] - - rustls: read of zero bytes might be okay - - When we're reading out plaintext from rustls' internal buffers, we might - get a read of zero bytes (meaning a clean TCP close, including - close_notify). However, we shouldn't return immediately when that - happens, since we may have already copied out some plaintext bytes. - Break out of the loop when we get a read of zero bytes, and figure out - which path we're dealing with. - - Acked-by: Kevin Burke - - Closes #8003 - -- [Jacob Hoffman-Andrews brought this change] - - rustls: remove incorrect EOF check - - The update to rustls-ffi 0.8.0 changed handling of EOF and close_notify. - From the CHANGELOG: - - > Handling of unclean close and the close_notify TLS alert. Mirroring - > upstream changes, a rustls_connection now tracks TCP closed state like - > so: rustls_connection_read_tls considers a 0-length read from its - > callback to mean "TCP stream was closed by peer." If that happens - > before the peer sent close_notify, rustls_connection_read will return - > RUSTLS_RESULT_UNEXPECTED_EOF once the available plaintext bytes are - > exhausted. This is useful to protect against truncation attacks. Note: - > some TLS implementations don't send close_notify. If you are already - > getting length information from your protocol (e.g. Content-Length in - > HTTP) you may choose to ignore UNEXPECTED_EOF so long as the number of - > plaintext bytes was as expected. - - That means we don't need to check for unclean EOF in `cr_recv()`, - because `process_new_packets()` will give us an error if appropriate. - - Closes #8003 - -- lib1939: make it endure torture tests - - Follow-up to f0b7099a10d1a - - Closes #8007 - -- azure: make the "w/o HTTP/SMTP/IMAP" build disable SSL proper - - The configure line would previously depend on a configure mistake using - --without-openssl that is fixed and now this configure line needs - adjusting to use --without-ssl. - - Follow-up to b589696f0312d - - Closes #8006 - -- [Jacob Hoffman-Andrews brought this change] - - configure: add -lm to configure for rustls build. - - Note: The list of libraries that rustc tells us we need to include is - longer, but also includes some more platform-specific libraries that I - am not sure how to effectively incorporate. Adding just -lm seems to - solve an immediate problem, so I'm adding just that. - - Closes #8002 - -- curl_share_setopt.3: refer to CURLSHOPT_USERDATA(3) properly - -- curl_share_setopt.3: split out options into their own manpages - - CURLSHOPT_LOCKFUNC.3 - CURLSHOPT_SHARE.3 - CURLSHOPT_UNLOCKFUNC.3 - CURLSHOPT_UNSHARE.3 - CURLSHOPT_USERDATA.3 - - Closes #7998 - -- http_proxy: make Curl_connect_done() work for proxy disabled builds - - ... by making it an empty macro then. - - Follow-up to f0b7099a10d1a - Reported-by: Vincent Grande - Fixes #7995 - Closes #7996 - -- Curl_connect_done: handle being called twice - - Follow-up to f0b7099a10d1a7c - - When torture testing 1021, it turns out the Curl_connect_done function - might be called twice and that previously then wrongly cleared the HTTP - pointer in the second invoke. - - Closes #7999 - -- [Stan Hu brought this change] - - configure: don't enable TLS when --without-* flags are used - - Previously specifying `--without-gnutls` would unexpectedly attempt to - compile with GnuTLS, effectively interpreting this as - `--with-gnutls`. This caused a significant amount of confusion when - `libcurl` was built with SSL disabled since GnuTLS wasn't present. - - 68d89f24 dropped the `--without-*` options from the configure help, but - `AC_ARG_WITH` still defines these flags automatically. As - https://www.gnu.org/software/autoconf/manual/autoconf-2.60/html_node/External-Software.html - describes, the `action-if-given` is called when the user specifies - `--with-*` or `--without-*` options. - - To prevent this confusion, we make the `--without` flag do the right - thing by ignoring the value if it set to "no". - - Closes #7994 - -- [Rikard Falkeborn brought this change] - - docs/checksrc: Add documentation for STRERROR - - Closes #7991 - -- vtls/rustls: adapt to the updated rustls_version proto - - Closes #7956 - -- [Kevin Burke brought this change] - - vtls/rustls: handle RUSTLS_RESULT_PLAINTEXT_EMPTY - - Previously we'd return CURLE_READ_ERROR if we received this, instead - of triggering the error handling logic that's present in the next if - block down. - - After this change, curl requests to https://go.googlesource.com using - HTTP/2 complete successfully. - - Fixes #7949 - Closes #7948 - -- [Kevin Burke brought this change] - - zuul: update build environment for rustls-ffi 0.8.0 - -- [Kevin Burke brought this change] - - vtls/rustls: update to compile with rustls-ffi v0.8.0 - - Some method names, as well as the generated library name, were changed - in a recent refactoring. - - Further, change the default configuration instructions to check for - Hyper in either "target/debug" or "target/release" - the latter - contains an optimized build configuration. - - Fixes #7947 - Closes #7948 - -- RELEASE-NOTES: synced - - and bump the version to 7.80.1 - -- multi: shut down CONNECT in Curl_detach_connnection - - ... to prevent a lingering pointer that would lead to a double-free. - - Added test 1939 to verify. - - Reported-by: Stephen M. Coakley - Fixes #7982 - Closes #7986 - -- curl_easy_cleanup.3: remove from multi handle first - - Easy handles that are used by the multi interface should be removed from - the multi handle before they are cleaned up. - - Reported-by: Stephen M. Coakley - Ref: #7982 - Closes #7983 - -- url.c: fix the SIGPIPE comment for Curl_close - - Closes #7984 - -Version 7.80.0 (10 Nov 2021) - -Daniel Stenberg (10 Nov 2021) -- RELEASE-NOTES: synced - - for curl 7.80.0 - -- THANKS: add contributors from the 7.80.0 cycle - -- [Tatsuhiro Tsujikawa brought this change] - - ngtcp2: advertise h3 as well as h3-29 - - Advertise h3 as well as h3-29 since some servers out there require h3 - for QUIC v1. - - Closes #7979 - -- [Tatsuhiro Tsujikawa brought this change] - - ngtcp2: use QUIC v1 consistently - - Since we switched to v1 quic_transport_parameters codepoint in #7960 - with quictls, lets use QUIC v1 consistently. - - Closes #7979 - -- [Tatsuhiro Tsujikawa brought this change] - - ngtcp2: compile with the latest nghttp3 - - Closes #7978 - -Marc Hoersken (9 Nov 2021) -- tests: add Schannel-specific tests and disable unsupported ones - - Adds Schannel variants of SSLpinning tests that include the option - --ssl-revoke-best-effort to ignore certificate revocation check - failures which is required due to our custom test CA certificate. - - Disable the original variants if the Schannel backend is enabled. - - Also skip all IDN tests which are broken while using an msys shell. - - This is a step to simplify test exclusions for Windows and MinGW. - - Reviewed-by: Jay Satiro - Reviewed-by: Marcel Raad - Reviewed-by: Daniel Stenberg - Closes #7968 - -Daniel Stenberg (8 Nov 2021) -- docs: NAME fixes in easy option man pages - - Closes #7975 - -- [Roger Young brought this change] - - ftp: make the MKD retry to retry once per directory - - Reported-by: Roger Young - Fixes #7967 - Closes #7976 - -- tool_operate: reorder code to avoid compiler warning - - tool_operate.c(889) : warning C4701: potentially uninitialized local - variable 'per' use - - Follow-up to cc71d352651a0d95 - Reported-by: Marc Hörsken - Bug: https://github.com/curl/curl/pull/7922#issuecomment-963042676 - Closes #7971 - -- curl_easy_perform.3: add a para about recv and send data - - Reported-by: Godwin Stewart - Fixes #7973 - Closes #7974 - -- tool_operate: fclose stream only if fopened - - Fixes torture test failures - Follow-up to cc71d352651 - - Closes #7972 - -- libcurl-easy.3: language polish - -- limit-rate.d: this is average over several seconds - - Closes #7970 - -- docs: reduce/avoid English contractions - - You're => You are - Hasn't => Has not - Doesn't => Does not - Don't => Do not - You'll => You will - etc - - Closes #7930 - -- tool_operate: fix torture leaks with etags - - Spotted by torture testing 343 344 345 347. - - Follow-up from cc71d352651a0 - Pointed-out-by: Dan Fandrich - - Closes #7969 - -- [Amaury Denoyelle brought this change] - - ngtcp2: support latest QUIC TLS RFC9001 - - QUIC Transport Parameters Extension has been changed between draft-29 - and latest RFC9001. Most notably, its identifier has been updated from - 0xffa5 to 0x0039. The version is selected through the QUIC TLS library - via the legacy codepoint. - - Disable the usage of legacy codepoint in curl to switch to latest - RFC9001. This is required to be able to keep up with latest QUIC - implementations. - - Acked-by: Tatsuhiro Tsujikawa - Closes #7960 - -- test1173: make manpage-syntax.pl spot \n errors in examples - -- man pages: fix backslash-n in examples - - ... to be proper backslash-backslash-n sequences to render nicely in man - and on website. - - Follow-up to 24155569d8a - Reported-by: Sergey Markelov - - Fixes https://github.com/curl/curl-www/issues/163 - Closes #7962 - -- scripts/release-notes.pl: use out of repo links verbatim in refs - -- tool_operate: a failed etag save now only fails that transfer - - When failing to create the output file for saving an etag, only fail - that particular single transfer and allow others to follow. - - In a serial transfer setup, if no transfer at all is done due to them - all being skipped because of this error, curl will output an error - message and return exit code 26. - - Added test 369 and 370 to verify. - - Reported-by: Earnestly on github - Ref: #7942 - Closes #7945 - -- [Kevin Burke brought this change] - - .github: retry macos "brew install" command on failure - - Previously we saw errors attempting to run "brew install", see - https://github.com/curl/curl/runs/4095721123?check_suite_focus=true for - an example, since this command is idempotent, it is safe to run again. - - Closes #7955 - -- CURLOPT_ALTSVC_CTRL.3: mention conn reuse is preferred - - Ref: https://github.com/curl/curl/discussions/7954 - - Closes #7957 - -- RELEASE-NOTES: synced - -- zuul: pin the quiche build to use an older cmake-rs - - The latest cmake-rs assumes cmake's --parallel works. That was added in - cmake 3.12, but a lot of our CI builds run on Ubuntu Bionic which only - has cmake 3.10. - - Fixes #7927 - Closes #7952 - -- [Marc Hoersken brought this change] - - Revert "src/tool_filetime: disable -Wformat on mingw for this file" - - This reverts commit 7c88fe375b15c44d77bccc9ab733b8069d228e6f. - - Follow up to #6535 as the pragma is obsolete with warnf - - Closes #7941 - -Jay Satiro (2 Nov 2021) -- schannel: fix memory leak due to failed SSL connection - - - Call schannel_shutdown if the SSL connection fails. - - Prior to this change schannel_shutdown (which shuts down the SSL - connection as well as memory cleanup) was not called when the SSL - connection failed (eg due to failed handshake). - - Co-authored-by: Gisle Vanem - - Fixes https://github.com/curl/curl/issues/7877 - Closes https://github.com/curl/curl/pull/7878 - -Daniel Stenberg (2 Nov 2021) -- Curl_updateconninfo: store addresses for QUIC connections too - - So that CURLINFO_PRIMARY_IP etc work for HTTP/3 like for other HTTP - versions. - - Reported-by: Jerome Mao - Fixes #7939 - Closes #7944 - -- [Sergio Durigan Junior brought this change] - - curl.1: fix typos in the manpage - - s/transfering/transferring/ - s/transfered/transferred/ - - Signed-off-by: Sergio Durigan Junior <sergiodj@sergiodj.net> - Closes #7937 - -Marc Hoersken (1 Nov 2021) -- tests/smbserver.py: fix compatibility with impacket 0.9.23+ - - impacket now performs sanity checks if the requested and to - be served file path actually is inside the real share path. - - Ref: https://github.com/SecureAuthCorp/impacket/pull/1066 - - Fixes #7924 - Closes #7935 - -Daniel Stenberg (1 Nov 2021) -- docs: reduce use of "very" - - "Very" should be avoided in most texts. If intensifiers are needed, try - find better words instead. - - Closes #7936 - -- [Tatsuhiro Tsujikawa brought this change] - - ngtcp2: specify the missing required callback functions - - Closes #7929 - -- CURLOPT_[PROXY]_SSL_CIPHER_LIST.3: bold instead of quote - - Bold the example ciphers instead of using single quotes, which then also - avoids the problem of how to use single quotes when first in a line. - - Also rephrased the pages a little. - - Reported-by: Sergio Durigan Junior - Ref: #7928 - Closes #7934 - -- gen.pl: replace leading single quotes with \(aq - - ... and allow single quotes to be used "normally" in the .d files. - - Makes the output curl.1 use better nroff. - - Reported-by: Sergio Durigan Junior - Ref: #7928 - Closes #7933 - -Marc Hoersken (1 Nov 2021) -- tests: kill some test servers afterwards to avoid locked logfiles - - Reviewed-by: Daniel Stenberg - Closes #7925 - -Daniel Stenberg (1 Nov 2021) -- smooth-gtk-thread.c: enhance the mutex lock use - - Reported-by: ryancaicse on github - Fixes #7926 - Closes #7931 - -Marc Hoersken (31 Oct 2021) -- CI/runtests.pl: restore -u flag, but remove it from CI runs - - This makes it possible to use -u again for local testing, - but removes the flag from CI config files and make targets. - - Reviewed-by: Daniel Stenberg - - Partially reverts #7841 - Closes #7921 - -Daniel Stenberg (29 Oct 2021) -- [Jonathan Cardoso Machado brought this change] - - CURLOPT_HSTSWRITEFUNCTION.3: using CURLOPT_HSTS_CTRL is required - - Closes #7923 - -- [Axel Morawietz brought this change] - - imap: display quota information - - Show response to "GETQUOTAROOT INBOX" command. - - Closes #6973 - -- RELEASE-NOTES: synced - -- [Boris Rasin brought this change] - - cmake: fix error getting LOCATION property on non-imported target - - Closes #7885 - -- [Xiaoke Wang brought this change] - - url: check the return value of curl_url() - - Closes #7917 - -- [Roy Li brought this change] - - configure.ac: replace krb5-config with pkg-config - - The rationale is that custom *-config tools don't work well when - cross-compiling or using sysroots (such as when using Yocto project) and - require custom fixing for each of them; pkg-config on the other hand - works similarly everywhere. - - Signed-off-by: Roy Li <rongqing.li@windriver.com> - Signed-off-by: Alexander Kanavin <alex@linutronix.de> - - Closes #7916 - -- test1160: edited to work with hyper - - Closes #7912 - -- data/DISABLED: enable tests that now work with hyper - - Closes #7911 - -- test559: add 'HTTP' in keywords - - Makes it run fine with hyper - - Closes #7911 - -- test552: updated to work with hyper - - Closes #7911 - -Marc Hoersken (27 Oct 2021) -- github: fix incomplete permission to label PRs for Hacktoberfest - - Unfortunately the GitHub API requires a token with write permission - for both issues and pull-requests to edit labels on even just PRs. - - Follow up to #7897 - -Daniel Stenberg (27 Oct 2021) -- opt-manpages: use 'Added in' instead of 'Since' - - Closes #7913 - -Marc Hoersken (27 Oct 2021) -- github: fix missing permission to label PRs for Hacktoberfest - - Follow up to #7897 - - Test references to see if permissions are now sufficient: - - Closes #7832 - Closes #7897 - -- CI: more use of test-ci make target and verbose output - - Replace test-nonflaky with test-ci and enable verbose output - in all remaining CIs except Zuul which is customized a lot. - - Reviewed-by: Daniel Stenberg - Reviewed-by: Jay Satiro - - Follow up to #7785 - Closes #7832 - -- github: add support for Hacktoberfest using labels - - Automatically add hacktoberfest-accepted label to PRs opened between - September 30th and November 1st once a commit with a close reference - to it is pushed onto the master branch. - - With this workflow we can participate in Hacktoberfest while not - relying on GitHub to identify PRs as merged due to our rebasing. - - Requires hacktoberfest-accepted labels to exist for PRs on the - participating repository. Also requires hacktoberfest topic on - the participating repository to avoid applying to forked repos. - - Reviewed-by: Daniel Stenberg - - Fixes #7865 - Closes #7897 - -Daniel Stenberg (27 Oct 2021) -- http: reject HTTP response codes < 100 - - ... which then also includes negative ones as test 1430 uses. - - This makes native + hyper backend act identically on this and therefore - test 1430 can now be enabled when building with hyper. Adjust test 1431 - as well. - - Closes #7909 - -- [Kerem Kat brought this change] - - docs: fix typo in CURLOPT_TRAILERFUNCTION example - - Closes #7910 - -- docs/HYPER: remove some remaining issues, add HTTP/0.9 limitation - -- configure: when hyper is selected, deselect nghttp2 - - Closes #7908 - -- [Patrick Monnerat brought this change] - - sendf: accept zero-length data in Curl_client_write() - - Historically, Curl_client_write() used a length value of 0 as a marker - for a null-terminated data string. This feature has been removed in - commit f4b85d2. To detect leftover uses of the feature, a DEBUGASSERT - statement rejecting a length with value 0 was introduced, effectively - precluding use of this function with zero-length data. - - The current commit removes the DEBUGASSERT and makes the function to - return immediately if length is 0. - - A direct effect is to fix trying to output a zero-length distinguished - name in openldap. - - Another DEBUGASSERT statement is also rephrased for better readability. - - Closes #7898 - -- hyper: disable test 1294 since hyper doesn't allow such crazy headers - - Closes #7905 - -- c-hyper: make CURLOPT_SUPPRESS_CONNECT_HEADERS work - - Verified by the enabled test 1288 - - Closes #7905 - -- test1287: make work on hyper - - Closes #7905 - -- test1266/1267: disabled on hyper: no HTTP/0.9 support - - Closes #7905 - -Viktor Szakats (25 Oct 2021) -- Makefile.m32: fix to not require OpenSSL with -libssh2 or -rtmp options - - Previously, -libssh2/-rtmp options assumed that OpenSSL is also enabled - (and then failed with an error when not finding expected OpenSSL headers), - but this isn't necessarly true, e.g. when building both libssh2 and curl - against Schannel. This patch makes sure to only enable the OpenSSL backend - with -libssh2/-rtmp, when there was no SSL option explicitly selected. - - - Re-implement the logic as a single block of script. - - Also fix an indentation while there. - - Assisted-by: Jay Satiro - - Closes #7895 - -Daniel Stenberg (25 Oct 2021) -- docs: consistent use of "Added in" - - Make them all say "Added in [version]" without using 'curl' or 'libcurl' - in that phrase. - -- man pages: require all to use the same section header order - - This is the same order we already enforce among the options' man pages: - consistency is good. Add lots of previously missing examples. - - Adjust the manpage-syntax script for this purpose, used in test 1173. - - Closes #7904 - -- [David Hu brought this change] - - docs/HTTP3: improve build instructions - - 1. If writing to a system path if the command is not prefixed with - `sudo` it will cause a permission denied error - - 2. The patched OpenSSL branch has been updated to `openssl-3.0.0+quic` - to match upstream OpenSSL version. - - 3. We should not disable GnuTLS docs. - - Updated some commands about `make install` - - Closes #7842 - -- [Ricardo Martins brought this change] - - CMake: restore support for SecureTransport on iOS - - Restore support for building curl for iOS with SecureTransport enabled. - - Closes #7501 - -- tests: enable more tests with hyper - - Adjusted 1144, 1164 and 1176. - - Closes #7900 - -- docs: provide "RETURN VALUE" section for more func manpages - - Three were missing, one used a non-standard name for the header. - - Closes #7902 - -Jay Satiro (25 Oct 2021) -- curl_multi_socket_action.3: add a "RETURN VALUE" section - - .. because it may not be immediately clear to the user what - curl_multi_socket_action returns. - - Ref: https://curl.se/mail/lib-2021-10/0035.html - - Closes https://github.com/curl/curl/pull/7901 - -Daniel Stenberg (24 Oct 2021) -- RELEASE-NOTES: synced - -- [Samuel Henrique brought this change] - - tests: use python3 in test 1451 - - This is a continuation of commit ec91b5a69000bea0794bbb3 in which - changing this test was missed. There are no other python2 leftovers - now. - - Based on a Debian patch originally written by Alessandro Ghedini - <ghedo@debian.org> - - Closes #7899 - -- [Eddie Lumpkin brought this change] - - lib: fixing comment spelling typos in lib files - - Closes #7894 - Signed-off-by: ewlumpkin <ewlumpkin@gmail.com> - -- openssl: if verifypeer is not requested, skip the CA loading - - It was previously done mostly to show a match/non-match in the verbose - output even when verification was not asked for. This change skips the - loading of the CA certs unless verifypeer is set to save memory and CPU. - - Closes #7892 - -- curl-confopts.m4: remove --enable/disable-hidden-symbols - - These configure options have been saying "deprecated" since 9e24b9c7af - (April 2012). It was about time we remove them. - - Closes #7891 - -- c-hyper: don't abort CONNECT responses early when auth-in-progress - - ... and make sure to stop ignoring the body once the CONNECT is done. - - This should make test 206 work proper again and not be flaky. - - Closes #7889 - -- hyper: does not support disabling CURLOPT_HTTP_TRANSFER_DECODING - - Simply because hyper doesn't have this ability. Mentioned in docs now. - - Skip test 326 then - - Closes #7889 - -- test262: don't attempt with hyper - - This test verifies that curl works with binary zeroes in HTTP response - headers and hyper refuses such. They're not kosher http. - - Closes #7889 - -- c-hyper: make test 217 run - - Closes #7889 - -- DISABLED: enable test 209+213 for hyper - - Follow-up to 823d3ab855c - - Closes #7889 - -- test207: accept a different error code for hyper - - It returns HYPERE_UNEXPECTED_EOF for this case which we convert to the - somewhat generic CURLE_RECV_ERROR. - - Closes #7889 diff --git a/libs/libcurl/docs/THANKS b/libs/libcurl/docs/THANKS index b9f6eee256..b898341c95 100644 --- a/libs/libcurl/docs/THANKS +++ b/libs/libcurl/docs/THANKS @@ -6,6 +6,7 @@ 0xee on github 0xflotus on github +12932 on github 1337vt on github 1ocalhost on github 3dyd on github @@ -39,7 +40,9 @@ Adrian Peniak Adrian Schuur Adriano Meirelles afrind on github +Aftab Alam ahodesuka on github +ajak in #curl Ajit Dhumale Akhil Kedia Aki Koskinen @@ -100,6 +103,7 @@ Alexander Sinditskiy Alexander Traud Alexander V. Tikhonov Alexander Zhuravlev +Alexandre Bury Alexandre Pion Alexey Borzov Alexey Eremikhin @@ -144,6 +148,7 @@ Andreas Rieke Andreas Roth Andreas Schneider Andreas Schuldei +Andreas Sommer Andreas Streichardt Andreas Wurf Andrei Benea @@ -273,6 +278,7 @@ Benjamin Gerard Benjamin Gilbert Benjamin Johnson Benjamin Kircher +Benjamin Loison Benjamin Riefenstahl Benjamin Ritcey Benjamin Sergeant @@ -321,6 +327,7 @@ Boris Rasin Boris Verkhovskiy Brad Burdick Brad Fitzpatrick +Brad Forschinger Brad Harder Brad Hards Brad King @@ -357,6 +364,7 @@ Bruno Thomsen Bryan Henderson Bryan Kemp bsammon on github +bsergean on github Bubu on github buzo-ffm on github bxac on github @@ -386,6 +394,7 @@ Catalin Patulea causal-agent on github cbartl on github cclauss on github +Cering on github Cesar Eduardo Barros Chad Monroe Chandrakant Bagul @@ -434,6 +443,7 @@ Christopher Head Christopher Palow Christopher R. Palmer Christopher Reid +Christopher Sauer Christopher Stone Chungtsun Li Ciprian Badescu @@ -515,10 +525,12 @@ Daniel Carpenter Daniel Cater Daniel Egger Daniel Gustafsson +Daniel Hallberg Daniel Hwang Daniel Jeliński Daniel Johnson Daniel Kahn Gillmor +Daniel Katz Daniel Krügler Daniel Kurečka Daniel Lee Hwang @@ -557,6 +569,7 @@ David Binderman David Blaikie David Bohman David Byron +David Carlier David Cohen David Cook David Demelier @@ -579,6 +592,7 @@ David LeBlanc David Lopes David Lord David McCreedy +David McLaughlin David Odin David Phillips David Rosenstrauch @@ -651,9 +665,12 @@ Dmitry S. Baikov Dmitry Wagin dnivras on github Dolbneff A.V +Domen Kožar Domenico Andreoli Dominick Meglio Dominik Hölzl +Dominik Klemba +Dominik Thalhammer Dominique Leuenberger Don J Olmstead Dongliang Mu @@ -675,6 +692,7 @@ Duane Cathey Duncan Mac-Vicar Prett Duncan Wilcox Dustin Boswell +Dustin Howett Dusty Mabe Duy Phan Thanh Dwarakanath Yadavalli @@ -692,6 +710,7 @@ Eddie Lumpkin Edgaras Janušauskas Edin Kadribasic Edmond Yu +Edoardo Lolletti Eduard Bloch Edward Kimmel Edward Rudd @@ -711,6 +730,7 @@ Elliot Saba Ellis Pritchard Elmira A Semenova Elms +Eloy Degen elsamuko on github emanruse on github Emanuele Bovisio @@ -719,6 +739,7 @@ Emil Engler Emil Lerner Emil Romanus Emiliano Ida +Emilio López Emmanuel Tychon Enrico Scholz Enrik Berkhan @@ -763,11 +784,12 @@ Evan Jordan Evangelos Foutras Even Rouault Evert Pot -Evgeny Grin +Evgeny Grin (Karlson2k) Evgeny Turnaev eXeC64 on github Eygene Ryabinkin Eylem Ugurel +Fabian Fischer Fabian Frank Fabian Hiernaux Fabian Keil @@ -913,6 +935,7 @@ Gustaf Hui Gustavo Grieco Guy Poizat GwanYeong Kim +Gwen Shapira Gwenole Beauchesne Gökhan Şengün Götz Babin-Ebell @@ -958,7 +981,9 @@ Henry Roeland Herve Amblard HexTheDragon Hidemoto Nakada +highmtworks on github Himanshu Gupta +Hiroki Kurosawa Ho-chi Chen Hoi-Ho Chan Hongli Lai @@ -1017,6 +1042,7 @@ Isaiah Norton Ishan SinghLevett Ithubg on github Ivan Avdeev +Ivan Tsybulin IvanoG on github Ivo Bellin Salarin iz8mbw on github @@ -1029,6 +1055,7 @@ Jacob Barthelmeh Jacob Hoffman-Andrews Jacob Meuser Jacob Moshenko +Jacob Tolar Jactry Zeng Jad Chamcham Jaime Fullaondo @@ -1143,6 +1170,7 @@ Jesse Tan jethrogb on github jhoyla on github Jie He +Jilayne Lovejoy Jim Beveridge Jim Drash Jim Freeman @@ -1179,6 +1207,7 @@ Johannes G. Kristinsson Johannes Lesr Johannes Schindelin John A. Bristor +John Bampton John Bradshaw John Butterfield John Coffey @@ -1226,6 +1255,7 @@ Jon Travis Jon Turner Jon Wilkes Jonas Forsman +Jonas Haag Jonas Minnberg Jonas Schnelli Jonas Vautherin @@ -1251,6 +1281,7 @@ Josh Kapell Josh Soref joshhe on github Joshua Kwan +Joshua Root Joshua Swink Josie Huddleston Josip Medved @@ -1282,12 +1313,14 @@ Junho Choi Jurij Smakov jurisuk on github Juro Bystricky +justchen1369 on github Justin Clift Justin Ehlert Justin Fletcher Justin Karneges Justin Maggard jveazey on github +jvvprasad78 on github jzinn on github János Fekete Jérémy Rocher @@ -1299,6 +1332,7 @@ ka7 on github Kael1117 on github Kai Engert Kai Noda +Kai Pastor Kai Sommerfeld Kai-Uwe Rommel Kalle Vahlman @@ -1310,7 +1344,6 @@ Kantanat Wannapaka Kari Pahula Karl Chen Karl Moerder -Karlson2k on github Karol Pietrzak Kartik Mahajan Kaspar Brand @@ -1319,9 +1352,11 @@ Katsuhiko YOSHIDA Kazuho Oku Kees Cook Kees Dekker +Keitagit-kun on github Keith MacDonald Keith McGuigan Keith Mok +Kelly Kaoudis Ken Brown Ken Hirsch Ken Rastatter @@ -1440,6 +1475,7 @@ Linus Nielsen Feltzing Linus Nordberg Lior Kaplan Lisa Xu +Litter White Liviu Chircu Liza Alenchery lllaffer on github @@ -1474,6 +1510,7 @@ Luo Jinghua Luong Dinh Dung Luz Paz Luật Nguyễn +lwthiker on github Lyman Epp Lyndon Hill M.R.T on github @@ -1513,6 +1550,7 @@ Marcin Gryszkalis Marcin Konicki Marco Deckel Marco G. Salvagno +Marco Kamner Marco Maggi Marcos Diazr Marcus Hoffmann @@ -1528,6 +1566,7 @@ Mark Davies Mark Dodgson Mark Hamilton Mark Incley +Mark Itzcovitz Mark Karpeles Mark Lentczner Mark Nottingham @@ -1567,8 +1606,10 @@ Martin Lemke Martin Skinner Martin Staael Martin Storsjö +Martin Strunz Martin V Martin Vejnár +Martin Ågren Marty Kuhrt Maruko Masaya Suzuki @@ -1576,9 +1617,11 @@ masbug on github Massimiliano Fantuzzi Massimiliano Ziccardi Massimo Callegari +MasterInQuestion on github Mateusz Loskot Mathias Axelsson Mathias Gumz +Mathieu Carbonneaux Mathieu Legare Matias N. Goldberg Mats Lidell @@ -1599,6 +1642,7 @@ Matthew Blain Matthew Clarke Matthew Hall Matthew Kerwin +Matthew Thompson Matthew Whitehead Matthias Bolte Matthias Gatto @@ -1641,10 +1685,12 @@ Michael Calmer Michael Cronenworth Michael Curtis Michael Day +Michael Drake Michael Felt Michael Forney Michael Gmelin Michael Goffioul +Michael Heimpold Michael Hordijk Michael Jahn Michael Jerris @@ -1667,6 +1713,7 @@ Michael Smith Michael Stapelberg Michael Steuer Michael Stillwell +Michael Trebilcock Michael Vittiglio Michael Wallner Michal Bonino @@ -1734,8 +1781,10 @@ Muhammed Yavuz Nuzumlalı Murugan Balraj Muz Dima Myk Taylor +n0name321 on github Nach M. S. Nagai H +Nao Yonashiro naost3rn on github Nate Prewitt Nathan Coulter @@ -1823,12 +1872,14 @@ Oli Kingshott Oliver Gondža Oliver Graute Oliver Kuckertz +Oliver Roberts Oliver Schindler Oliver Urbann Olivier Berger Olivier Brunel Omar Ramadan omau on github +opensignature on github Orange Tsai Oren Souroujon Oren Tirosh @@ -1884,6 +1935,7 @@ Paul Nolan Paul Oliver Paul Querna Paul Saab +Paul Seligman Paul Vixie Paulo Roberto Tomasi Pavel Cenek @@ -1914,6 +1966,7 @@ Peter Bray Peter Forret Peter Frühberger Peter Gal +Peter Goodman Peter Heuchert Peter Hjalmarsson Peter Korsgaard @@ -1940,6 +1993,7 @@ Petr Bahula Petr Novak Petr Pisar Petr Voytsik +Petr Štetiar Phil Blundell Phil Crump Phil E. Taylor @@ -1948,7 +2002,7 @@ Phil Lisiecki Phil Pellouchoud Philip Craig Philip Gladstone -Philip H +Philip Heiduck Philip Langdale Philip Prindeville Philipp Klaus Krause @@ -1975,7 +2029,9 @@ Pramod Sharma Prash Dush Praveen Pvs Prithvi MK +privetryan on github Priyanka Shah +ProceduralMan on github Przemysław Tomaszewski pszemus on github puckipedia on github @@ -2094,6 +2150,8 @@ Rob Jones Rob Sanders Rob Stanzel Rob Ward +RobBotic1 on github +Robby Simpson Robert A. Monat Robert B. Harris Robert Brose @@ -2141,6 +2199,7 @@ Ron Eldor Ron Parker Ron Zapp Ronnie Mose +Rosen Penev Rosimildo da Silva Ross Burton Roy Bellingan @@ -2165,6 +2224,7 @@ Ryan Sleevi Ryan Winograd ryancaicse on github Ryuichi KAWAMATA +rzrymiak on github Rémy Léone S. Moonesamy Sai Ram Kunala @@ -2220,6 +2280,7 @@ Sebastian Sterk Senthil Raja Velu Sergei Kuzmin Sergei Nikulov +Sergey Bronnikov Sergey Markelov Sergey Ogryzkov Sergey Tatarincev @@ -2237,6 +2298,7 @@ Sevan Janiyan Sgharat on github Sh Diao Shachaf Ben-Kiki +ShadowZzj on github Shailesh Kapse Shankar Jadhavar Shao Shuchao @@ -2244,6 +2306,7 @@ Sharad Gupta Shard Sharon Brizinov Shaun Jackman +Shaun Mirani Shawn Landden Shawn Poulson Shikha Sharma @@ -2278,6 +2341,7 @@ Spezifant on github Spiridonoff A.V Spoon Man Spork Schivago +ssdbest on github sspiri on github sstruchtrup on github Stadler Stephan @@ -2342,6 +2406,7 @@ Stian Soiland-Reyes Stoned Elipot stootill on github Stuart Henderson +Sukanya Hanumanthu SumatraPeter on github Sune Ahlgren Sunny Bean @@ -2369,6 +2434,7 @@ tarek112 on github Tatsuhiro Tsujikawa tawmoto on github tbugfinder on github +Ted Lyngmo Teemu Yli-Elsila Temprimus Terri Oda @@ -2376,8 +2442,10 @@ Terry Wu thanhchungbtc on github The Infinnovation team TheAssassin on github +TheKnarf on github Theodore Dubois therealhirudo on github +Thiago Suchorski tholin on github Thomas Bouzerar Thomas Braun @@ -2396,6 +2464,7 @@ Thomas Schwinge Thomas Tonino Thomas van Hesteren Thomas Vegas +Thomas Weißschuh Thorsten Schöning Tiit Pikma Till Maas @@ -2434,8 +2503,10 @@ Tobias Hintze Tobias Lindgren Tobias Markus Tobias Nießen +Tobias Nygren Tobias Nyholm Tobias Rundström +Tobias Schaefer Tobias Stoeckmann Toby Peterson Todd A Ouska @@ -2487,6 +2558,7 @@ Toshio Kuratomi Toshiyuki Maezawa tpaukrt on github Traian Nicolescu +Trail of Bits Travis Burtrum Travis Obenhaus Trivikram Kamat @@ -2516,6 +2588,7 @@ Valerii Zapodovnikov vanillajonathan on github Varnavas Papaioannou Vasiliy Faronov +Vasiliy Ulyanov Vasily Lobaskin Vasy Okhin Venkat Akella @@ -2548,6 +2621,7 @@ Vladimir Lazarenko Vladimir Panteleev Vladimir Varlamov Vlastimil Ovčáčík +vlubart on github Vojtech Janota Vojtech Minarik Vojtěch Král @@ -2586,6 +2660,7 @@ Wojciech Zwiefka Wolf Vollprecht Wouter Van Rooy Wu Yongzheng +Wu Zheng Wyatt O'Day Wyatt OʼDay x2018 on github @@ -2612,6 +2687,7 @@ ygthien on github Yi Huang Yiming Jing Yingwei Liu +yiyuaner on github Ymir1711 on github Yonggang Luo Yongkang Huang @@ -2622,6 +2698,7 @@ Yu Xin Yukihiro Kawada Yun SangHo Yuri Slobodyanyuk +Yuriy Chernyshov Yuriy Sosov Yusuke Nakamura Yves Arrouye @@ -2635,6 +2712,7 @@ zelinchen on github Zenju on github Zero King Zhang Xiuhua +zhanghu on xiaomi Zhao Yisha Zhaoyang Wu Zhibiao Wu @@ -2646,6 +2724,7 @@ Zvi Har'El zzq1015 on github Ádler Jonas Gross Érico Nogueira +Érico Nogueira Rolim İsmail Dönmez Łukasz Domeradzki Štefan Kremeň diff --git a/libs/libcurl/include/curl/curl.h b/libs/libcurl/include/curl/curl.h index b00648e791..e28dd0b5a0 100644 --- a/libs/libcurl/include/curl/curl.h +++ b/libs/libcurl/include/curl/curl.h @@ -75,7 +75,8 @@ defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \ (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \ - (defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) + (defined(__MidnightBSD_version) && (__MidnightBSD_version < 100000)) || \ + defined(__sun__) #include <sys/select.h> #endif @@ -577,7 +578,7 @@ typedef enum { CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ - CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_OBSOLETE75, /* 75 - NOT IN USE since 7.82.0 */ CURLE_OBSOLETE76, /* 76 - NOT IN USE since 7.82.0 */ CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing or wrong format */ @@ -680,6 +681,7 @@ typedef enum { #define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME #define CURLE_LDAP_INVALID_URL CURLE_OBSOLETE62 #define CURLE_CONV_REQD CURLE_OBSOLETE76 +#define CURLE_CONV_FAILED CURLE_OBSOLETE75 /* This was the error code 50 in 7.7.3 and a few earlier versions, this is no longer used by libcurl but is instead #defined here only to not @@ -838,8 +840,8 @@ enum curl_khstat { CURLKHSTAT_FINE_ADD_TO_FILE, CURLKHSTAT_FINE, CURLKHSTAT_REJECT, /* reject the connection, return an error */ - CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so - this causes a CURLE_DEFER error but otherwise the + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now. + Causes a CURLE_PEER_FAILED_VERIFICATION error but the connection will be left intact etc */ CURLKHSTAT_FINE_REPLACE, /* accept and replace the wrong key*/ CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ @@ -1009,7 +1011,8 @@ typedef CURLSTScode (*curl_hstswrite_callback)(CURL *easy, #define CURLHSTS_ENABLE (long)(1<<0) #define CURLHSTS_READONLYFILE (long)(1<<1) -/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +/* The CURLPROTO_ defines below are for the **deprecated** CURLOPT_*PROTOCOLS + options. Do not use. */ #define CURLPROTO_HTTP (1<<0) #define CURLPROTO_HTTPS (1<<1) #define CURLPROTO_FTP (1<<2) @@ -1475,12 +1478,11 @@ typedef enum { Note that setting multiple bits may cause extra network round-trips. */ CURLOPT(CURLOPT_PROXYAUTH, CURLOPTTYPE_VALUES, 111), - /* FTP option that changes the timeout, in seconds, associated with - getting a response. This is different from transfer timeout time and - essentially places a demand on the FTP server to acknowledge commands - in a timely manner. */ - CURLOPT(CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112), -#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + /* Option that changes the timeout, in seconds, associated with getting a + response. This is different from transfer timeout time and essentially + places a demand on the server to acknowledge commands in a timely + manner. For FTP, SMTP, IMAP and POP3. */ + CURLOPT(CURLOPT_SERVER_RESPONSE_TIMEOUT, CURLOPTTYPE_LONG, 112), /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to tell libcurl to use those IP versions only. This only has effect on @@ -2143,6 +2145,18 @@ typedef enum { /* set the SSH host key callback custom pointer */ CURLOPT(CURLOPT_SSH_HOSTKEYDATA, CURLOPTTYPE_CBPOINT, 317), + /* specify which protocols that are allowed to be used for the transfer, + which thus helps the app which takes URLs from users or other external + inputs and want to restrict what protocol(s) to deal with. Defaults to + all built-in protocols. */ + CURLOPT(CURLOPT_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 318), + + /* specify which protocols that libcurl is allowed to follow directs to */ + CURLOPT(CURLOPT_REDIR_PROTOCOLS_STR, CURLOPTTYPE_STRINGPOINT, 319), + + /* websockets options */ + CURLOPT(CURLOPT_WS_OPTIONS, CURLOPTTYPE_LONG, 320), + CURLOPT_LASTENTRY /* the last unused */ } CURLoption; @@ -2168,6 +2182,9 @@ typedef enum { #define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD #define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL +/* */ +#define CURLOPT_FTP_RESPONSE_TIMEOUT CURLOPT_SERVER_RESPONSE_TIMEOUT + #else /* This is set if CURL_NO_OLDIES is defined at compile-time */ #undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ @@ -2182,7 +2199,7 @@ typedef enum { #define CURL_IPRESOLVE_V4 1 /* uses only IPv4 addresses/connections */ #define CURL_IPRESOLVE_V6 2 /* uses only IPv6 addresses/connections */ - /* three convenient "aliases" that follow the name scheme better */ + /* Convenient "aliases" */ #define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ @@ -3095,6 +3112,7 @@ CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); #include "urlapi.h" #include "options.h" #include "header.h" +#include "websockets.h" /* the typechecker doesn't work in C++ (yet) */ #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ diff --git a/libs/libcurl/include/curl/curlver.h b/libs/libcurl/include/curl/curlver.h index a21446e346..2e7124e6ea 100644 --- a/libs/libcurl/include/curl/curlver.h +++ b/libs/libcurl/include/curl/curlver.h @@ -32,12 +32,12 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.84.0" +#define LIBCURL_VERSION "7.86.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 84 +#define LIBCURL_VERSION_MINOR 86 #define LIBCURL_VERSION_PATCH 0 /* This is the numeric version of the libcurl version number, meant for easier @@ -59,7 +59,7 @@ CURL_VERSION_BITS() macro since curl's own configure script greps for it and needs it to contain the full number. */ -#define LIBCURL_VERSION_NUM 0x075400 +#define LIBCURL_VERSION_NUM 0x075600 /* * This is the date and time when the full source package was created. The @@ -70,7 +70,7 @@ * * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "2022-06-27" +#define LIBCURL_TIMESTAMP "2022-10-26" #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) #define CURL_AT_LEAST_VERSION(x,y,z) \ diff --git a/libs/libcurl/include/curl/header.h b/libs/libcurl/include/curl/header.h index 6af29c0c0a..1598c6f113 100644 --- a/libs/libcurl/include/curl/header.h +++ b/libs/libcurl/include/curl/header.h @@ -24,6 +24,10 @@ * ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + struct curl_header { char *name; /* this might not use the same case */ char *value; @@ -63,4 +67,8 @@ CURL_EXTERN struct curl_header *curl_easy_nextheader(CURL *easy, int request, struct curl_header *prev); +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + #endif /* CURLINC_HEADER_H */ diff --git a/libs/libcurl/include/curl/multi.h b/libs/libcurl/include/curl/multi.h index 30104925b7..2f3ec37a76 100644 --- a/libs/libcurl/include/curl/multi.h +++ b/libs/libcurl/include/curl/multi.h @@ -124,7 +124,7 @@ struct curl_waitfd { /* * Name: curl_multi_init() * - * Desc: inititalize multi-style curl usage + * Desc: initialize multi-style curl usage * * Returns: a new CURLM handle to use in all 'curl_multi' functions. */ diff --git a/libs/libcurl/include/curl/options.h b/libs/libcurl/include/curl/options.h index c8ac827c07..a792687cf4 100644 --- a/libs/libcurl/include/curl/options.h +++ b/libs/libcurl/include/curl/options.h @@ -33,7 +33,7 @@ typedef enum { CURLOT_VALUES, /* (a defined set or bitmask) */ CURLOT_OFF_T, /* curl_off_t (a range of values) */ CURLOT_OBJECT, /* pointer (void *) */ - CURLOT_STRING, /* (char * to zero terminated buffer) */ + CURLOT_STRING, /* (char * to null-terminated buffer) */ CURLOT_SLIST, /* (struct curl_slist *) */ CURLOT_CBPTR, /* (void * passed as-is to a callback) */ CURLOT_BLOB, /* blob (struct curl_blob *) */ diff --git a/libs/libcurl/include/curl/typecheck-gcc.h b/libs/libcurl/include/curl/typecheck-gcc.h index d7c7a9a309..2dabcb4166 100644 --- a/libs/libcurl/include/curl/typecheck-gcc.h +++ b/libs/libcurl/include/curl/typecheck-gcc.h @@ -272,9 +272,9 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t, (option) == CURLOPT_DNS_SERVERS || \ (option) == CURLOPT_DOH_URL || \ (option) == CURLOPT_EGDSOCKET || \ - (option) == CURLOPT_FTPPORT || \ (option) == CURLOPT_FTP_ACCOUNT || \ (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_FTPPORT || \ (option) == CURLOPT_HSTS || \ (option) == CURLOPT_INTERFACE || \ (option) == CURLOPT_ISSUERCERT || \ @@ -288,10 +288,8 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t, (option) == CURLOPT_PASSWORD || \ (option) == CURLOPT_PINNEDPUBLICKEY || \ (option) == CURLOPT_PRE_PROXY || \ + (option) == CURLOPT_PROTOCOLS_STR || \ (option) == CURLOPT_PROXY || \ - (option) == CURLOPT_PROXYPASSWORD || \ - (option) == CURLOPT_PROXYUSERNAME || \ - (option) == CURLOPT_PROXYUSERPWD || \ (option) == CURLOPT_PROXY_CAINFO || \ (option) == CURLOPT_PROXY_CAPATH || \ (option) == CURLOPT_PROXY_CRLFILE || \ @@ -299,17 +297,21 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t, (option) == CURLOPT_PROXY_KEYPASSWD || \ (option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \ (option) == CURLOPT_PROXY_SERVICE_NAME || \ + (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \ (option) == CURLOPT_PROXY_SSLCERT || \ (option) == CURLOPT_PROXY_SSLCERTTYPE || \ (option) == CURLOPT_PROXY_SSLKEY || \ (option) == CURLOPT_PROXY_SSLKEYTYPE || \ - (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \ (option) == CURLOPT_PROXY_TLS13_CIPHERS || \ (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \ (option) == CURLOPT_PROXY_TLSAUTH_TYPE || \ (option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYUSERPWD || \ (option) == CURLOPT_RANDOM_FILE || \ (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_REDIR_PROTOCOLS_STR || \ (option) == CURLOPT_REFERER || \ (option) == CURLOPT_REQUEST_TARGET || \ (option) == CURLOPT_RTSP_SESSION_ID || \ diff --git a/libs/libcurl/include/curl/websockets.h b/libs/libcurl/include/curl/websockets.h new file mode 100644 index 0000000000..4d57f91e56 --- /dev/null +++ b/libs/libcurl/include/curl/websockets.h @@ -0,0 +1,83 @@ +#ifndef CURLINC_WEBSOCKETS_H +#define CURLINC_WEBSOCKETS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +struct curl_ws_frame { + int age; /* zero */ + int flags; /* See the CURLWS_* defines */ + curl_off_t offset; /* the offset of this data into the frame */ + curl_off_t bytesleft; /* number of pending bytes left of the payload */ +}; + +/* flag bits */ +#define CURLWS_TEXT (1<<0) +#define CURLWS_BINARY (1<<1) +#define CURLWS_CONT (1<<2) +#define CURLWS_CLOSE (1<<3) +#define CURLWS_PING (1<<4) +#define CURLWS_OFFSET (1<<5) + +/* + * NAME curl_ws_recv() + * + * DESCRIPTION + * + * Receives data from the websocket connection. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, + size_t *recv, + struct curl_ws_frame **metap); + +/* sendflags for curl_ws_send() */ +#define CURLWS_PONG (1<<6) + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the websocket connection. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer, + size_t buflen, size_t *sent, + curl_off_t framesize, + unsigned int sendflags); + +/* bits for the CURLOPT_WS_OPTIONS bitmask: */ +#define CURLWS_RAW_MODE (1<<0) + +CURL_EXTERN struct curl_ws_frame *curl_ws_meta(CURL *curl); + +#ifdef __cplusplus +} +#endif + +#endif /* CURLINC_WEBSOCKETS_H */ diff --git a/libs/libcurl/libcurl.vcxproj b/libs/libcurl/libcurl.vcxproj index ac9b3256ba..dcf778d377 100644 --- a/libs/libcurl/libcurl.vcxproj +++ b/libs/libcurl/libcurl.vcxproj @@ -62,9 +62,6 @@ <ClCompile Include="src\curl_addrinfo.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
- <ClCompile Include="src\curl_ctype.c">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
<ClCompile Include="src\curl_des.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@@ -119,9 +116,6 @@ <ClCompile Include="src\doh.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
- <ClCompile Include="src\dotdot.c">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
<ClCompile Include="src\dynbuf.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@@ -269,6 +263,9 @@ <ClCompile Include="src\nonblock.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="src\noproxy.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="src\openldap.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
@@ -443,6 +440,9 @@ <ClCompile Include="src\wildcard.c">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="src\ws.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClInclude Include="src\altsvc.h" />
<ClInclude Include="src\amigaos.h" />
<ClInclude Include="src\arpa_telnet.h" />
@@ -505,6 +505,7 @@ <ClInclude Include="src\formdata.h" />
<ClInclude Include="src\ftp.h" />
<ClInclude Include="src\ftplistparser.h" />
+ <ClInclude Include="src\functypes.h" />
<ClInclude Include="src\getinfo.h" />
<ClInclude Include="src\gopher.h" />
<ClInclude Include="src\h2h3.h" />
@@ -532,6 +533,7 @@ <ClInclude Include="src\multiif.h" />
<ClInclude Include="src\netrc.h" />
<ClInclude Include="src\nonblock.h" />
+ <ClInclude Include="src\noproxy.h" />
<ClInclude Include="src\parsedate.h" />
<ClInclude Include="src\pingpong.h" />
<ClInclude Include="src\pop3.h" />
@@ -574,6 +576,7 @@ <ClInclude Include="src\version_win32.h" />
<ClInclude Include="src\warnless.h" />
<ClInclude Include="src\wildcard.h" />
+ <ClInclude Include="src\ws.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\strcase.c">
diff --git a/libs/libcurl/libcurl.vcxproj.filters b/libs/libcurl/libcurl.vcxproj.filters index d6047ad7e7..018e89301b 100644 --- a/libs/libcurl/libcurl.vcxproj.filters +++ b/libs/libcurl/libcurl.vcxproj.filters @@ -38,9 +38,6 @@ <ClCompile Include="src\curl_addrinfo.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="src\curl_ctype.c">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="src\curl_des.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -95,7 +92,7 @@ <ClCompile Include="src\doh.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="src\dotdot.c">
+ <ClCompile Include="src\dynbuf.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\easy.c">
@@ -242,6 +239,9 @@ <ClCompile Include="src\nonblock.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\noproxy.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="src\openldap.c">
<Filter>Source Files</Filter>
</ClCompile>
@@ -449,7 +449,7 @@ <ClCompile Include="src\version.c">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="src\dynbuf.c">
+ <ClCompile Include="src\ws.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@@ -607,6 +607,9 @@ <ClInclude Include="src\dotdot.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\dynbuf.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="src\easyif.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -637,6 +640,9 @@ <ClInclude Include="src\ftplistparser.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\functypes.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="src\getinfo.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -718,6 +724,9 @@ <ClInclude Include="src\nonblock.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\noproxy.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="src\parsedate.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -844,7 +853,7 @@ <ClInclude Include="src\wildcard.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="src\dynbuf.h">
+ <ClInclude Include="src\ws.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
diff --git a/libs/libcurl/src/CMakeLists.txt b/libs/libcurl/src/CMakeLists.txt index f9987517d6..8cea346c34 100644 --- a/libs/libcurl/src/CMakeLists.txt +++ b/libs/libcurl/src/CMakeLists.txt @@ -23,6 +23,7 @@ ########################################################################### set(LIB_NAME libcurl) set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library") +add_definitions(-DBUILDING_LIBCURL) if(BUILD_SHARED_LIBS) set(CURL_STATICLIB NO) @@ -95,7 +96,7 @@ if(NOT BUILD_SHARED_LIBS) set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB) endif() -target_link_libraries(${LIB_NAME} ${CURL_LIBS}) +target_link_libraries(${LIB_NAME} PRIVATE ${CURL_LIBS}) set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL @@ -119,7 +120,6 @@ endif() if(WIN32) if(BUILD_SHARED_LIBS) - set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "_USRDLL") if(MSVC) # Add "_imp" as a suffix before the extension to avoid conflicting with # the statically linked "libcurl.lib" @@ -132,14 +132,16 @@ target_include_directories(${LIB_NAME} INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>) -install(TARGETS ${LIB_NAME} - EXPORT ${TARGETS_EXPORT_NAME} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) - -export(TARGETS ${LIB_NAME} - APPEND FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake - NAMESPACE ${PROJECT_NAME}:: -) +if(CURL_ENABLE_EXPORT_TARGET) + install(TARGETS ${LIB_NAME} + EXPORT ${TARGETS_EXPORT_NAME} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + + export(TARGETS ${LIB_NAME} + FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake + NAMESPACE ${PROJECT_NAME}:: + ) +endif() diff --git a/libs/libcurl/src/Makefile.am b/libs/libcurl/src/Makefile.am index 18ce47ea95..5d2df8bffb 100644 --- a/libs/libcurl/src/Makefile.am +++ b/libs/libcurl/src/Makefile.am @@ -75,6 +75,12 @@ AM_CPPFLAGS += -DBUILDING_LIBCURL AM_LDFLAGS = AM_CFLAGS = +# Makefile.inc provides the CSOURCES and HHEADERS defines +include Makefile.inc + +libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS) +libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS) + libcurl_la_CPPFLAGS_EXTRA = libcurl_la_LDFLAGS_EXTRA = libcurl_la_CFLAGS_EXTRA = @@ -102,6 +108,11 @@ endif if USE_CPPFLAG_CURL_STATICLIB libcurl_la_CPPFLAGS_EXTRA += -DCURL_STATICLIB +else +if OS_WINDOWS +libcurl_la_SOURCES += $(LIB_RCFILES) +$(LIB_RCFILES): $(top_srcdir)/include/curl/curlver.h +endif endif if DOING_CURL_SYMBOL_HIDING @@ -117,12 +128,6 @@ libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_LIBS) libcurlu_la_CFLAGS = $(AM_CFLAGS) -# Makefile.inc provides the CSOURCES and HHEADERS defines -include Makefile.inc - -libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS) -libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS) - CHECKSRC = $(CS_$(V)) CS_0 = @echo " RUN " $@; CS_1 = @@ -148,3 +153,9 @@ tidy: optiontable: perl optiontable.pl < $(top_srcdir)/include/curl/curl.h > easyoptions.c + +if OS_WINDOWS +# Warning is "normal": libtool: error: ignoring unknown tag RC +.rc.lo: + $(LIBTOOL) --tag=RC --mode=compile $(RC) -I$(top_srcdir)/include $(RCFLAGS) -i $< -o $@ +endif diff --git a/libs/libcurl/src/Makefile.in b/libs/libcurl/src/Makefile.in index e292dc384f..5742ca1cb2 100644 --- a/libs/libcurl/src/Makefile.in +++ b/libs/libcurl/src/Makefile.in @@ -119,12 +119,12 @@ host_triplet = @host@ # if symbol-hiding is enabled, hide them! @CURL_LT_SHLIB_USE_VERSIONED_SYMBOLS_FALSE@@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_5 = -export-symbols-regex '^curl_.*' @USE_CPPFLAG_CURL_STATICLIB_TRUE@am__append_6 = -DCURL_STATICLIB -@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_7 = -DCURL_HIDDEN_SYMBOLS -@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_8 = $(CFLAG_CURL_SYMBOL_HIDING) +@OS_WINDOWS_TRUE@@USE_CPPFLAG_CURL_STATICLIB_FALSE@am__append_7 = $(LIB_RCFILES) +@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_8 = -DCURL_HIDDEN_SYMBOLS +@DOING_CURL_SYMBOL_HIDING_TRUE@am__append_9 = $(CFLAG_CURL_SYMBOL_HIDING) subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compile_check_sizeof.m4 \ - $(top_srcdir)/m4/curl-amissl.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/curl-amissl.m4 \ $(top_srcdir)/m4/curl-bearssl.m4 \ $(top_srcdir)/m4/curl-compilers.m4 \ $(top_srcdir)/m4/curl-confopts.m4 \ @@ -187,22 +187,84 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) libcurl_la_LIBADD = +am__libcurl_la_SOURCES_DIST = altsvc.c amigaos.c asyn-ares.c \ + asyn-thread.c base64.c bufref.c c-hyper.c conncache.c \ + connect.c content_encoding.c cookie.c curl_addrinfo.c \ + curl_des.c curl_endian.c curl_fnmatch.c curl_get_line.c \ + curl_gethostname.c curl_gssapi.c curl_memrchr.c \ + curl_multibyte.c curl_ntlm_core.c curl_ntlm_wb.c curl_path.c \ + curl_range.c curl_rtmp.c curl_sasl.c curl_sspi.c \ + curl_threads.c dict.c doh.c dynbuf.c easy.c easygetopt.c \ + easyoptions.c escape.c file.c fileinfo.c fopen.c formdata.c \ + ftp.c ftplistparser.c getenv.c getinfo.c gopher.c h2h3.c \ + hash.c headers.c hmac.c hostasyn.c hostip.c hostip4.c \ + hostip6.c hostsyn.c hsts.c http.c http2.c http_chunks.c \ + http_digest.c http_negotiate.c http_ntlm.c http_proxy.c \ + http_aws_sigv4.c idn_win32.c if2ip.c imap.c inet_ntop.c \ + inet_pton.c krb5.c ldap.c llist.c md4.c md5.c memdebug.c \ + mime.c mprintf.c mqtt.c multi.c netrc.c nonblock.c noproxy.c \ + openldap.c parsedate.c pingpong.c pop3.c progress.c psl.c \ + rand.c rename.c rtsp.c select.c sendf.c setopt.c sha256.c \ + share.c slist.c smb.c smtp.c socketpair.c socks.c \ + socks_gssapi.c socks_sspi.c speedcheck.c splay.c strcase.c \ + strdup.c strerror.c strtok.c strtoofft.c system_win32.c \ + telnet.c tftp.c timediff.c timeval.c transfer.c url.c urlapi.c \ + version.c version_win32.c warnless.c wildcard.c ws.c \ + vauth/cleartext.c vauth/cram.c vauth/digest.c \ + vauth/digest_sspi.c vauth/gsasl.c vauth/krb5_gssapi.c \ + vauth/krb5_sspi.c vauth/ntlm.c vauth/ntlm_sspi.c \ + vauth/oauth2.c vauth/spnego_gssapi.c vauth/spnego_sspi.c \ + vauth/vauth.c vtls/bearssl.c vtls/gskit.c vtls/gtls.c \ + vtls/hostcheck.c vtls/keylog.c vtls/mbedtls.c \ + vtls/mbedtls_threadlock.c vtls/nss.c vtls/openssl.c \ + vtls/rustls.c vtls/schannel.c vtls/schannel_verify.c \ + vtls/sectransp.c vtls/vtls.c vtls/wolfssl.c vtls/x509asn1.c \ + vquic/msh3.c vquic/ngtcp2.c vquic/quiche.c vquic/vquic.c \ + vssh/libssh.c vssh/libssh2.c vssh/wolfssh.c altsvc.h amigaos.h \ + arpa_telnet.h asyn.h bufref.h c-hyper.h conncache.h connect.h \ + content_encoding.h cookie.h curl_addrinfo.h curl_base64.h \ + curl_ctype.h curl_des.h curl_endian.h curl_fnmatch.h \ + curl_get_line.h curl_gethostname.h curl_gssapi.h curl_hmac.h \ + curl_krb5.h curl_ldap.h curl_md4.h curl_md5.h curl_memory.h \ + curl_memrchr.h curl_multibyte.h curl_ntlm_core.h \ + curl_ntlm_wb.h curl_path.h curl_printf.h curl_range.h \ + curl_rtmp.h curl_sasl.h curl_setup.h curl_setup_once.h \ + curl_sha256.h curl_sspi.h curl_threads.h curlx.h dict.h doh.h \ + dynbuf.h easy_lock.h easyif.h easyoptions.h escape.h file.h \ + fileinfo.h fopen.h formdata.h functypes.h ftp.h \ + ftplistparser.h getinfo.h gopher.h h2h3.h hash.h headers.h \ + hostip.h hsts.h http.h http2.h http_chunks.h http_digest.h \ + http_negotiate.h http_ntlm.h http_proxy.h http_aws_sigv4.h \ + if2ip.h imap.h inet_ntop.h inet_pton.h llist.h memdebug.h \ + mime.h mqtt.h multihandle.h multiif.h netrc.h nonblock.h \ + noproxy.h parsedate.h pingpong.h pop3.h progress.h psl.h \ + quic.h rand.h rename.h rtsp.h select.h sendf.h setopt.h \ + setup-vms.h share.h sigpipe.h slist.h smb.h smtp.h sockaddr.h \ + socketpair.h socks.h speedcheck.h splay.h strcase.h strdup.h \ + strerror.h strtok.h strtoofft.h system_win32.h telnet.h tftp.h \ + timediff.h timeval.h transfer.h url.h urlapi-int.h urldata.h \ + version_win32.h warnless.h wildcard.h ws.h vauth/digest.h \ + vauth/ntlm.h vauth/vauth.h vtls/bearssl.h vtls/gskit.h \ + vtls/gtls.h vtls/hostcheck.h vtls/keylog.h vtls/mbedtls.h \ + vtls/mbedtls_threadlock.h vtls/nssg.h vtls/openssl.h \ + vtls/rustls.h vtls/schannel.h vtls/sectransp.h vtls/vtls.h \ + vtls/wolfssl.h vtls/x509asn1.h vquic/msh3.h vquic/ngtcp2.h \ + vquic/quiche.h vquic/vquic.h vssh/ssh.h libcurl.rc am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \ libcurl_la-asyn-ares.lo libcurl_la-asyn-thread.lo \ libcurl_la-base64.lo libcurl_la-bufref.lo \ libcurl_la-c-hyper.lo libcurl_la-conncache.lo \ libcurl_la-connect.lo libcurl_la-content_encoding.lo \ libcurl_la-cookie.lo libcurl_la-curl_addrinfo.lo \ - libcurl_la-curl_ctype.lo libcurl_la-curl_des.lo \ - libcurl_la-curl_endian.lo libcurl_la-curl_fnmatch.lo \ - libcurl_la-curl_get_line.lo libcurl_la-curl_gethostname.lo \ - libcurl_la-curl_gssapi.lo libcurl_la-curl_memrchr.lo \ - libcurl_la-curl_multibyte.lo libcurl_la-curl_ntlm_core.lo \ - libcurl_la-curl_ntlm_wb.lo libcurl_la-curl_path.lo \ - libcurl_la-curl_range.lo libcurl_la-curl_rtmp.lo \ - libcurl_la-curl_sasl.lo libcurl_la-curl_sspi.lo \ - libcurl_la-curl_threads.lo libcurl_la-dict.lo \ - libcurl_la-doh.lo libcurl_la-dotdot.lo libcurl_la-dynbuf.lo \ + libcurl_la-curl_des.lo libcurl_la-curl_endian.lo \ + libcurl_la-curl_fnmatch.lo libcurl_la-curl_get_line.lo \ + libcurl_la-curl_gethostname.lo libcurl_la-curl_gssapi.lo \ + libcurl_la-curl_memrchr.lo libcurl_la-curl_multibyte.lo \ + libcurl_la-curl_ntlm_core.lo libcurl_la-curl_ntlm_wb.lo \ + libcurl_la-curl_path.lo libcurl_la-curl_range.lo \ + libcurl_la-curl_rtmp.lo libcurl_la-curl_sasl.lo \ + libcurl_la-curl_sspi.lo libcurl_la-curl_threads.lo \ + libcurl_la-dict.lo libcurl_la-doh.lo libcurl_la-dynbuf.lo \ libcurl_la-easy.lo libcurl_la-easygetopt.lo \ libcurl_la-easyoptions.lo libcurl_la-escape.lo \ libcurl_la-file.lo libcurl_la-fileinfo.lo libcurl_la-fopen.lo \ @@ -223,13 +285,13 @@ am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \ libcurl_la-memdebug.lo libcurl_la-mime.lo \ libcurl_la-mprintf.lo libcurl_la-mqtt.lo libcurl_la-multi.lo \ libcurl_la-netrc.lo libcurl_la-nonblock.lo \ - libcurl_la-openldap.lo libcurl_la-parsedate.lo \ - libcurl_la-pingpong.lo libcurl_la-pop3.lo \ - libcurl_la-progress.lo libcurl_la-psl.lo libcurl_la-rand.lo \ - libcurl_la-rename.lo libcurl_la-rtsp.lo libcurl_la-select.lo \ - libcurl_la-sendf.lo libcurl_la-setopt.lo libcurl_la-sha256.lo \ - libcurl_la-share.lo libcurl_la-slist.lo libcurl_la-smb.lo \ - libcurl_la-smtp.lo libcurl_la-socketpair.lo \ + libcurl_la-noproxy.lo libcurl_la-openldap.lo \ + libcurl_la-parsedate.lo libcurl_la-pingpong.lo \ + libcurl_la-pop3.lo libcurl_la-progress.lo libcurl_la-psl.lo \ + libcurl_la-rand.lo libcurl_la-rename.lo libcurl_la-rtsp.lo \ + libcurl_la-select.lo libcurl_la-sendf.lo libcurl_la-setopt.lo \ + libcurl_la-sha256.lo libcurl_la-share.lo libcurl_la-slist.lo \ + libcurl_la-smb.lo libcurl_la-smtp.lo libcurl_la-socketpair.lo \ libcurl_la-socks.lo libcurl_la-socks_gssapi.lo \ libcurl_la-socks_sspi.lo libcurl_la-speedcheck.lo \ libcurl_la-splay.lo libcurl_la-strcase.lo libcurl_la-strdup.lo \ @@ -239,7 +301,7 @@ am__objects_1 = libcurl_la-altsvc.lo libcurl_la-amigaos.lo \ libcurl_la-timeval.lo libcurl_la-transfer.lo libcurl_la-url.lo \ libcurl_la-urlapi.lo libcurl_la-version.lo \ libcurl_la-version_win32.lo libcurl_la-warnless.lo \ - libcurl_la-wildcard.lo + libcurl_la-wildcard.lo libcurl_la-ws.lo am__dirstamp = $(am__leading_dot)dirstamp am__objects_2 = vauth/libcurl_la-cleartext.lo vauth/libcurl_la-cram.lo \ vauth/libcurl_la-digest.lo vauth/libcurl_la-digest_sspi.lo \ @@ -265,7 +327,10 @@ am__objects_6 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ am__objects_7 = am__objects_8 = $(am__objects_7) $(am__objects_7) $(am__objects_7) \ $(am__objects_7) $(am__objects_7) -am_libcurl_la_OBJECTS = $(am__objects_6) $(am__objects_8) +am__objects_9 = libcurl.lo +@OS_WINDOWS_TRUE@@USE_CPPFLAG_CURL_STATICLIB_FALSE@am__objects_10 = $(am__objects_9) +am_libcurl_la_OBJECTS = $(am__objects_6) $(am__objects_8) \ + $(am__objects_10) libcurl_la_OBJECTS = $(am_libcurl_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -275,22 +340,21 @@ libcurl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcurl_la_CFLAGS) \ $(CFLAGS) $(libcurl_la_LDFLAGS) $(LDFLAGS) -o $@ libcurlu_la_LIBADD = -am__objects_9 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \ +am__objects_11 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \ libcurlu_la-asyn-ares.lo libcurlu_la-asyn-thread.lo \ libcurlu_la-base64.lo libcurlu_la-bufref.lo \ libcurlu_la-c-hyper.lo libcurlu_la-conncache.lo \ libcurlu_la-connect.lo libcurlu_la-content_encoding.lo \ libcurlu_la-cookie.lo libcurlu_la-curl_addrinfo.lo \ - libcurlu_la-curl_ctype.lo libcurlu_la-curl_des.lo \ - libcurlu_la-curl_endian.lo libcurlu_la-curl_fnmatch.lo \ - libcurlu_la-curl_get_line.lo libcurlu_la-curl_gethostname.lo \ - libcurlu_la-curl_gssapi.lo libcurlu_la-curl_memrchr.lo \ - libcurlu_la-curl_multibyte.lo libcurlu_la-curl_ntlm_core.lo \ - libcurlu_la-curl_ntlm_wb.lo libcurlu_la-curl_path.lo \ - libcurlu_la-curl_range.lo libcurlu_la-curl_rtmp.lo \ - libcurlu_la-curl_sasl.lo libcurlu_la-curl_sspi.lo \ - libcurlu_la-curl_threads.lo libcurlu_la-dict.lo \ - libcurlu_la-doh.lo libcurlu_la-dotdot.lo libcurlu_la-dynbuf.lo \ + libcurlu_la-curl_des.lo libcurlu_la-curl_endian.lo \ + libcurlu_la-curl_fnmatch.lo libcurlu_la-curl_get_line.lo \ + libcurlu_la-curl_gethostname.lo libcurlu_la-curl_gssapi.lo \ + libcurlu_la-curl_memrchr.lo libcurlu_la-curl_multibyte.lo \ + libcurlu_la-curl_ntlm_core.lo libcurlu_la-curl_ntlm_wb.lo \ + libcurlu_la-curl_path.lo libcurlu_la-curl_range.lo \ + libcurlu_la-curl_rtmp.lo libcurlu_la-curl_sasl.lo \ + libcurlu_la-curl_sspi.lo libcurlu_la-curl_threads.lo \ + libcurlu_la-dict.lo libcurlu_la-doh.lo libcurlu_la-dynbuf.lo \ libcurlu_la-easy.lo libcurlu_la-easygetopt.lo \ libcurlu_la-easyoptions.lo libcurlu_la-escape.lo \ libcurlu_la-file.lo libcurlu_la-fileinfo.lo \ @@ -312,10 +376,11 @@ am__objects_9 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \ libcurlu_la-md4.lo libcurlu_la-md5.lo libcurlu_la-memdebug.lo \ libcurlu_la-mime.lo libcurlu_la-mprintf.lo libcurlu_la-mqtt.lo \ libcurlu_la-multi.lo libcurlu_la-netrc.lo \ - libcurlu_la-nonblock.lo libcurlu_la-openldap.lo \ - libcurlu_la-parsedate.lo libcurlu_la-pingpong.lo \ - libcurlu_la-pop3.lo libcurlu_la-progress.lo libcurlu_la-psl.lo \ - libcurlu_la-rand.lo libcurlu_la-rename.lo libcurlu_la-rtsp.lo \ + libcurlu_la-nonblock.lo libcurlu_la-noproxy.lo \ + libcurlu_la-openldap.lo libcurlu_la-parsedate.lo \ + libcurlu_la-pingpong.lo libcurlu_la-pop3.lo \ + libcurlu_la-progress.lo libcurlu_la-psl.lo libcurlu_la-rand.lo \ + libcurlu_la-rename.lo libcurlu_la-rtsp.lo \ libcurlu_la-select.lo libcurlu_la-sendf.lo \ libcurlu_la-setopt.lo libcurlu_la-sha256.lo \ libcurlu_la-share.lo libcurlu_la-slist.lo libcurlu_la-smb.lo \ @@ -330,8 +395,9 @@ am__objects_9 = libcurlu_la-altsvc.lo libcurlu_la-amigaos.lo \ libcurlu_la-timeval.lo libcurlu_la-transfer.lo \ libcurlu_la-url.lo libcurlu_la-urlapi.lo \ libcurlu_la-version.lo libcurlu_la-version_win32.lo \ - libcurlu_la-warnless.lo libcurlu_la-wildcard.lo -am__objects_10 = vauth/libcurlu_la-cleartext.lo \ + libcurlu_la-warnless.lo libcurlu_la-wildcard.lo \ + libcurlu_la-ws.lo +am__objects_12 = vauth/libcurlu_la-cleartext.lo \ vauth/libcurlu_la-cram.lo vauth/libcurlu_la-digest.lo \ vauth/libcurlu_la-digest_sspi.lo vauth/libcurlu_la-gsasl.lo \ vauth/libcurlu_la-krb5_gssapi.lo \ @@ -339,7 +405,7 @@ am__objects_10 = vauth/libcurlu_la-cleartext.lo \ vauth/libcurlu_la-ntlm_sspi.lo vauth/libcurlu_la-oauth2.lo \ vauth/libcurlu_la-spnego_gssapi.lo \ vauth/libcurlu_la-spnego_sspi.lo vauth/libcurlu_la-vauth.lo -am__objects_11 = vtls/libcurlu_la-bearssl.lo vtls/libcurlu_la-gskit.lo \ +am__objects_13 = vtls/libcurlu_la-bearssl.lo vtls/libcurlu_la-gskit.lo \ vtls/libcurlu_la-gtls.lo vtls/libcurlu_la-hostcheck.lo \ vtls/libcurlu_la-keylog.lo vtls/libcurlu_la-mbedtls.lo \ vtls/libcurlu_la-mbedtls_threadlock.lo vtls/libcurlu_la-nss.lo \ @@ -348,13 +414,13 @@ am__objects_11 = vtls/libcurlu_la-bearssl.lo vtls/libcurlu_la-gskit.lo \ vtls/libcurlu_la-schannel_verify.lo \ vtls/libcurlu_la-sectransp.lo vtls/libcurlu_la-vtls.lo \ vtls/libcurlu_la-wolfssl.lo vtls/libcurlu_la-x509asn1.lo -am__objects_12 = vquic/libcurlu_la-msh3.lo vquic/libcurlu_la-ngtcp2.lo \ +am__objects_14 = vquic/libcurlu_la-msh3.lo vquic/libcurlu_la-ngtcp2.lo \ vquic/libcurlu_la-quiche.lo vquic/libcurlu_la-vquic.lo -am__objects_13 = vssh/libcurlu_la-libssh.lo \ +am__objects_15 = vssh/libcurlu_la-libssh.lo \ vssh/libcurlu_la-libssh2.lo vssh/libcurlu_la-wolfssh.lo -am__objects_14 = $(am__objects_9) $(am__objects_10) $(am__objects_11) \ - $(am__objects_12) $(am__objects_13) -am_libcurlu_la_OBJECTS = $(am__objects_14) $(am__objects_8) +am__objects_16 = $(am__objects_11) $(am__objects_12) $(am__objects_13) \ + $(am__objects_14) $(am__objects_15) +am_libcurlu_la_OBJECTS = $(am__objects_16) $(am__objects_8) libcurlu_la_OBJECTS = $(am_libcurlu_la_OBJECTS) libcurlu_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcurlu_la_CFLAGS) \ @@ -387,7 +453,6 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurl_la-content_encoding.Plo \ ./$(DEPDIR)/libcurl_la-cookie.Plo \ ./$(DEPDIR)/libcurl_la-curl_addrinfo.Plo \ - ./$(DEPDIR)/libcurl_la-curl_ctype.Plo \ ./$(DEPDIR)/libcurl_la-curl_des.Plo \ ./$(DEPDIR)/libcurl_la-curl_endian.Plo \ ./$(DEPDIR)/libcurl_la-curl_fnmatch.Plo \ @@ -405,7 +470,6 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurl_la-curl_sspi.Plo \ ./$(DEPDIR)/libcurl_la-curl_threads.Plo \ ./$(DEPDIR)/libcurl_la-dict.Plo ./$(DEPDIR)/libcurl_la-doh.Plo \ - ./$(DEPDIR)/libcurl_la-dotdot.Plo \ ./$(DEPDIR)/libcurl_la-dynbuf.Plo \ ./$(DEPDIR)/libcurl_la-easy.Plo \ ./$(DEPDIR)/libcurl_la-easygetopt.Plo \ @@ -454,6 +518,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurl_la-multi.Plo \ ./$(DEPDIR)/libcurl_la-netrc.Plo \ ./$(DEPDIR)/libcurl_la-nonblock.Plo \ + ./$(DEPDIR)/libcurl_la-noproxy.Plo \ ./$(DEPDIR)/libcurl_la-openldap.Plo \ ./$(DEPDIR)/libcurl_la-parsedate.Plo \ ./$(DEPDIR)/libcurl_la-pingpong.Plo \ @@ -492,6 +557,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurl_la-version_win32.Plo \ ./$(DEPDIR)/libcurl_la-warnless.Plo \ ./$(DEPDIR)/libcurl_la-wildcard.Plo \ + ./$(DEPDIR)/libcurl_la-ws.Plo \ ./$(DEPDIR)/libcurlu_la-altsvc.Plo \ ./$(DEPDIR)/libcurlu_la-amigaos.Plo \ ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo \ @@ -504,7 +570,6 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurlu_la-content_encoding.Plo \ ./$(DEPDIR)/libcurlu_la-cookie.Plo \ ./$(DEPDIR)/libcurlu_la-curl_addrinfo.Plo \ - ./$(DEPDIR)/libcurlu_la-curl_ctype.Plo \ ./$(DEPDIR)/libcurlu_la-curl_des.Plo \ ./$(DEPDIR)/libcurlu_la-curl_endian.Plo \ ./$(DEPDIR)/libcurlu_la-curl_fnmatch.Plo \ @@ -523,7 +588,6 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurlu_la-curl_threads.Plo \ ./$(DEPDIR)/libcurlu_la-dict.Plo \ ./$(DEPDIR)/libcurlu_la-doh.Plo \ - ./$(DEPDIR)/libcurlu_la-dotdot.Plo \ ./$(DEPDIR)/libcurlu_la-dynbuf.Plo \ ./$(DEPDIR)/libcurlu_la-easy.Plo \ ./$(DEPDIR)/libcurlu_la-easygetopt.Plo \ @@ -573,6 +637,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurlu_la-multi.Plo \ ./$(DEPDIR)/libcurlu_la-netrc.Plo \ ./$(DEPDIR)/libcurlu_la-nonblock.Plo \ + ./$(DEPDIR)/libcurlu_la-noproxy.Plo \ ./$(DEPDIR)/libcurlu_la-openldap.Plo \ ./$(DEPDIR)/libcurlu_la-parsedate.Plo \ ./$(DEPDIR)/libcurlu_la-pingpong.Plo \ @@ -613,6 +678,7 @@ am__depfiles_remade = ./$(DEPDIR)/libcurl_la-altsvc.Plo \ ./$(DEPDIR)/libcurlu_la-version_win32.Plo \ ./$(DEPDIR)/libcurlu_la-warnless.Plo \ ./$(DEPDIR)/libcurlu_la-wildcard.Plo \ + ./$(DEPDIR)/libcurlu_la-ws.Plo \ vauth/$(DEPDIR)/libcurl_la-cleartext.Plo \ vauth/$(DEPDIR)/libcurl_la-cram.Plo \ vauth/$(DEPDIR)/libcurl_la-digest.Plo \ @@ -705,7 +771,7 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libcurl_la_SOURCES) $(libcurlu_la_SOURCES) -DIST_SOURCES = $(libcurl_la_SOURCES) $(libcurlu_la_SOURCES) +DIST_SOURCES = $(am__libcurl_la_SOURCES_DIST) $(libcurlu_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -856,6 +922,7 @@ PKGADD_VENDOR = @PKGADD_VENDOR@ PKGCONFIG = @PKGCONFIG@ RANDOM_FILE = @RANDOM_FILE@ RANLIB = @RANLIB@ +RC = @RC@ REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ SED = @SED@ SET_MAKE = @SET_MAKE@ @@ -880,6 +947,7 @@ USE_NGHTTP3 = @USE_NGHTTP3@ USE_NGTCP2 = @USE_NGTCP2@ USE_NGTCP2_CRYPTO_GNUTLS = @USE_NGTCP2_CRYPTO_GNUTLS@ USE_NGTCP2_CRYPTO_OPENSSL = @USE_NGTCP2_CRYPTO_OPENSSL@ +USE_NGTCP2_CRYPTO_WOLFSSL = @USE_NGTCP2_CRYPTO_WOLFSSL@ USE_NSS = @USE_NSS@ USE_OPENLDAP = @USE_OPENLDAP@ USE_QUICHE = @USE_QUICHE@ @@ -1011,16 +1079,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/lib \ VERSIONINFO = -version-info 12:0:8 AM_LDFLAGS = AM_CFLAGS = -libcurl_la_CPPFLAGS_EXTRA = $(am__append_6) $(am__append_7) -libcurl_la_LDFLAGS_EXTRA = $(am__append_1) $(am__append_2) \ - $(am__append_3) $(am__append_4) $(am__append_5) -libcurl_la_CFLAGS_EXTRA = $(am__append_8) -libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA) -libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS) -libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA) -libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS -libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_LIBS) -libcurlu_la_CFLAGS = $(AM_CFLAGS) LIB_VAUTH_CFILES = \ vauth/cleartext.c \ vauth/cram.c \ @@ -1109,7 +1167,6 @@ LIB_CFILES = \ content_encoding.c \ cookie.c \ curl_addrinfo.c \ - curl_ctype.c \ curl_des.c \ curl_endian.c \ curl_fnmatch.c \ @@ -1128,7 +1185,6 @@ LIB_CFILES = \ curl_threads.c \ dict.c \ doh.c \ - dotdot.c \ dynbuf.c \ easy.c \ easygetopt.c \ @@ -1178,6 +1234,7 @@ LIB_CFILES = \ multi.c \ netrc.c \ nonblock.c \ + noproxy.c \ openldap.c \ parsedate.c \ pingpong.c \ @@ -1217,7 +1274,8 @@ LIB_CFILES = \ version.c \ version_win32.c \ warnless.c \ - wildcard.c + wildcard.c \ + ws.c LIB_HFILES = \ altsvc.h \ @@ -1262,7 +1320,6 @@ LIB_HFILES = \ curlx.h \ dict.h \ doh.h \ - dotdot.h \ dynbuf.h \ easy_lock.h \ easyif.h \ @@ -1272,6 +1329,7 @@ LIB_HFILES = \ fileinfo.h \ fopen.h \ formdata.h \ + functypes.h \ ftp.h \ ftplistparser.h \ getinfo.h \ @@ -1301,6 +1359,7 @@ LIB_HFILES = \ multiif.h \ netrc.h \ nonblock.h \ + noproxy.h \ parsedate.h \ pingpong.h \ pop3.h \ @@ -1340,7 +1399,8 @@ LIB_HFILES = \ urldata.h \ version_win32.h \ warnless.h \ - wildcard.h + wildcard.h \ + ws.h LIB_RCFILES = libcurl.rc CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) \ @@ -1351,8 +1411,18 @@ HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) \ # Makefile.inc provides the CSOURCES and HHEADERS defines -libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS) +libcurl_la_SOURCES = $(CSOURCES) $(HHEADERS) $(am__append_7) libcurlu_la_SOURCES = $(CSOURCES) $(HHEADERS) +libcurl_la_CPPFLAGS_EXTRA = $(am__append_6) $(am__append_8) +libcurl_la_LDFLAGS_EXTRA = $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) $(am__append_5) +libcurl_la_CFLAGS_EXTRA = $(am__append_9) +libcurl_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcurl_la_CPPFLAGS_EXTRA) +libcurl_la_LDFLAGS = $(AM_LDFLAGS) $(libcurl_la_LDFLAGS_EXTRA) $(LDFLAGS) $(LIBCURL_LIBS) +libcurl_la_CFLAGS = $(AM_CFLAGS) $(libcurl_la_CFLAGS_EXTRA) +libcurlu_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_STATICLIB -DUNITTESTS +libcurlu_la_LDFLAGS = $(AM_LDFLAGS) -static $(LIBCURL_LIBS) +libcurlu_la_CFLAGS = $(AM_CFLAGS) CHECKSRC = $(CS_$(V)) CS_0 = @echo " RUN " $@; CS_1 = @@ -1365,7 +1435,7 @@ all: curl_config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: -.SUFFIXES: .c .lo .o .obj +.SUFFIXES: .c .lo .o .obj .rc $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -1662,7 +1732,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-content_encoding.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-cookie.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_addrinfo.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_ctype.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_des.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_endian.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_fnmatch.Plo@am__quote@ # am--include-marker @@ -1681,7 +1750,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-curl_threads.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dict.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-doh.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dotdot.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-dynbuf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-easy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-easygetopt.Plo@am__quote@ # am--include-marker @@ -1731,6 +1799,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-multi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-netrc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-nonblock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-noproxy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-openldap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-parsedate.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-pingpong.Plo@am__quote@ # am--include-marker @@ -1771,6 +1840,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-version_win32.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-warnless.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-wildcard.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurl_la-ws.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-altsvc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-amigaos.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-asyn-ares.Plo@am__quote@ # am--include-marker @@ -1783,7 +1853,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-content_encoding.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-cookie.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_addrinfo.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_ctype.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_des.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_endian.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_fnmatch.Plo@am__quote@ # am--include-marker @@ -1802,7 +1871,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-curl_threads.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dict.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-doh.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dotdot.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-dynbuf.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-easy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-easygetopt.Plo@am__quote@ # am--include-marker @@ -1852,6 +1920,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-multi.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-netrc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-nonblock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-noproxy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-openldap.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-parsedate.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-pingpong.Plo@am__quote@ # am--include-marker @@ -1892,6 +1961,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-version_win32.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-warnless.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-wildcard.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcurlu_la-ws.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-cleartext.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-cram.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@vauth/$(DEPDIR)/libcurl_la-digest.Plo@am__quote@ # am--include-marker @@ -2079,13 +2149,6 @@ libcurl_la-curl_addrinfo.lo: curl_addrinfo.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c -libcurl_la-curl_ctype.lo: curl_ctype.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_ctype.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_ctype.Tpo -c -o libcurl_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_ctype.Tpo $(DEPDIR)/libcurl_la-curl_ctype.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ctype.c' object='libcurl_la-curl_ctype.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c - libcurl_la-curl_des.lo: curl_des.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-curl_des.lo -MD -MP -MF $(DEPDIR)/libcurl_la-curl_des.Tpo -c -o libcurl_la-curl_des.lo `test -f 'curl_des.c' || echo '$(srcdir)/'`curl_des.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-curl_des.Tpo $(DEPDIR)/libcurl_la-curl_des.Plo @@ -2212,13 +2275,6 @@ libcurl_la-doh.lo: doh.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-doh.lo `test -f 'doh.c' || echo '$(srcdir)/'`doh.c -libcurl_la-dotdot.lo: dotdot.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-dotdot.lo -MD -MP -MF $(DEPDIR)/libcurl_la-dotdot.Tpo -c -o libcurl_la-dotdot.lo `test -f 'dotdot.c' || echo '$(srcdir)/'`dotdot.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-dotdot.Tpo $(DEPDIR)/libcurl_la-dotdot.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dotdot.c' object='libcurl_la-dotdot.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-dotdot.lo `test -f 'dotdot.c' || echo '$(srcdir)/'`dotdot.c - libcurl_la-dynbuf.lo: dynbuf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-dynbuf.lo -MD -MP -MF $(DEPDIR)/libcurl_la-dynbuf.Tpo -c -o libcurl_la-dynbuf.lo `test -f 'dynbuf.c' || echo '$(srcdir)/'`dynbuf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-dynbuf.Tpo $(DEPDIR)/libcurl_la-dynbuf.Plo @@ -2562,6 +2618,13 @@ libcurl_la-nonblock.lo: nonblock.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-nonblock.lo `test -f 'nonblock.c' || echo '$(srcdir)/'`nonblock.c +libcurl_la-noproxy.lo: noproxy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-noproxy.lo -MD -MP -MF $(DEPDIR)/libcurl_la-noproxy.Tpo -c -o libcurl_la-noproxy.lo `test -f 'noproxy.c' || echo '$(srcdir)/'`noproxy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-noproxy.Tpo $(DEPDIR)/libcurl_la-noproxy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='noproxy.c' object='libcurl_la-noproxy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-noproxy.lo `test -f 'noproxy.c' || echo '$(srcdir)/'`noproxy.c + libcurl_la-openldap.lo: openldap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-openldap.lo -MD -MP -MF $(DEPDIR)/libcurl_la-openldap.Tpo -c -o libcurl_la-openldap.lo `test -f 'openldap.c' || echo '$(srcdir)/'`openldap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-openldap.Tpo $(DEPDIR)/libcurl_la-openldap.Plo @@ -2842,6 +2905,13 @@ libcurl_la-wildcard.lo: wildcard.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-wildcard.lo `test -f 'wildcard.c' || echo '$(srcdir)/'`wildcard.c +libcurl_la-ws.lo: ws.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT libcurl_la-ws.lo -MD -MP -MF $(DEPDIR)/libcurl_la-ws.Tpo -c -o libcurl_la-ws.lo `test -f 'ws.c' || echo '$(srcdir)/'`ws.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurl_la-ws.Tpo $(DEPDIR)/libcurl_la-ws.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ws.c' object='libcurl_la-ws.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -c -o libcurl_la-ws.lo `test -f 'ws.c' || echo '$(srcdir)/'`ws.c + vauth/libcurl_la-cleartext.lo: vauth/cleartext.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurl_la_CPPFLAGS) $(CPPFLAGS) $(libcurl_la_CFLAGS) $(CFLAGS) -MT vauth/libcurl_la-cleartext.lo -MD -MP -MF vauth/$(DEPDIR)/libcurl_la-cleartext.Tpo -c -o vauth/libcurl_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurl_la-cleartext.Tpo vauth/$(DEPDIR)/libcurl_la-cleartext.Plo @@ -3178,13 +3248,6 @@ libcurlu_la-curl_addrinfo.lo: curl_addrinfo.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_addrinfo.lo `test -f 'curl_addrinfo.c' || echo '$(srcdir)/'`curl_addrinfo.c -libcurlu_la-curl_ctype.lo: curl_ctype.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_ctype.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_ctype.Tpo -c -o libcurlu_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_ctype.Tpo $(DEPDIR)/libcurlu_la-curl_ctype.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='curl_ctype.c' object='libcurlu_la-curl_ctype.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_ctype.lo `test -f 'curl_ctype.c' || echo '$(srcdir)/'`curl_ctype.c - libcurlu_la-curl_des.lo: curl_des.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_des.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_des.Tpo -c -o libcurlu_la-curl_des.lo `test -f 'curl_des.c' || echo '$(srcdir)/'`curl_des.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-curl_des.Tpo $(DEPDIR)/libcurlu_la-curl_des.Plo @@ -3311,13 +3374,6 @@ libcurlu_la-doh.lo: doh.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-doh.lo `test -f 'doh.c' || echo '$(srcdir)/'`doh.c -libcurlu_la-dotdot.lo: dotdot.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-dotdot.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-dotdot.Tpo -c -o libcurlu_la-dotdot.lo `test -f 'dotdot.c' || echo '$(srcdir)/'`dotdot.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-dotdot.Tpo $(DEPDIR)/libcurlu_la-dotdot.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dotdot.c' object='libcurlu_la-dotdot.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-dotdot.lo `test -f 'dotdot.c' || echo '$(srcdir)/'`dotdot.c - libcurlu_la-dynbuf.lo: dynbuf.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-dynbuf.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-dynbuf.Tpo -c -o libcurlu_la-dynbuf.lo `test -f 'dynbuf.c' || echo '$(srcdir)/'`dynbuf.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-dynbuf.Tpo $(DEPDIR)/libcurlu_la-dynbuf.Plo @@ -3661,6 +3717,13 @@ libcurlu_la-nonblock.lo: nonblock.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-nonblock.lo `test -f 'nonblock.c' || echo '$(srcdir)/'`nonblock.c +libcurlu_la-noproxy.lo: noproxy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-noproxy.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-noproxy.Tpo -c -o libcurlu_la-noproxy.lo `test -f 'noproxy.c' || echo '$(srcdir)/'`noproxy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-noproxy.Tpo $(DEPDIR)/libcurlu_la-noproxy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='noproxy.c' object='libcurlu_la-noproxy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-noproxy.lo `test -f 'noproxy.c' || echo '$(srcdir)/'`noproxy.c + libcurlu_la-openldap.lo: openldap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-openldap.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-openldap.Tpo -c -o libcurlu_la-openldap.lo `test -f 'openldap.c' || echo '$(srcdir)/'`openldap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-openldap.Tpo $(DEPDIR)/libcurlu_la-openldap.Plo @@ -3941,6 +4004,13 @@ libcurlu_la-wildcard.lo: wildcard.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-wildcard.lo `test -f 'wildcard.c' || echo '$(srcdir)/'`wildcard.c +libcurlu_la-ws.lo: ws.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT libcurlu_la-ws.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-ws.Tpo -c -o libcurlu_la-ws.lo `test -f 'ws.c' || echo '$(srcdir)/'`ws.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcurlu_la-ws.Tpo $(DEPDIR)/libcurlu_la-ws.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ws.c' object='libcurlu_la-ws.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -c -o libcurlu_la-ws.lo `test -f 'ws.c' || echo '$(srcdir)/'`ws.c + vauth/libcurlu_la-cleartext.lo: vauth/cleartext.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(libcurlu_la_CFLAGS) $(CFLAGS) -MT vauth/libcurlu_la-cleartext.lo -MD -MP -MF vauth/$(DEPDIR)/libcurlu_la-cleartext.Tpo -c -o vauth/libcurlu_la-cleartext.lo `test -f 'vauth/cleartext.c' || echo '$(srcdir)/'`vauth/cleartext.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) vauth/$(DEPDIR)/libcurlu_la-cleartext.Tpo vauth/$(DEPDIR)/libcurlu_la-cleartext.Plo @@ -4351,7 +4421,6 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurl_la-content_encoding.Plo -rm -f ./$(DEPDIR)/libcurl_la-cookie.Plo -rm -f ./$(DEPDIR)/libcurl_la-curl_addrinfo.Plo - -rm -f ./$(DEPDIR)/libcurl_la-curl_ctype.Plo -rm -f ./$(DEPDIR)/libcurl_la-curl_des.Plo -rm -f ./$(DEPDIR)/libcurl_la-curl_endian.Plo -rm -f ./$(DEPDIR)/libcurl_la-curl_fnmatch.Plo @@ -4370,7 +4439,6 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurl_la-curl_threads.Plo -rm -f ./$(DEPDIR)/libcurl_la-dict.Plo -rm -f ./$(DEPDIR)/libcurl_la-doh.Plo - -rm -f ./$(DEPDIR)/libcurl_la-dotdot.Plo -rm -f ./$(DEPDIR)/libcurl_la-dynbuf.Plo -rm -f ./$(DEPDIR)/libcurl_la-easy.Plo -rm -f ./$(DEPDIR)/libcurl_la-easygetopt.Plo @@ -4420,6 +4488,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurl_la-multi.Plo -rm -f ./$(DEPDIR)/libcurl_la-netrc.Plo -rm -f ./$(DEPDIR)/libcurl_la-nonblock.Plo + -rm -f ./$(DEPDIR)/libcurl_la-noproxy.Plo -rm -f ./$(DEPDIR)/libcurl_la-openldap.Plo -rm -f ./$(DEPDIR)/libcurl_la-parsedate.Plo -rm -f ./$(DEPDIR)/libcurl_la-pingpong.Plo @@ -4460,6 +4529,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurl_la-version_win32.Plo -rm -f ./$(DEPDIR)/libcurl_la-warnless.Plo -rm -f ./$(DEPDIR)/libcurl_la-wildcard.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ws.Plo -rm -f ./$(DEPDIR)/libcurlu_la-altsvc.Plo -rm -f ./$(DEPDIR)/libcurlu_la-amigaos.Plo -rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo @@ -4472,7 +4542,6 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurlu_la-content_encoding.Plo -rm -f ./$(DEPDIR)/libcurlu_la-cookie.Plo -rm -f ./$(DEPDIR)/libcurlu_la-curl_addrinfo.Plo - -rm -f ./$(DEPDIR)/libcurlu_la-curl_ctype.Plo -rm -f ./$(DEPDIR)/libcurlu_la-curl_des.Plo -rm -f ./$(DEPDIR)/libcurlu_la-curl_endian.Plo -rm -f ./$(DEPDIR)/libcurlu_la-curl_fnmatch.Plo @@ -4491,7 +4560,6 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurlu_la-curl_threads.Plo -rm -f ./$(DEPDIR)/libcurlu_la-dict.Plo -rm -f ./$(DEPDIR)/libcurlu_la-doh.Plo - -rm -f ./$(DEPDIR)/libcurlu_la-dotdot.Plo -rm -f ./$(DEPDIR)/libcurlu_la-dynbuf.Plo -rm -f ./$(DEPDIR)/libcurlu_la-easy.Plo -rm -f ./$(DEPDIR)/libcurlu_la-easygetopt.Plo @@ -4541,6 +4609,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurlu_la-multi.Plo -rm -f ./$(DEPDIR)/libcurlu_la-netrc.Plo -rm -f ./$(DEPDIR)/libcurlu_la-nonblock.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-noproxy.Plo -rm -f ./$(DEPDIR)/libcurlu_la-openldap.Plo -rm -f ./$(DEPDIR)/libcurlu_la-parsedate.Plo -rm -f ./$(DEPDIR)/libcurlu_la-pingpong.Plo @@ -4581,6 +4650,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libcurlu_la-version_win32.Plo -rm -f ./$(DEPDIR)/libcurlu_la-warnless.Plo -rm -f ./$(DEPDIR)/libcurlu_la-wildcard.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ws.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-cleartext.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-cram.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-digest.Plo @@ -4710,7 +4780,6 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurl_la-content_encoding.Plo -rm -f ./$(DEPDIR)/libcurl_la-cookie.Plo -rm -f ./$(DEPDIR)/libcurl_la-curl_addrinfo.Plo - -rm -f ./$(DEPDIR)/libcurl_la-curl_ctype.Plo -rm -f ./$(DEPDIR)/libcurl_la-curl_des.Plo -rm -f ./$(DEPDIR)/libcurl_la-curl_endian.Plo -rm -f ./$(DEPDIR)/libcurl_la-curl_fnmatch.Plo @@ -4729,7 +4798,6 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurl_la-curl_threads.Plo -rm -f ./$(DEPDIR)/libcurl_la-dict.Plo -rm -f ./$(DEPDIR)/libcurl_la-doh.Plo - -rm -f ./$(DEPDIR)/libcurl_la-dotdot.Plo -rm -f ./$(DEPDIR)/libcurl_la-dynbuf.Plo -rm -f ./$(DEPDIR)/libcurl_la-easy.Plo -rm -f ./$(DEPDIR)/libcurl_la-easygetopt.Plo @@ -4779,6 +4847,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurl_la-multi.Plo -rm -f ./$(DEPDIR)/libcurl_la-netrc.Plo -rm -f ./$(DEPDIR)/libcurl_la-nonblock.Plo + -rm -f ./$(DEPDIR)/libcurl_la-noproxy.Plo -rm -f ./$(DEPDIR)/libcurl_la-openldap.Plo -rm -f ./$(DEPDIR)/libcurl_la-parsedate.Plo -rm -f ./$(DEPDIR)/libcurl_la-pingpong.Plo @@ -4819,6 +4888,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurl_la-version_win32.Plo -rm -f ./$(DEPDIR)/libcurl_la-warnless.Plo -rm -f ./$(DEPDIR)/libcurl_la-wildcard.Plo + -rm -f ./$(DEPDIR)/libcurl_la-ws.Plo -rm -f ./$(DEPDIR)/libcurlu_la-altsvc.Plo -rm -f ./$(DEPDIR)/libcurlu_la-amigaos.Plo -rm -f ./$(DEPDIR)/libcurlu_la-asyn-ares.Plo @@ -4831,7 +4901,6 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurlu_la-content_encoding.Plo -rm -f ./$(DEPDIR)/libcurlu_la-cookie.Plo -rm -f ./$(DEPDIR)/libcurlu_la-curl_addrinfo.Plo - -rm -f ./$(DEPDIR)/libcurlu_la-curl_ctype.Plo -rm -f ./$(DEPDIR)/libcurlu_la-curl_des.Plo -rm -f ./$(DEPDIR)/libcurlu_la-curl_endian.Plo -rm -f ./$(DEPDIR)/libcurlu_la-curl_fnmatch.Plo @@ -4850,7 +4919,6 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurlu_la-curl_threads.Plo -rm -f ./$(DEPDIR)/libcurlu_la-dict.Plo -rm -f ./$(DEPDIR)/libcurlu_la-doh.Plo - -rm -f ./$(DEPDIR)/libcurlu_la-dotdot.Plo -rm -f ./$(DEPDIR)/libcurlu_la-dynbuf.Plo -rm -f ./$(DEPDIR)/libcurlu_la-easy.Plo -rm -f ./$(DEPDIR)/libcurlu_la-easygetopt.Plo @@ -4900,6 +4968,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurlu_la-multi.Plo -rm -f ./$(DEPDIR)/libcurlu_la-netrc.Plo -rm -f ./$(DEPDIR)/libcurlu_la-nonblock.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-noproxy.Plo -rm -f ./$(DEPDIR)/libcurlu_la-openldap.Plo -rm -f ./$(DEPDIR)/libcurlu_la-parsedate.Plo -rm -f ./$(DEPDIR)/libcurlu_la-pingpong.Plo @@ -4940,6 +5009,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcurlu_la-version_win32.Plo -rm -f ./$(DEPDIR)/libcurlu_la-warnless.Plo -rm -f ./$(DEPDIR)/libcurlu_la-wildcard.Plo + -rm -f ./$(DEPDIR)/libcurlu_la-ws.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-cleartext.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-cram.Plo -rm -f vauth/$(DEPDIR)/libcurl_la-digest.Plo @@ -5050,6 +5120,7 @@ uninstall-am: uninstall-libLTLIBRARIES .PRECIOUS: Makefile +@OS_WINDOWS_TRUE@@USE_CPPFLAG_CURL_STATICLIB_FALSE@$(LIB_RCFILES): $(top_srcdir)/include/curl/curlver.h checksrc: $(CHECKSRC)(@PERL@ $(top_srcdir)/scripts/checksrc.pl -D$(srcdir) \ @@ -5065,6 +5136,10 @@ tidy: optiontable: perl optiontable.pl < $(top_srcdir)/include/curl/curl.h > easyoptions.c +# Warning is "normal": libtool: error: ignoring unknown tag RC +@OS_WINDOWS_TRUE@.rc.lo: +@OS_WINDOWS_TRUE@ $(LIBTOOL) --tag=RC --mode=compile $(RC) -I$(top_srcdir)/include $(RCFLAGS) -i $< -o $@ + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/libs/libcurl/src/Makefile.inc b/libs/libcurl/src/Makefile.inc index 9bd8e324bd..b2d2e9e52f 100644 --- a/libs/libcurl/src/Makefile.inc +++ b/libs/libcurl/src/Makefile.inc @@ -110,7 +110,6 @@ LIB_CFILES = \ content_encoding.c \ cookie.c \ curl_addrinfo.c \ - curl_ctype.c \ curl_des.c \ curl_endian.c \ curl_fnmatch.c \ @@ -129,7 +128,6 @@ LIB_CFILES = \ curl_threads.c \ dict.c \ doh.c \ - dotdot.c \ dynbuf.c \ easy.c \ easygetopt.c \ @@ -179,6 +177,7 @@ LIB_CFILES = \ multi.c \ netrc.c \ nonblock.c \ + noproxy.c \ openldap.c \ parsedate.c \ pingpong.c \ @@ -218,7 +217,8 @@ LIB_CFILES = \ version.c \ version_win32.c \ warnless.c \ - wildcard.c + wildcard.c \ + ws.c LIB_HFILES = \ altsvc.h \ @@ -263,7 +263,6 @@ LIB_HFILES = \ curlx.h \ dict.h \ doh.h \ - dotdot.h \ dynbuf.h \ easy_lock.h \ easyif.h \ @@ -273,6 +272,7 @@ LIB_HFILES = \ fileinfo.h \ fopen.h \ formdata.h \ + functypes.h \ ftp.h \ ftplistparser.h \ getinfo.h \ @@ -302,6 +302,7 @@ LIB_HFILES = \ multiif.h \ netrc.h \ nonblock.h \ + noproxy.h \ parsedate.h \ pingpong.h \ pop3.h \ @@ -341,7 +342,8 @@ LIB_HFILES = \ urldata.h \ version_win32.h \ warnless.h \ - wildcard.h + wildcard.h \ + ws.h LIB_RCFILES = libcurl.rc diff --git a/libs/libcurl/src/Makefile.m32 b/libs/libcurl/src/Makefile.m32 index 1987b237e5..b8b56f8c98 100644 --- a/libs/libcurl/src/Makefile.m32 +++ b/libs/libcurl/src/Makefile.m32 @@ -22,430 +22,308 @@ # #*************************************************************************** -########################################################################### +# Makefile for building curl parts with MinGW and optional features. # -## Makefile for building libcurl.a with MingW (GCC-3.2 or later or LLVM/Clang) -## and optionally OpenSSL (1.0.2a), libssh2 (1.5), zlib (1.2.8), librtmp (2.4), -## brotli (1.0.1), zstd (1.4.5) -## -## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...] -## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn -## -## Hint: you can also set environment vars to control the build, f.e.: -## set ZLIB_PATH=c:/zlib-1.2.8 -## set ZLIB=1 +# Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...] +# Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn # -########################################################################### +# Set component roots via envvar <feature>_PATH. Also available for +# customization: CC, RC, AR, CPPFLAGS, LDFLAGS, LIBS, CFLAGS, RCFLAGS, +# ARCH[=custom], CROSSPREFIX, CURL_LDFLAGS_BIN, CURL_LDFLAGS_LIB, CURL_DLL_SUFFIX, +# and more for individual components (see below). -# Edit the path below to point to the base of your Zlib sources. -ifndef ZLIB_PATH -ZLIB_PATH = ../../zlib-1.2.8 -endif -# Edit the path below to point to the base of your Zstandard sources. -ifndef ZSTD_PATH -ZSTD_PATH = ../../zstd-1.4.5 -endif -# Edit the path below to point to the base of your Brotli sources. -ifndef BROTLI_PATH -BROTLI_PATH = ../../brotli-1.0.1 -endif -# Edit the path below to point to the base of your OpenSSL package. -ifndef OPENSSL_PATH -OPENSSL_PATH = ../../openssl-1.0.2a -endif -# Edit the path below to point to the base of your LibSSH2 package. -ifndef LIBSSH2_PATH -LIBSSH2_PATH = ../../libssh2-1.5.0 -endif -# Edit the path below to point to the base of your librtmp package. -ifndef LIBRTMP_PATH -LIBRTMP_PATH = ../../librtmp-2.4 -endif -# Edit the path below to point to the base of your libgsasl package. -ifndef LIBGSASL_PATH -LIBGSASL_PATH = ../../libgsasl-1.10.0 -endif -# Edit the path below to point to the base of your libidn2 package. -ifndef LIBIDN2_PATH -LIBIDN2_PATH = ../../libidn2-2.0.3 -endif -# Edit the path below to point to the base of your MS IDN package. -# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1 -# https://www.microsoft.com/en-us/download/details.aspx?id=734 -ifndef WINIDN_PATH -WINIDN_PATH = ../../Microsoft IDN Mitigation APIs -endif -# Edit the path below to point to the base of your Novell LDAP NDK. -ifndef LDAP_SDK -LDAP_SDK = c:/novell/ndk/cldapsdk/win32 -endif -# Edit the path below to point to the base of your nghttp2 package. -ifndef NGHTTP2_PATH -NGHTTP2_PATH = ../../nghttp2-1.0.0 -endif -# Edit the path below to point to the base of your nghttp3 package. -ifndef NGHTTP3_PATH -NGHTTP3_PATH = ../../nghttp3-1.0.0 -endif -# Edit the path below to point to the base of your ngtcp2 package. -ifndef NGTCP2_PATH -NGTCP2_PATH = ../../ngtcp2-1.0.0 -endif +# This script is reused by 'src' and 'docs/examples' Makefile.m32 scripts. +# Skip lib-specific parts when called through them. +ifndef PROOT +PROOT := .. -PROOT = .. +CPPFLAGS += -DBUILDING_LIBCURL -# Edit the path below to point to the base of your c-ares package. -ifndef LIBCARES_PATH -LIBCARES_PATH = $(PROOT)/ares -endif +### Sources and targets -ifeq ($(CURL_CC),) -CURL_CC := $(CROSSPREFIX)gcc -endif -ifeq ($(CURL_AR),) -CURL_AR := $(CROSSPREFIX)ar -endif -ifeq ($(CURL_RANLIB),) -CURL_RANLIB := $(CROSSPREFIX)ranlib -endif +# Provides CSOURCES, HHEADERS, LIB_RCFILES +include Makefile.inc -CC = $(CURL_CC) -CFLAGS = -O3 $(CURL_CFLAG_EXTRAS) -W -Wall -LDFLAGS = $(CURL_LDFLAG_EXTRAS) $(CURL_LDFLAG_EXTRAS_DLL) -AR = $(CURL_AR) -RANLIB = $(CURL_RANLIB) -RC = $(CROSSPREFIX)windres -RCFLAGS = --include-dir=$(PROOT)/include -DDEBUGBUILD=0 -O coff -STRIP = $(CROSSPREFIX)strip -g - -# Set environment var ARCH to your architecture to override autodetection. -ifndef ARCH -ifeq ($(findstring x86_64,$(shell $(CC) -dumpmachine)),x86_64) -ARCH = w64 -else -ARCH = w32 -endif -endif +libcurl_dll_LIBRARY := libcurl$(CURL_DLL_SUFFIX).dll +libcurl_dll_a_LIBRARY := libcurl.dll.a +libcurl_a_LIBRARY := libcurl.a -ifeq ($(ARCH),w64) -CFLAGS += -m64 -LDFLAGS += -m64 -RCFLAGS += -F pe-x86-64 -else -CFLAGS += -m32 -LDFLAGS += -m32 -RCFLAGS += -F pe-i386 -endif +TARGETS := $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) -# Platform-dependent helper tool macros -ifeq ($(findstring /sh,$(SHELL)),/sh) -DEL = rm -f $1 -RMDIR = rm -fr $1 -MKDIR = mkdir -p $1 -COPY = -cp -afv $1 $2 -#COPYR = -cp -afr $1/* $2 -COPYR = -rsync -aC $1/* $2 -TOUCH = touch $1 -CAT = cat -ECHONL = echo "" -DL = ' -else -ifeq "$(OS)" "Windows_NT" -DEL = -del 2>NUL /q /f $(subst /,\,$1) -RMDIR = -rd 2>NUL /q /s $(subst /,\,$1) -else -DEL = -del 2>NUL $(subst /,\,$1) -RMDIR = -deltree 2>NUL /y $(subst /,\,$1) -endif -MKDIR = -md 2>NUL $(subst /,\,$1) -COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) -COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2) -TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,, -CAT = type -ECHONL = $(ComSpec) /c echo. +libcurl_a_OBJECTS := $(patsubst %.c,%.o,$(notdir $(strip $(CSOURCES)))) +libcurl_a_DEPENDENCIES := $(strip $(CSOURCES) $(HHEADERS)) +libcurl_dll_OBJECTS := $(libcurl_a_OBJECTS) +libcurl_dll_OBJECTS += $(patsubst %.rc,%.res,$(strip $(LIB_RCFILES))) +vpath %.c vauth vquic vssh vtls + +TOCLEAN := $(libcurl_dll_OBJECTS) +TOVCLEAN := $(libcurl_dll_LIBRARY:.dll=.def) $(libcurl_dll_a_LIBRARY) + +### Local rules + +# Keep this at the top to act as the default target. +all: $(TARGETS) + +$(libcurl_a_LIBRARY): $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES) + @$(call DEL, $@) + $(AR) rcs $@ $(libcurl_a_OBJECTS) + +$(libcurl_dll_LIBRARY): $(libcurl_dll_OBJECTS) + $(CC) $(LDFLAGS) -shared $(CURL_LDFLAGS_LIB) -o $@ $(libcurl_dll_OBJECTS) $(LIBS) \ + -Wl,--output-def,$(@:.dll=.def),--out-implib,$(libcurl_dll_a_LIBRARY) endif -######################################################## -## Nothing more to do below this line! +CPPFLAGS += -I. -I$(PROOT)/include +RCFLAGS += -I$(PROOT)/include + +CC := $(CROSSPREFIX)$(CC) +AR := $(CROSSPREFIX)$(AR) +RC ?= $(CROSSPREFIX)windres -ifneq ($(findstring -dyn,$(CFG)),) -DYN = 1 +ifneq ($(ARCH),custom) + # Set environment var ARCH to your architecture to override auto-detection. + ifndef ARCH + ifneq ($(findstring x86_64,$(shell $(CC) -dumpmachine)),) + ARCH := w64 + else + ARCH := w32 + endif + endif + ifeq ($(ARCH),w64) + CFLAGS += -m64 + LDFLAGS += -m64 + RCFLAGS += --target=pe-x86-64 + else + CFLAGS += -m32 + LDFLAGS += -m32 + RCFLAGS += --target=pe-i386 + endif endif -ifneq ($(findstring -ares,$(CFG)),) -ARES = 1 + +### Optional features + +ifneq ($(findstring -unicode,$(CFG)),) + CPPFLAGS += -DUNICODE -D_UNICODE + CURL_LDFLAGS_BIN += -municode endif + +# CPPFLAGS below are only necessary when building libcurl via 'lib' (see +# comments below about exceptions). Always include them anyway to match +# behavior of other build systems. + +# Linker options to exclude for shared mode executables. +_LDFLAGS := +_LIBS := + ifneq ($(findstring -sync,$(CFG)),) -SYNC = 1 + CPPFLAGS += -DUSE_SYNC_DNS +else ifneq ($(findstring -ares,$(CFG)),) + LIBCARES_PATH ?= $(PROOT)/../c-ares + CPPFLAGS += -DUSE_ARES + CPPFLAGS += -I"$(LIBCARES_PATH)/include" + _LDFLAGS += -L"$(LIBCARES_PATH)/lib" + _LIBS += -lcares endif + ifneq ($(findstring -rtmp,$(CFG)),) -RTMP = 1 -ZLIB = 1 + LIBRTMP_PATH ?= $(PROOT)/../librtmp + CPPFLAGS += -DUSE_LIBRTMP + CPPFLAGS += -I"$(LIBRTMP_PATH)" + _LDFLAGS += -L"$(LIBRTMP_PATH)/librtmp" + _LIBS += -lrtmp -lwinmm + ZLIB := 1 endif + ifneq ($(findstring -ssh2,$(CFG)),) -SSH2 = 1 -ZLIB = 1 + LIBSSH2_PATH ?= $(PROOT)/../libssh2 + CPPFLAGS += -DUSE_LIBSSH2 + CPPFLAGS += -I"$(LIBSSH2_PATH)/include" + _LDFLAGS += -L"$(LIBSSH2_PATH)/lib" + _LDFLAGS += -L"$(LIBSSH2_PATH)/win32" + _LIBS += -lssh2 +else ifneq ($(findstring -libssh,$(CFG)),) + LIBSSH_PATH ?= $(PROOT)/../libssh + CPPFLAGS += -DUSE_LIBSSH + CPPFLAGS += -I"$(LIBSSH_PATH)/include" + _LDFLAGS += -L"$(LIBSSH_PATH)/lib" + _LIBS += -lssh +else ifneq ($(findstring -wolfssh,$(CFG)),) + WOLFSSH_PATH ?= $(PROOT)/../wolfssh + CPPFLAGS += -DUSE_WOLFSSH + CPPFLAGS += -I"$(WOLFSSH_PATH)/include" + _LDFLAGS += -L"$(WOLFSSH_PATH)/lib" + _LIBS += -lwolfssh endif + ifneq ($(findstring -ssl,$(CFG)),) -SSL = 1 + OPENSSL_PATH ?= $(PROOT)/../openssl + CPPFLAGS += -DUSE_OPENSSL + CPPFLAGS += -DCURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG + OPENSSL_INCLUDE ?= $(OPENSSL_PATH)/include + OPENSSL_LIBPATH ?= $(OPENSSL_PATH)/lib + CPPFLAGS += -I"$(OPENSSL_INCLUDE)" + _LDFLAGS += -L"$(OPENSSL_LIBPATH)" + OPENSSL_LIBS ?= -lssl -lcrypto + _LIBS += $(OPENSSL_LIBS) + + ifneq ($(wildcard $(OPENSSL_INCLUDE)/openssl/aead.h),) + OPENSSL := boringssl + else + # including libressl + OPENSSL := openssl + endif + + ifneq ($(findstring -srp,$(CFG)),) + ifneq ($(wildcard $(OPENSSL_INCLUDE)/openssl/srp.h),) + # OpenSSL 1.0.1 and later. + CPPFLAGS += -DHAVE_OPENSSL_SRP -DUSE_TLS_SRP + endif + endif + SSLLIBS += 1 +else ifneq ($(findstring -wolfssl,$(CFG)),) + WOLFSSL_PATH ?= $(PROOT)/../zlib + CPPFLAGS += -DUSE_WOLFSSL + CPPFLAGS += -DSIZEOF_LONG_LONG=8 + CPPFLAGS += -I"$(WOLFSSL_PATH)/include" + _LDFLAGS += -L"$(WOLFSSL_PATH)/lib" + _LIBS += -lwolfssl + OPENSSL := wolfssl + SSLLIBS += 1 +endif +ifneq ($(findstring -mbedtls,$(CFG)),) + MBEDTLS_PATH ?= $(PROOT)/../zlib + CPPFLAGS += -DUSE_MBEDTLS + CPPFLAGS += -I"$(MBEDTLS_PATH)/include" + _LDFLAGS += -L"$(MBEDTLS_PATH)/lib" + _LIBS += -lmbedtls -lmbedx509 -lmbedcrypto + SSLLIBS += 1 +endif +ifneq ($(findstring -schannel,$(CFG)),) + CPPFLAGS += -DUSE_SCHANNEL + SSLLIBS += 1 endif -ifneq ($(findstring -srp,$(CFG)),) -SRP = 1 + +ifneq ($(findstring -nghttp2,$(CFG)),) + NGHTTP2_PATH ?= $(PROOT)/../nghttp2 + CPPFLAGS += -DUSE_NGHTTP2 + CPPFLAGS += -I"$(NGHTTP2_PATH)/include" + _LDFLAGS += -L"$(NGHTTP2_PATH)/lib" + _LIBS += -lnghttp2 +endif + +ifeq ($(findstring -nghttp3,$(CFG))$(findstring -ngtcp2,$(CFG)),-nghttp3-ngtcp2) + NGHTTP3_PATH ?= $(PROOT)/../nghttp3 + CPPFLAGS += -DUSE_NGHTTP3 + CPPFLAGS += -I"$(NGHTTP3_PATH)/include" + _LDFLAGS += -L"$(NGHTTP3_PATH)/lib" + _LIBS += -lnghttp3 + + NGTCP2_PATH ?= $(PROOT)/../ngtcp2 + CPPFLAGS += -DUSE_NGTCP2 + CPPFLAGS += -I"$(NGTCP2_PATH)/include" + _LDFLAGS += -L"$(NGTCP2_PATH)/lib" + ifneq ($(OPENSSL),) + NGTCP2_LIBS ?= -lngtcp2_crypto_$(OPENSSL) + endif + _LIBS += -lngtcp2 $(NGTCP2_LIBS) endif -ifneq ($(findstring -zlib,$(CFG)),) -ZLIB = 1 + +ifneq ($(findstring -zlib,$(CFG))$(ZLIB),) + ZLIB_PATH ?= $(PROOT)/../zlib + # These CPPFLAGS are also required when compiling the curl tool via 'src'. + CPPFLAGS += -DHAVE_LIBZ + CPPFLAGS += -I"$(ZLIB_PATH)" + _LDFLAGS += -L"$(ZLIB_PATH)" + _LIBS += -lz endif ifneq ($(findstring -zstd,$(CFG)),) -ZSTD = 1 + ZSTD_PATH ?= $(PROOT)/../zstd + CPPFLAGS += -DHAVE_ZSTD + CPPFLAGS += -I"$(ZSTD_PATH)/include" + _LDFLAGS += -L"$(ZSTD_PATH)/lib" + ZSTD_LIBS ?= -lzstd + _LIBS += $(ZSTD_LIBS) endif ifneq ($(findstring -brotli,$(CFG)),) -BROTLI = 1 + BROTLI_PATH ?= $(PROOT)/../brotli + CPPFLAGS += -DHAVE_BROTLI + CPPFLAGS += -I"$(BROTLI_PATH)/include" + _LDFLAGS += -L"$(BROTLI_PATH)/lib" + BROTLI_LIBS ?= -lbrotlidec -lbrotlicommon + _LIBS += $(BROTLI_LIBS) endif ifneq ($(findstring -gsasl,$(CFG)),) -GSASL = 1 + LIBGSASL_PATH ?= $(PROOT)/../gsasl + CPPFLAGS += -DUSE_GSASL + CPPFLAGS += -I"$(LIBGSASL_PATH)/include" + _LDFLAGS += -L"$(LIBGSASL_PATH)/lib" + _LIBS += -lgsasl endif + ifneq ($(findstring -idn2,$(CFG)),) -IDN2 = 1 -endif -ifneq ($(findstring -winidn,$(CFG)),) -WINIDN = 1 + LIBIDN2_PATH ?= $(PROOT)/../libidn2 + CPPFLAGS += -DUSE_LIBIDN2 + CPPFLAGS += -I"$(LIBIDN2_PATH)/include" + _LDFLAGS += -L"$(LIBIDN2_PATH)/lib" + _LIBS += -lidn2 + +ifneq ($(findstring -psl,$(CFG)),) + LIBPSL_PATH ?= $(PROOT)/../libpsl + CPPFLAGS += -DUSE_LIBPSL + CPPFLAGS += -I"$(LIBPSL_PATH)/include" + _LDFLAGS += -L"$(LIBPSL_PATH)/lib" + _LIBS += -lpsl +endif +else ifneq ($(findstring -winidn,$(CFG)),) + CPPFLAGS += -DUSE_WIN32_IDN + CPPFLAGS += -DWANT_IDN_PROTOTYPES + _LIBS += -lnormaliz endif + ifneq ($(findstring -sspi,$(CFG)),) -SSPI = 1 -endif -ifneq ($(findstring -ldaps,$(CFG)),) -LDAPS = 1 + CPPFLAGS += -DUSE_WINDOWS_SSPI endif ifneq ($(findstring -ipv6,$(CFG)),) -IPV6 = 1 -endif -ifneq ($(findstring -schannel,$(CFG))$(findstring -winssl,$(CFG)),) -SCHANNEL = 1 -SSPI = 1 -endif -ifneq ($(findstring -nghttp2,$(CFG)),) -NGHTTP2 = 1 -endif -ifneq ($(findstring -nghttp3,$(CFG)),) -NGHTTP3 = 1 + CPPFLAGS += -DENABLE_IPV6 endif -ifneq ($(findstring -ngtcp2,$(CFG)),) -NGTCP2 = 1 -endif -ifneq ($(findstring -unicode,$(CFG)),) -UNICODE = 1 +ifneq ($(findstring -ldaps,$(CFG)),) + CPPFLAGS += -DHAVE_LDAP_SSL endif -# SSH2 and RTMP require an SSL library; assume OpenSSL if none specified -ifneq ($(SSH2)$(RTMP),) - ifeq ($(SSL)$(SCHANNEL),) - SSL = 1 - endif +ifeq ($(findstring -lldap,$(LIBS)),) + _LIBS += -lwldap32 endif +_LIBS += -lws2_32 -lcrypt32 -lbcrypt -INCLUDES = -I. -I../include -CFLAGS += -DBUILDING_LIBCURL -ifdef SSL - ifdef SCHANNEL - CFLAGS += -DCURL_WITH_MULTI_SSL - endif -endif -ifdef UNICODE - CFLAGS += -DUNICODE -D_UNICODE +ifneq ($(findstring 11,$(subst $() ,,$(SSLLIBS))),) + CPPFLAGS += -DCURL_WITH_MULTI_SSL endif -ifdef SYNC - CFLAGS += -DUSE_SYNC_DNS -else - ifdef ARES - INCLUDES += -I"$(LIBCARES_PATH)" - CFLAGS += -DUSE_ARES -DCARES_STATICLIB - DLL_LIBS += -L"$(LIBCARES_PATH)" -lcares - libcurl_dll_DEPENDENCIES = $(LIBCARES_PATH)/libcares.a - endif -endif -ifdef RTMP - INCLUDES += -I"$(LIBRTMP_PATH)" - CFLAGS += -DUSE_LIBRTMP - DLL_LIBS += -L"$(LIBRTMP_PATH)/librtmp" -lrtmp -lwinmm -endif -ifdef NGHTTP2 - INCLUDES += -I"$(NGHTTP2_PATH)/include" - CFLAGS += -DUSE_NGHTTP2 - DLL_LIBS += -L"$(NGHTTP2_PATH)/lib" -lnghttp2 -endif -ifdef SSH2 - INCLUDES += -I"$(LIBSSH2_PATH)/include" -I"$(LIBSSH2_PATH)/win32" - CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H - DLL_LIBS += -L"$(LIBSSH2_PATH)/win32" -lssh2 - ifdef SCHANNEL - ifndef DYN - DLL_LIBS += -lbcrypt -lcrypt32 - endif - endif -endif -ifdef SSL - ifdef NGHTTP3 - INCLUDES += -I"$(NGHTTP3_PATH)/include" - CFLAGS += -DUSE_NGHTTP3 - DLL_LIBS += -L"$(NGHTTP3_PATH)/lib" -lnghttp3 - ifdef NGTCP2 - INCLUDES += -I"$(NGTCP2_PATH)/include" - CFLAGS += -DUSE_NGTCP2 - DLL_LIBS += -L"$(NGTCP2_PATH)/lib" -lngtcp2 -lngtcp2_crypto_openssl - endif - endif - - ifndef OPENSSL_INCLUDE - ifeq "$(wildcard $(OPENSSL_PATH)/outinc)" "$(OPENSSL_PATH)/outinc" - OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc - endif - ifeq "$(wildcard $(OPENSSL_PATH)/include)" "$(OPENSSL_PATH)/include" - OPENSSL_INCLUDE = $(OPENSSL_PATH)/include - endif - endif - ifneq "$(wildcard $(OPENSSL_INCLUDE)/openssl/opensslv.h)" "$(OPENSSL_INCLUDE)/openssl/opensslv.h" - $(error Invalid path to OpenSSL package: $(OPENSSL_PATH)) - endif - ifndef OPENSSL_LIBPATH - ifeq "$(wildcard $(OPENSSL_PATH)/out)" "$(OPENSSL_PATH)/out" - OPENSSL_LIBPATH = $(OPENSSL_PATH)/out - OPENSSL_LIBS = -leay32 -lssl32 - endif - ifeq "$(wildcard $(OPENSSL_PATH)/lib)" "$(OPENSSL_PATH)/lib" - OPENSSL_LIBPATH = $(OPENSSL_PATH)/lib - OPENSSL_LIBS = -lcrypto -lssl - endif - endif - ifndef DYN - OPENSSL_LIBS += -lgdi32 -lcrypt32 - endif - INCLUDES += -I"$(OPENSSL_INCLUDE)" - CFLAGS += -DUSE_OPENSSL - DLL_LIBS += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS) - ifdef SRP - ifeq "$(wildcard $(OPENSSL_INCLUDE)/openssl/srp.h)" "$(OPENSSL_INCLUDE)/openssl/srp.h" - CFLAGS += -DHAVE_OPENSSL_SRP -DUSE_TLS_SRP - endif - endif -endif -ifdef SCHANNEL - CFLAGS += -DUSE_SCHANNEL - DLL_LIBS += -lcrypt32 +ifndef DYN + LDFLAGS += $(_LDFLAGS) + LIBS += $(_LIBS) endif -ifdef ZLIB - INCLUDES += -I"$(ZLIB_PATH)" - CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H - DLL_LIBS += -L"$(ZLIB_PATH)" -lz -endif -ifdef ZSTD - INCLUDES += -I"$(ZSTD_PATH)/include" - CFLAGS += -DHAVE_ZSTD - DLL_LIBS += -L"$(ZSTD_PATH)/lib" - ifdef ZSTD_LIBS - DLL_LIBS += $(ZSTD_LIBS) - else - DLL_LIBS += -lzstd - endif -endif -ifdef BROTLI - INCLUDES += -I"$(BROTLI_PATH)/include" - CFLAGS += -DHAVE_BROTLI - DLL_LIBS += -L"$(BROTLI_PATH)/lib" - ifdef BROTLI_LIBS - DLL_LIBS += $(BROTLI_LIBS) - else - DLL_LIBS += -lbrotlidec - endif -endif -ifdef GSASL - INCLUDES += -I"$(LIBGSASL_PATH)/include" - CFLAGS += -DUSE_GSASL - DLL_LIBS += -L"$(LIBGSASL_PATH)/lib" -lgsasl -endif -ifdef IDN2 - INCLUDES += -I"$(LIBIDN2_PATH)/include" - CFLAGS += -DUSE_LIBIDN2 - DLL_LIBS += -L"$(LIBIDN2_PATH)/lib" -lidn2 -else -ifdef WINIDN - CFLAGS += -DUSE_WIN32_IDN - CFLAGS += -DWANT_IDN_PROTOTYPES - DLL_LIBS += -L"$(WINIDN_PATH)" -lnormaliz -endif -endif -ifdef SSPI - CFLAGS += -DUSE_WINDOWS_SSPI -endif -ifdef SPNEGO - CFLAGS += -DHAVE_SPNEGO -endif -ifdef IPV6 - CFLAGS += -DENABLE_IPV6 -endif -ifdef LDAPS - CFLAGS += -DHAVE_LDAP_SSL -endif -ifdef USE_LDAP_NOVELL - INCLUDES += -I"$(LDAP_SDK)/inc" - CFLAGS += -DCURL_HAS_NOVELL_LDAPSDK - DLL_LIBS += -L"$(LDAP_SDK)/lib/mscvc" -lldapsdk -lldapssl -lldapx -endif -ifdef USE_LDAP_OPENLDAP - INCLUDES += -I"$(LDAP_SDK)/include" - CFLAGS += -DCURL_HAS_OPENLDAP_LDAPSDK - DLL_LIBS += -L"$(LDAP_SDK)/lib" -lldap -llber -endif -ifndef USE_LDAP_NOVELL -ifndef USE_LDAP_OPENLDAP - DLL_LIBS += -lwldap32 -endif -endif -DLL_LIBS += -lws2_32 -# Makefile.inc provides the CSOURCES and HHEADERS defines -include Makefile.inc +### Global rules -ifeq ($(CURL_DLL_A_SUFFIX),) -CURL_DLL_A_SUFFIX := dll +ifneq ($(findstring /sh,$(SHELL)),) +DEL = rm -f $1 +COPY = -cp -afv $1 $2 +else +DEL = -del 2>NUL /q /f $(subst /,\,$1) +COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2) endif -libcurl_dll_LIBRARY = libcurl$(CURL_DLL_SUFFIX).dll -libcurl_dll_a_LIBRARY = libcurl$(CURL_DLL_A_SUFFIX).a -libcurl_a_LIBRARY = libcurl.a - -libcurl_a_OBJECTS := $(patsubst %.c,%.o,$(strip $(CSOURCES))) -libcurl_a_DEPENDENCIES := $(strip $(CSOURCES) $(HHEADERS)) - -RESOURCE = libcurl.res - - -all: $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) - -$(libcurl_a_LIBRARY): $(libcurl_a_OBJECTS) $(libcurl_a_DEPENDENCIES) - @$(call DEL, $@) - $(AR) cru $@ $(libcurl_a_OBJECTS) - $(RANLIB) $@ - $(STRIP) $@ - -# remove the last line above to keep debug info - -$(libcurl_dll_LIBRARY): $(libcurl_a_OBJECTS) $(RESOURCE) $(libcurl_dll_DEPENDENCIES) - @$(call DEL, $@) - $(CC) $(LDFLAGS) -shared -o $@ \ - -Wl,--output-def,$(@:.dll=.def),--out-implib,$(libcurl_dll_a_LIBRARY) \ - $(libcurl_a_OBJECTS) $(RESOURCE) $(DLL_LIBS) +all: $(TARGETS) %.o: %.c - $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@ + $(CC) -W -Wall $(CFLAGS) $(CPPFLAGS) -c $< %.res: %.rc - $(RC) $(RCFLAGS) -i $< -o $@ + $(RC) -O coff $(RCFLAGS) -i $< -o $@ clean: - @$(call DEL, $(libcurl_a_OBJECTS) $(RESOURCE)) + @$(call DEL, $(TOCLEAN)) distclean vclean: clean - @$(call DEL, $(libcurl_a_LIBRARY) $(libcurl_dll_LIBRARY) $(libcurl_dll_LIBRARY:.dll=.def) $(libcurl_dll_a_LIBRARY)) - -$(LIBCARES_PATH)/libcares.a: - $(MAKE) -C $(LIBCARES_PATH) -f Makefile.m32 + @$(call DEL, $(TARGETS) $(TOVCLEAN)) diff --git a/libs/libcurl/src/altsvc.c b/libs/libcurl/src/altsvc.c index 2c0b3bdc43..7bca840151 100644 --- a/libs/libcurl/src/altsvc.c +++ b/libs/libcurl/src/altsvc.c @@ -52,15 +52,7 @@ #define MAX_ALTSVC_ALPNLENSTR "10" #define MAX_ALTSVC_ALPNLEN 10 -#if defined(USE_QUICHE) && !defined(UNITTESTS) -#define H3VERSION "h3-29" -#elif defined(USE_NGTCP2) && !defined(UNITTESTS) -#define H3VERSION "h3-29" -#elif defined(USE_MSH3) && !defined(UNITTESTS) -#define H3VERSION "h3-29" -#else #define H3VERSION "h3" -#endif static enum alpnid alpn2alpnid(char *name) { @@ -470,6 +462,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, struct altsvc *as; unsigned short dstport = srcport; /* the same by default */ CURLcode result = getalnum(&p, alpnbuf, sizeof(alpnbuf)); + size_t entries = 0; #ifdef CURL_DISABLE_VERBOSE_STRINGS (void)data; #endif @@ -480,11 +473,10 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, DEBUGASSERT(asi); - /* Flush all cached alternatives for this source origin, if any */ - altsvc_flush(asi, srcalpnid, srchost, srcport); - /* "clear" is a magic keyword */ if(strcasecompare(alpnbuf, "clear")) { + /* Flush cached alternatives for this source origin */ + altsvc_flush(asi, srcalpnid, srchost, srcport); return CURLE_OK; } @@ -502,6 +494,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, bool quoted = FALSE; time_t maxage = 24 * 3600; /* default is 24 hours */ bool persist = FALSE; + bool valid = TRUE; p++; if(*p != ':') { /* host name starts here */ @@ -511,7 +504,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, len = p - hostp; if(!len || (len >= MAX_ALTSVC_HOSTLEN)) { infof(data, "Excessive alt-svc host name, ignoring."); - dstalpnid = ALPN_none; + valid = FALSE; } else { memcpy(namebuf, hostp, len); @@ -528,10 +521,11 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, unsigned long port = strtoul(++p, &end_ptr, 10); if(port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') { infof(data, "Unknown alt-svc port number, ignoring."); - dstalpnid = ALPN_none; + valid = FALSE; } + else + dstport = curlx_ultous(port); p = end_ptr; - dstport = curlx_ultous(port); } if(*p++ != '\"') break; @@ -583,7 +577,12 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, persist = TRUE; } } - if(dstalpnid) { + if(dstalpnid && valid) { + if(!entries++) + /* Flush cached alternatives for this source origin, if any - when + this is the first entry of the line. */ + altsvc_flush(asi, srcalpnid, srchost, srcport); + as = altsvc_createid(srchost, dsthost, srcalpnid, dstalpnid, srcport, dstport); @@ -597,10 +596,6 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, Curl_alpnid2str(dstalpnid)); } } - else { - infof(data, "Unknown alt-svc protocol \"%s\", skipping.", - alpnbuf); - } } else break; diff --git a/libs/libcurl/src/amigaos.c b/libs/libcurl/src/amigaos.c index 6c144095f8..e8c2fc02e0 100644 --- a/libs/libcurl/src/amigaos.c +++ b/libs/libcurl/src/amigaos.c @@ -25,8 +25,16 @@ #include "curl_setup.h" #ifdef __AMIGA__ -# include "amigaos.h" -# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) + +#include <curl/curl.h> + +#include "hostip.h" +#include "amigaos.h" + +#ifdef HAVE_PROTO_BSDSOCKET_H +# if defined(__amigaos4__) +# include <bsdsocket/socketbasetags.h> +# elif !defined(USE_AMISSL) # include <amitcp/socketbasetags.h> # endif # ifdef __libnix__ @@ -38,8 +46,154 @@ #include "curl_memory.h" #include "memdebug.h" -#ifdef __AMIGA__ -#if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) +#ifdef HAVE_PROTO_BSDSOCKET_H + +#ifdef __amigaos4__ +/* + * AmigaOS 4.x specific code + */ + +/* + * hostip4.c - Curl_ipv4_resolve_r() replacement code + * + * Logic that needs to be considered are the following build cases: + * - newlib networking + * - clib2 networking + * - direct bsdsocket.library networking (usually AmiSSL builds) + * Each with the threaded resolver enabled or not. + * + * With the threaded resolver enabled, try to use gethostbyname_r() where + * available, otherwise (re)open bsdsocket.library and fallback to + * gethostbyname(). + */ + +#include <proto/bsdsocket.h> + +static struct SocketIFace *__CurlISocket = NULL; +static uint32 SocketFeatures = 0; + +#define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01 +#define HAVE_BSDSOCKET_GETADDRINFO 0x02 + +CURLcode Curl_amiga_init(void) +{ + struct SocketIFace *ISocket; + struct Library *base = OpenLibrary("bsdsocket.library", 4); + + if(base) { + ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); + if(ISocket) { + ULONG enabled = 0; + + SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE, + SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled, + TAG_DONE); + + if(enabled) { + SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R; + } + + __CurlISocket = ISocket; + + atexit(Curl_amiga_cleanup); + + return CURLE_OK; + } + CloseLibrary(base); + } + + return CURLE_FAILED_INIT; +} + +void Curl_amiga_cleanup(void) +{ + if(__CurlISocket) { + struct Library *base = __CurlISocket->Data.LibBase; + DropInterface((struct Interface *)__CurlISocket); + CloseLibrary(base); + __CurlISocket = NULL; + } +} + +#ifdef CURLRES_AMIGA +/* + * Because we need to handle the different cases in hostip4.c at run-time, + * not at compile-time, based on what was detected in Curl_amiga_init(), + * we replace it completely with our own as to not complicate the baseline + * code. Assumes malloc/calloc/free are thread safe because Curl_he2ai() + * allocates memory also. + */ + +struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, + int port) +{ + struct Curl_addrinfo *ai = NULL; + struct hostent *h; + struct SocketIFace *ISocket = __CurlISocket; + + if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) { + LONG h_errnop = 0; + struct hostent *buf; + + buf = calloc(1, CURL_HOSTENT_SIZE); + if(buf) { + h = gethostbyname_r((STRPTR)hostname, buf, + (char *)buf + sizeof(struct hostent), + CURL_HOSTENT_SIZE - sizeof(struct hostent), + &h_errnop); + if(h) { + ai = Curl_he2ai(h, port); + } + free(buf); + } + } + else { + #ifdef CURLRES_THREADED + /* gethostbyname() is not thread safe, so we need to reopen bsdsocket + * on the thread's context + */ + struct Library *base = OpenLibrary("bsdsocket.library", 4); + if(base) { + ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); + if(ISocket) { + h = gethostbyname((STRPTR)hostname); + if(h) { + ai = Curl_he2ai(h, port); + } + DropInterface((struct Interface *)ISocket); + } + CloseLibrary(base); + } + #else + /* not using threaded resolver - safe to use this as-is */ + h = gethostbyname(hostname); + if(h) { + ai = Curl_he2ai(h, port); + } + #endif + } + + return ai; +} +#endif /* CURLRES_AMIGA */ + +#ifdef USE_AMISSL +int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *errorfds, struct timeval *timeout) +{ + int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0); + /* Ensure Ctrl-C signal is actioned */ + if((r == -1) && (SOCKERRNO == EINTR)) + raise(SIGINT); + return r; +} +#endif /* USE_AMISSL */ + +#elif !defined(USE_AMISSL) /* __amigaos4__ */ +/* + * Amiga OS3 specific code + */ + struct Library *SocketBase = NULL; extern int errno, h_errno; @@ -49,7 +203,7 @@ void __request(const char *msg); # define __request(msg) Printf(msg "\n\a") #endif -void Curl_amiga_cleanup() +void Curl_amiga_cleanup(void) { if(SocketBase) { CloseLibrary(SocketBase); @@ -57,68 +211,36 @@ void Curl_amiga_cleanup() } } -bool Curl_amiga_init() +CURLcode Curl_amiga_init(void) { if(!SocketBase) SocketBase = OpenLibrary("bsdsocket.library", 4); if(!SocketBase) { __request("No TCP/IP Stack running!"); - return FALSE; + return CURLE_FAILED_INIT; } if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno, SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl", TAG_DONE)) { __request("SocketBaseTags ERROR"); - return FALSE; + return CURLE_FAILED_INIT; } #ifndef __libnix__ atexit(Curl_amiga_cleanup); #endif - return TRUE; + return CURLE_OK; } #ifdef __libnix__ ADD2EXIT(Curl_amiga_cleanup, -50); #endif -#endif /* HAVE_PROTO_BSDSOCKET_H */ +#endif /* !USE_AMISSL */ -#ifdef USE_AMISSL -void Curl_amiga_X509_free(X509 *a) -{ - X509_free(a); -} - -/* AmiSSL replaces many functions with macros. Curl requires pointer - * to some of these functions. Thus, we have to encapsulate these macros. - */ - -#include "warnless.h" - -int (SHA256_Init)(SHA256_CTX *c) -{ - return SHA256_Init(c); -}; - -int (SHA256_Update)(SHA256_CTX *c, const void *data, size_t len) -{ - return SHA256_Update(c, data, curlx_uztoui(len)); -}; - -int (SHA256_Final)(unsigned char *md, SHA256_CTX *c) -{ - return SHA256_Final(md, c); -}; - -void (X509_INFO_free)(X509_INFO *a) -{ - X509_INFO_free(a); -}; +#endif /* HAVE_PROTO_BSDSOCKET_H */ -#endif /* USE_AMISSL */ #endif /* __AMIGA__ */ - diff --git a/libs/libcurl/src/amigaos.h b/libs/libcurl/src/amigaos.h index 8757aa8e73..9abfb59eac 100644 --- a/libs/libcurl/src/amigaos.h +++ b/libs/libcurl/src/amigaos.h @@ -25,22 +25,18 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL) +#if defined(__AMIGA__) && defined(HAVE_PROTO_BSDSOCKET_H) && \ + (!defined(USE_AMISSL) || defined(__amigaos4__)) -bool Curl_amiga_init(); -void Curl_amiga_cleanup(); +CURLcode Curl_amiga_init(void); +void Curl_amiga_cleanup(void); #else -#define Curl_amiga_init() 1 +#define Curl_amiga_init() CURLE_OK #define Curl_amiga_cleanup() Curl_nop_stmt #endif -#ifdef USE_AMISSL -#include <openssl/x509v3.h> -void Curl_amiga_X509_free(X509 *a); -#endif /* USE_AMISSL */ - #endif /* HEADER_CURL_AMIGAOS_H */ diff --git a/libs/libcurl/src/asyn-ares.c b/libs/libcurl/src/asyn-ares.c index 8b620a1d64..33edba1395 100644 --- a/libs/libcurl/src/asyn-ares.c +++ b/libs/libcurl/src/asyn-ares.c @@ -115,6 +115,7 @@ struct thread_data { #ifndef HAVE_CARES_GETADDRINFO struct curltime happy_eyeballs_dns_time; /* when this timer started, or 0 */ #endif + char hostname[1]; }; /* How long we are willing to wait for additional parallel responses after @@ -252,8 +253,6 @@ void Curl_resolver_kill(struct Curl_easy *data) */ static void destroy_async_data(struct Curl_async *async) { - free(async->hostname); - if(async->tdata) { struct thread_data *res = async->tdata; if(res) { @@ -265,8 +264,6 @@ static void destroy_async_data(struct Curl_async *async) } async->tdata = NULL; } - - async->hostname = NULL; } /* @@ -749,7 +746,7 @@ static void addrinfo_cb(void *arg, int status, int timeouts, * Curl_resolver_getaddrinfo() - when using ares * * Returns name information about the given hostname and port number. If - * successful, the 'hostent' is returned and the forth argument will point to + * successful, the 'hostent' is returned and the fourth argument will point to * memory we need to free after use. That memory *MUST* be freed with * Curl_freeaddrinfo(), nothing else. */ @@ -758,25 +755,18 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, int port, int *waitp) { - char *bufp; - + struct thread_data *res = NULL; + size_t namelen = strlen(hostname); *waitp = 0; /* default to synchronous response */ - bufp = strdup(hostname); - if(bufp) { - struct thread_data *res = NULL; - free(data->state.async.hostname); - data->state.async.hostname = bufp; + res = calloc(sizeof(struct thread_data) + namelen, 1); + if(res) { + strcpy(res->hostname, hostname); + data->state.async.hostname = res->hostname; data->state.async.port = port; data->state.async.done = FALSE; /* not done */ data->state.async.status = 0; /* clear */ data->state.async.dns = NULL; /* clear */ - res = calloc(sizeof(struct thread_data), 1); - if(!res) { - free(data->state.async.hostname); - data->state.async.hostname = NULL; - return NULL; - } data->state.async.tdata = res; /* initial status - failed */ @@ -789,13 +779,17 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, int pf = PF_INET; memset(&hints, 0, sizeof(hints)); #ifdef CURLRES_IPV6 - if(Curl_ipv6works(data)) + if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) /* The stack seems to be IPv6-enabled */ pf = PF_UNSPEC; #endif /* CURLRES_IPV6 */ hints.ai_family = pf; hints.ai_socktype = (data->conn->transport == TRNSPRT_TCP)? SOCK_STREAM : SOCK_DGRAM; + /* Since the service is a numerical one, set the hint flags + * accordingly to save a call to getservbyname in inside C-Ares + */ + hints.ai_flags = ARES_AI_NUMERICSERV; msnprintf(service, sizeof(service), "%d", port); res->num_pending = 1; ares_getaddrinfo((ares_channel)data->state.async.resolver, hostname, @@ -804,7 +798,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, #else #ifdef HAVE_CARES_IPV6 - if(Curl_ipv6works(data)) { + if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) { /* The stack seems to be IPv6-enabled */ res->num_pending = 2; diff --git a/libs/libcurl/src/asyn-thread.c b/libs/libcurl/src/asyn-thread.c index d0edc32608..8b375eb5ee 100644 --- a/libs/libcurl/src/asyn-thread.c +++ b/libs/libcurl/src/asyn-thread.c @@ -264,23 +264,28 @@ int init_thread_sync_data(struct thread_data *td, return 1; err_exit: - /* Memory allocation failed */ +#ifndef CURL_DISABLE_SOCKETPAIR + if(tsd->sock_pair[0] != CURL_SOCKET_BAD) { + sclose(tsd->sock_pair[0]); + tsd->sock_pair[0] = CURL_SOCKET_BAD; + } +#endif destroy_thread_sync_data(tsd); return 0; } -static int getaddrinfo_complete(struct Curl_easy *data) +static CURLcode getaddrinfo_complete(struct Curl_easy *data) { struct thread_sync_data *tsd = conn_thread_sync_data(data); - int rc; + CURLcode result; - rc = Curl_addrinfo_callback(data, tsd->sock_error, tsd->res); + result = Curl_addrinfo_callback(data, tsd->sock_error, tsd->res); /* The tsd->res structure has been copied to async.dns and perhaps the DNS cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it. */ tsd->res = NULL; - return rc; + return result; } @@ -702,7 +707,7 @@ struct Curl_addrinfo *Curl_resolver_getaddrinfo(struct Curl_easy *data, *waitp = 0; /* default to synchronous response */ #ifdef CURLRES_IPV6 - if(Curl_ipv6works(data)) + if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) /* The stack seems to be IPv6-enabled */ pf = PF_UNSPEC; #endif /* CURLRES_IPV6 */ diff --git a/libs/libcurl/src/asyn.h b/libs/libcurl/src/asyn.h index 80ca54d787..1aab21aaa7 100644 --- a/libs/libcurl/src/asyn.h +++ b/libs/libcurl/src/asyn.h @@ -148,7 +148,7 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data, * Curl_resolver_getaddrinfo() - when using this resolver * * Returns name information about the given hostname and port number. If - * successful, the 'hostent' is returned and the forth argument will point to + * successful, the 'hostent' is returned and the fourth argument will point to * memory we need to free after use. That memory *MUST* be freed with * Curl_freeaddrinfo(), nothing else. * diff --git a/libs/libcurl/src/base64.c b/libs/libcurl/src/base64.c index d5d79cf96b..52654c2bc3 100644 --- a/libs/libcurl/src/base64.c +++ b/libs/libcurl/src/base64.c @@ -43,10 +43,11 @@ #include "memdebug.h" /* ---- Base64 Encoding/Decoding Table --- */ +/* Padding character string starts at offset 64. */ static const char base64[]= - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; -/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648 +/* The Base 64 encoding with a URL and filename safe alphabet, RFC 4648 section 5 */ static const char base64url[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; @@ -54,25 +55,18 @@ static const char base64url[]= static size_t decodeQuantum(unsigned char *dest, const char *src) { size_t padding = 0; - const char *s, *p; + const char *s; unsigned long i, x = 0; for(i = 0, s = src; i < 4; i++, s++) { if(*s == '=') { - x = (x << 6); + x <<= 6; padding++; } else { - unsigned long v = 0; - p = base64; - - while(*p && (*p != *s)) { - v++; - p++; - } - - if(*p == *s) - x = (x << 6) + v; + const char *p = strchr(base64, *s); + if(p) + x = (x << 6) + curlx_uztoul(p - base64); else return 0; } @@ -109,11 +103,11 @@ CURLcode Curl_base64_decode(const char *src, unsigned char **outptr, size_t *outlen) { size_t srclen = 0; - size_t length = 0; size_t padding = 0; size_t i; size_t numQuantums; size_t rawlen = 0; + const char *padptr; unsigned char *pos; unsigned char *newstr; @@ -126,19 +120,17 @@ CURLcode Curl_base64_decode(const char *src, return CURLE_BAD_CONTENT_ENCODING; /* Find the position of any = padding characters */ - while((src[length] != '=') && src[length]) - length++; - - /* A maximum of two = padding characters is allowed */ - if(src[length] == '=') { + padptr = strchr(src, '='); + if(padptr) { padding++; - if(src[length + 1] == '=') + /* A maximum of two = padding characters is allowed */ + if(padptr[1] == '=') padding++; - } - /* Check the = padding characters weren't part way through the input */ - if(length + padding != srclen) - return CURLE_BAD_CONTENT_ENCODING; + /* Check the = padding characters weren't part way through the input */ + if(padptr + padding != src + srclen) + return CURLE_BAD_CONTENT_ENCODING; + } /* Calculate the number of quantums */ numQuantums = srclen / 4; @@ -146,7 +138,7 @@ CURLcode Curl_base64_decode(const char *src, /* Calculate the size of the decoded string */ rawlen = (numQuantums * 3) - padding; - /* Allocate our buffer including room for a zero terminator */ + /* Allocate our buffer including room for a null-terminator */ newstr = malloc(rawlen + 1); if(!newstr) return CURLE_OUT_OF_MEMORY; @@ -187,6 +179,7 @@ static CURLcode base64_encode(const char *table64, char *output; char *base64data; const char *indata = inputbuff; + const char *padstr = &table64[64]; /* Point to padding string. */ *outptr = NULL; *outlen = 0; @@ -224,27 +217,30 @@ static CURLcode base64_encode(const char *table64, switch(inputparts) { case 1: /* only one byte read */ - msnprintf(output, 5, "%c%c==", - table64[obuf[0]], - table64[obuf[1]]); + i = msnprintf(output, 5, "%c%c%s%s", + table64[obuf[0]], + table64[obuf[1]], + padstr, + padstr); break; case 2: /* two bytes read */ - msnprintf(output, 5, "%c%c%c=", - table64[obuf[0]], - table64[obuf[1]], - table64[obuf[2]]); + i = msnprintf(output, 5, "%c%c%c%s", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]], + padstr); break; default: - msnprintf(output, 5, "%c%c%c%c", - table64[obuf[0]], - table64[obuf[1]], - table64[obuf[2]], - table64[obuf[3]]); + i = msnprintf(output, 5, "%c%c%c%c", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]], + table64[obuf[3]]); break; } - output += 4; + output += i; } /* Zero terminate */ @@ -272,8 +268,6 @@ static CURLcode base64_encode(const char *table64, * Returns CURLE_OK on success, otherwise specific error code. Function * output shall not be considered valid unless CURLE_OK is returned. * - * When encoded data length is 0, returns NULL in *outptr. - * * @unittest: 1302 */ CURLcode Curl_base64_encode(const char *inputbuff, size_t insize, @@ -295,8 +289,6 @@ CURLcode Curl_base64_encode(const char *inputbuff, size_t insize, * Returns CURLE_OK on success, otherwise specific error code. Function * output shall not be considered valid unless CURLE_OK is returned. * - * When encoded data length is 0, returns NULL in *outptr. - * * @unittest: 1302 */ CURLcode Curl_base64url_encode(const char *inputbuff, size_t insize, diff --git a/libs/libcurl/src/c-hyper.c b/libs/libcurl/src/c-hyper.c index 69b904e531..86abcdb0fa 100644 --- a/libs/libcurl/src/c-hyper.c +++ b/libs/libcurl/src/c-hyper.c @@ -54,6 +54,7 @@ #include "multiif.h" #include "progress.h" #include "content_encoding.h" +#include "ws.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -471,6 +472,24 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, if(result) break; + k->deductheadercount = + (100 <= http_status && 199 >= http_status)?k->headerbytecount:0; +#ifdef USE_WEBSOCKETS + if(k->upgr101 == UPGR101_WS) { + if(http_status == 101) { + /* verify the response */ + result = Curl_ws_accept(data); + if(result) + return result; + } + else { + failf(data, "Expected 101, got %u", k->httpcode); + result = CURLE_HTTP_RETURNED_ERROR; + break; + } + } +#endif + /* Curl_http_auth_act() checks what authentication methods that are * available and decides which one (if any) to use. It will set 'newurl' * if an auth method was picked. */ @@ -692,9 +711,18 @@ static int uploadstreamed(void *userdata, hyper_context *ctx, data->state.hresult = result; return HYPER_POLL_ERROR; } - if(!fillcount) - /* done! */ - *chunk = NULL; + if(!fillcount) { + if((data->req.keepon & KEEP_SEND_PAUSE) != KEEP_SEND_PAUSE) + /* done! */ + *chunk = NULL; + else { + /* paused, save a waker */ + if(data->hyp.send_body_waker) + hyper_waker_free(data->hyp.send_body_waker); + data->hyp.send_body_waker = hyper_context_waker(ctx); + return HYPER_POLL_PENDING; + } + } else { hyper_buf *copy = hyper_buf_copy((uint8_t *)data->state.ulbuf, fillcount); if(copy) @@ -909,12 +937,13 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) result = CURLE_OUT_OF_MEMORY; goto error; } - if(conn->negnpn == CURL_HTTP_VERSION_2) { + if(conn->alpn == CURL_HTTP_VERSION_2) { hyper_clientconn_options_http2(options, 1); h2 = TRUE; } hyper_clientconn_options_set_preserve_header_case(options, 1); hyper_clientconn_options_set_preserve_header_order(options, 1); + hyper_clientconn_options_http1_allow_multiline_headers(options, 1); hyper_clientconn_options_exec(options, h->exec); @@ -1004,10 +1033,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) /* For HTTP/2, we show the Host: header as if we sent it, to make it look like for HTTP/1 but it isn't actually sent since :authority is then used. */ - result = Curl_debug(data, CURLINFO_HEADER_OUT, data->state.aptr.host, - strlen(data->state.aptr.host)); - if(result) - goto error; + Curl_debug(data, CURLINFO_HEADER_OUT, data->state.aptr.host, + strlen(data->state.aptr.host)); } if(data->state.aptr.proxyuserpwd) { @@ -1115,6 +1142,9 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(result) goto error; + if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS)) + result = Curl_ws_request(data, headers); + result = Curl_add_timecondition(data, headers); if(result) goto error; @@ -1127,9 +1157,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(result) goto error; - result = Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"\r\n", 2); - if(result) - goto error; + Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"\r\n", 2); data->req.upload_chunky = FALSE; sendtask = hyper_clientconn_send(client, req); diff --git a/libs/libcurl/src/c-hyper.h b/libs/libcurl/src/c-hyper.h index 91a62619c3..70507ad2a4 100644 --- a/libs/libcurl/src/c-hyper.h +++ b/libs/libcurl/src/c-hyper.h @@ -36,6 +36,7 @@ struct hyptransfer { const hyper_executor *exec; hyper_task *endtask; hyper_waker *exp100_waker; + hyper_waker *send_body_waker; }; size_t Curl_hyper_recv(void *userp, hyper_context *ctx, diff --git a/libs/libcurl/src/config-amigaos.h b/libs/libcurl/src/config-amigaos.h index 79186c6378..b7356c7629 100644 --- a/libs/libcurl/src/config-amigaos.h +++ b/libs/libcurl/src/config-amigaos.h @@ -33,26 +33,15 @@ #define HAVE_ARPA_INET_H 1 #define HAVE_CLOSESOCKET_CAMEL 1 #define HAVE_ERRNO_H 1 -#define HAVE_INET_ADDR 1 #define HAVE_INTTYPES_H 1 #define HAVE_IOCTLSOCKET_CAMEL 1 #define HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 -#define HAVE_LIBZ 1 #define HAVE_LONGLONG 1 -#define HAVE_MALLOC_H 1 -#define HAVE_MEMORY_H 1 #define HAVE_NETDB_H 1 #define HAVE_NETINET_IN_H 1 #define HAVE_NET_IF_H 1 -#define HAVE_OPENSSL_CRYPTO_H 1 -#define HAVE_OPENSSL_ERR_H 1 -#define HAVE_OPENSSL_PEM_H 1 -#define HAVE_OPENSSL_RSA_H 1 -#define HAVE_OPENSSL_SSL_H 1 -#define HAVE_OPENSSL_X509_H 1 #define HAVE_PWD_H 1 #define HAVE_RAND_EGD 1 -#define HAVE_RAND_STATUS 1 #define HAVE_SELECT 1 #define HAVE_SETJMP_H 1 #define HAVE_SIGNAL 1 @@ -60,11 +49,9 @@ #define HAVE_SOCKET 1 #define HAVE_STRCASECMP 1 #define HAVE_STRDUP 1 -#define HAVE_STRFTIME 1 #define HAVE_STRICMP 1 #define HAVE_STRINGS_H 1 #define HAVE_STRING_H 1 -#define HAVE_STRSTR 1 #define HAVE_STRUCT_TIMEVAL 1 #define HAVE_SYS_PARAM_H 1 #define HAVE_SYS_SOCKET_H 1 @@ -73,22 +60,22 @@ #define HAVE_SYS_TIME_H 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_TIME_H 1 -#define HAVE_UNAME 1 #define HAVE_UNISTD_H 1 #define HAVE_UTIME 1 #define HAVE_UTIME_H 1 #define HAVE_WRITABLE_ARGV 1 -#define HAVE_ZLIB_H 1 #define HAVE_SYS_IOCTL_H 1 #define NEED_MALLOC_H 1 #define SIZEOF_INT 4 -#define SIZEOF_SHORT 2 #define SIZEOF_SIZE_T 4 +#ifndef SIZEOF_CURL_OFF_T +#define SIZEOF_CURL_OFF_T 8 +#endif + #define USE_MANUAL 1 -#define USE_OPENSSL 1 #define CURL_DISABLE_LDAP 1 #define OS "AmigaOS" @@ -100,11 +87,6 @@ #define PACKAGE_TARNAME "curl" #define PACKAGE_VERSION "-" #define CURL_CA_BUNDLE "s:curl-ca-bundle.crt" - -#define SELECT_TYPE_ARG1 int -#define SELECT_TYPE_ARG234 (fd_set *) -#define SELECT_TYPE_ARG5 (struct timeval *) - #define STDC_HEADERS 1 #define TIME_WITH_SYS_TIME 1 @@ -133,15 +115,6 @@ #define RECV_TYPE_ARG4 long #define RECV_TYPE_RETV long -#define HAVE_RECVFROM 1 -#define RECVFROM_TYPE_ARG1 long -#define RECVFROM_TYPE_ARG2 char -#define RECVFROM_TYPE_ARG3 long -#define RECVFROM_TYPE_ARG4 long -#define RECVFROM_TYPE_ARG5 struct sockaddr -#define RECVFROM_TYPE_ARG6 long -#define RECVFROM_TYPE_RETV long - #define HAVE_SEND 1 #define SEND_TYPE_ARG1 int #define SEND_QUAL_ARG2 const diff --git a/libs/libcurl/src/config-dos.h b/libs/libcurl/src/config-dos.h index 9fb7743957..8e3c940d9c 100644 --- a/libs/libcurl/src/config-dos.h +++ b/libs/libcurl/src/config-dos.h @@ -45,23 +45,19 @@ #define HAVE_FCNTL_H 1 #define HAVE_FREEADDRINFO 1 #define HAVE_GETADDRINFO 1 -#define HAVE_GETPROTOBYNAME 1 #define HAVE_GETTIMEOFDAY 1 #define HAVE_IO_H 1 -#define HAVE_IOCTL 1 #define HAVE_IOCTL_FIONBIO 1 #define HAVE_IOCTLSOCKET 1 #define HAVE_IOCTLSOCKET_FIONBIO 1 #define HAVE_LOCALE_H 1 #define HAVE_LONGLONG 1 -#define HAVE_MEMORY_H 1 #define HAVE_NETDB_H 1 #define HAVE_NETINET_IN_H 1 #define HAVE_NETINET_TCP_H 1 #define HAVE_NET_IF_H 1 #define HAVE_PROCESS_H 1 #define HAVE_RECV 1 -#define HAVE_RECVFROM 1 #define HAVE_SELECT 1 #define HAVE_SEND 1 #define HAVE_SETJMP_H 1 @@ -73,7 +69,6 @@ #define HAVE_STRICMP 1 #define HAVE_STRTOLL 1 #define HAVE_STRUCT_TIMEVAL 1 -#define HAVE_STRUCT_IN6_ADDR 1 #define HAVE_SYS_IOCTL_H 1 #define HAVE_SYS_SOCKET_H 1 #define HAVE_SYS_STAT_H 1 @@ -85,14 +80,12 @@ #define SIZEOF_INT 4 #define SIZEOF_LONG 4 -#define SIZEOF_LONG_DOUBLE 16 -#define SIZEOF_SHORT 2 #define SIZEOF_SIZE_T 4 #define SIZEOF_CURL_OFF_T 4 #define STDC_HEADERS 1 #define TIME_WITH_SYS_TIME 1 -/* Qualifiers for send(), recv(), and recvfrom() */ +/* Qualifiers for send() and recv() */ #define SEND_TYPE_ARG1 int #define SEND_QUAL_ARG2 const @@ -107,32 +100,15 @@ #define RECV_TYPE_ARG4 int #define RECV_TYPE_RETV int -#define RECVFROM_TYPE_ARG1 int -#define RECVFROM_TYPE_ARG2 void -#define RECVFROM_TYPE_ARG3 int -#define RECVFROM_TYPE_ARG4 int -#define RECVFROM_TYPE_ARG5 struct sockaddr -#define RECVFROM_TYPE_ARG6 int -#define RECVFROM_TYPE_RETV int -#define RECVFROM_TYPE_ARG2_IS_VOID 1 - #define BSD /* CURLDEBUG definition enables memory tracking */ /* #define CURLDEBUG */ -/* USE_ZLIB on cmd-line */ -#ifdef USE_ZLIB - #define HAVE_ZLIB_H 1 +#ifdef USE_ZLIB /* Deprecated. Use HAVE_LIBZ instead. */ #define HAVE_LIBZ 1 #endif -/* USE_OPENSSL on cmd-line */ -#ifdef USE_OPENSSL - #define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 - #define OPENSSL_NO_KRB5 1 -#endif - /* to disable LDAP */ #define CURL_DISABLE_LDAP 1 diff --git a/libs/libcurl/src/config-mac.h b/libs/libcurl/src/config-mac.h index dd1d9a7ea6..ed07019e6b 100644 --- a/libs/libcurl/src/config-mac.h +++ b/libs/libcurl/src/config-mac.h @@ -47,7 +47,6 @@ #define HAVE_GETTIMEOFDAY 1 #define HAVE_FCNTL_H 1 #define HAVE_SYS_STAT_H 1 -#define HAVE_ALLOCA_H 1 #define HAVE_STDLIB_H 1 #define HAVE_TIME_H 1 #define HAVE_UTIME_H 1 @@ -59,10 +58,6 @@ #define HAVE_ALARM 1 #define HAVE_FTRUNCATE 1 #define HAVE_UTIME 1 -#define HAVE_SETVBUF 1 -#define HAVE_STRFTIME 1 -#define HAVE_INET_ADDR 1 -#define HAVE_MEMCPY 1 #define HAVE_SELECT 1 #define HAVE_SOCKET 1 #define HAVE_STRUCT_TIMEVAL 1 @@ -76,14 +71,11 @@ #define CURL_DISABLE_LDAP 1 -#define HAVE_RAND_STATUS 1 #define HAVE_RAND_EGD 1 -#define HAVE_IOCTL 1 #define HAVE_IOCTL_FIONBIO 1 #define SIZEOF_INT 4 -#define SIZEOF_SHORT 2 #define SIZEOF_SIZE_T 4 #define HAVE_RECV 1 @@ -93,16 +85,6 @@ #define RECV_TYPE_ARG4 int #define RECV_TYPE_RETV ssize_t -#define HAVE_RECVFROM 1 -#define RECVFROM_TYPE_ARG1 int -#define RECVFROM_TYPE_ARG2 void -#define RECVFROM_TYPE_ARG3 size_t -#define RECVFROM_TYPE_ARG4 int -#define RECVFROM_TYPE_ARG5 struct sockaddr -#define RECVFROM_TYPE_ARG6 int -#define RECVFROM_TYPE_RETV ssize_t -#define RECVFROM_TYPE_ARG2_IS_VOID 1 - #define HAVE_SEND 1 #define SEND_TYPE_ARG1 int #define SEND_QUAL_ARG2 const diff --git a/libs/libcurl/src/config-os400.h b/libs/libcurl/src/config-os400.h index f6113fc699..2eef1a0c1b 100644 --- a/libs/libcurl/src/config-os400.h +++ b/libs/libcurl/src/config-os400.h @@ -35,9 +35,6 @@ /* Version number of this archive. */ #undef VERSION -/* Define if you have the getpass function. */ -#undef HAVE_GETPASS - /* Define cpu-machine-OS */ #define OS "OS/400" @@ -57,9 +54,6 @@ /* Define if you need the _REENTRANT define for some functions */ #undef NEED_REENTRANT -/* Define if you have the Kerberos4 libraries (including -ldes) */ -#undef HAVE_KRB4 - /* Define if you want to enable IPv6 support */ #define ENABLE_IPV6 @@ -78,9 +72,6 @@ /* Define to 1 if you have the alarm function. */ #define HAVE_ALARM 1 -/* Define if you have the <alloca.h> header file. */ -#undef HAVE_ALLOCA_H - /* Define if you have the <arpa/inet.h> header file. */ #define HAVE_ARPA_INET_H @@ -99,9 +90,6 @@ /* Define if you have the `gethostname' function. */ #define HAVE_GETHOSTNAME -/* Define if you have the <getopt.h> header file. */ -#undef HAVE_GETOPT_H - /* Define if you have the `getpass_r' function. */ #undef HAVE_GETPASS_R @@ -111,9 +99,6 @@ /* Define if you have the `getpwuid' function. */ #define HAVE_GETPWUID -/* Define if you have the `getservbyname' function. */ -#define HAVE_GETSERVBYNAME - /* Define to 1 if you have the getsockname function. */ #define HAVE_GETSOCKNAME 1 @@ -123,30 +108,12 @@ /* Define if you have the `timeval' struct. */ #define HAVE_STRUCT_TIMEVAL -/* Define if you have the `inet_addr' function. */ -#define HAVE_INET_ADDR - /* Define if you have the <inttypes.h> header file. */ #define HAVE_INTTYPES_H /* Define if you have the <io.h> header file. */ #undef HAVE_IO_H -/* Define if you have the `krb_get_our_ip_for_realm' function. */ -#undef HAVE_KRB_GET_OUR_IP_FOR_REALM - -/* Define if you have the <krb.h> header file. */ -#undef HAVE_KRB_H - -/* Define if you have the `nsl' library (-lnsl). */ -#undef HAVE_LIBNSL - -/* Define if you have the `resolv' library (-lresolv). */ -#undef HAVE_LIBRESOLV - -/* Define if you have the `resolve' library (-lresolve). */ -#undef HAVE_LIBRESOLVE - /* Define if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET @@ -162,72 +129,27 @@ /* Define if you have the MIT gssapi libraries */ #undef HAVE_GSSMIT -/* Define if you have the `ucb' library (-lucb). */ -#undef HAVE_LIBUCB - -/* Define if you have the `localtime_r' function. */ -#define HAVE_LOCALTIME_R - -/* Define if you have the <malloc.h> header file. */ -#define HAVE_MALLOC_H - /* Define if you need the malloc.h header file even with stdlib.h */ /* #define NEED_MALLOC_H 1 */ -/* Define if you have the <memory.h> header file. */ -#undef HAVE_MEMORY_H - /* Define if you have the <netdb.h> header file. */ #define HAVE_NETDB_H -/* Define if you have the <netinet/if_ether.h> header file. */ -#undef HAVE_NETINET_IF_ETHER_H - /* Define if you have the <netinet/in.h> header file. */ #define HAVE_NETINET_IN_H /* Define if you have the <net/if.h> header file. */ #define HAVE_NET_IF_H -/* Define if you have the <openssl/crypto.h> header file. */ -#undef HAVE_OPENSSL_CRYPTO_H - -/* Define if you have the <openssl/err.h> header file. */ -#undef HAVE_OPENSSL_ERR_H - -/* Define if you have the <openssl/pem.h> header file. */ -#undef HAVE_OPENSSL_PEM_H - -/* Define if you have the <openssl/rsa.h> header file. */ -#undef HAVE_OPENSSL_RSA_H - -/* Define if you have the <openssl/ssl.h> header file. */ -#undef HAVE_OPENSSL_SSL_H - -/* Define if you have the <openssl/x509.h> header file. */ -#undef HAVE_OPENSSL_X509_H - -/* Define if you have the <pem.h> header file. */ -#undef HAVE_PEM_H - /* Define if you have the <pwd.h> header file. */ #define HAVE_PWD_H /* Define if you have the `RAND_egd' function. */ #undef HAVE_RAND_EGD -/* Define if you have the `RAND_screen' function. */ -#undef HAVE_RAND_SCREEN - -/* Define if you have the `RAND_status' function. */ -#undef HAVE_RAND_STATUS - /* Define if you have the `select' function. */ #define HAVE_SELECT -/* Define if you have the `setvbuf' function. */ -#define HAVE_SETVBUF - /* Define if you have the `sigaction' function. */ #define HAVE_SIGACTION @@ -266,10 +188,6 @@ /* Define if you have the `strdup' function. */ #define HAVE_STRDUP - -/* Define if you have the `strftime' function. */ -#define HAVE_STRFTIME - /* Define if you have the <strings.h> header file. */ #define HAVE_STRINGS_H @@ -279,9 +197,6 @@ /* Define if you have the <stropts.h> header file. */ #undef HAVE_STROPTS_H -/* Define if you have the `strstr' function. */ -#define HAVE_STRSTR - /* Define if you have the `strtok_r' function. */ #define HAVE_STRTOK_R @@ -324,33 +239,21 @@ /* Define if you have the <time.h> header file. */ #define HAVE_TIME_H -/* Define if you have the `uname' function. */ -#undef HAVE_UNAME - /* Define if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H -/* Define if you have the <x509.h> header file. */ -#undef HAVE_X509_H - /* Name of package */ #undef PACKAGE /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 -/* The size of a `long double', as computed by sizeof. */ -#define SIZEOF_LONG_DOUBLE 8 - /* Define if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG /* The size of a `long long', as computed by sizeof. */ #define SIZEOF_LONG_LONG 8 -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 @@ -360,10 +263,6 @@ /* The size of `curl_off_t', as computed by sizeof. */ #define SIZEOF_CURL_OFF_T 8 -/* Whether long long constants must be suffixed by LL. */ - -#define HAVE_LL - /* Define this if you have struct sockaddr_storage */ #define HAVE_STRUCT_SOCKADDR_STORAGE @@ -395,9 +294,6 @@ /* Define to `unsigned' if <sys/types.h> does not define. */ #undef size_t -/* Define if you have the ioctl function. */ -#define HAVE_IOCTL - /* Define if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO @@ -431,30 +327,6 @@ /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int -/* Define if you have the recvfrom function. */ -#define HAVE_RECVFROM - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 int - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 char - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 int - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int - /* Define if you have the send function. */ #define HAVE_SEND diff --git a/libs/libcurl/src/config-plan9.h b/libs/libcurl/src/config-plan9.h index 75aac7272f..49a719c1aa 100644 --- a/libs/libcurl/src/config-plan9.h +++ b/libs/libcurl/src/config-plan9.h @@ -48,7 +48,6 @@ #error not implement #else #define SIZEOF_INT 4 -#define SIZEOF_SHORT 2 #define SIZEOF_LONG 4 #define SIZEOF_OFF_T 8 #define SIZEOF_CURL_OFF_T 4 /* curl_off_t = timediff_t = int */ @@ -63,23 +62,7 @@ #define RECV_TYPE_ARG4 int #define RECV_TYPE_RETV int -#define HAVE_RECVFROM 1 -#define RECVFROM_TYPE_ARG1 int -#define RECVFROM_TYPE_ARG2 void -#define RECVFROM_TYPE_ARG2_IS_VOID 1 -#define RECVFROM_TYPE_ARG3 int -#define RECVFROM_TYPE_ARG4 int -#define RECVFROM_TYPE_ARG5 void -#define RECVFROM_TYPE_ARG5_IS_VOID 1 -#define RECVFROM_TYPE_ARG6 int -#define RECVFROM_TYPE_ARG6_IS_VOID 1 -#define RECVFROM_TYPE_RETV int - #define HAVE_SELECT 1 -#define SELECT_TYPE_ARG1 int -#define SELECT_TYPE_ARG234 fd_set * -#define SELECT_TYPE_ARG5 struct timeval * -#define SELECT_TYPE_RETV int #define HAVE_SEND 1 #define SEND_TYPE_ARG1 int @@ -94,7 +77,6 @@ #define HAVE_ASSERT_H 1 #define HAVE_BASENAME 1 #define HAVE_BOOL_T 1 -#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 #define HAVE_ERRNO_H 1 #define HAVE_FCNTL 1 #define HAVE_FCNTL_H 1 @@ -102,23 +84,17 @@ #define HAVE_FTRUNCATE 1 #define HAVE_GETADDRINFO 1 #define HAVE_GETEUID 1 -#define HAVE_GETHOSTBYNAME 1 #define HAVE_GETHOSTNAME 1 #define HAVE_GETPPID 1 -#define HAVE_GETPROTOBYNAME 1 #define HAVE_GETPWUID 1 #define HAVE_GETTIMEOFDAY 1 #define HAVE_GMTIME_R 1 -#define HAVE_INET_ADDR 1 #define HAVE_INET_NTOP 1 #define HAVE_INET_PTON 1 #define HAVE_INTTYPES_H 1 -#define HAVE_IOCTL 1 #define HAVE_LIBGEN_H 1 #define HAVE_LIBZ 1 -#define HAVE_LL 1 #define HAVE_LOCALE_H 1 -#define HAVE_LOCALTIME_R 1 #define HAVE_LONGLONG 1 #define HAVE_NETDB_H 1 #define HAVE_NETINET_IN_H 1 @@ -127,26 +103,14 @@ #define HAVE_SYS_SELECT_H 1 #define USE_OPENSSL 1 -#define HAVE_OPENSSL_CRYPTO_H 1 -#define HAVE_OPENSSL_ERR_H 1 -#define HAVE_OPENSSL_PEM_H 1 -#define HAVE_OPENSSL_PKCS12_H 1 -#define HAVE_OPENSSL_RSA_H 1 -#define HAVE_OPENSSL_SSL_H 1 -#define HAVE_OPENSSL_X509_H 1 #define HAVE_PIPE 1 -#define HAVE_POLL 1 #define HAVE_POLL_FINE 1 #define HAVE_POLL_H 1 #define HAVE_PTHREAD_H 1 -#define HAVE_RAND_STATUS 1 #define HAVE_SETJMP_H 1 #define HAVE_SETLOCALE 1 -#define HAVE_SETSOCKOPT 1 -#define HAVE_SOCK_OPTS 1 /* for /sys/include/ape/sys/socket.h */ - #define HAVE_SIGACTION 1 #define HAVE_SIGNAL 1 #define HAVE_SIGNAL_H 1 @@ -156,12 +120,10 @@ #define HAVE_SSL_GET_SHUTDOWN 1 #define HAVE_STDBOOL_H 1 #define HAVE_STDINT_H 1 -#define HAVE_STDIO_H 1 #define HAVE_STDLIB_H 1 #define HAVE_STRCASECMP 1 #define HAVE_STRDUP 1 #define HAVE_STRING_H 1 -#define HAVE_STRSTR 1 #define HAVE_STRTOK_R 1 #define HAVE_STRTOLL 1 #define HAVE_STRUCT_TIMEVAL 1 @@ -172,21 +134,15 @@ #define HAVE_SYS_STAT_H 1 #define HAVE_SYS_TIME_H 1 #define HAVE_SYS_TYPES_H 1 -#define HAVE_SYS_UIO_H 1 #define HAVE_SYS_UN_H 1 #define HAVE_TERMIOS_H 1 #define HAVE_TIME_H 1 -#define HAVE_UNAME 1 #define HAVE_UNISTD_H 1 #define HAVE_UTIME 1 #define HAVE_UTIME_H 1 -#define HAVE_WRITEV 1 - -#define HAVE_ZLIB_H 1 #define HAVE_POSIX_STRERROR_R 1 #define HAVE_STRERROR_R 1 -#define STRERROR_R_TYPE_ARG3 int #define TIME_WITH_SYS_TIME 1 #define USE_MANUAL 1 diff --git a/libs/libcurl/src/config-riscos.h b/libs/libcurl/src/config-riscos.h index 3836562402..d6c81f3eb9 100644 --- a/libs/libcurl/src/config-riscos.h +++ b/libs/libcurl/src/config-riscos.h @@ -34,9 +34,6 @@ /* Version number of this archive. */ #undef VERSION -/* Define if you have the getpass function. */ -#undef HAVE_GETPASS - /* Define cpu-machine-OS */ #define OS "ARM-RISC OS" @@ -55,9 +52,6 @@ /* Define if you need the _REENTRANT define for some functions */ #undef NEED_REENTRANT -/* Define if you have the Kerberos4 libraries (including -ldes) */ -#undef HAVE_KRB4 - /* Define if you want to enable IPv6 support */ #undef ENABLE_IPV6 @@ -79,9 +73,6 @@ /* Define if you have the alarm function. */ #define HAVE_ALARM -/* Define if you have the <alloca.h> header file. */ -#define HAVE_ALLOCA_H - /* Define if you have the <arpa/inet.h> header file. */ #define HAVE_ARPA_INET_H @@ -109,117 +100,48 @@ /* Define if you have the `gethostname' function. */ #define HAVE_GETHOSTNAME -/* Define if you have the <getopt.h> header file. */ -#define HAVE_GETOPT_H - /* Define if you have the `getpass_r' function. */ #undef HAVE_GETPASS_R /* Define if you have the `getpwuid' function. */ #undef HAVE_GETPWUID -/* Define if you have the `getservbyname' function. */ -#undef HAVE_GETSERVBYNAME - /* Define if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY /* Define if you have the `timeval' struct. */ #define HAVE_STRUCT_TIMEVAL -/* Define if you have the `inet_addr' function. */ -#undef HAVE_INET_ADDR - /* Define if you have the <inttypes.h> header file. */ #define HAVE_INTTYPES_H /* Define if you have the <io.h> header file. */ #undef HAVE_IO_H -/* Define if you have the `krb_get_our_ip_for_realm' function. */ -#undef HAVE_KRB_GET_OUR_IP_FOR_REALM - -/* Define if you have the <krb.h> header file. */ -#undef HAVE_KRB_H - -/* Define if you have the `nsl' library (-lnsl). */ -#undef HAVE_LIBNSL - -/* Define if you have the `resolv' library (-lresolv). */ -#undef HAVE_LIBRESOLV - -/* Define if you have the `resolve' library (-lresolve). */ -#undef HAVE_LIBRESOLVE - /* Define if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET -/* Define if you have the `ucb' library (-lucb). */ -#undef HAVE_LIBUCB - -/* Define if you have the `localtime_r' function. */ -#undef HAVE_LOCALTIME_R - -/* Define if you have the <malloc.h> header file. */ -#define HAVE_MALLOC_H - /* Define if you need the malloc.h header file even with stdlib.h */ /* #define NEED_MALLOC_H 1 */ -/* Define if you have the <memory.h> header file. */ -#undef HAVE_MEMORY_H - /* Define if you have the <netdb.h> header file. */ #define HAVE_NETDB_H -/* Define if you have the <netinet/if_ether.h> header file. */ -#undef HAVE_NETINET_IF_ETHER_H - /* Define if you have the <netinet/in.h> header file. */ #define HAVE_NETINET_IN_H /* Define if you have the <net/if.h> header file. */ #define HAVE_NET_IF_H -/* Define if you have the <openssl/crypto.h> header file. */ -#undef HAVE_OPENSSL_CRYPTO_H - -/* Define if you have the <openssl/err.h> header file. */ -#undef HAVE_OPENSSL_ERR_H - -/* Define if you have the <openssl/pem.h> header file. */ -#undef HAVE_OPENSSL_PEM_H - -/* Define if you have the <openssl/rsa.h> header file. */ -#undef HAVE_OPENSSL_RSA_H - -/* Define if you have the <openssl/ssl.h> header file. */ -#undef HAVE_OPENSSL_SSL_H - -/* Define if you have the <openssl/x509.h> header file. */ -#undef HAVE_OPENSSL_X509_H - -/* Define if you have the <pem.h> header file. */ -#undef HAVE_PEM_H - /* Define if you have the <pwd.h> header file. */ #undef HAVE_PWD_H /* Define if you have the `RAND_egd' function. */ #undef HAVE_RAND_EGD -/* Define if you have the `RAND_screen' function. */ -#undef HAVE_RAND_SCREEN - -/* Define if you have the `RAND_status' function. */ -#undef HAVE_RAND_STATUS - /* Define if you have the `select' function. */ #define HAVE_SELECT -/* Define if you have the `setvbuf' function. */ -#undef HAVE_SETVBUF - /* Define if you have the `sigaction' function. */ #undef HAVE_SIGACTION @@ -250,9 +172,6 @@ /* Define if you have the `strdup' function. */ #define HAVE_STRDUP -/* Define if you have the `strftime' function. */ -#define HAVE_STRFTIME - /* Define if you have the `stricmp' function. */ #define HAVE_STRICMP @@ -262,9 +181,6 @@ /* Define if you have the <string.h> header file. */ #define HAVE_STRING_H -/* Define if you have the `strstr' function. */ -#define HAVE_STRSTR - /* Define if you have the `strtok_r' function. */ #undef HAVE_STRTOK_R @@ -301,30 +217,18 @@ /* Define if you have the <time.h> header file. */ #undef HAVE_TIME_H -/* Define if you have the `uname' function. */ -#define HAVE_UNAME - /* Define if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H -/* Define if you have the <x509.h> header file. */ -#undef HAVE_X509_H - /* Name of package */ #undef PACKAGE /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 -/* The size of `long double', as computed by sizeof. */ -#undef SIZEOF_LONG_DOUBLE - /* The size of `long long', as computed by sizeof. */ #undef SIZEOF_LONG_LONG -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 @@ -359,9 +263,6 @@ /* Define to `int' if <sys/types.h> does not define. */ #undef ssize_t -/* Define if you have the ioctl function. */ -#define HAVE_IOCTL - /* Define if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO @@ -386,33 +287,6 @@ /* Define to the function return type for recv. */ #define RECV_TYPE_RETV ssize_t -/* Define 1 if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 int - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 void - -/* Define if the type pointed by arg 2 for recvfrom is void. */ -#define RECVFROM_TYPE_ARG2_IS_VOID - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 size_t - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV ssize_t - /* Define if you have the send function. */ #define HAVE_SEND 1 diff --git a/libs/libcurl/src/config-win32.h b/libs/libcurl/src/config-win32.h index 824b9beebb..00e8663d2f 100644 --- a/libs/libcurl/src/config-win32.h +++ b/libs/libcurl/src/config-win32.h @@ -44,11 +44,6 @@ /* Define if you have the <fcntl.h> header file. */ #define HAVE_FCNTL_H 1 -/* Define if you have the <getopt.h> header file. */ -#if defined(__MINGW32__) || defined(__POCC__) -#define HAVE_GETOPT_H 1 -#endif - /* Define to 1 if you have the <inttypes.h> header file. */ #if defined(_MSC_VER) && (_MSC_VER >= 1800) #define HAVE_INTTYPES_H 1 @@ -83,7 +78,8 @@ /* #define HAVE_SSL_H 1 */ /* Define to 1 if you have the <stdbool.h> header file. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1800) +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || \ + defined(__MINGW64_VERSION_MAJOR) #define HAVE_STDBOOL_H 1 #endif @@ -143,6 +139,17 @@ #define HAVE_WS2TCPIP_H 1 #endif +/* Define to 1 if you have the <setjmp.h> header file. */ +#define HAVE_SETJMP_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <libgen.h> header file. */ +#if defined(__MINGW64_VERSION_MAJOR) +#define HAVE_LIBGEN_H 1 +#endif + /* ---------------------------------------------------------------- */ /* OTHER HEADER INFO */ /* ---------------------------------------------------------------- */ @@ -154,7 +161,8 @@ /* #define TIME_WITH_SYS_TIME 1 */ /* Define to 1 if bool is an available type. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1800) +#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || \ + defined(__MINGW64_VERSION_MAJOR) #define HAVE_BOOL_T 1 #endif @@ -165,11 +173,10 @@ /* Define if you have the closesocket function. */ #define HAVE_CLOSESOCKET 1 -/* Define if you don't have vprintf but do have _doprnt. */ -/* #define HAVE_DOPRNT 1 */ - /* Define if you have the ftruncate function. */ -/* #define HAVE_FTRUNCATE 1 */ +#if defined(__MINGW64_VERSION_MAJOR) +#define HAVE_FTRUNCATE 1 +#endif /* Define to 1 if you have the `getpeername' function. */ #define HAVE_GETPEERNAME 1 @@ -180,37 +187,15 @@ /* Define if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 -/* Define if you have the getpass function. */ -/* #define HAVE_GETPASS 1 */ - -/* Define if you have the getservbyname function. */ -#define HAVE_GETSERVBYNAME 1 - -/* Define if you have the getprotobyname function. */ -#define HAVE_GETPROTOBYNAME - /* Define if you have the gettimeofday function. */ /* #define HAVE_GETTIMEOFDAY 1 */ -/* Define if you have the inet_addr function. */ -#define HAVE_INET_ADDR 1 - /* Define if you have the ioctlsocket function. */ #define HAVE_IOCTLSOCKET 1 /* Define if you have a working ioctlsocket FIONBIO function. */ #define HAVE_IOCTLSOCKET_FIONBIO 1 -/* Define if you have the RAND_screen function when using SSL. */ -#define HAVE_RAND_SCREEN 1 - -/* Define if you have the `RAND_status' function when using SSL. */ -#define HAVE_RAND_STATUS 1 - -/* Define if you have the `CRYPTO_cleanup_all_ex_data' function. - This is present in OpenSSL versions after 0.9.6b */ -#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 - /* Define if you have the select function. */ #define HAVE_SELECT 1 @@ -220,16 +205,9 @@ /* Define if you have the setmode function. */ #define HAVE_SETMODE 1 -/* Define if you have the setvbuf function. */ -#define HAVE_SETVBUF 1 - /* Define if you have the socket function. */ #define HAVE_SOCKET 1 -/* Define if libSSH2 is in use */ -#define USE_LIBSSH2 1 -#define HAVE_LIBSSH2_H 1 - /* Define if you have the strcasecmp function. */ #ifdef __MINGW32__ #define HAVE_STRCASECMP 1 @@ -238,18 +216,9 @@ /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 -/* Define if you have the strftime function. */ -#define HAVE_STRFTIME 1 - /* Define if you have the stricmp function. */ #define HAVE_STRICMP 1 -/* Define if you have the strnicmp function. */ -#define HAVE_STRNICMP 1 - -/* Define if you have the strstr function. */ -#define HAVE_STRSTR 1 - /* Define if you have the strtoll function. */ #if defined(__MINGW32__) || defined(__POCC__) || \ (defined(_MSC_VER) && (_MSC_VER >= 1800)) @@ -279,30 +248,6 @@ /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int -/* Define if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 SOCKET - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 char - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 int - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int - /* Define if you have the send function. */ #define HAVE_SEND 1 @@ -324,6 +269,31 @@ /* Define to the function return type for send. */ #define SEND_TYPE_RETV int +/* Define to 1 if you have the snprintf function. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +#define HAVE_SNPRINTF 1 +#endif + +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 /* Vista */ +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +#define HAVE_INET_NTOP 1 +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +#define HAVE_INET_PTON 1 +#endif + +/* Define to 1 if you have the `basename' function. */ +#if defined(__MINGW64_VERSION_MAJOR) +#define HAVE_BASENAME 1 +#endif + +/* Define to 1 if you have the strtok_r function. */ +#if defined(__MINGW64_VERSION_MAJOR) +#define HAVE_STRTOK_R 1 +#endif + +/* Define to 1 if you have the signal function. */ +#define HAVE_SIGNAL 1 + /* ---------------------------------------------------------------- */ /* TYPEDEF REPLACEMENTS */ /* ---------------------------------------------------------------- */ @@ -350,15 +320,9 @@ /* Define to the size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 -/* Define to the size of `long double', as computed by sizeof. */ -#define SIZEOF_LONG_DOUBLE 16 - /* Define to the size of `long long', as computed by sizeof. */ /* #define SIZEOF_LONG_LONG 8 */ -/* Define to the size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - /* Define to the size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 @@ -372,6 +336,11 @@ /* Define to the size of `curl_off_t', as computed by sizeof. */ #define SIZEOF_CURL_OFF_T 8 +/* Define to the size of `off_t', as computed by sizeof. */ +#ifndef SIZEOF_OFF_T +#define SIZEOF_OFF_T 8 +#endif + /* ---------------------------------------------------------------- */ /* BSD-style lwIP TCP/IP stack SPECIFIC */ /* ---------------------------------------------------------------- */ @@ -392,7 +361,6 @@ # undef SEND_TYPE_ARG3 # define HAVE_FREEADDRINFO # define HAVE_GETADDRINFO -# define HAVE_GETHOSTBYNAME # define HAVE_GETHOSTBYNAME_R # define HAVE_GETHOSTBYNAME_R_6 # define LWIP_POSIX_SOCKETS_IO_NAMES 0 @@ -583,11 +551,6 @@ Vista /* Define if struct sockaddr_in6 has the sin6_scope_id member. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 -#if defined(HAVE_WINSOCK2_H) && defined(_WIN32_WINNT) && \ - (_WIN32_WINNT >= 0x0600) -#define HAVE_STRUCT_POLLFD 1 -#endif - /* ---------------------------------------------------------------- */ /* LARGE FILE SUPPORT */ /* ---------------------------------------------------------------- */ @@ -612,6 +575,13 @@ Vista # define USE_WIN32_SMALL_FILES #endif +/* Number of bits in a file offset, on hosts where this is settable. */ +#if defined(USE_WIN32_LARGE_FILES) && defined(__MINGW64_VERSION_MAJOR) +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +#endif + /* ---------------------------------------------------------------- */ /* DNS RESOLVER SPECIALTY */ /* ---------------------------------------------------------------- */ @@ -637,7 +607,7 @@ Vista /* LDAP SUPPORT */ /* ---------------------------------------------------------------- */ -#if defined(CURL_HAS_NOVELL_LDAPSDK) || defined(CURL_HAS_MOZILLA_LDAPSDK) +#if defined(CURL_HAS_NOVELL_LDAPSDK) #undef USE_WIN32_LDAP #define HAVE_LDAP_SSL_H 1 #define HAVE_LDAP_URL_PARSE 1 @@ -654,9 +624,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 @@ -670,7 +637,7 @@ Vista /* ---------------------------------------------------------------- */ /* Define cpu-machine-OS */ -#undef OS +#if !defined(OS) #if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */ #define OS "i386-pc-win32" #elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */ @@ -684,6 +651,7 @@ Vista #else #define OS "unknown-pc-win32" #endif +#endif /* Name of package */ #define PACKAGE "curl" diff --git a/libs/libcurl/src/config-win32ce.h b/libs/libcurl/src/config-win32ce.h index 90f9eeae2f..308bfe9e0a 100644 --- a/libs/libcurl/src/config-win32ce.h +++ b/libs/libcurl/src/config-win32ce.h @@ -44,9 +44,6 @@ /* Define if you have the <fcntl.h> header file. */ #define HAVE_FCNTL_H 1 -/* Define if you have the <getopt.h> header file. */ -/* #define HAVE_GETOPT_H 1 */ - /* Define if you have the <io.h> header file. */ #define HAVE_IO_H 1 @@ -135,42 +132,21 @@ /* Define if you have the closesocket function. */ #define HAVE_CLOSESOCKET 1 -/* Define if you don't have vprintf but do have _doprnt. */ -/* #define HAVE_DOPRNT 1 */ - /* Define if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 -/* Define if you have the getpass function. */ -/* #define HAVE_GETPASS 1 */ - -/* Define if you have the getservbyname function. */ -#define HAVE_GETSERVBYNAME 1 - /* Define if you have the gettimeofday function. */ /* #define HAVE_GETTIMEOFDAY 1 */ -/* Define if you have the inet_addr function. */ -#define HAVE_INET_ADDR 1 - /* Define if you have the ioctlsocket function. */ #define HAVE_IOCTLSOCKET 1 /* Define if you have a working ioctlsocket FIONBIO function. */ #define HAVE_IOCTLSOCKET_FIONBIO 1 -/* Define if you have the RAND_screen function when using SSL */ -#define HAVE_RAND_SCREEN 1 - -/* Define if you have the `RAND_status' function when using SSL. */ -#define HAVE_RAND_STATUS 1 - /* Define if you have the select function. */ #define HAVE_SELECT 1 -/* Define if you have the setvbuf function. */ -#define HAVE_SETVBUF 1 - /* Define if you have the socket function. */ #define HAVE_SOCKET 1 @@ -180,18 +156,9 @@ /* Define if you have the strdup function. */ /* #define HAVE_STRDUP 1 */ -/* Define if you have the strftime function. */ -/* #define HAVE_STRFTIME 1 */ - /* Define if you have the stricmp function. */ /* #define HAVE_STRICMP 1 */ -/* Define if you have the strnicmp function. */ -/* #define HAVE_STRNICMP 1 */ - -/* Define if you have the strstr function. */ -#define HAVE_STRSTR 1 - /* Define if you have the strtoll function. */ #if defined(__MINGW32__) #define HAVE_STRTOLL 1 @@ -218,30 +185,6 @@ /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int -/* Define if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 SOCKET - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 char - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 int - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int - /* Define if you have the send function. */ #define HAVE_SEND 1 @@ -285,15 +228,9 @@ /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 -/* The size of `long double', as computed by sizeof. */ -#define SIZEOF_LONG_DOUBLE 16 - /* The size of `long long', as computed by sizeof. */ /* #define SIZEOF_LONG_LONG 8 */ -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - /* Define to the size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 diff --git a/libs/libcurl/src/conncache.c b/libs/libcurl/src/conncache.c index 2a399c8814..a557ac6dc9 100644 --- a/libs/libcurl/src/conncache.c +++ b/libs/libcurl/src/conncache.c @@ -498,7 +498,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data) conn = curr->ptr; if(!CONN_INUSE(conn) && !conn->bits.close && - !conn->bits.connect_only) { + !conn->connect_only) { /* Set higher score for the age passed since the connection was used */ score = Curl_timediff(now, conn->lastused); diff --git a/libs/libcurl/src/conncache.h b/libs/libcurl/src/conncache.h index 6ec2757433..94664bc357 100644 --- a/libs/libcurl/src/conncache.h +++ b/libs/libcurl/src/conncache.h @@ -31,6 +31,7 @@ * be shared. */ +#include <curl/curl.h> #include "timeval.h" struct connectdata; diff --git a/libs/libcurl/src/connect.c b/libs/libcurl/src/connect.c index 424197234c..ac007c61b0 100644 --- a/libs/libcurl/src/connect.c +++ b/libs/libcurl/src/connect.c @@ -625,7 +625,8 @@ void Curl_persistconninfo(struct Curl_easy *data, struct connectdata *conn, else data->info.conn_local_ip[0] = 0; data->info.conn_scheme = conn->handler->scheme; - data->info.conn_protocol = conn->handler->protocol; + /* conn_protocol can only provide "old" protocols */ + data->info.conn_protocol = (conn->handler->protocol) & CURLPROTO_MASK; data->info.conn_primary_port = conn->port; data->info.conn_remote_port = conn->remote_port; data->info.conn_local_port = local_port; @@ -761,11 +762,10 @@ void Curl_updateconninfo(struct Curl_easy *data, struct connectdata *conn, char local_ip[MAX_IPADR_LEN] = ""; int local_port = -1; - if(conn->transport == TRNSPRT_TCP) { - if(!conn->bits.reuse && !conn->bits.tcp_fastopen) - Curl_conninfo_remote(data, conn, sockfd); - Curl_conninfo_local(data, sockfd, local_ip, &local_port); - } /* end of TCP-only section */ + if(!conn->bits.reuse && + (conn->transport != TRNSPRT_TCP || !conn->bits.tcp_fastopen)) + Curl_conninfo_remote(data, conn, sockfd); + Curl_conninfo_local(data, sockfd, local_ip, &local_port); /* persist connection info in session handle */ Curl_persistconninfo(data, conn, local_ip, local_port); @@ -903,6 +903,8 @@ CURLcode Curl_is_connected(struct Curl_easy *data, conn->tempsock[i] = CURL_SOCKET_BAD; post_SOCKS(data, conn, sockindex, connected); connkeep(conn, "HTTP/3 default"); + if(conn->tempsock[other] != CURL_SOCKET_BAD) + Curl_quic_disconnect(data, conn, other); return CURLE_OK; } /* When a QUIC connect attempt fails, the better error explanation is in @@ -1037,7 +1039,6 @@ CURLcode Curl_is_connected(struct Curl_easy *data, (conn->tempsock[1] == CURL_SOCKET_BAD)) { /* no more addresses to try */ const char *hostname; - char buffer[STRERROR_LEN]; CURLcode failreason = result; /* if the first address family runs out of addresses to try before the @@ -1064,11 +1065,7 @@ CURLcode Curl_is_connected(struct Curl_easy *data, "%" CURL_FORMAT_TIMEDIFF_T " ms: %s", hostname, conn->port, Curl_timediff(now, data->progress.t_startsingle), -#ifdef ENABLE_QUIC - (conn->transport == TRNSPRT_QUIC) ? - curl_easy_strerror(result) : -#endif - Curl_strerror(error, buffer, sizeof(buffer))); + curl_easy_strerror(result)); Curl_quic_disconnect(data, conn, 0); Curl_quic_disconnect(data, conn, 1); @@ -1200,6 +1197,7 @@ static CURLcode singleipconnect(struct Curl_easy *data, #ifdef TCP_FASTOPEN_CONNECT int optval = 1; #endif + const char *ipmsg; char buffer[STRERROR_LEN]; curl_socket_t *sockp = &conn->tempsock[tempindex]; *sockp = CURL_SOCKET_BAD; @@ -1217,7 +1215,13 @@ static CURLcode singleipconnect(struct Curl_easy *data, Curl_closesocket(data, conn, sockfd); return CURLE_OK; } - infof(data, " Trying %s:%d...", ipaddress, port); +#ifdef ENABLE_IPV6 + if(addr.family == AF_INET6) + ipmsg = " Trying [%s]:%d..."; + else +#endif + ipmsg = " Trying %s:%d..."; + infof(data, ipmsg, ipaddress, port); #ifdef ENABLE_IPV6 is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) && @@ -1604,9 +1608,20 @@ CURLcode Curl_socket(struct Curl_easy *data, */ addr->family = ai->ai_family; - addr->socktype = (conn->transport == TRNSPRT_TCP) ? SOCK_STREAM : SOCK_DGRAM; - addr->protocol = conn->transport != TRNSPRT_TCP ? IPPROTO_UDP : - ai->ai_protocol; + switch(conn->transport) { + case TRNSPRT_TCP: + addr->socktype = SOCK_STREAM; + addr->protocol = IPPROTO_TCP; + break; + case TRNSPRT_UNIX: + addr->socktype = SOCK_STREAM; + addr->protocol = IPPROTO_IP; + break; + default: /* UDP and QUIC */ + addr->socktype = SOCK_DGRAM; + addr->protocol = IPPROTO_UDP; + break; + } addr->addrlen = ai->ai_addrlen; if(addr->addrlen > sizeof(struct Curl_sockaddr_storage)) @@ -1667,20 +1682,6 @@ CURLcode Curl_socket(struct Curl_easy *data, } #endif -#if defined(__linux__) && defined(IP_RECVERR) - if(addr->socktype == SOCK_DGRAM) { - int one = 1; - switch(addr->family) { - case AF_INET: - (void)setsockopt(*sockfd, SOL_IP, IP_RECVERR, &one, sizeof(one)); - break; - case AF_INET6: - (void)setsockopt(*sockfd, SOL_IPV6, IPV6_RECVERR, &one, sizeof(one)); - break; - } - } -#endif - return CURLE_OK; } diff --git a/libs/libcurl/src/content_encoding.c b/libs/libcurl/src/content_encoding.c index 95ba48a2dd..bfc13e254d 100644 --- a/libs/libcurl/src/content_encoding.c +++ b/libs/libcurl/src/content_encoding.c @@ -28,7 +28,7 @@ #include <curl/curl.h> #include <stddef.h> -#ifdef HAVE_ZLIB_H +#ifdef HAVE_LIBZ #include <zlib.h> #endif @@ -82,8 +82,9 @@ typedef enum { ZLIB_INIT_GZIP /* initialized in transparent gzip mode */ } zlibInitState; -/* Writer parameters. */ -struct zlib_params { +/* Deflate and gzip writer. */ +struct zlib_writer { + struct contenc_writer super; zlibInitState zlib_init; /* zlib init state */ uInt trailerlen; /* Remaining trailer byte count. */ z_stream z; /* State structure for zlib. */ @@ -135,7 +136,7 @@ exit_zlib(struct Curl_easy *data, } static CURLcode process_trailer(struct Curl_easy *data, - struct zlib_params *zp) + struct zlib_writer *zp) { z_stream *z = &zp->z; CURLcode result = CURLE_OK; @@ -162,7 +163,7 @@ static CURLcode inflate_stream(struct Curl_easy *data, struct contenc_writer *writer, zlibInitState started) { - struct zlib_params *zp = (struct zlib_params *) &writer->params; + struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ uInt nread = z->avail_in; Bytef *orig_in = z->next_in; @@ -265,7 +266,7 @@ static CURLcode inflate_stream(struct Curl_easy *data, static CURLcode deflate_init_writer(struct Curl_easy *data, struct contenc_writer *writer) { - struct zlib_params *zp = (struct zlib_params *) &writer->params; + struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ if(!writer->downstream) @@ -285,7 +286,7 @@ static CURLcode deflate_unencode_write(struct Curl_easy *data, struct contenc_writer *writer, const char *buf, size_t nbytes) { - struct zlib_params *zp = (struct zlib_params *) &writer->params; + struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ /* Set the compressed input when this function is called */ @@ -302,7 +303,7 @@ static CURLcode deflate_unencode_write(struct Curl_easy *data, static void deflate_close_writer(struct Curl_easy *data, struct contenc_writer *writer) { - struct zlib_params *zp = (struct zlib_params *) &writer->params; + struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ exit_zlib(data, z, &zp->zlib_init, CURLE_OK); @@ -314,7 +315,7 @@ static const struct content_encoding deflate_encoding = { deflate_init_writer, deflate_unencode_write, deflate_close_writer, - sizeof(struct zlib_params) + sizeof(struct zlib_writer) }; @@ -322,7 +323,7 @@ static const struct content_encoding deflate_encoding = { static CURLcode gzip_init_writer(struct Curl_easy *data, struct contenc_writer *writer) { - struct zlib_params *zp = (struct zlib_params *) &writer->params; + struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ if(!writer->downstream) @@ -439,7 +440,7 @@ static CURLcode gzip_unencode_write(struct Curl_easy *data, struct contenc_writer *writer, const char *buf, size_t nbytes) { - struct zlib_params *zp = (struct zlib_params *) &writer->params; + struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ if(zp->zlib_init == ZLIB_INIT_GZIP) { @@ -566,7 +567,7 @@ static CURLcode gzip_unencode_write(struct Curl_easy *data, static void gzip_close_writer(struct Curl_easy *data, struct contenc_writer *writer) { - struct zlib_params *zp = (struct zlib_params *) &writer->params; + struct zlib_writer *zp = (struct zlib_writer *) writer; z_stream *z = &zp->z; /* zlib state structure */ exit_zlib(data, z, &zp->zlib_init, CURLE_OK); @@ -578,15 +579,16 @@ static const struct content_encoding gzip_encoding = { gzip_init_writer, gzip_unencode_write, gzip_close_writer, - sizeof(struct zlib_params) + sizeof(struct zlib_writer) }; #endif /* HAVE_LIBZ */ #ifdef HAVE_BROTLI -/* Writer parameters. */ -struct brotli_params { +/* Brotli writer. */ +struct brotli_writer { + struct contenc_writer super; BrotliDecoderState *br; /* State structure for brotli. */ }; @@ -631,7 +633,7 @@ static CURLcode brotli_map_error(BrotliDecoderErrorCode be) static CURLcode brotli_init_writer(struct Curl_easy *data, struct contenc_writer *writer) { - struct brotli_params *bp = (struct brotli_params *) &writer->params; + struct brotli_writer *bp = (struct brotli_writer *) writer; (void) data; if(!writer->downstream) @@ -645,7 +647,7 @@ static CURLcode brotli_unencode_write(struct Curl_easy *data, struct contenc_writer *writer, const char *buf, size_t nbytes) { - struct brotli_params *bp = (struct brotli_params *) &writer->params; + struct brotli_writer *bp = (struct brotli_writer *) writer; const uint8_t *src = (const uint8_t *) buf; char *decomp; uint8_t *dst; @@ -692,7 +694,8 @@ static CURLcode brotli_unencode_write(struct Curl_easy *data, static void brotli_close_writer(struct Curl_easy *data, struct contenc_writer *writer) { - struct brotli_params *bp = (struct brotli_params *) &writer->params; + struct brotli_writer *bp = (struct brotli_writer *) writer; + (void) data; if(bp->br) { @@ -707,14 +710,15 @@ static const struct content_encoding brotli_encoding = { brotli_init_writer, brotli_unencode_write, brotli_close_writer, - sizeof(struct brotli_params) + sizeof(struct brotli_writer) }; #endif #ifdef HAVE_ZSTD -/* Writer parameters. */ -struct zstd_params { +/* Zstd writer. */ +struct zstd_writer { + struct contenc_writer super; ZSTD_DStream *zds; /* State structure for zstd. */ void *decomp; }; @@ -722,7 +726,8 @@ struct zstd_params { static CURLcode zstd_init_writer(struct Curl_easy *data, struct contenc_writer *writer) { - struct zstd_params *zp = (struct zstd_params *)&writer->params; + struct zstd_writer *zp = (struct zstd_writer *) writer; + (void)data; if(!writer->downstream) @@ -738,7 +743,7 @@ static CURLcode zstd_unencode_write(struct Curl_easy *data, const char *buf, size_t nbytes) { CURLcode result = CURLE_OK; - struct zstd_params *zp = (struct zstd_params *)&writer->params; + struct zstd_writer *zp = (struct zstd_writer *) writer; ZSTD_inBuffer in; ZSTD_outBuffer out; size_t errorCode; @@ -777,7 +782,8 @@ static CURLcode zstd_unencode_write(struct Curl_easy *data, static void zstd_close_writer(struct Curl_easy *data, struct contenc_writer *writer) { - struct zstd_params *zp = (struct zstd_params *)&writer->params; + struct zstd_writer *zp = (struct zstd_writer *) writer; + (void)data; if(zp->decomp) { @@ -796,7 +802,7 @@ static const struct content_encoding zstd_encoding = { zstd_init_writer, zstd_unencode_write, zstd_close_writer, - sizeof(struct zstd_params) + sizeof(struct zstd_writer) }; #endif @@ -829,7 +835,7 @@ static const struct content_encoding identity_encoding = { identity_init_writer, identity_unencode_write, identity_close_writer, - 0 + sizeof(struct contenc_writer) }; @@ -921,7 +927,7 @@ static const struct content_encoding client_encoding = { client_init_writer, client_unencode_write, client_close_writer, - 0 + sizeof(struct contenc_writer) }; @@ -964,7 +970,7 @@ static const struct content_encoding error_encoding = { error_init_writer, error_unencode_write, error_close_writer, - 0 + sizeof(struct contenc_writer) }; /* Create an unencoding writer stage using the given handler. */ @@ -973,8 +979,10 @@ new_unencoding_writer(struct Curl_easy *data, const struct content_encoding *handler, struct contenc_writer *downstream) { - size_t sz = offsetof(struct contenc_writer, params) + handler->paramsize; - struct contenc_writer *writer = (struct contenc_writer *)calloc(1, sz); + struct contenc_writer *writer; + + DEBUGASSERT(handler->writersize >= sizeof(struct contenc_writer)); + writer = (struct contenc_writer *) calloc(1, handler->writersize); if(writer) { writer->handler = handler; @@ -1044,7 +1052,7 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data, size_t namelen; /* Parse a single encoding name. */ - while(ISSPACE(*enclist) || *enclist == ',') + while(ISBLANK(*enclist) || *enclist == ',') enclist++; name = enclist; diff --git a/libs/libcurl/src/content_encoding.h b/libs/libcurl/src/content_encoding.h index 81bddd1be1..3c278cf727 100644 --- a/libs/libcurl/src/content_encoding.h +++ b/libs/libcurl/src/content_encoding.h @@ -28,7 +28,6 @@ struct contenc_writer { const struct content_encoding *handler; /* Encoding handler. */ struct contenc_writer *downstream; /* Downstream writer. */ - void *params; /* Encoding-specific storage (variable length). */ }; /* Content encoding writer. */ @@ -42,7 +41,7 @@ struct content_encoding { const char *buf, size_t nbytes); void (*close_writer)(struct Curl_easy *data, struct contenc_writer *writer); - size_t paramsize; + size_t writersize; }; diff --git a/libs/libcurl/src/cookie.c b/libs/libcurl/src/cookie.c index cb57b86387..8eaedeeb7f 100644 --- a/libs/libcurl/src/cookie.c +++ b/libs/libcurl/src/cookie.c @@ -442,6 +442,29 @@ static bool bad_domain(const char *domain) } /* + RFC 6265 section 4.1.1 says a server should accept this range: + + cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + + But Firefox and Chrome as of June 2022 accept space, comma and double-quotes + fine. The prime reason for filtering out control bytes is that some HTTP + servers return 400 for requests that contain such. +*/ +static int invalid_octets(const char *p) +{ + /* Reject all bytes \x01 - \x1f (*except* \x09, TAB) + \x7f */ + static const char badoctets[] = { + "\x01\x02\x03\x04\x05\x06\x07\x08\x0a" + "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" + "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f" + }; + size_t len; + /* scan for all the octets that are *not* in cookie-octet */ + len = strcspn(p, badoctets); + return (p[len] != '\0'); +} + +/* * Curl_cookie_add * * Add a single cookie line to the cookie keeping object. Be aware that @@ -514,7 +537,7 @@ Curl_cookie_add(struct Curl_easy *data, do { /* we have a <what>=<this> pair or a stand-alone word here */ name[0] = what[0] = 0; /* init the buffers */ - if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n=] =%" + if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\t\r\n=] =%" MAX_NAME_TXT "[^;\r\n]", name, what)) { /* @@ -568,6 +591,13 @@ Curl_cookie_add(struct Curl_easy *data, while(*whatptr && ISBLANK(*whatptr)) whatptr++; + /* Reject cookies with a TAB inside the content */ + if(strchr(whatptr, '\t')) { + freecookie(co); + infof(data, "cookie contains TAB, dropping"); + return NULL; + } + /* * Check if we have a reserved prefix set before anything else, as we * otherwise have to test for the prefix in both the cookie name and @@ -595,6 +625,11 @@ Curl_cookie_add(struct Curl_easy *data, badcookie = TRUE; break; } + if(invalid_octets(whatptr) || invalid_octets(name)) { + infof(data, "invalid octets in name/value, cookie dropped"); + badcookie = TRUE; + break; + } } else if(!len) { /* @@ -637,7 +672,7 @@ Curl_cookie_add(struct Curl_easy *data, break; } } - else if(strcasecompare("domain", name)) { + else if(strcasecompare("domain", name) && whatptr[0]) { bool is_ip; /* @@ -1436,7 +1471,7 @@ struct Cookie *Curl_cookie_getlist(struct Curl_easy *data, matches++; if(matches >= MAX_COOKIE_SEND_AMOUNT) { - infof(data, "Included max number of cookies (%u) in request!", + infof(data, "Included max number of cookies (%zu) in request!", matches); break; } diff --git a/libs/libcurl/src/curl_addrinfo.c b/libs/libcurl/src/curl_addrinfo.c index d5d11113f4..72e778b34e 100644 --- a/libs/libcurl/src/curl_addrinfo.c +++ b/libs/libcurl/src/curl_addrinfo.c @@ -279,7 +279,7 @@ Curl_he2ai(const struct hostent *he, int port) for(i = 0; (curr = he->h_addr_list[i]) != NULL; i++) { size_t ss_size; - size_t namelen = strlen(he->h_name) + 1; /* include zero termination */ + size_t namelen = strlen(he->h_name) + 1; /* include null-terminatior */ #ifdef ENABLE_IPV6 if(he->h_addrtype == AF_INET6) ss_size = sizeof(struct sockaddr_in6); diff --git a/libs/libcurl/src/curl_config.h.cmake b/libs/libcurl/src/curl_config.h.cmake index eb2c62b971..3ba14923cd 100644 --- a/libs/libcurl/src/curl_config.h.cmake +++ b/libs/libcurl/src/curl_config.h.cmake @@ -23,9 +23,6 @@ ***************************************************************************/ /* lib/curl_config.h.in. Generated somehow by cmake. */ -/* when building libcurl itself */ -#cmakedefine BUILDING_LIBCURL 1 - /* Location of default ca bundle */ #cmakedefine CURL_CA_BUNDLE "${CURL_CA_BUNDLE}" @@ -147,9 +144,6 @@ /* Define to 1 if you have the alarm function. */ #cmakedefine HAVE_ALARM 1 -/* Define to 1 if you have the <alloca.h> header file. */ -#cmakedefine HAVE_ALLOCA_H 1 - /* Define to 1 if you have the <arpa/inet.h> header file. */ #cmakedefine HAVE_ARPA_INET_H 1 @@ -159,6 +153,9 @@ /* Define to 1 if you have the <assert.h> header file. */ #cmakedefine HAVE_ASSERT_H 1 +/* Define to 1 if you have _Atomic support. */ +#cmakedefine HAVE_ATOMIC 1 + /* Define to 1 if you have the `fchmod' function. */ #cmakedefine HAVE_FCHMOD 1 @@ -177,12 +174,6 @@ /* Define to 1 if you have the `closesocket' function. */ #cmakedefine HAVE_CLOSESOCKET 1 -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ -#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#cmakedefine HAVE_DLFCN_H 1 - /* Define to 1 if you have the <errno.h> header file. */ #cmakedefine HAVE_ERRNO_H 1 @@ -204,15 +195,15 @@ /* Define to 1 if you have a working getaddrinfo function. */ #cmakedefine HAVE_GETADDRINFO 1 +/* Define to 1 if the getaddrinfo function is threadsafe. */ +#cmakedefine HAVE_GETADDRINFO_THREADSAFE 1 + /* Define to 1 if you have the `geteuid' function. */ #cmakedefine HAVE_GETEUID 1 /* Define to 1 if you have the `getppid' function. */ #cmakedefine HAVE_GETPPID 1 -/* Define to 1 if you have the gethostbyname function. */ -#cmakedefine HAVE_GETHOSTBYNAME 1 - /* Define to 1 if you have the gethostbyname_r function. */ #cmakedefine HAVE_GETHOSTBYNAME_R 1 @@ -237,9 +228,6 @@ /* Define to 1 if you have the `getppid' function. */ #cmakedefine HAVE_GETPPID 1 -/* Define to 1 if you have the `getprotobyname' function. */ -#cmakedefine HAVE_GETPROTOBYNAME 1 - /* Define to 1 if you have the `getpeername' function. */ #cmakedefine HAVE_GETPEERNAME 1 @@ -291,18 +279,9 @@ /* Define to 1 if you have the `idna_strerror' function. */ #cmakedefine HAVE_IDNA_STRERROR 1 -/* Define to 1 if you have the `idn_free' function. */ -#cmakedefine HAVE_IDN_FREE 1 - -/* Define to 1 if you have the <idn-free.h> header file. */ -#cmakedefine HAVE_IDN_FREE_H 1 - /* Define to 1 if you have the <ifaddrs.h> header file. */ #cmakedefine HAVE_IFADDRS_H 1 -/* Define to 1 if you have the `inet_addr' function. */ -#cmakedefine HAVE_INET_ADDR 1 - /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #cmakedefine HAVE_INET_NTOP 1 @@ -318,9 +297,6 @@ /* Define to 1 if you have the <inttypes.h> header file. */ #cmakedefine HAVE_INTTYPES_H 1 -/* Define to 1 if you have the ioctl function. */ -#cmakedefine HAVE_IOCTL 1 - /* Define to 1 if you have the ioctlsocket function. */ #cmakedefine HAVE_IOCTLSOCKET 1 @@ -343,21 +319,9 @@ /* Define to 1 if you have the <io.h> header file. */ #cmakedefine HAVE_IO_H 1 -/* if you have the Kerberos4 libraries (including -ldes) */ -#cmakedefine HAVE_KRB4 1 - -/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ -#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM 1 - -/* Define to 1 if you have the <krb.h> header file. */ -#cmakedefine HAVE_KRB_H 1 - /* Define to 1 if you have the lber.h header file. */ #cmakedefine HAVE_LBER_H 1 -/* Define to 1 if you have the ldapssl.h header file. */ -#cmakedefine HAVE_LDAPSSL_H 1 - /* Define to 1 if you have the ldap.h header file. */ #cmakedefine HAVE_LDAP_H 1 @@ -379,30 +343,12 @@ /* Define to 1 if you have the idn2.h header file. */ #cmakedefine HAVE_IDN2_H 1 -/* Define to 1 if you have the `resolv' library (-lresolv). */ -#cmakedefine HAVE_LIBRESOLV 1 - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -#cmakedefine HAVE_LIBRESOLVE 1 - /* Define to 1 if you have the `socket' library (-lsocket). */ #cmakedefine HAVE_LIBSOCKET 1 -/* Define to 1 if you have the `psl' library (-lpsl). */ -#cmakedefine HAVE_LIBPSL 1 - -/* Define to 1 if you have the <libpsl.h> header file. */ -#cmakedefine HAVE_LIBPSL_H 1 - /* Define to 1 if you have the `ssh2' library (-lssh2). */ #cmakedefine HAVE_LIBSSH2 1 -/* Define to 1 if you have the <libssh2.h> header file. */ -#cmakedefine HAVE_LIBSSH2_H 1 - -/* Define to 1 if you have the <libssh/libssh.h> header file. */ -#cmakedefine HAVE_LIBSSH_LIBSSH_H 1 - /* if zlib is available */ #cmakedefine HAVE_LIBZ 1 @@ -412,24 +358,12 @@ /* if zstd is available */ #cmakedefine HAVE_ZSTD 1 -/* if your compiler supports LL */ -#cmakedefine HAVE_LL 1 - /* Define to 1 if you have the <locale.h> header file. */ #cmakedefine HAVE_LOCALE_H 1 -/* Define to 1 if you have a working localtime_r function. */ -#cmakedefine HAVE_LOCALTIME_R 1 - /* Define to 1 if the compiler supports the 'long long' data type. */ #cmakedefine HAVE_LONGLONG 1 -/* Define to 1 if you have the malloc.h header file. */ -#cmakedefine HAVE_MALLOC_H 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#cmakedefine HAVE_MEMORY_H 1 - /* Define to 1 if you have the MSG_NOSIGNAL flag. */ #cmakedefine HAVE_MSG_NOSIGNAL 1 @@ -448,42 +382,12 @@ /* Define to 1 if you have the <net/if.h> header file. */ #cmakedefine HAVE_NET_IF_H 1 -/* Define to 1 if NI_WITHSCOPEID exists and works. */ -#cmakedefine HAVE_NI_WITHSCOPEID 1 - /* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */ #cmakedefine HAVE_OLD_GSSMIT 1 -/* Define to 1 if you have the <openssl/crypto.h> header file. */ -#cmakedefine HAVE_OPENSSL_CRYPTO_H 1 - -/* Define to 1 if you have the <openssl/err.h> header file. */ -#cmakedefine HAVE_OPENSSL_ERR_H 1 - -/* Define to 1 if you have the <openssl/pem.h> header file. */ -#cmakedefine HAVE_OPENSSL_PEM_H 1 - -/* Define to 1 if you have the <openssl/pkcs12.h> header file. */ -#cmakedefine HAVE_OPENSSL_PKCS12_H 1 - -/* Define to 1 if you have the <openssl/rsa.h> header file. */ -#cmakedefine HAVE_OPENSSL_RSA_H 1 - -/* Define to 1 if you have the <openssl/ssl.h> header file. */ -#cmakedefine HAVE_OPENSSL_SSL_H 1 - -/* Define to 1 if you have the <openssl/x509.h> header file. */ -#cmakedefine HAVE_OPENSSL_X509_H 1 - -/* Define to 1 if you have the <pem.h> header file. */ -#cmakedefine HAVE_PEM_H 1 - /* Define to 1 if you have the `pipe' function. */ #cmakedefine HAVE_PIPE 1 -/* Define to 1 if you have a working poll function. */ -#cmakedefine HAVE_POLL 1 - /* If you have a fine poll */ #cmakedefine HAVE_POLL_FINE 1 @@ -502,18 +406,9 @@ /* Define to 1 if you have the `RAND_egd' function. */ #cmakedefine HAVE_RAND_EGD 1 -/* Define to 1 if you have the `RAND_screen' function. */ -#cmakedefine HAVE_RAND_SCREEN 1 - -/* Define to 1 if you have the `RAND_status' function. */ -#cmakedefine HAVE_RAND_STATUS 1 - /* Define to 1 if you have the recv function. */ #cmakedefine HAVE_RECV 1 -/* Define to 1 if you have the recvfrom function. */ -#cmakedefine HAVE_RECVFROM 1 - /* Define to 1 if you have the select function. */ #cmakedefine HAVE_SELECT 1 @@ -541,9 +436,6 @@ /* Define to 1 if you have the `setrlimit' function. */ #cmakedefine HAVE_SETRLIMIT 1 -/* Define to 1 if you have the setsockopt function. */ -#cmakedefine HAVE_SETSOCKOPT 1 - /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ #cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1 @@ -568,27 +460,27 @@ /* Define to 1 if you have the `socket' function. */ #cmakedefine HAVE_SOCKET 1 +/* Define to 1 if you have the socketpair function. */ +#cmakedefine HAVE_SOCKETPAIR 1 + /* Define to 1 if you have the <ssl.h> header file. */ #cmakedefine HAVE_SSL_H 1 +/* Define to 1 if you have the <stdatomic.h> header file. */ +#cmakedefine HAVE_STDATOMIC_H 1 + /* Define to 1 if you have the <stdbool.h> header file. */ #cmakedefine HAVE_STDBOOL_H 1 /* Define to 1 if you have the <stdint.h> header file. */ #cmakedefine HAVE_STDINT_H 1 -/* Define to 1 if you have the <stdio.h> header file. */ -#cmakedefine HAVE_STDIO_H 1 - /* Define to 1 if you have the <stdlib.h> header file. */ #cmakedefine HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #cmakedefine HAVE_STRCASECMP 1 -/* Define to 1 if you have the strcasestr function. */ -#cmakedefine HAVE_STRCASESTR 1 - /* Define to 1 if you have the strcmpi function. */ #cmakedefine HAVE_STRCMPI 1 @@ -607,18 +499,9 @@ /* Define to 1 if you have the <string.h> header file. */ #cmakedefine HAVE_STRING_H 1 -/* Define to 1 if you have the strncmpi function. */ -#cmakedefine HAVE_STRNCMPI 1 - -/* Define to 1 if you have the strnicmp function. */ -#cmakedefine HAVE_STRNICMP 1 - /* Define to 1 if you have the <stropts.h> header file. */ #cmakedefine HAVE_STROPTS_H 1 -/* Define to 1 if you have the strstr function. */ -#cmakedefine HAVE_STRSTR 1 - /* Define to 1 if you have the strtok_r function. */ #cmakedefine HAVE_STRTOK_R 1 @@ -664,9 +547,6 @@ /* Define to 1 if you have the <sys/types.h> header file. */ #cmakedefine HAVE_SYS_TYPES_H 1 -/* Define to 1 if you have the <sys/uio.h> header file. */ -#cmakedefine HAVE_SYS_UIO_H 1 - /* Define to 1 if you have the <sys/un.h> header file. */ #cmakedefine HAVE_SYS_UN_H 1 @@ -682,15 +562,6 @@ /* Define to 1 if you have the <time.h> header file. */ #cmakedefine HAVE_TIME_H 1 -/* Define to 1 if you have the <tld.h> header file. */ -#cmakedefine HAVE_TLD_H 1 - -/* Define to 1 if you have the `tld_strerror' function. */ -#cmakedefine HAVE_TLD_STRERROR 1 - -/* Define to 1 if you have the `uname' function. */ -#cmakedefine HAVE_UNAME 1 - /* Define to 1 if you have the <unistd.h> header file. */ #cmakedefine HAVE_UNISTD_H 1 @@ -709,9 +580,6 @@ /* Define to 1 if compiler supports old gcc variadic macro style. */ #cmakedefine HAVE_VARIADIC_MACROS_GCC 1 -/* Define to 1 if you have the winber.h header file. */ -#cmakedefine HAVE_WINBER_H 1 - /* Define to 1 if you have the windows.h header file. */ #cmakedefine HAVE_WINDOWS_H 1 @@ -724,28 +592,12 @@ /* Define this symbol if your OS supports changing the contents of argv */ #cmakedefine HAVE_WRITABLE_ARGV 1 -/* Define to 1 if you have the writev function. */ -#cmakedefine HAVE_WRITEV 1 - /* Define to 1 if you have the ws2tcpip.h header file. */ #cmakedefine HAVE_WS2TCPIP_H 1 -/* Define to 1 if you have the <x509.h> header file. */ -#cmakedefine HAVE_X509_H 1 - /* Define if you have the <process.h> header file. */ #cmakedefine HAVE_PROCESS_H 1 -/* if you have the zlib.h header file */ -#cmakedefine HAVE_ZLIB_H 1 - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#cmakedefine LT_OBJDIR ${LT_OBJDIR} - -/* If you lack a fine basename() prototype */ -#cmakedefine NEED_BASENAME_PROTO 1 - /* Define to 1 if you need the lber.h header file even with ldap.h */ #cmakedefine NEED_LBER_H 1 @@ -779,84 +631,6 @@ /* a suitable file to read random data from */ #cmakedefine RANDOM_FILE "${RANDOM_FILE}" -/* Define to the type of arg 1 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG1 ${RECVFROM_TYPE_ARG1} - -/* Define to the type pointed by arg 2 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG2 ${RECVFROM_TYPE_ARG2} - -/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ -#cmakedefine RECVFROM_TYPE_ARG2_IS_VOID 1 - -/* Define to the type of arg 3 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG3 ${RECVFROM_TYPE_ARG3} - -/* Define to the type of arg 4 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG4 ${RECVFROM_TYPE_ARG4} - -/* Define to the type pointed by arg 5 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG5 ${RECVFROM_TYPE_ARG5} - -/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ -#cmakedefine RECVFROM_TYPE_ARG5_IS_VOID 1 - -/* Define to the type pointed by arg 6 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG6 ${RECVFROM_TYPE_ARG6} - -/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ -#cmakedefine RECVFROM_TYPE_ARG6_IS_VOID 1 - -/* Define to the function return type for recvfrom. */ -#cmakedefine RECVFROM_TYPE_RETV ${RECVFROM_TYPE_RETV} - -/* Define to the type of arg 1 for recv. */ -#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1} - -/* Define to the type of arg 2 for recv. */ -#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2} - -/* Define to the type of arg 3 for recv. */ -#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3} - -/* Define to the type of arg 4 for recv. */ -#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4} - -/* Define to the function return type for recv. */ -#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV} - -/* Define to the type qualifier of arg 5 for select. */ -#cmakedefine SELECT_QUAL_ARG5 ${SELECT_QUAL_ARG5} - -/* Define to the type of arg 1 for select. */ -#cmakedefine SELECT_TYPE_ARG1 ${SELECT_TYPE_ARG1} - -/* Define to the type of args 2, 3 and 4 for select. */ -#cmakedefine SELECT_TYPE_ARG234 ${SELECT_TYPE_ARG234} - -/* Define to the type of arg 5 for select. */ -#cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5} - -/* Define to the function return type for select. */ -#cmakedefine SELECT_TYPE_RETV ${SELECT_TYPE_RETV} - -/* Define to the type qualifier of arg 2 for send. */ -#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2} - -/* Define to the type of arg 1 for send. */ -#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1} - -/* Define to the type of arg 2 for send. */ -#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2} - -/* Define to the type of arg 3 for send. */ -#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3} - -/* Define to the type of arg 4 for send. */ -#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4} - -/* Define to the function return type for send. */ -#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV} - /* Note: SIZEOF_* variables are fetched with CMake through check_type_size(). As per CMake documentation on CheckTypeSize, C preprocessor code is @@ -869,9 +643,6 @@ /* The size of `int', as computed by sizeof. */ ${SIZEOF_INT_CODE} -/* The size of `short', as computed by sizeof. */ -${SIZEOF_SHORT_CODE} - /* The size of `long', as computed by sizeof. */ ${SIZEOF_LONG_CODE} @@ -890,9 +661,6 @@ ${SIZEOF_TIME_T_CODE} /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS 1 -/* Define to the type of arg 3 for strerror_r. */ -#cmakedefine STRERROR_R_TYPE_ARG3 ${STRERROR_R_TYPE_ARG3} - /* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ #cmakedefine TIME_WITH_SYS_TIME 1 @@ -981,9 +749,6 @@ ${SIZEOF_TIME_T_CODE} /* enable multiple SSL backends */ #cmakedefine CURL_WITH_MULTI_SSL 1 -/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */ -#cmakedefine USE_YASSLEMUL 1 - /* Version number of package */ #cmakedefine VERSION ${VERSION} @@ -1027,3 +792,6 @@ ${SIZEOF_TIME_T_CODE} /* to make the compiler know the prototypes of Windows IDN APIs */ #cmakedefine WANT_IDN_PROTOTYPES 1 + +/* Define to 1 to enable websocket support. */ +#cmakedefine USE_WEBSOCKETS 1 diff --git a/libs/libcurl/src/curl_config.h.in b/libs/libcurl/src/curl_config.h.in index e9dbf75734..06e1dd252a 100644 --- a/libs/libcurl/src/curl_config.h.in +++ b/libs/libcurl/src/curl_config.h.in @@ -141,9 +141,6 @@ /* Define to 1 if you have the alarm function. */ #undef HAVE_ALARM -/* Define to 1 if you have the <alloca.h> header file. */ -#undef HAVE_ALLOCA_H - /* Define to 1 if you have the <arpa/inet.h> header file. */ #undef HAVE_ARPA_INET_H @@ -340,9 +337,6 @@ /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H -/* Define to 1 if you have the ioctl function. */ -#undef HAVE_IOCTL - /* Define to 1 if you have the ioctlsocket function. */ #undef HAVE_IOCTLSOCKET @@ -356,27 +350,15 @@ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ #undef HAVE_IOCTLSOCKET_FIONBIO -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#undef HAVE_IOCTL_FIONBIO - -/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -#undef HAVE_IOCTL_SIOCGIFADDR - /* Define to 1 if you have the <io.h> header file. */ #undef HAVE_IO_H /* Define to 1 if you have the lber.h header file. */ #undef HAVE_LBER_H -/* Define to 1 if you have the ldapssl.h header file. */ -#undef HAVE_LDAPSSL_H - /* Define to 1 if you have the ldap.h header file. */ #undef HAVE_LDAP_H -/* Define to 1 if you have the `ldap_init_fd' function. */ -#undef HAVE_LDAP_INIT_FD - /* Use LDAPS implementation */ #undef HAVE_LDAP_SSL @@ -407,12 +389,6 @@ /* Define to 1 if you have the `ssh2' library (-lssh2). */ #undef HAVE_LIBSSH2 -/* Define to 1 if you have the <libssh2.h> header file. */ -#undef HAVE_LIBSSH2_H - -/* Define to 1 if you have the <libssh/libssh.h> header file. */ -#undef HAVE_LIBSSH_LIBSSH_H - /* Define to 1 if you have the `ssl' library (-lssl). */ #undef HAVE_LIBSSL @@ -428,27 +404,15 @@ /* Define to 1 if you have the <linux/tcp.h> header file. */ #undef HAVE_LINUX_TCP_H -/* if your compiler supports LL */ -#undef HAVE_LL - /* Define to 1 if you have the <locale.h> header file. */ #undef HAVE_LOCALE_H -/* Define to 1 if you have a working localtime_r function. */ -#undef HAVE_LOCALTIME_R - /* Define to 1 if the compiler supports the 'long long' data type. */ #undef HAVE_LONGLONG /* Define to 1 if you have the `mach_absolute_time' function. */ #undef HAVE_MACH_ABSOLUTE_TIME -/* Define to 1 if you have the malloc.h header file. */ -#undef HAVE_MALLOC_H - -/* Define to 1 if you have the memory.h header file. */ -#undef HAVE_MEMORY_H - /* Define to 1 if you have the memrchr function or macro. */ #undef HAVE_MEMRCHR @@ -526,9 +490,6 @@ /* if you have the PK11_CreateManagedGenericObject function */ #undef HAVE_PK11_CREATEMANAGEDGENERICOBJECT -/* Define to 1 if you have a working poll function. */ -#undef HAVE_POLL - /* If you have a fine poll */ #undef HAVE_POLL_FINE @@ -586,12 +547,6 @@ /* Define to 1 if you have the `setrlimit' function. */ #undef HAVE_SETRLIMIT -/* Define to 1 if you have the setsockopt function. */ -#undef HAVE_SETSOCKOPT - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -#undef HAVE_SETSOCKOPT_SO_NONBLOCK - /* Define to 1 if you have the sigaction function. */ #undef HAVE_SIGACTION @@ -607,6 +562,9 @@ /* Define to 1 if you have the sigsetjmp function or macro. */ #undef HAVE_SIGSETJMP +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + /* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ #undef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID @@ -625,6 +583,9 @@ /* Define to 1 if you have the <ssl.h> header file. */ #undef HAVE_SSL_H +/* Define to 1 if you have the <stdatomic.h> header file. */ +#undef HAVE_STDATOMIC_H + /* Define to 1 if you have the <stdbool.h> header file. */ #undef HAVE_STDBOOL_H @@ -658,18 +619,6 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H -/* Define to 1 if you have the strncmpi function. */ -#undef HAVE_STRNCMPI - -/* Define to 1 if you have the strnicmp function. */ -#undef HAVE_STRNICMP - -/* Define to 1 if you have the <stropts.h> header file. */ -#undef HAVE_STROPTS_H - -/* Define to 1 if you have the strstr function. */ -#undef HAVE_STRSTR - /* Define to 1 if you have the strtok_r function. */ #undef HAVE_STRTOK_R @@ -745,9 +694,6 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H -/* Define to 1 if you have the `usleep' function. */ -#undef HAVE_USLEEP - /* Define to 1 if you have the `utime' function. */ #undef HAVE_UTIME @@ -763,9 +709,6 @@ /* Define to 1 if compiler supports old gcc variadic macro style. */ #undef HAVE_VARIADIC_MACROS_GCC -/* Define to 1 if you have the winber.h header file. */ -#undef HAVE_WINBER_H - /* Define to 1 if you have the wincrypt.h header file. */ #undef HAVE_WINCRYPT_H @@ -793,18 +736,12 @@ /* Define this symbol if your OS supports changing the contents of argv */ #undef HAVE_WRITABLE_ARGV -/* Define to 1 if you have the writev function. */ -#undef HAVE_WRITEV - /* Define to 1 if you have the ws2tcpip.h header file. */ #undef HAVE_WS2TCPIP_H /* Define to 1 if you have the <x509.h> header file. */ #undef HAVE_X509_H -/* if you have the zlib.h header file */ -#undef HAVE_ZLIB_H - /* if libzstd is in use */ #undef HAVE_ZSTD @@ -817,12 +754,6 @@ /* Define to 1 if you need the lber.h header file even with ldap.h */ #undef NEED_LBER_H -/* Define to 1 if you need the malloc.h header file even with stdlib.h */ -#undef NEED_MALLOC_H - -/* Define to 1 if you need the memory.h header file even with stdlib.h */ -#undef NEED_MEMORY_H - /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ #undef NEED_REENTRANT @@ -862,76 +793,25 @@ /* a suitable file to read random data from */ #undef RANDOM_FILE -/* Define to the type of arg 1 for recv. */ -#undef RECV_TYPE_ARG1 - -/* Define to the type of arg 2 for recv. */ -#undef RECV_TYPE_ARG2 - -/* Define to the type of arg 3 for recv. */ -#undef RECV_TYPE_ARG3 - -/* Define to the type of arg 4 for recv. */ -#undef RECV_TYPE_ARG4 - -/* Define to the function return type for recv. */ -#undef RECV_TYPE_RETV - -/* Define to the type qualifier of arg 5 for select. */ -#undef SELECT_QUAL_ARG5 - -/* Define to the type of arg 1 for select. */ -#undef SELECT_TYPE_ARG1 - -/* Define to the type of args 2, 3 and 4 for select. */ -#undef SELECT_TYPE_ARG234 - -/* Define to the type of arg 5 for select. */ -#undef SELECT_TYPE_ARG5 - -/* Define to the function return type for select. */ -#undef SELECT_TYPE_RETV - -/* Define to the type qualifier of arg 2 for send. */ -#undef SEND_QUAL_ARG2 - -/* Define to the type of arg 1 for send. */ -#undef SEND_TYPE_ARG1 - -/* Define to the type of arg 2 for send. */ -#undef SEND_TYPE_ARG2 - -/* Define to the type of arg 3 for send. */ -#undef SEND_TYPE_ARG3 - -/* Define to the type of arg 4 for send. */ -#undef SEND_TYPE_ARG4 - -/* Define to the function return type for send. */ -#undef SEND_TYPE_RETV - -/* The number of bytes in type curl_off_t */ +/* Size of curl_off_t in number of bytes */ #undef SIZEOF_CURL_OFF_T -/* The number of bytes in type int */ +/* Size of int in number of bytes */ #undef SIZEOF_INT -/* The number of bytes in type long */ +/* Size of long in number of bytes */ #undef SIZEOF_LONG -/* The number of bytes in type long long */ +/* Size of long long in number of bytes */ #undef SIZEOF_LONG_LONG -/* The number of bytes in type off_t */ +/* Size of off_t in number of bytes */ #undef SIZEOF_OFF_T -/* The number of bytes in type short */ -#undef SIZEOF_SHORT - -/* The number of bytes in type size_t */ +/* Size of size_t in number of bytes */ #undef SIZEOF_SIZE_T -/* The number of bytes in type time_t */ +/* Size of time_t in number of bytes */ #undef SIZEOF_TIME_T /* Define to 1 if all of the C90 standard headers exist (not just the ones @@ -939,9 +819,6 @@ backward compatibility; new code need not use it. */ #undef STDC_HEADERS -/* Define to the type of arg 3 for strerror_r. */ -#undef STRERROR_R_TYPE_ARG3 - /* if AmiSSL is in use */ #undef USE_AMISSL @@ -999,6 +876,9 @@ /* if ngtcp2_crypto_openssl is in use */ #undef USE_NGTCP2_CRYPTO_OPENSSL +/* if ngtcp2_crypto_wolfssl is in use */ +#undef USE_NGTCP2_CRYPTO_WOLFSSL + /* if NSS is enabled */ #undef USE_NSS @@ -1032,6 +912,9 @@ /* Use Unix domain sockets */ #undef USE_UNIX_SOCKETS +/* enable websockets support */ +#undef USE_WEBSOCKETS + /* Define to 1 if you are building a Windows target with crypto API support. */ #undef USE_WIN32_CRYPTO diff --git a/libs/libcurl/src/curl_ctype.c b/libs/libcurl/src/curl_ctype.c deleted file mode 100644 index e1a8445151..0000000000 --- a/libs/libcurl/src/curl_ctype.c +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#include "curl_setup.h" - -#undef _U -#define _U (1<<0) /* upper case */ -#undef _L -#define _L (1<<1) /* lower case */ -#undef _N -#define _N (1<<2) /* decimal numerical digit */ -#undef _S -#define _S (1<<3) /* space */ -#undef _P -#define _P (1<<4) /* punctuation */ -#undef _C -#define _C (1<<5) /* control */ -#undef _X -#define _X (1<<6) /* hexadecimal letter */ -#undef _B -#define _B (1<<7) /* blank */ - -static const unsigned char ascii[128] = { - _C, _C, _C, _C, _C, _C, _C, _C, - _C, _C|_S, _C|_S, _C|_S, _C|_S, _C|_S, _C, _C, - _C, _C, _C, _C, _C, _C, _C, _C, - _C, _C, _C, _C, _C, _C, _C, _C, - _S|_B, _P, _P, _P, _P, _P, _P, _P, - _P, _P, _P, _P, _P, _P, _P, _P, - _N, _N, _N, _N, _N, _N, _N, _N, - _N, _N, _P, _P, _P, _P, _P, _P, - _P, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U|_X, _U, - _U, _U, _U, _U, _U, _U, _U, _U, - _U, _U, _U, _U, _U, _U, _U, _U, - _U, _U, _U, _P, _P, _P, _P, _P, - _P, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L|_X, _L, - _L, _L, _L, _L, _L, _L, _L, _L, - _L, _L, _L, _L, _L, _L, _L, _L, - _L, _L, _L, _P, _P, _P, _P, _C -}; - -int Curl_isspace(int c) -{ - if((c < 0) || (c >= 0x80)) - return FALSE; - return (ascii[c] & _S); -} - -int Curl_isdigit(int c) -{ - if((c < 0) || (c >= 0x80)) - return FALSE; - return (ascii[c] & _N); -} - -int Curl_isalnum(int c) -{ - if((c < 0) || (c >= 0x80)) - return FALSE; - return (ascii[c] & (_N|_U|_L)); -} - -int Curl_isxdigit(int c) -{ - if((c < 0) || (c >= 0x80)) - return FALSE; - return (ascii[c] & (_N|_X)); -} - -int Curl_isgraph(int c) -{ - if((c < 0) || (c >= 0x80) || (c == ' ')) - return FALSE; - return (ascii[c] & (_N|_X|_U|_L|_P|_S)); -} - -int Curl_isprint(int c) -{ - if((c < 0) || (c >= 0x80)) - return FALSE; - return (ascii[c] & (_N|_X|_U|_L|_P|_S)); -} - -int Curl_isalpha(int c) -{ - if((c < 0) || (c >= 0x80)) - return FALSE; - return (ascii[c] & (_U|_L)); -} - -int Curl_isupper(int c) -{ - if((c < 0) || (c >= 0x80)) - return FALSE; - return (ascii[c] & (_U)); -} - -int Curl_islower(int c) -{ - if((c < 0) || (c >= 0x80)) - return FALSE; - return (ascii[c] & (_L)); -} - -int Curl_iscntrl(int c) -{ - if((c < 0) || (c >= 0x80)) - return FALSE; - return (ascii[c] & (_C)); -} - diff --git a/libs/libcurl/src/curl_ctype.h b/libs/libcurl/src/curl_ctype.h index c70945a8d2..dc6b8cab86 100644 --- a/libs/libcurl/src/curl_ctype.h +++ b/libs/libcurl/src/curl_ctype.h @@ -24,32 +24,24 @@ * ***************************************************************************/ -#include "curl_setup.h" +#define ISLOWHEXALHA(x) (((x) >= 'a') && ((x) <= 'f')) +#define ISUPHEXALHA(x) (((x) >= 'A') && ((x) <= 'F')) -int Curl_isspace(int c); -int Curl_isdigit(int c); -int Curl_isalnum(int c); -int Curl_isxdigit(int c); -int Curl_isgraph(int c); -int Curl_isprint(int c); -int Curl_isalpha(int c); -int Curl_isupper(int c); -int Curl_islower(int c); -int Curl_iscntrl(int c); +#define ISLOWCNTRL(x) ((x) >= 0 && ((x) <= 0x1f)) +#define IS7F(x) ((x) == 0x7f) -#define ISSPACE(x) (Curl_isspace((int) ((unsigned char)x))) -#define ISDIGIT(x) (Curl_isdigit((int) ((unsigned char)x))) -#define ISALNUM(x) (Curl_isalnum((int) ((unsigned char)x))) -#define ISXDIGIT(x) (Curl_isxdigit((int) ((unsigned char)x))) -#define ISGRAPH(x) (Curl_isgraph((int) ((unsigned char)x))) -#define ISALPHA(x) (Curl_isalpha((int) ((unsigned char)x))) -#define ISPRINT(x) (Curl_isprint((int) ((unsigned char)x))) -#define ISUPPER(x) (Curl_isupper((int) ((unsigned char)x))) -#define ISLOWER(x) (Curl_islower((int) ((unsigned char)x))) -#define ISCNTRL(x) (Curl_iscntrl((int) ((unsigned char)x))) -#define ISASCII(x) (((x) >= 0) && ((x) <= 0x80)) +#define ISLOWPRINT(x) (((x) >= 9) && ((x) <= 0x0d)) -#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \ - (((unsigned char)x) == '\t')) +#define ISPRINT(x) (ISLOWPRINT(x) || (((x) >= ' ') && ((x) <= 0x7e))) +#define ISGRAPH(x) (ISLOWPRINT(x) || (((x) > ' ') && ((x) <= 0x7e))) +#define ISCNTRL(x) (ISLOWCNTRL(x) || IS7F(x)) +#define ISALPHA(x) (ISLOWER(x) || ISUPPER(x)) +#define ISXDIGIT(x) (ISDIGIT(x) || ISLOWHEXALHA(x) || ISUPHEXALHA(x)) +#define ISALNUM(x) (ISDIGIT(x) || ISLOWER(x) || ISUPPER(x)) +#define ISUPPER(x) (((x) >= 'A') && ((x) <= 'Z')) +#define ISLOWER(x) (((x) >= 'a') && ((x) <= 'z')) +#define ISDIGIT(x) (((x) >= '0') && ((x) <= '9')) +#define ISBLANK(x) (((x) == ' ') || ((x) == '\t')) +#define ISSPACE(x) (ISBLANK(x) || (((x) >= 0xa) && ((x) <= 0x0d))) #endif /* HEADER_CURL_CTYPE_H */ diff --git a/libs/libcurl/src/curl_des.c b/libs/libcurl/src/curl_des.c index 6d52cd3635..a2bf648c29 100644 --- a/libs/libcurl/src/curl_des.c +++ b/libs/libcurl/src/curl_des.c @@ -41,7 +41,7 @@ * * The function is a port of the Java based oddParity() function over at: * - * https://davenport.sourceforge.io/ntlm.html + * https://davenport.sourceforge.net/ntlm.html * * Parameters: * diff --git a/libs/libcurl/src/curl_get_line.c b/libs/libcurl/src/curl_get_line.c index 6a26bb254f..22e3705f4c 100644 --- a/libs/libcurl/src/curl_get_line.c +++ b/libs/libcurl/src/curl_get_line.c @@ -25,7 +25,7 @@ #include "curl_setup.h" #if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \ - !defined(CURL_DISABLE_HSTS) + !defined(CURL_DISABLE_HSTS) || !defined(CURL_DISABLE_NETRC) #include "curl_get_line.h" #include "curl_memory.h" @@ -33,8 +33,8 @@ #include "memdebug.h" /* - * get_line() makes sure to only return complete whole lines that fit in 'len' - * bytes and end with a newline. + * Curl_get_line() makes sure to only return complete whole lines that fit in + * 'len' bytes and end with a newline. */ char *Curl_get_line(char *buf, int len, FILE *input) { diff --git a/libs/libcurl/src/curl_hmac.h b/libs/libcurl/src/curl_hmac.h index 77dce0f165..36c0bd62e5 100644 --- a/libs/libcurl/src/curl_hmac.h +++ b/libs/libcurl/src/curl_hmac.h @@ -26,6 +26,8 @@ #ifndef CURL_DISABLE_CRYPTO_AUTH +#include <curl/curl.h> + #define HMAC_MD5_LENGTH 16 typedef CURLcode (* HMAC_hinit_func)(void *context); diff --git a/libs/libcurl/src/curl_ntlm_core.c b/libs/libcurl/src/curl_ntlm_core.c index eabb000d14..38e193c186 100644 --- a/libs/libcurl/src/curl_ntlm_core.c +++ b/libs/libcurl/src/curl_ntlm_core.c @@ -29,7 +29,7 @@ /* * NTLM details: * - * https://davenport.sourceforge.io/ntlm.html + * https://davenport.sourceforge.net/ntlm.html * https://www.innovation.ch/java/ntlm.html */ @@ -60,17 +60,17 @@ #if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) -#ifdef USE_WOLFSSL +#if defined(USE_OPENSSL) +# include <openssl/des.h> +# include <openssl/md5.h> +# include <openssl/ssl.h> +# include <openssl/rand.h> +#else # include <wolfssl/options.h> # include <wolfssl/openssl/des.h> # include <wolfssl/openssl/md5.h> # include <wolfssl/openssl/ssl.h> # include <wolfssl/openssl/rand.h> -#else -# include <openssl/des.h> -# include <openssl/md5.h> -# include <openssl/ssl.h> -# include <openssl/rand.h> #endif # if (defined(OPENSSL_VERSION_NUMBER) && \ diff --git a/libs/libcurl/src/curl_ntlm_wb.c b/libs/libcurl/src/curl_ntlm_wb.c index f1eb9c6319..33dcf0ce25 100644 --- a/libs/libcurl/src/curl_ntlm_wb.c +++ b/libs/libcurl/src/curl_ntlm_wb.c @@ -30,7 +30,7 @@ /* * NTLM details: * - * https://davenport.sourceforge.io/ntlm.html + * https://davenport.sourceforge.net/ntlm.html * https://www.innovation.ch/java/ntlm.html */ diff --git a/libs/libcurl/src/curl_path.c b/libs/libcurl/src/curl_path.c index ba1b717231..b55e83047d 100644 --- a/libs/libcurl/src/curl_path.c +++ b/libs/libcurl/src/curl_path.c @@ -18,7 +18,7 @@ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * - * SPDX-License-Identifier: curl + * SPDX-License-Identifier: curl AND ISC * ***************************************************************************/ @@ -122,7 +122,8 @@ CURLcode Curl_get_pathname(const char **cpp, char **path, char *homedir) bool relativePath = false; static const char WHITESPACE[] = " \t\r\n"; - if(!*cp) { + DEBUGASSERT(homedir); + if(!*cp || !homedir) { *cpp = NULL; *path = NULL; return CURLE_QUOTE_ERROR; diff --git a/libs/libcurl/src/curl_range.c b/libs/libcurl/src/curl_range.c index 9e03c3d4a6..dd92d05b39 100644 --- a/libs/libcurl/src/curl_range.c +++ b/libs/libcurl/src/curl_range.c @@ -47,7 +47,7 @@ CURLcode Curl_range(struct Curl_easy *data) from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from); if(from_t == CURL_OFFT_FLOW) return CURLE_RANGE_ERROR; - while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + while(*ptr && (ISBLANK(*ptr) || (*ptr == '-'))) ptr++; to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); if(to_t == CURL_OFFT_FLOW) diff --git a/libs/libcurl/src/curl_setup.h b/libs/libcurl/src/curl_setup.h index 4bc8aea38c..ac27b130c6 100644 --- a/libs/libcurl/src/curl_setup.h +++ b/libs/libcurl/src/curl_setup.h @@ -158,8 +158,6 @@ /* please, do it beyond the point further indicated in this file. */ /* ================================================================ */ -#include <curl/curl.h> - /* * Disable other protocols when http is the only one desired. */ @@ -219,7 +217,7 @@ /* ================================================================ */ /* No system header file shall be included in this file before this */ -/* point. The only allowed ones are those included from curl/system.h */ +/* point. */ /* ================================================================ */ /* @@ -246,6 +244,8 @@ # include "setup-win32.h" #endif +#include <curl/system.h> + /* * Use getaddrinfo to resolve the IPv4 address literal. If the current network * interface doesn't support IPv4, but supports IPv6, NAT64, and DNS64, @@ -274,14 +274,41 @@ #endif #ifdef __AMIGA__ +# ifdef __amigaos4__ +# define __USE_INLINE__ + /* use our own resolver which uses runtime feature detection */ +# define CURLRES_AMIGA + /* getaddrinfo() currently crashes bsdsocket.library, so disable */ +# undef HAVE_GETADDRINFO +# if !(defined(__NEWLIB__) || \ + (defined(__CLIB2__) && defined(__THREAD_SAFE))) + /* disable threaded resolver with clib2 - requires newlib or clib-ts */ +# undef USE_THREADS_POSIX +# endif +# endif # include <exec/types.h> # include <exec/execbase.h> # include <proto/exec.h> # include <proto/dos.h> # include <unistd.h> -# ifdef HAVE_PROTO_BSDSOCKET_H -# include <proto/bsdsocket.h> /* ensure bsdsocket.library use */ -# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0) +# if defined(HAVE_PROTO_BSDSOCKET_H) && \ + (!defined(__amigaos4__) || defined(USE_AMISSL)) + /* use bsdsocket.library directly, instead of libc networking functions */ +# include <proto/bsdsocket.h> +# ifdef __amigaos4__ + int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *errorfds, struct timeval *timeout); +# define select(a,b,c,d,e) Curl_amiga_select(a,b,c,d,e) +# else +# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0) +# endif + /* must not use libc's fcntl() on bsdsocket.library sockfds! */ +# undef HAVE_FCNTL +# undef HAVE_FCNTL_O_NONBLOCK +# else + /* use libc networking and hence close() and fnctl() */ +# undef HAVE_CLOSESOCKET_CAMEL +# undef HAVE_IOCTLSOCKET_CAMEL # endif /* * In clib2 arpa/inet.h warns that some prototypes may clash @@ -295,8 +322,10 @@ #include <assert.h> #endif -#ifdef __TANDEM /* for nsr-tandem-nsk systems */ -#include <floss.h> +#ifdef __TANDEM /* for ns*-tandem-nsk systems */ +# if ! defined __LP64 +# include <floss.h> /* FLOSS is only used for 32-bit builds. */ +# endif #endif #ifndef STDC_HEADERS /* no standard C headers! */ @@ -563,7 +592,6 @@ /* now undef the stock libc functions just to avoid them being used */ # undef HAVE_GETADDRINFO # undef HAVE_FREEADDRINFO -# undef HAVE_GETHOSTBYNAME #elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) # define CURLRES_ASYNCH # define CURLRES_THREADED @@ -714,12 +742,12 @@ #define SHUT_RDWR 0x02 #endif -/* Define S_ISREG if not defined by system headers, f.e. MSVC */ +/* Define S_ISREG if not defined by system headers, e.g. MSVC */ #if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) #endif -/* Define S_ISDIR if not defined by system headers, f.e. MSVC */ +/* Define S_ISDIR if not defined by system headers, e.g. MSVC */ #if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif diff --git a/libs/libcurl/src/curl_setup_once.h b/libs/libcurl/src/curl_setup_once.h index 656dc08373..f09b00f9f2 100644 --- a/libs/libcurl/src/curl_setup_once.h +++ b/libs/libcurl/src/curl_setup_once.h @@ -33,7 +33,6 @@ #include <stdlib.h> #include <string.h> #include <stdarg.h> -#include <ctype.h> #include <time.h> #ifdef HAVE_ERRNO_H @@ -88,6 +87,8 @@ #include <sys/socket.h> #endif +#include "functypes.h" + #ifdef __hpux # if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL) # ifdef OLD_APP32_64BIT_OFF_T @@ -150,20 +151,10 @@ struct timeval { * SEND_TYPE_RETV must also be defined. */ -#if !defined(RECV_TYPE_ARG1) || \ - !defined(RECV_TYPE_ARG2) || \ - !defined(RECV_TYPE_ARG3) || \ - !defined(RECV_TYPE_ARG4) || \ - !defined(RECV_TYPE_RETV) - /* */ - Error Missing_definition_of_return_and_arguments_types_of_recv - /* */ -#else #define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \ (RECV_TYPE_ARG2)(y), \ (RECV_TYPE_ARG3)(z), \ (RECV_TYPE_ARG4)(0)) -#endif #else /* HAVE_RECV */ #ifndef sread /* */ @@ -180,21 +171,10 @@ struct timeval { (SEND_TYPE_ARG3)(z)) #elif defined(HAVE_SEND) -#if !defined(SEND_TYPE_ARG1) || \ - !defined(SEND_QUAL_ARG2) || \ - !defined(SEND_TYPE_ARG2) || \ - !defined(SEND_TYPE_ARG3) || \ - !defined(SEND_TYPE_ARG4) || \ - !defined(SEND_TYPE_RETV) - /* */ - Error Missing_definition_of_return_and_arguments_types_of_send - /* */ -#else #define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \ (SEND_QUAL_ARG2 SEND_TYPE_ARG2)(y), \ (SEND_TYPE_ARG3)(z), \ (SEND_TYPE_ARG4)(SEND_4TH_ARG)) -#endif #else /* HAVE_SEND */ #ifndef swrite /* */ @@ -204,46 +184,6 @@ struct timeval { #endif /* HAVE_SEND */ -#if 0 -#if defined(HAVE_RECVFROM) -/* - * Currently recvfrom is only used on udp sockets. - */ -#if !defined(RECVFROM_TYPE_ARG1) || \ - !defined(RECVFROM_TYPE_ARG2) || \ - !defined(RECVFROM_TYPE_ARG3) || \ - !defined(RECVFROM_TYPE_ARG4) || \ - !defined(RECVFROM_TYPE_ARG5) || \ - !defined(RECVFROM_TYPE_ARG6) || \ - !defined(RECVFROM_TYPE_RETV) - /* */ - Error Missing_definition_of_return_and_arguments_types_of_recvfrom - /* */ -#else -#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \ - (RECVFROM_TYPE_ARG2 *)(b), \ - (RECVFROM_TYPE_ARG3) (bl), \ - (RECVFROM_TYPE_ARG4) (0), \ - (RECVFROM_TYPE_ARG5 *)(f), \ - (RECVFROM_TYPE_ARG6 *)(fl)) -#endif -#else /* HAVE_RECVFROM */ -#ifndef sreadfrom - /* */ - Error Missing_definition_of_macro_sreadfrom - /* */ -#endif -#endif /* HAVE_RECVFROM */ - - -#ifdef RECVFROM_TYPE_ARG6_IS_VOID -# define RECVFROM_ARG6_T int -#else -# define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6 -#endif -#endif /* if 0 */ - - /* * Function-like macro definition used to close a socket. */ @@ -269,9 +209,6 @@ struct timeval { # define sfcntl fcntl #endif -#define TOLOWER(x) (tolower((int) ((unsigned char)x))) - - /* * 'bool' stuff compatible with HP-UX headers. */ diff --git a/libs/libcurl/src/curl_sha256.h b/libs/libcurl/src/curl_sha256.h index 82fcdff8ea..754c761fb3 100644 --- a/libs/libcurl/src/curl_sha256.h +++ b/libs/libcurl/src/curl_sha256.h @@ -26,6 +26,7 @@ ***************************************************************************/ #ifndef CURL_DISABLE_CRYPTO_AUTH +#include <curl/curl.h> #include "curl_hmac.h" extern const struct HMAC_params Curl_HMAC_SHA256[1]; diff --git a/libs/libcurl/src/doh.c b/libs/libcurl/src/doh.c index a21c94f880..3b1d5d60ef 100644 --- a/libs/libcurl/src/doh.c +++ b/libs/libcurl/src/doh.c @@ -243,6 +243,7 @@ static CURLcode dohprobe(struct Curl_easy *data, the gcc typecheck helpers */ struct dynbuf *resp = &p->serverdoh; ERROR_CHECK_SETOPT(CURLOPT_URL, url); + ERROR_CHECK_SETOPT(CURLOPT_DEFAULT_PROTOCOL, "https"); ERROR_CHECK_SETOPT(CURLOPT_WRITEFUNCTION, doh_write_cb); ERROR_CHECK_SETOPT(CURLOPT_WRITEDATA, resp); ERROR_CHECK_SETOPT(CURLOPT_POSTFIELDS, p->dohbuffer); @@ -395,7 +396,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, goto error; dohp->pending++; - if(Curl_ipv6works(data)) { + if((conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) { /* create IPv6 DoH request */ result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6], DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH], @@ -791,7 +792,7 @@ doh2ai(const struct dohentry *de, const char *hostname, int port) #endif CURLcode result = CURLE_OK; int i; - size_t hostlen = strlen(hostname) + 1; /* include zero terminator */ + size_t hostlen = strlen(hostname) + 1; /* include null-terminator */ if(!de) /* no input == no output! */ diff --git a/libs/libcurl/src/doh.h b/libs/libcurl/src/doh.h index f8b6435350..678e807fe4 100644 --- a/libs/libcurl/src/doh.h +++ b/libs/libcurl/src/doh.h @@ -29,21 +29,6 @@ #ifndef CURL_DISABLE_DOH -/* - * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name - * and returns a 'Curl_addrinfo *' with the address information. - */ - -struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, - const char *hostname, - int port, - int *waitp); - -CURLcode Curl_doh_is_resolved(struct Curl_easy *data, - struct Curl_dns_entry **dns); - -int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks); - typedef enum { DOH_OK, DOH_DNS_BAD_LABEL, /* 1 */ @@ -69,6 +54,38 @@ typedef enum { DNS_TYPE_DNAME = 39 /* RFC6672 */ } DNStype; +/* one of these for each DoH request */ +struct dnsprobe { + CURL *easy; + DNStype dnstype; + unsigned char dohbuffer[512]; + size_t dohlen; + struct dynbuf serverdoh; +}; + +struct dohdata { + struct curl_slist *headers; + struct dnsprobe probe[DOH_PROBE_SLOTS]; + unsigned int pending; /* still outstanding requests */ + int port; + const char *host; +}; + +/* + * Curl_doh() resolve a name using DoH (DNS-over-HTTPS). It resolves a name + * and returns a 'Curl_addrinfo *' with the address information. + */ + +struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, + const char *hostname, + int port, + int *waitp); + +CURLcode Curl_doh_is_resolved(struct Curl_easy *data, + struct Curl_dns_entry **dns); + +int Curl_doh_getsock(struct connectdata *conn, curl_socket_t *socks); + #define DOH_MAX_ADDR 24 #define DOH_MAX_CNAME 4 diff --git a/libs/libcurl/src/dotdot.c b/libs/libcurl/src/dotdot.c deleted file mode 100644 index 0b045315d0..0000000000 --- a/libs/libcurl/src/dotdot.c +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * SPDX-License-Identifier: curl - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include <curl/curl.h> - -#include "dotdot.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * "Remove Dot Segments" - * https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4 - */ - -/* - * Curl_dedotdotify() - * @unittest: 1395 - * - * This function gets a null-terminated path with dot and dotdot sequences - * passed in and strips them off according to the rules in RFC 3986 section - * 5.2.4. - * - * The function handles a query part ('?' + stuff) appended but it expects - * that fragments ('#' + stuff) have already been cut off. - * - * RETURNS - * - * an allocated dedotdotified output string - */ -char *Curl_dedotdotify(const char *input) -{ - size_t inlen = strlen(input); - char *clone; - size_t clen = inlen; /* the length of the cloned input */ - char *out = malloc(inlen + 1); - char *outptr; - char *orgclone; - char *queryp; - if(!out) - return NULL; /* out of memory */ - - *out = 0; /* null-terminates, for inputs like "./" */ - - /* get a cloned copy of the input */ - clone = strdup(input); - if(!clone) { - free(out); - return NULL; - } - orgclone = clone; - outptr = out; - - if(!*clone) { - /* zero length string, return that */ - free(out); - return clone; - } - - /* - * To handle query-parts properly, we must find it and remove it during the - * dotdot-operation and then append it again at the end to the output - * string. - */ - queryp = strchr(clone, '?'); - if(queryp) - *queryp = 0; - - do { - - /* A. If the input buffer begins with a prefix of "../" or "./", then - remove that prefix from the input buffer; otherwise, */ - - if(!strncmp("./", clone, 2)) { - clone += 2; - clen -= 2; - } - else if(!strncmp("../", clone, 3)) { - clone += 3; - clen -= 3; - } - - /* B. if the input buffer begins with a prefix of "/./" or "/.", where - "." is a complete path segment, then replace that prefix with "/" in - the input buffer; otherwise, */ - else if(!strncmp("/./", clone, 3)) { - clone += 2; - clen -= 2; - } - else if(!strcmp("/.", clone)) { - clone[1]='/'; - clone++; - clen -= 1; - } - - /* C. if the input buffer begins with a prefix of "/../" or "/..", where - ".." is a complete path segment, then replace that prefix with "/" in - the input buffer and remove the last segment and its preceding "/" (if - any) from the output buffer; otherwise, */ - - else if(!strncmp("/../", clone, 4)) { - clone += 3; - clen -= 3; - /* remove the last segment from the output buffer */ - while(outptr > out) { - outptr--; - if(*outptr == '/') - break; - } - *outptr = 0; /* null-terminate where it stops */ - } - else if(!strcmp("/..", clone)) { - clone[2]='/'; - clone += 2; - clen -= 2; - /* remove the last segment from the output buffer */ - while(outptr > out) { - outptr--; - if(*outptr == '/') - break; - } - *outptr = 0; /* null-terminate where it stops */ - } - - /* D. if the input buffer consists only of "." or "..", then remove - that from the input buffer; otherwise, */ - - else if(!strcmp(".", clone) || !strcmp("..", clone)) { - *clone = 0; - *out = 0; - } - - else { - /* E. move the first path segment in the input buffer to the end of - the output buffer, including the initial "/" character (if any) and - any subsequent characters up to, but not including, the next "/" - character or the end of the input buffer. */ - - do { - *outptr++ = *clone++; - clen--; - } while(*clone && (*clone != '/')); - *outptr = 0; - } - - } while(*clone); - - if(queryp) { - size_t qlen; - /* There was a query part, append that to the output. The 'clone' string - may now have been altered so we copy from the original input string - from the correct index. */ - size_t oindex = queryp - orgclone; - qlen = strlen(&input[oindex]); - memcpy(outptr, &input[oindex], qlen + 1); /* include the end zero byte */ - } - - free(orgclone); - return out; -} diff --git a/libs/libcurl/src/dynbuf.c b/libs/libcurl/src/dynbuf.c index 3b907dbe2e..0b1cf9afd8 100644 --- a/libs/libcurl/src/dynbuf.c +++ b/libs/libcurl/src/dynbuf.c @@ -128,7 +128,6 @@ void Curl_dyn_reset(struct dynbuf *s) s->leng = 0; } -#ifdef USE_NGTCP2 /* * Specify the size of the tail to keep (number of bytes from the end of the * buffer). The rest will be dropped. @@ -153,7 +152,6 @@ CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail) return CURLE_OK; } -#endif /* * Appends a buffer with length. @@ -255,3 +253,18 @@ size_t Curl_dyn_len(const struct dynbuf *s) DEBUGASSERT(!s->leng || s->bufr); return s->leng; } + +/* + * Set a new (smaller) length. + */ +CURLcode Curl_dyn_setlen(struct dynbuf *s, size_t set) +{ + DEBUGASSERT(s); + DEBUGASSERT(s->init == DYNINIT); + DEBUGASSERT(!s->leng || s->bufr); + if(set > s->leng) + return CURLE_BAD_FUNCTION_ARGUMENT; + s->leng = set; + s->bufr[s->leng] = 0; + return CURLE_OK; +} diff --git a/libs/libcurl/src/dynbuf.h b/libs/libcurl/src/dynbuf.h index c1e97235de..04a728c779 100644 --- a/libs/libcurl/src/dynbuf.h +++ b/libs/libcurl/src/dynbuf.h @@ -24,6 +24,8 @@ * ***************************************************************************/ +#include <curl/curl.h> + #ifndef BUILDING_LIBCURL /* this renames the functions so that the tool code can use the same code without getting symbol collisions */ @@ -38,12 +40,13 @@ #define Curl_dyn_len(a) curlx_dyn_len(a) #define Curl_dyn_reset(a) curlx_dyn_reset(a) #define Curl_dyn_tail(a,b) curlx_dyn_tail(a,b) +#define Curl_dyn_setlen(a,b) curlx_dyn_setlen(a,b) #define curlx_dynbuf dynbuf /* for the struct name */ #endif struct dynbuf { char *bufr; /* point to a null-terminated allocated buffer */ - size_t leng; /* number of bytes *EXCLUDING* the zero terminator */ + size_t leng; /* number of bytes *EXCLUDING* the null-terminator */ size_t allc; /* size of the current allocation */ size_t toobig; /* size limit for the buffer */ #ifdef DEBUGBUILD @@ -63,6 +66,7 @@ CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap) WARN_UNUSED_RESULT; void Curl_dyn_reset(struct dynbuf *s); CURLcode Curl_dyn_tail(struct dynbuf *s, size_t trail); +CURLcode Curl_dyn_setlen(struct dynbuf *s, size_t set); char *Curl_dyn_ptr(const struct dynbuf *s); unsigned char *Curl_dyn_uptr(const struct dynbuf *s); size_t Curl_dyn_len(const struct dynbuf *s); diff --git a/libs/libcurl/src/easy.c b/libs/libcurl/src/easy.c index 704a59df62..b8ac1ef8a8 100644 --- a/libs/libcurl/src/easy.c +++ b/libs/libcurl/src/easy.c @@ -82,11 +82,12 @@ #include "altsvc.h" #include "hsts.h" +#include "easy_lock.h" + /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" #include "memdebug.h" -#include "easy_lock.h" /* true globals -- for curl_global_init() and curl_global_cleanup() */ static unsigned int initialized; @@ -177,7 +178,7 @@ static CURLcode global_init(long flags, bool memoryfuncs) #endif #ifdef __AMIGA__ - if(!Curl_amiga_init()) { + if(Curl_amiga_init()) { DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n")); goto fail; } @@ -725,7 +726,7 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events) else { /* this multi handle will only ever have a single easy handled attached to it, so make it use minimal hashes */ - multi = Curl_multi_handle(1, 3); + multi = Curl_multi_handle(1, 3, 7); if(!multi) return CURLE_OUT_OF_MEMORY; data->multi_easy = multi; @@ -943,7 +944,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data) goto fail; } -#ifdef USE_ALTSVC +#ifndef CURL_DISABLE_ALTSVC if(data->asi) { outcurl->asi = Curl_altsvc_init(); if(!outcurl->asi) @@ -1132,6 +1133,16 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) } } +#ifdef USE_HYPER + if(!(newstate & KEEP_SEND_PAUSE)) { + /* need to wake the send body waker */ + if(data->hyp.send_body_waker) { + hyper_waker_wake(data->hyp.send_body_waker); + data->hyp.send_body_waker = NULL; + } + } +#endif + /* if there's no error and we're not pausing both directions, we want to have this handle checked soon */ if((newstate & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) != @@ -1160,8 +1171,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) } -static CURLcode easy_connection(struct Curl_easy *data, - curl_socket_t *sfd, +static CURLcode easy_connection(struct Curl_easy *data, curl_socket_t *sfd, struct connectdata **connp) { if(!data) @@ -1220,11 +1230,12 @@ CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen, } /* - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + * Sends data over the connected socket. + * + * This is the private internal version of curl_easy_send() */ -CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, - size_t buflen, size_t *n) +CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer, + size_t buflen, ssize_t *n) { curl_socket_t sfd; CURLcode result; @@ -1232,9 +1243,6 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, struct connectdata *c = NULL; SIGPIPE_VARIABLE(pipe_st); - if(Curl_is_in_callback(data)) - return CURLE_RECURSIVE_API_CALL; - result = easy_connection(data, &sfd, &c); if(result) return result; @@ -1256,8 +1264,25 @@ CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, if(!result && !n1) return CURLE_AGAIN; - *n = (size_t)n1; + *n = n1; + + return result; +} + +/* + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, + size_t buflen, size_t *n) +{ + ssize_t written = 0; + CURLcode result; + if(Curl_is_in_callback(data)) + return CURLE_RECURSIVE_API_CALL; + result = Curl_senddata(data, buffer, buflen, &written); + *n = (size_t)written; return result; } diff --git a/libs/libcurl/src/easy_lock.h b/libs/libcurl/src/easy_lock.h index 819f50ce81..d96e56b8d8 100644 --- a/libs/libcurl/src/easy_lock.h +++ b/libs/libcurl/src/easy_lock.h @@ -28,17 +28,51 @@ #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 +#ifdef __MINGW32__ +#ifndef __MINGW64_VERSION_MAJOR +#if (__MINGW32_MAJOR_VERSION < 5) || \ + (__MINGW32_MAJOR_VERSION == 5 && __MINGW32_MINOR_VERSION == 0) +/* mingw >= 5.0.1 defines SRWLOCK, and slightly different from MS define */ +typedef PVOID SRWLOCK, *PSRWLOCK; +#endif +#endif +#ifndef SRWLOCK_INIT +#define SRWLOCK_INIT NULL +#endif +#endif /* __MINGW32__ */ + #define curl_simple_lock SRWLOCK #define CURL_SIMPLE_LOCK_INIT SRWLOCK_INIT #define curl_simple_lock_lock(m) AcquireSRWLockExclusive(m) #define curl_simple_lock_unlock(m) ReleaseSRWLockExclusive(m) -#elif defined (HAVE_ATOMIC) +#elif defined(HAVE_ATOMIC) && defined(HAVE_STDATOMIC_H) #include <stdatomic.h> +#if defined(HAVE_SCHED_YIELD) +#include <sched.h> +#endif + +#define curl_simple_lock atomic_int +#define CURL_SIMPLE_LOCK_INIT 0 -#define curl_simple_lock atomic_bool -#define CURL_SIMPLE_LOCK_INIT false +/* a clang-thing */ +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + +#ifndef __INTEL_COMPILER +/* The Intel compiler tries to look like GCC *and* clang *and* lies in its + __has_builtin() function, so override it. */ + +/* if GCC on i386/x86_64 or if the built-in is present */ +#if ( (defined(__GNUC__) && !defined(__clang__)) && \ + (defined(__i386__) || defined(__x86_64__))) || \ + __has_builtin(__builtin_ia32_pause) +#define HAVE_BUILTIN_IA32_PAUSE +#endif + +#endif static inline void curl_simple_lock_lock(curl_simple_lock *lock) { @@ -48,10 +82,10 @@ static inline void curl_simple_lock_lock(curl_simple_lock *lock) /* Reduce cache coherency traffic */ while(atomic_load_explicit(lock, memory_order_relaxed)) { /* Reduce load (not mandatory) */ -#if defined(__i386__) || defined(__x86_64__) +#ifdef HAVE_BUILTIN_IA32_PAUSE __builtin_ia32_pause(); #elif defined(__aarch64__) - asm volatile("yield" ::: "memory"); + __asm__ volatile("yield" ::: "memory"); #elif defined(HAVE_SCHED_YIELD) sched_yield(); #endif diff --git a/libs/libcurl/src/easyif.h b/libs/libcurl/src/easyif.h index 615df3f067..205382cd07 100644 --- a/libs/libcurl/src/easyif.h +++ b/libs/libcurl/src/easyif.h @@ -27,6 +27,9 @@ /* * Prototypes for library-wide functions provided by easy.c */ +CURLcode Curl_senddata(struct Curl_easy *data, const void *buffer, + size_t buflen, ssize_t *n); + #ifdef CURLDEBUG CURL_EXTERN CURLcode curl_easy_perform_ev(struct Curl_easy *easy); #endif diff --git a/libs/libcurl/src/easyoptions.c b/libs/libcurl/src/easyoptions.c index c99f135ffe..e59b63af7a 100644 --- a/libs/libcurl/src/easyoptions.c +++ b/libs/libcurl/src/easyoptions.c @@ -107,7 +107,8 @@ struct curl_easyoption Curl_easyopts[] = { {"FTP_CREATE_MISSING_DIRS", CURLOPT_FTP_CREATE_MISSING_DIRS, CURLOT_LONG, 0}, {"FTP_FILEMETHOD", CURLOPT_FTP_FILEMETHOD, CURLOT_VALUES, 0}, - {"FTP_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOT_LONG, 0}, + {"FTP_RESPONSE_TIMEOUT", CURLOPT_SERVER_RESPONSE_TIMEOUT, + CURLOT_LONG, CURLOT_FLAG_ALIAS}, {"FTP_SKIP_PASV_IP", CURLOPT_FTP_SKIP_PASV_IP, CURLOT_LONG, 0}, {"FTP_SSL", CURLOPT_USE_SSL, CURLOT_VALUES, CURLOT_FLAG_ALIAS}, {"FTP_SSL_CCC", CURLOPT_FTP_SSL_CCC, CURLOT_LONG, 0}, @@ -203,6 +204,7 @@ struct curl_easyoption Curl_easyopts[] = { {"PROGRESSDATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, {"PROGRESSFUNCTION", CURLOPT_PROGRESSFUNCTION, CURLOT_FUNCTION, 0}, {"PROTOCOLS", CURLOPT_PROTOCOLS, CURLOT_LONG, 0}, + {"PROTOCOLS_STR", CURLOPT_PROTOCOLS_STR, CURLOT_STRING, 0}, {"PROXY", CURLOPT_PROXY, CURLOT_STRING, 0}, {"PROXYAUTH", CURLOPT_PROXYAUTH, CURLOT_VALUES, 0}, {"PROXYHEADER", CURLOPT_PROXYHEADER, CURLOT_SLIST, 0}, @@ -245,6 +247,7 @@ struct curl_easyoption Curl_easyopts[] = { {"READDATA", CURLOPT_READDATA, CURLOT_CBPTR, 0}, {"READFUNCTION", CURLOPT_READFUNCTION, CURLOT_FUNCTION, 0}, {"REDIR_PROTOCOLS", CURLOPT_REDIR_PROTOCOLS, CURLOT_LONG, 0}, + {"REDIR_PROTOCOLS_STR", CURLOPT_REDIR_PROTOCOLS_STR, CURLOT_STRING, 0}, {"REFERER", CURLOPT_REFERER, CURLOT_STRING, 0}, {"REQUEST_TARGET", CURLOPT_REQUEST_TARGET, CURLOT_STRING, 0}, {"RESOLVE", CURLOPT_RESOLVE, CURLOT_SLIST, 0}, @@ -264,8 +267,8 @@ struct curl_easyoption Curl_easyopts[] = { {"SASL_IR", CURLOPT_SASL_IR, CURLOT_LONG, 0}, {"SEEKDATA", CURLOPT_SEEKDATA, CURLOT_CBPTR, 0}, {"SEEKFUNCTION", CURLOPT_SEEKFUNCTION, CURLOT_FUNCTION, 0}, - {"SERVER_RESPONSE_TIMEOUT", CURLOPT_FTP_RESPONSE_TIMEOUT, - CURLOT_LONG, CURLOT_FLAG_ALIAS}, + {"SERVER_RESPONSE_TIMEOUT", CURLOPT_SERVER_RESPONSE_TIMEOUT, + CURLOT_LONG, 0}, {"SERVICE_NAME", CURLOPT_SERVICE_NAME, CURLOT_STRING, 0}, {"SHARE", CURLOPT_SHARE, CURLOT_OBJECT, 0}, {"SOCKOPTDATA", CURLOPT_SOCKOPTDATA, CURLOT_CBPTR, 0}, @@ -275,14 +278,14 @@ struct curl_easyoption Curl_easyopts[] = { {"SOCKS5_GSSAPI_SERVICE", CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOT_STRING, 0}, {"SSH_AUTH_TYPES", CURLOPT_SSH_AUTH_TYPES, CURLOT_VALUES, 0}, {"SSH_COMPRESSION", CURLOPT_SSH_COMPRESSION, CURLOT_LONG, 0}, + {"SSH_HOSTKEYDATA", CURLOPT_SSH_HOSTKEYDATA, CURLOT_CBPTR, 0}, + {"SSH_HOSTKEYFUNCTION", CURLOPT_SSH_HOSTKEYFUNCTION, CURLOT_FUNCTION, 0}, {"SSH_HOST_PUBLIC_KEY_MD5", CURLOPT_SSH_HOST_PUBLIC_KEY_MD5, CURLOT_STRING, 0}, {"SSH_HOST_PUBLIC_KEY_SHA256", CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256, CURLOT_STRING, 0}, {"SSH_KEYDATA", CURLOPT_SSH_KEYDATA, CURLOT_CBPTR, 0}, {"SSH_KEYFUNCTION", CURLOPT_SSH_KEYFUNCTION, CURLOT_FUNCTION, 0}, - {"SSH_HOSTKEYDATA", CURLOPT_SSH_HOSTKEYDATA, CURLOT_CBPTR, 0}, - {"SSH_HOSTKEYFUNCTION", CURLOPT_SSH_HOSTKEYFUNCTION, CURLOT_FUNCTION, 0}, {"SSH_KNOWNHOSTS", CURLOPT_SSH_KNOWNHOSTS, CURLOT_STRING, 0}, {"SSH_PRIVATE_KEYFILE", CURLOPT_SSH_PRIVATE_KEYFILE, CURLOT_STRING, 0}, {"SSH_PUBLIC_KEYFILE", CURLOPT_SSH_PUBLIC_KEYFILE, CURLOT_STRING, 0}, @@ -351,10 +354,11 @@ struct curl_easyoption Curl_easyopts[] = { {"WRITEDATA", CURLOPT_WRITEDATA, CURLOT_CBPTR, 0}, {"WRITEFUNCTION", CURLOPT_WRITEFUNCTION, CURLOT_FUNCTION, 0}, {"WRITEHEADER", CURLOPT_HEADERDATA, CURLOT_CBPTR, CURLOT_FLAG_ALIAS}, + {"WS_OPTIONS", CURLOPT_WS_OPTIONS, CURLOT_LONG, 0}, {"XFERINFODATA", CURLOPT_XFERINFODATA, CURLOT_CBPTR, 0}, {"XFERINFOFUNCTION", CURLOPT_XFERINFOFUNCTION, CURLOT_FUNCTION, 0}, {"XOAUTH2_BEARER", CURLOPT_XOAUTH2_BEARER, CURLOT_STRING, 0}, - {NULL, CURLOPT_LASTENTRY, 0, 0} /* end of table */ + {NULL, CURLOPT_LASTENTRY, CURLOT_LONG, 0} /* end of table */ }; #ifdef DEBUGBUILD @@ -364,6 +368,6 @@ struct curl_easyoption Curl_easyopts[] = { */ int Curl_easyopts_check(void) { - return ((CURLOPT_LASTENTRY%10000) != (317 + 1)); + return ((CURLOPT_LASTENTRY%10000) != (320 + 1)); } #endif diff --git a/libs/libcurl/src/escape.c b/libs/libcurl/src/escape.c index 650e40932c..da7e5524f7 100644 --- a/libs/libcurl/src/escape.c +++ b/libs/libcurl/src/escape.c @@ -77,6 +77,9 @@ char *curl_unescape(const char *string, int length) return curl_easy_unescape(NULL, string, length, NULL); } +/* Escapes for URL the given unescaped string of given length. + * 'data' is ignored since 7.82.0. + */ char *curl_easy_escape(struct Curl_easy *data, const char *string, int inlength) { @@ -118,8 +121,6 @@ char *curl_easy_escape(struct Curl_easy *data, const char *string, * Returns a pointer to a malloced string in *ostring with length given in * *olen. If length == 0, the length is assumed to be strlen(string). * - * 'data' can be set to NULL - * * ctrl options: * - REJECT_NADA: accept everything * - REJECT_CTRL: rejects control characters (byte codes lower than 32) in @@ -193,6 +194,7 @@ CURLcode Curl_urldecode(const char *string, size_t length, * pointer to a malloced string with length given in *olen. * If length == 0, the length is assumed to be strlen(string). * If olen == NULL, no output length is stored. + * 'data' is ignored since 7.82.0. */ char *curl_easy_unescape(struct Curl_easy *data, const char *string, int length, int *olen) diff --git a/libs/libcurl/src/file.c b/libs/libcurl/src/file.c index 40a5e42fa3..d82d57b463 100644 --- a/libs/libcurl/src/file.c +++ b/libs/libcurl/src/file.c @@ -71,6 +71,8 @@ #if defined(WIN32) || defined(MSDOS) || defined(__EMX__) #define DOS_FILESYSTEM 1 +#elif defined(__amigaos4__) +#define AMIGA_FILESYSTEM 1 #endif #ifdef OPEN_NEEDS_ARG3 @@ -196,8 +198,33 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done) return CURLE_URL_MALFORMAT; } + #ifdef AMIGA_FILESYSTEM + /* + * A leading slash in an AmigaDOS path denotes the parent + * directory, and hence we block this as it is relative. + * Absolute paths start with 'volumename:', so we check for + * this first. Failing that, we treat the path as a real unix + * path, but only if the application was compiled with -lunix. + */ + fd = -1; + file->path = real_path; + + if(real_path[0] == '/') { + extern int __unix_path_semantics; + if(strchr(real_path + 1, ':')) { + /* Amiga absolute path */ + fd = open_readonly(real_path + 1, O_RDONLY); + file->path++; + } + else if(__unix_path_semantics) { + /* -lunix fallback */ + fd = open_readonly(real_path, O_RDONLY); + } + } + #else fd = open_readonly(real_path, O_RDONLY); file->path = real_path; + #endif #endif file->freepath = real_path; /* free this when done */ @@ -236,7 +263,7 @@ static CURLcode file_disconnect(struct Curl_easy *data, { (void)dead_connection; /* not used */ (void)conn; - return file_done(data, 0, 0); + return file_done(data, CURLE_OK, FALSE); } #ifdef DOS_FILESYSTEM diff --git a/libs/libcurl/src/formdata.c b/libs/libcurl/src/formdata.c index f5ed3653df..46542b4329 100644 --- a/libs/libcurl/src/formdata.c +++ b/libs/libcurl/src/formdata.c @@ -251,8 +251,10 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost, } } else { - /* This is not array-state, get next option */ - option = va_arg(params, CURLformoption); + /* This is not array-state, get next option. This gets an 'int' with + va_arg() because CURLformoption might be a smaller type than int and + might cause compiler warnings and wrong behavior. */ + option = (CURLformoption)va_arg(params, int); if(CURLFORM_END == option) break; } diff --git a/libs/libcurl/src/ftp.c b/libs/libcurl/src/ftp.c index e6e9821c9c..f1a25b23dc 100644 --- a/libs/libcurl/src/ftp.c +++ b/libs/libcurl/src/ftp.c @@ -516,10 +516,9 @@ static CURLcode AllowServerConnect(struct Curl_easy *data, bool *connected) } else { /* Add timeout to multi handle and break out of the loop */ - if(*connected == FALSE) { - Curl_expire(data, data->set.accepttimeout > 0 ? - data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, 0); - } + Curl_expire(data, data->set.accepttimeout ? + data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, + EXPIRE_FTP_ACCEPT); } return result; @@ -2130,9 +2129,11 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, default: infof(data, "unsupported MDTM reply format"); break; - case 550: /* "No such file or directory" */ - failf(data, "Given file does not exist"); - result = CURLE_REMOTE_FILE_NOT_FOUND; + case 550: /* 550 is used for several different problems, e.g. + "No such file or directory" or "Permission denied". + It does not mean that the file does not exist at all. */ + infof(data, "MDTM failed: file does not exist or permission problem," + " continuing"); break; } diff --git a/libs/libcurl/src/ftplistparser.c b/libs/libcurl/src/ftplistparser.c index 09476e55f4..40f5f3f189 100644 --- a/libs/libcurl/src/ftplistparser.c +++ b/libs/libcurl/src/ftplistparser.c @@ -422,7 +422,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, char *endptr = finfo->b_data + 6; /* here we can deal with directory size, pass the leading whitespace and then the digits */ - while(ISSPACE(*endptr)) + while(ISBLANK(*endptr)) endptr++; while(ISDIGIT(*endptr)) endptr++; @@ -894,7 +894,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, parser->item_length++; switch(parser->state.NT.sub.time) { case PL_WINNT_TIME_PRESPACE: - if(!ISSPACE(c)) { + if(!ISBLANK(c)) { parser->state.NT.sub.time = PL_WINNT_TIME_TIME; } break; diff --git a/libs/libcurl/src/functypes.h b/libs/libcurl/src/functypes.h new file mode 100644 index 0000000000..8891b1d5d6 --- /dev/null +++ b/libs/libcurl/src/functypes.h @@ -0,0 +1,115 @@ +#ifndef HEADER_CURL_FUNCTYPES_H +#define HEADER_CURL_FUNCTYPES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ + +#include "curl_setup.h" + +/* defaults: + + ssize_t recv(int, void *, size_t, int); + ssize_t send(int, const void *, size_t, int); + + If other argument or return types are needed: + + 1. For systems that run configure or cmake, the alternatives are provided + here. + 2. For systems with config-*.h files, define them there. +*/ + +#ifdef WIN32 +/* int recv(SOCKET, char *, int, int) */ +#define RECV_TYPE_ARG1 SOCKET +#define RECV_TYPE_ARG2 char * +#define RECV_TYPE_ARG3 int +#define RECV_TYPE_RETV int + +/* int send(SOCKET, const char *, int, int); */ +#define SEND_TYPE_ARG1 SOCKET +#define SEND_TYPE_ARG2 char * +#define SEND_TYPE_ARG3 int +#define SEND_TYPE_RETV int + +#elif defined(__AMIGA__) /* Any AmigaOS flavour */ + +/* long recv(long, char *, long, long); */ +#define RECV_TYPE_ARG1 long +#define RECV_TYPE_ARG2 char * +#define RECV_TYPE_ARG3 long +#define RECV_TYPE_ARG4 long +#define RECV_TYPE_RETV long + +/* int send(int, const char *, int, int); */ +#define SEND_TYPE_ARG1 int +#define SEND_TYPE_ARG2 char * +#define SEND_TYPE_ARG3 int +#define SEND_TYPE_RETV int +#endif + + +#ifndef RECV_TYPE_ARG1 +#define RECV_TYPE_ARG1 int +#endif + +#ifndef RECV_TYPE_ARG2 +#define RECV_TYPE_ARG2 void * +#endif + +#ifndef RECV_TYPE_ARG3 +#define RECV_TYPE_ARG3 size_t +#endif + +#ifndef RECV_TYPE_ARG4 +#define RECV_TYPE_ARG4 int +#endif + +#ifndef RECV_TYPE_RETV +#define RECV_TYPE_RETV ssize_t +#endif + +#ifndef SEND_QUAL_ARG2 +#define SEND_QUAL_ARG2 const +#endif + +#ifndef SEND_TYPE_ARG1 +#define SEND_TYPE_ARG1 int +#endif + +#ifndef SEND_TYPE_ARG2 +#define SEND_TYPE_ARG2 void * +#endif + +#ifndef SEND_TYPE_ARG3 +#define SEND_TYPE_ARG3 size_t +#endif + +#ifndef SEND_TYPE_ARG4 +#define SEND_TYPE_ARG4 int +#endif + +#ifndef SEND_TYPE_RETV +#define SEND_TYPE_RETV ssize_t +#endif + +#endif /* HEADER_CURL_FUNCTYPES_H */ diff --git a/libs/libcurl/src/getinfo.c b/libs/libcurl/src/getinfo.c index 758cf54bbe..c3556b3102 100644 --- a/libs/libcurl/src/getinfo.c +++ b/libs/libcurl/src/getinfo.c @@ -578,7 +578,7 @@ CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...) CURLcode result = CURLE_UNKNOWN_OPTION; if(!data) - return result; + return CURLE_BAD_FUNCTION_ARGUMENT; va_start(arg, info); diff --git a/libs/libcurl/src/h2h3.c b/libs/libcurl/src/h2h3.c index 9453cf55b7..50254ad0fa 100644 --- a/libs/libcurl/src/h2h3.c +++ b/libs/libcurl/src/h2h3.c @@ -191,7 +191,7 @@ CURLcode Curl_pseudo_headers(struct Curl_easy *data, vptr = Curl_checkheaders(data, STRCONST(H2H3_PSEUDO_SCHEME)); if(vptr) { vptr += sizeof(H2H3_PSEUDO_SCHEME); - while(*vptr && ISSPACE(*vptr)) + while(*vptr && ISBLANK(*vptr)) vptr++; nva[2].value = vptr; infof(data, "set pseudo header %s to %s", H2H3_PSEUDO_SCHEME, vptr); @@ -258,9 +258,6 @@ CURLcode Curl_pseudo_headers(struct Curl_easy *data, nva[i].valuelen = (end - hdbuf); } - nva[i].value = hdbuf; - nva[i].valuelen = (end - hdbuf); - ++i; } diff --git a/libs/libcurl/src/headers.c b/libs/libcurl/src/headers.c index 154623737a..978c918f4f 100644 --- a/libs/libcurl/src/headers.c +++ b/libs/libcurl/src/headers.c @@ -74,8 +74,8 @@ CURLHcode curl_easy_header(CURL *easy, struct Curl_header_store *hs = NULL; struct Curl_header_store *pick = NULL; if(!name || !hout || !data || - (type > (CURLH_HEADER|CURLH_TRAILER|CURLH_CONNECT|CURLH_1XX)) || - !type || (request < -1)) + (type > (CURLH_HEADER|CURLH_TRAILER|CURLH_CONNECT|CURLH_1XX| + CURLH_PSEUDO)) || !type || (request < -1)) return CURLHE_BAD_ARGUMENT; if(!Curl_llist_count(&data->state.httphdrs)) return CURLHE_NOHEADERS; /* no headers available */ @@ -207,7 +207,7 @@ static CURLcode namevalue(char *header, size_t hlen, unsigned int type, return CURLE_BAD_FUNCTION_ARGUMENT; /* skip all leading space letters */ - while(*header && ISSPACE(*header)) + while(*header && ISBLANK(*header)) header++; *value = header; @@ -237,7 +237,7 @@ static CURLcode unfold_value(struct Curl_easy *data, const char *value, vlen--; /* save only one leading space */ - while((vlen > 1) && ISSPACE(value[0]) && ISSPACE(value[1])) { + while((vlen > 1) && ISBLANK(value[0]) && ISBLANK(value[1])) { vlen--; value++; } @@ -259,7 +259,7 @@ static CURLcode unfold_value(struct Curl_easy *data, const char *value, /* put the data at the end of the previous data, not the newline */ memcpy(&newhs->value[olen], value, vlen); - newhs->value[olen + vlen] = 0; /* zero terminate at newline */ + newhs->value[olen + vlen] = 0; /* null-terminate at newline */ /* insert this node into the list of headers */ Curl_llist_insert_next(&data->state.httphdrs, data->state.httphdrs.tail, diff --git a/libs/libcurl/src/hostip.c b/libs/libcurl/src/hostip.c index 1ced9d2e9c..941ecacf4a 100644 --- a/libs/libcurl/src/hostip.c +++ b/libs/libcurl/src/hostip.c @@ -181,7 +181,7 @@ create_hostcache_id(const char *name, int port, char *ptr, size_t buflen) len = buflen - 7; /* store and lower case the name */ while(len--) - *ptr++ = (char)TOLOWER(*name++); + *ptr++ = Curl_raw_tolower(*name++); msnprintf(ptr, 7, ":%u", port); } @@ -297,6 +297,31 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data, } } + /* See if the returned entry matches the required resolve mode */ + if(dns && data->conn->ip_version != CURL_IPRESOLVE_WHATEVER) { + int pf = PF_INET; + bool found = false; + struct Curl_addrinfo *addr = dns->addr; + +#ifdef PF_INET6 + if(data->conn->ip_version == CURL_IPRESOLVE_V6) + pf = PF_INET6; +#endif + + while(addr) { + if(addr->ai_family == pf) { + found = true; + break; + } + addr = addr->ai_next; + } + + if(!found) { + infof(data, "Hostname in DNS cache doesn't have needed family, zapped"); + dns = NULL; /* the memory deallocation is being handled by the hash */ + Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1); + } + } return dns; } @@ -463,12 +488,12 @@ Curl_cache_addr(struct Curl_easy *data, } #ifdef ENABLE_IPV6 -/* return a static IPv6 resolve for 'localhost' */ -static struct Curl_addrinfo *get_localhost6(int port) +/* return a static IPv6 ::1 for the name */ +static struct Curl_addrinfo *get_localhost6(int port, const char *name) { struct Curl_addrinfo *ca; const size_t ss_size = sizeof(struct sockaddr_in6); - const size_t hostlen = strlen("localhost"); + const size_t hostlen = strlen(name); struct sockaddr_in6 sa6; unsigned char ipv6[16]; unsigned short port16 = (unsigned short)(port & 0xffff); @@ -493,19 +518,19 @@ static struct Curl_addrinfo *get_localhost6(int port) ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo)); memcpy(ca->ai_addr, &sa6, ss_size); ca->ai_canonname = (char *)ca->ai_addr + ss_size; - strcpy(ca->ai_canonname, "localhost"); + strcpy(ca->ai_canonname, name); return ca; } #else -#define get_localhost6(x) NULL +#define get_localhost6(x,y) NULL #endif -/* return a static IPv4 resolve for 'localhost' */ -static struct Curl_addrinfo *get_localhost(int port) +/* return a static IPv4 127.0.0.1 for the given name */ +static struct Curl_addrinfo *get_localhost(int port, const char *name) { struct Curl_addrinfo *ca; const size_t ss_size = sizeof(struct sockaddr_in); - const size_t hostlen = strlen("localhost"); + const size_t hostlen = strlen(name); struct sockaddr_in sa; unsigned int ipv4; unsigned short port16 = (unsigned short)(port & 0xffff); @@ -529,8 +554,8 @@ static struct Curl_addrinfo *get_localhost(int port) ca->ai_addr = (void *)((char *)ca + sizeof(struct Curl_addrinfo)); memcpy(ca->ai_addr, &sa, ss_size); ca->ai_canonname = (char *)ca->ai_addr + ss_size; - strcpy(ca->ai_canonname, "localhost"); - ca->ai_next = get_localhost6(port); + strcpy(ca->ai_canonname, name); + ca->ai_next = get_localhost6(port, name); return ca; } @@ -546,7 +571,11 @@ bool Curl_ipv6works(struct Curl_easy *data) have the info kept for fast re-use */ DEBUGASSERT(data); DEBUGASSERT(data->multi); - return data->multi->ipv6_works; + if(data->multi->ipv6_up == IPV6_UNKNOWN) { + bool works = Curl_ipv6works(NULL); + data->multi->ipv6_up = works ? IPV6_WORKS : IPV6_DEAD; + } + return data->multi->ipv6_up == IPV6_WORKS; } else { int ipv6_works = -1; @@ -583,6 +612,17 @@ bool Curl_host_is_ipnum(const char *hostname) return FALSE; } + +/* return TRUE if 'part' is a case insensitive tail of 'full' */ +static bool tailmatch(const char *full, const char *part) +{ + size_t plen = strlen(part); + size_t flen = strlen(full); + if(plen > flen) + return FALSE; + return strncasecompare(part, &full[flen - plen], plen); +} + /* * Curl_resolv() is the main name resolve function within libcurl. It resolves * a name and returns a pointer to the entry in the 'entry' argument (if one @@ -718,8 +758,9 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, if(conn->ip_version == CURL_IPRESOLVE_V6 && !Curl_ipv6works(data)) return CURLRESOLV_ERROR; - if(strcasecompare(hostname, "localhost")) - addr = get_localhost(port); + if(strcasecompare(hostname, "localhost") || + tailmatch(hostname, ".localhost")) + addr = get_localhost(port, hostname); #ifndef CURL_DISABLE_DOH else if(allowDOH && data->set.doh && !ipnum) addr = Curl_doh(data, hostname, port, &respwait); @@ -993,9 +1034,9 @@ static void freednsentry(void *freethis) /* * Curl_init_dnscache() inits a new DNS cache. */ -void Curl_init_dnscache(struct Curl_hash *hash) +void Curl_init_dnscache(struct Curl_hash *hash, int size) { - Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare, + Curl_hash_init(hash, size, Curl_hash_str, Curl_str_key_compare, freednsentry); } diff --git a/libs/libcurl/src/hostip.h b/libs/libcurl/src/hostip.h index 4b603378bd..9d3170737c 100644 --- a/libs/libcurl/src/hostip.h +++ b/libs/libcurl/src/hostip.h @@ -132,7 +132,7 @@ void Curl_resolv_unlock(struct Curl_easy *data, struct Curl_dns_entry *dns); /* init a new dns cache */ -void Curl_init_dnscache(struct Curl_hash *hash); +void Curl_init_dnscache(struct Curl_hash *hash, int hashsize); /* prune old entries from the DNS cache */ void Curl_hostcache_prune(struct Curl_easy *data); diff --git a/libs/libcurl/src/hostip4.c b/libs/libcurl/src/hostip4.c index 47da6055a9..1dd54e879d 100644 --- a/libs/libcurl/src/hostip4.c +++ b/libs/libcurl/src/hostip4.c @@ -112,7 +112,8 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, #endif /* CURLRES_SYNCH */ #endif /* CURLRES_IPV4 */ -#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES) +#if defined(CURLRES_IPV4) && \ + !defined(CURLRES_ARES) && !defined(CURLRES_AMIGA) /* * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function. @@ -297,4 +298,5 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, return ai; } -#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */ +#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) && + !defined(CURLRES_AMIGA) */ diff --git a/libs/libcurl/src/hostip6.c b/libs/libcurl/src/hostip6.c index d9868628c3..c62c254c72 100644 --- a/libs/libcurl/src/hostip6.c +++ b/libs/libcurl/src/hostip6.c @@ -96,8 +96,8 @@ static void dump_addrinfo(struct connectdata *conn, * non-ares version). * * Returns name information about the given hostname and port number. If - * successful, the 'addrinfo' is returned and the forth argument will point to - * memory we need to free after use. That memory *MUST* be freed with + * successful, the 'addrinfo' is returned and the fourth argument will point + * to memory we need to free after use. That memory *MUST* be freed with * Curl_freeaddrinfo(), nothing else. */ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, @@ -117,7 +117,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, *waitp = 0; /* synchronous response only */ - if(Curl_ipv6works(data)) + if((data->conn->ip_version != CURL_IPRESOLVE_V4) && Curl_ipv6works(data)) /* The stack seems to be IPv6-enabled */ pf = PF_UNSPEC; diff --git a/libs/libcurl/src/hsts.c b/libs/libcurl/src/hsts.c index 4ba0f30726..e3b686ebfa 100644 --- a/libs/libcurl/src/hsts.c +++ b/libs/libcurl/src/hsts.c @@ -156,7 +156,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, return CURLE_OK; do { - while(*p && ISSPACE(*p)) + while(*p && ISBLANK(*p)) p++; if(Curl_strncasecompare("max-age=", p, 8)) { bool quoted = FALSE; @@ -167,7 +167,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, return CURLE_BAD_FUNCTION_ARGUMENT; p += 8; - while(*p && ISSPACE(*p)) + while(*p && ISBLANK(*p)) p++; if(*p == '\"') { p++; @@ -200,7 +200,7 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, p++; } - while(*p && ISSPACE(*p)) + while(*p && ISBLANK(*p)) p++; if(*p == ';') p++; diff --git a/libs/libcurl/src/http.c b/libs/libcurl/src/http.c index 258722a602..f57859e8b0 100644 --- a/libs/libcurl/src/http.c +++ b/libs/libcurl/src/http.c @@ -84,6 +84,7 @@ #include "strdup.h" #include "altsvc.h" #include "hsts.h" +#include "ws.h" #include "c-hyper.h" /* The last 3 #include files should be in this order */ @@ -114,6 +115,10 @@ static int https_getsock(struct Curl_easy *data, #endif static CURLcode http_setup_conn(struct Curl_easy *data, struct connectdata *conn); +#ifdef USE_WEBSOCKETS +static CURLcode ws_setup_conn(struct Curl_easy *data, + struct connectdata *conn); +#endif /* * HTTP handler interface. @@ -142,6 +147,32 @@ const struct Curl_handler Curl_handler_http = { PROTOPT_USERPWDCTRL }; +#ifdef USE_WEBSOCKETS +const struct Curl_handler Curl_handler_ws = { + "WS", /* scheme */ + ws_setup_conn, /* setup_connection */ + Curl_http, /* do_it */ + Curl_http_done, /* done */ + ZERO_NULL, /* do_more */ + Curl_http_connect, /* connect_it */ + ZERO_NULL, /* connecting */ + ZERO_NULL, /* doing */ + ZERO_NULL, /* proto_getsock */ + http_getsock_do, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ + PORT_HTTP, /* defport */ + CURLPROTO_WS, /* protocol */ + CURLPROTO_HTTP, /* family */ + PROTOPT_CREDSPERREQUEST | /* flags */ + PROTOPT_USERPWDCTRL +}; +#endif + #ifdef USE_SSL /* * HTTPS handler interface. @@ -166,11 +197,38 @@ const struct Curl_handler Curl_handler_https = { PORT_HTTPS, /* defport */ CURLPROTO_HTTPS, /* protocol */ CURLPROTO_HTTP, /* family */ - PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | /* flags */ + PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */ + PROTOPT_USERPWDCTRL +}; + +#ifdef USE_WEBSOCKETS +const struct Curl_handler Curl_handler_wss = { + "WSS", /* scheme */ + ws_setup_conn, /* setup_connection */ + Curl_http, /* do_it */ + Curl_http_done, /* done */ + ZERO_NULL, /* do_more */ + Curl_http_connect, /* connect_it */ + https_connecting, /* connecting */ + ZERO_NULL, /* doing */ + https_getsock, /* proto_getsock */ + http_getsock_do, /* doing_getsock */ + ZERO_NULL, /* domore_getsock */ + ZERO_NULL, /* perform_getsock */ + ZERO_NULL, /* disconnect */ + ZERO_NULL, /* readwrite */ + ZERO_NULL, /* connection_check */ + ZERO_NULL, /* attach connection */ + PORT_HTTPS, /* defport */ + CURLPROTO_WSS, /* protocol */ + CURLPROTO_HTTP, /* family */ + PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */ PROTOPT_USERPWDCTRL }; #endif +#endif + static CURLcode http_setup_conn(struct Curl_easy *data, struct connectdata *conn) { @@ -205,6 +263,16 @@ static CURLcode http_setup_conn(struct Curl_easy *data, return CURLE_OK; } +#ifdef USE_WEBSOCKETS +static CURLcode ws_setup_conn(struct Curl_easy *data, + struct connectdata *conn) +{ + /* websockets is 1.1 only (for now) */ + data->state.httpwant = CURL_HTTP_VERSION_1_1; + return http_setup_conn(data, conn); +} +#endif + #ifndef CURL_DISABLE_PROXY /* * checkProxyHeaders() checks the linked list of custom proxy headers @@ -653,21 +721,6 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data) return result; } -/* - * Curl_allow_auth_to_host() tells if authentication, cookies or other - * "sensitive data" can (still) be sent to this host. - */ -bool Curl_allow_auth_to_host(struct Curl_easy *data) -{ - struct connectdata *conn = data->conn; - return (!data->state.this_is_a_follow || - data->set.allow_auth_to_other_hosts || - (data->state.first_host && - strcasecompare(data->state.first_host, conn->host.name) && - (data->state.first_remote_port == conn->remote_port) && - (data->state.first_remote_protocol == conn->handler->protocol))); -} - #ifndef CURL_DISABLE_HTTP_AUTH /* * Output the correct authentication header depending on the auth type @@ -866,7 +919,7 @@ Curl_http_output_auth(struct Curl_easy *data, /* To prevent the user+password to get sent to other than the original host due to a location-follow */ - if(Curl_allow_auth_to_host(data) + if(Curl_auth_allowed_to_host(data) #ifndef CURL_DISABLE_NETRC || conn->bits.netrc #endif @@ -1518,7 +1571,7 @@ CURLcode Curl_http_connect(struct Curl_easy *data, bool *done) } #endif - if(conn->given->protocol & CURLPROTO_HTTPS) { + if(conn->given->flags & PROTOPT_SSL) { /* perform SSL initialization */ result = https_connecting(data, done); if(result) @@ -1643,6 +1696,7 @@ CURLcode Curl_http_done(struct Curl_easy *data, Curl_mime_cleanpart(&http->form); Curl_dyn_reset(&data->state.headerb); Curl_hyper_done(data); + Curl_ws_done(data); if(status) return status; @@ -1919,7 +1973,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data, checkprefix("Cookie:", compare)) && /* be careful of sending this potentially sensitive header to other hosts */ - !Curl_allow_auth_to_host(data)) + !Curl_auth_allowed_to_host(data)) ; else { #ifdef USE_HYPER @@ -2032,7 +2086,7 @@ CURLcode Curl_add_timecondition(struct Curl_easy *data, void Curl_http_method(struct Curl_easy *data, struct connectdata *conn, const char **method, Curl_HttpReq *reqp) { - Curl_HttpReq httpreq = data->state.httpreq; + Curl_HttpReq httpreq = (Curl_HttpReq)data->state.httpreq; const char *request; if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && data->set.upload) @@ -2151,9 +2205,9 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn) [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ const char *host = conn->host.name; - if(((conn->given->protocol&CURLPROTO_HTTPS) && + if(((conn->given->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS)) && (conn->remote_port == PORT_HTTPS)) || - ((conn->given->protocol&CURLPROTO_HTTP) && + ((conn->given->protocol&(CURLPROTO_HTTP|CURLPROTO_WS)) && (conn->remote_port == PORT_HTTP)) ) /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include the port number in the host string */ @@ -2702,6 +2756,13 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn, FIRSTSOCKET); if(result) failf(data, "Failed sending HTTP request"); +#ifdef USE_WEBSOCKETS + else if((conn->handler->protocol & (CURLPROTO_WS|CURLPROTO_WSS)) && + !(data->set.connect_only)) + /* Set up the transfer for two-way since without CONNECT_ONLY set, this + request probably wants to send data too post upgrade */ + Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, FIRSTSOCKET); +#endif else /* HTTP GET/HEAD download: */ Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1); @@ -2731,7 +2792,7 @@ CURLcode Curl_http_cookies(struct Curl_easy *data, const char *host = data->state.aptr.cookiehost ? data->state.aptr.cookiehost : conn->host.name; const bool secure_context = - conn->handler->protocol&CURLPROTO_HTTPS || + conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) || strcasecompare("localhost", host) || !strcmp(host, "127.0.0.1") || !strcmp(host, "[::1]") ? TRUE : FALSE; @@ -3044,7 +3105,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(conn->transport != TRNSPRT_QUIC) { if(conn->httpversion < 20) { /* unless the connection is re-used and already http2 */ - switch(conn->negnpn) { + switch(conn->alpn) { case CURL_HTTP_VERSION_2: conn->httpversion = 20; /* we know we're on HTTP/2 now */ @@ -3256,6 +3317,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) } result = Curl_http_cookies(data, conn, &req); + if(!result && conn->handler->protocol&(CURLPROTO_WS|CURLPROTO_WSS)) + result = Curl_ws_request(data, &req); if(!result) result = Curl_add_timecondition(data, &req); if(!result) @@ -3520,15 +3583,15 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, else if(checkprefix("Retry-After:", headp)) { /* Retry-After = HTTP-date / delay-seconds */ curl_off_t retry_after = 0; /* zero for unknown or "now" */ - time_t date = Curl_getdate_capped(headp + strlen("Retry-After:")); - if(-1 == date) { - /* not a date, try it as a decimal number */ - (void)curlx_strtoofft(headp + strlen("Retry-After:"), - NULL, 10, &retry_after); + /* Try it as a decimal number, if it works it is not a date */ + (void)curlx_strtoofft(headp + strlen("Retry-After:"), + NULL, 10, &retry_after); + if(!retry_after) { + time_t date = Curl_getdate_capped(headp + strlen("Retry-After:")); + if(-1 != date) + /* convert date to number of seconds into the future */ + retry_after = date - time(NULL); } - else - /* convert date to number of seconds into the future */ - retry_after = date - time(NULL); data->info.retry_after = retry_after; /* store it */ } else if(!k->http_bodyless && checkprefix("Content-Range:", headp)) { @@ -3540,7 +3603,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, The second format was added since Sun's webserver JavaWebServer/1.1.1 obviously sends the header this way! The third added since some servers use that! - The forth means the requested range was unsatisfied. + The fourth means the requested range was unsatisfied. */ char *ptr = headp + strlen("Content-Range:"); @@ -3568,7 +3631,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, const char *host = data->state.aptr.cookiehost? data->state.aptr.cookiehost:conn->host.name; const bool secure_context = - conn->handler->protocol&CURLPROTO_HTTPS || + conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) || strcasecompare("localhost", host) || !strcmp(host, "127.0.0.1") || !strcmp(host, "[::1]") ? TRUE : FALSE; @@ -3652,7 +3715,14 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, #ifndef CURL_DISABLE_HSTS /* If enabled, the header is incoming and this is over HTTPS */ else if(data->hsts && checkprefix("Strict-Transport-Security:", headp) && - (conn->handler->flags & PROTOPT_SSL)) { + ((conn->handler->flags & PROTOPT_SSL) || +#ifdef CURLDEBUG + /* allow debug builds to circumvent the HTTPS restriction */ + getenv("CURL_HSTS_HTTP") +#else + 0 +#endif + )) { CURLcode check = Curl_hsts_parse(data->hsts, data->state.up.hostname, headp + strlen("Strict-Transport-Security:")); @@ -3734,7 +3804,7 @@ CURLcode Curl_http_statusline(struct Curl_easy *data, connclose(conn, "HTTP/1.0 close after body"); } else if(conn->httpversion == 20 || - (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) { + (k->upgr101 == UPGR101_H2 && k->httpcode == 101)) { DEBUGF(infof(data, "HTTP/2 found, allow multiplexing")); /* HTTP/2 cannot avoid multiplexing since it is a core functionality of the protocol */ @@ -3960,9 +4030,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, break; case 101: /* Switching Protocols */ - if(k->upgr101 == UPGR101_REQUESTED) { + if(k->upgr101 == UPGR101_H2) { /* Switching to HTTP/2 */ - infof(data, "Received 101"); + infof(data, "Received 101, Switching to HTTP/2"); k->upgr101 = UPGR101_RECEIVED; /* we'll get more headers (HTTP/2 response) */ @@ -3976,8 +4046,21 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, return result; *nread = 0; } +#ifdef USE_WEBSOCKETS + else if(k->upgr101 == UPGR101_WS) { + /* verify the response */ + result = Curl_ws_accept(data); + if(result) + return result; + k->header = FALSE; /* no more header to parse! */ + if(data->set.connect_only) { + k->keepon &= ~KEEP_RECV; /* read no more content */ + *nread = 0; + } + } +#endif else { - /* Switching to another protocol (e.g. WebSocket) */ + /* Not switching to another protocol */ k->header = FALSE; /* no more header to parse! */ } break; @@ -4070,6 +4153,16 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, return CURLE_HTTP_RETURNED_ERROR; } +#ifdef USE_WEBSOCKETS + /* All non-101 HTTP status codes are bad when wanting to upgrade to + websockets */ + if(data->req.upgr101 == UPGR101_WS) { + failf(data, "Refused WebSockets upgrade: %d", k->httpcode); + return CURLE_HTTP_RETURNED_ERROR; + } +#endif + + data->req.deductheadercount = (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0; diff --git a/libs/libcurl/src/http.h b/libs/libcurl/src/http.h index 9eff6b1ff9..f7cbb34244 100644 --- a/libs/libcurl/src/http.h +++ b/libs/libcurl/src/http.h @@ -24,6 +24,7 @@ * ***************************************************************************/ #include "curl_setup.h" +#include "ws.h" typedef enum { HTTPREQ_GET, @@ -50,6 +51,15 @@ extern const struct Curl_handler Curl_handler_http; extern const struct Curl_handler Curl_handler_https; #endif +#ifdef USE_WEBSOCKETS +extern const struct Curl_handler Curl_handler_ws; + +#ifdef USE_SSL +extern const struct Curl_handler Curl_handler_wss; +#endif +#endif /* websockets */ + + /* Header specific functions */ bool Curl_compareheader(const char *headerline, /* line to check */ const char *header, /* header keyword _with_ colon */ @@ -218,6 +228,10 @@ struct HTTP { HTTPSEND_BODY /* sending body */ } sending; +#ifdef USE_WEBSOCKETS + struct websocket ws; +#endif + #ifndef CURL_DISABLE_HTTP struct dynbuf send_buffer; /* used if the request couldn't be sent in one chunk, points to an allocated send_buffer @@ -227,13 +241,11 @@ struct HTTP { /*********** for HTTP/2 we store stream-local data here *************/ int32_t stream_id; /* stream we are interested in */ - bool bodystarted; /* We store non-final and final response headers here, per-stream */ struct dynbuf header_recvbuf; size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into upper layer */ struct dynbuf trailer_recvbuf; - int status_code; /* HTTP status code */ const uint8_t *pausedata; /* pointer to data received in on_data_chunk */ size_t pauselen; /* the number of bytes left in data */ bool close_handled; /* TRUE if stream closure is handled by libcurl */ @@ -244,6 +256,8 @@ struct HTTP { uint32_t error; /* HTTP/2 stream error code */ #endif #if defined(USE_NGHTTP2) || defined(USE_NGHTTP3) + bool bodystarted; + int status_code; /* HTTP status code */ bool closed; /* TRUE on HTTP2 stream close */ char *mem; /* points to a buffer in memory to store received data */ size_t len; /* size of the buffer 'mem' points to */ @@ -260,6 +274,7 @@ struct HTTP { #ifndef USE_MSH3 /*********** for HTTP/3 we store stream-local data here *************/ int64_t stream3_id; /* stream we are interested in */ + uint64_t error3; /* HTTP/3 stream error code */ bool firstheader; /* FALSE until headers arrive */ bool firstbody; /* FALSE until body arrives */ bool h3req; /* FALSE until request is issued */ @@ -366,10 +381,4 @@ Curl_http_output_auth(struct Curl_easy *data, bool proxytunnel); /* TRUE if this is the request setting up the proxy tunnel */ -/* - * Curl_allow_auth_to_host() tells if authentication, cookies or other - * "sensitive data" can (still) be sent to this host. - */ -bool Curl_allow_auth_to_host(struct Curl_easy *data); - #endif /* HEADER_CURL_HTTP_H */ diff --git a/libs/libcurl/src/http2.c b/libs/libcurl/src/http2.c index f6364d0e02..b7409b027d 100644 --- a/libs/libcurl/src/http2.c +++ b/libs/libcurl/src/http2.c @@ -1277,6 +1277,27 @@ void Curl_http2_done(struct Curl_easy *data, bool premature) } } +static int client_new(struct connectdata *conn, + nghttp2_session_callbacks *callbacks) +{ +#if NGHTTP2_VERSION_NUM < 0x013200 + /* before 1.50.0 */ + return nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn); +#else + nghttp2_option *o; + int rc = nghttp2_option_new(&o); + if(rc) + return rc; + /* turn off RFC 9113 leading and trailing white spaces validation against + HTTP field value. */ + nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(o, 1); + rc = nghttp2_session_client_new2(&conn->proto.httpc.h2, callbacks, conn, + o); + nghttp2_option_del(o); + return rc; +#endif +} + /* * Initialize nghttp2 for a Curl connection */ @@ -1317,7 +1338,7 @@ static CURLcode http2_init(struct Curl_easy *data, struct connectdata *conn) nghttp2_session_callbacks_set_error_callback(callbacks, error_callback); /* The nghttp2 session is not yet setup, do it */ - rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn); + rc = client_new(conn, callbacks); nghttp2_session_callbacks_del(callbacks); @@ -1371,7 +1392,7 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req, NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64); free(base64); - k->upgr101 = UPGR101_REQUESTED; + k->upgr101 = UPGR101_H2; return result; } diff --git a/libs/libcurl/src/http_aws_sigv4.c b/libs/libcurl/src/http_aws_sigv4.c index 390236bc6c..440eb385f8 100644 --- a/libs/libcurl/src/http_aws_sigv4.c +++ b/libs/libcurl/src/http_aws_sigv4.c @@ -29,8 +29,6 @@ #include "urldata.h" #include "strcase.h" #include "strdup.h" -#include "vauth/vauth.h" -#include "vauth/digest.h" #include "http_aws_sigv4.h" #include "curl_sha256.h" #include "transfer.h" @@ -46,6 +44,8 @@ #include "curl_memory.h" #include "memdebug.h" +#include "slist.h" + #define HMAC_SHA256(k, kl, d, dl, o) \ do { \ ret = Curl_hmacit(Curl_HMAC_SHA256, \ @@ -53,49 +53,241 @@ (unsigned int)kl, \ (unsigned char *)d, \ (unsigned int)dl, o); \ - if(ret != CURLE_OK) { \ + if(ret) { \ goto fail; \ } \ } while(0) +#define TIMESTAMP_SIZE 17 + static void sha256_to_hex(char *dst, unsigned char *sha, size_t dst_l) { int i; DEBUGASSERT(dst_l >= 65); for(i = 0; i < 32; ++i) { - curl_msnprintf(dst + (i * 2), dst_l - (i * 2), "%02x", sha[i]); + msnprintf(dst + (i * 2), dst_l - (i * 2), "%02x", sha[i]); + } +} + +static char *find_date_hdr(struct Curl_easy *data, const char *sig_hdr) +{ + char *tmp = Curl_checkheaders(data, sig_hdr, strlen(sig_hdr)); + + if(tmp) + return tmp; + return Curl_checkheaders(data, STRCONST("Date")); +} + +/* remove whitespace, and lowercase all headers */ +static void trim_headers(struct curl_slist *head) +{ + struct curl_slist *l; + for(l = head; l; l = l->next) { + char *value; /* to read from */ + char *store; + size_t colon = strcspn(l->data, ":"); + Curl_strntolower(l->data, l->data, colon); + + value = &l->data[colon]; + if(!*value) + continue; + ++value; + store = value; + + /* skip leading whitespace */ + while(*value && ISBLANK(*value)) + value++; + + while(*value) { + int space = 0; + while(*value && ISBLANK(*value)) { + value++; + space++; + } + if(space) { + /* replace any number of consecutive whitespace with a single space, + unless at the end of the string, then nothing */ + if(*value) + *store++ = ' '; + } + else + *store++ = *value++; + } + *store = 0; /* null terminate */ } } +/* maximum lenth for the aws sivg4 parts */ +#define MAX_SIGV4_LEN 64 +#define MAX_SIGV4_LEN_TXT "64" + +#define DATE_HDR_KEY_LEN (MAX_SIGV4_LEN + sizeof("X--Date")) + +#define MAX_HOST_LEN 255 +/* FQDN + host: */ +#define FULL_HOST_LEN (MAX_HOST_LEN + sizeof("host:")) + +/* string been x-PROVIDER-date:TIMESTAMP, I need +1 for ':' */ +#define DATE_FULL_HDR_LEN (DATE_HDR_KEY_LEN + TIMESTAMP_SIZE + 1) + +/* timestamp should point to a buffer of at last TIMESTAMP_SIZE bytes */ +static CURLcode make_headers(struct Curl_easy *data, + const char *hostname, + char *timestamp, + char *provider1, + char **date_header, + struct dynbuf *canonical_headers, + struct dynbuf *signed_headers) +{ + char date_hdr_key[DATE_HDR_KEY_LEN]; + char date_full_hdr[DATE_FULL_HDR_LEN]; + struct curl_slist *head = NULL; + struct curl_slist *tmp_head = NULL; + CURLcode ret = CURLE_OUT_OF_MEMORY; + struct curl_slist *l; + int again = 1; + + /* provider1 mid */ + Curl_strntolower(provider1, provider1, strlen(provider1)); + provider1[0] = Curl_raw_toupper(provider1[0]); + + msnprintf(date_hdr_key, DATE_HDR_KEY_LEN, "X-%s-Date", provider1); + + /* provider1 lowercase */ + Curl_strntolower(provider1, provider1, 1); /* first byte only */ + msnprintf(date_full_hdr, DATE_FULL_HDR_LEN, + "x-%s-date:%s", provider1, timestamp); + + if(Curl_checkheaders(data, STRCONST("Host"))) { + head = NULL; + } + else { + char full_host[FULL_HOST_LEN + 1]; + + if(data->state.aptr.host) { + size_t pos; + + if(strlen(data->state.aptr.host) > FULL_HOST_LEN) { + ret = CURLE_URL_MALFORMAT; + goto fail; + } + strcpy(full_host, data->state.aptr.host); + /* remove /r/n as the separator for canonical request must be '\n' */ + pos = strcspn(full_host, "\n\r"); + full_host[pos] = 0; + } + else { + if(strlen(hostname) > MAX_HOST_LEN) { + ret = CURLE_URL_MALFORMAT; + goto fail; + } + msnprintf(full_host, FULL_HOST_LEN, "host:%s", hostname); + } + + head = curl_slist_append(NULL, full_host); + if(!head) + goto fail; + } + + + for(l = data->set.headers; l; l = l->next) { + tmp_head = curl_slist_append(head, l->data); + if(!tmp_head) + goto fail; + head = tmp_head; + } + + trim_headers(head); + + *date_header = find_date_hdr(data, date_hdr_key); + if(!*date_header) { + tmp_head = curl_slist_append(head, date_full_hdr); + if(!tmp_head) + goto fail; + head = tmp_head; + *date_header = curl_maprintf("%s: %s", date_hdr_key, timestamp); + } + else { + char *value; + + *date_header = strdup(*date_header); + if(!*date_header) + goto fail; + + value = strchr(*date_header, ':'); + if(!value) + goto fail; + ++value; + while(ISBLANK(*value)) + ++value; + strncpy(timestamp, value, TIMESTAMP_SIZE - 1); + timestamp[TIMESTAMP_SIZE - 1] = 0; + } + + /* alpha-sort in a case sensitive manner */ + do { + again = 0; + for(l = head; l; l = l->next) { + struct curl_slist *next = l->next; + + if(next && strcmp(l->data, next->data) > 0) { + char *tmp = l->data; + + l->data = next->data; + next->data = tmp; + again = 1; + } + } + } while(again); + + for(l = head; l; l = l->next) { + char *tmp; + + if(Curl_dyn_add(canonical_headers, l->data)) + goto fail; + if(Curl_dyn_add(canonical_headers, "\n")) + goto fail; + + tmp = strchr(l->data, ':'); + if(tmp) + *tmp = 0; + + if(l != head) { + if(Curl_dyn_add(signed_headers, ";")) + goto fail; + } + if(Curl_dyn_add(signed_headers, l->data)) + goto fail; + } + + ret = CURLE_OK; +fail: + curl_slist_free_all(head); + + return ret; +} + CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) { CURLcode ret = CURLE_OUT_OF_MEMORY; struct connectdata *conn = data->conn; size_t len; - const char *tmp0; - const char *tmp1; - char *provider0_low = NULL; - char *provider0_up = NULL; - char *provider1_low = NULL; - char *provider1_mid = NULL; - char *region = NULL; - char *service = NULL; + const char *arg; + char provider0[MAX_SIGV4_LEN + 1]=""; + char provider1[MAX_SIGV4_LEN + 1]=""; + char region[MAX_SIGV4_LEN + 1]=""; + char service[MAX_SIGV4_LEN + 1]=""; const char *hostname = conn->host.name; -#ifdef DEBUGBUILD - char *force_timestamp; -#endif time_t clock; struct tm tm; - char timestamp[17]; + char timestamp[TIMESTAMP_SIZE]; char date[9]; - const char *content_type = Curl_checkheaders(data, STRCONST("Content-Type")); - char *canonical_headers = NULL; - char *signed_headers = NULL; - Curl_HttpReq httpreq; - const char *method; - size_t post_data_len; - const char *post_data = data->set.postfields ? data->set.postfields : ""; + struct dynbuf canonical_headers; + struct dynbuf signed_headers; + char *date_header = NULL; + const char *post_data = data->set.postfields; + size_t post_data_len = 0; unsigned char sha_hash[32]; char sha_hex[65]; char *canonical_request = NULL; @@ -103,10 +295,9 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) char *credential_scope = NULL; char *str_to_sign = NULL; const char *user = data->state.aptr.user ? data->state.aptr.user : ""; - const char *passwd = data->state.aptr.passwd ? data->state.aptr.passwd : ""; char *secret = NULL; - unsigned char tmp_sign0[32] = {0}; - unsigned char tmp_sign1[32] = {0}; + unsigned char sign0[32] = {0}; + unsigned char sign1[32] = {0}; char *auth_headers = NULL; DEBUGASSERT(!proxy); @@ -117,6 +308,10 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) return CURLE_OK; } + /* we init thoses buffers here, so goto fail will free initialized dynbuf */ + Curl_dyn_init(&canonical_headers, CURL_MAX_HTTP_HEADER); + Curl_dyn_init(&signed_headers, CURL_MAX_HTTP_HEADER); + /* * Parameters parsing * Google and Outscale use the same OSC or GOOG, @@ -124,223 +319,154 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) * AWS is the default because most of non-amazon providers * are still using aws:amz as a prefix. */ - tmp0 = data->set.str[STRING_AWS_SIGV4] ? + arg = data->set.str[STRING_AWS_SIGV4] ? data->set.str[STRING_AWS_SIGV4] : "aws:amz"; - tmp1 = strchr(tmp0, ':'); - len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0); - if(len < 1) { - infof(data, "first provider can't be empty"); + + /* provider1[:provider2[:region[:service]]] + + No string can be longer than N bytes of non-whitespace + */ + (void)sscanf(arg, "%" MAX_SIGV4_LEN_TXT "[^:]" + ":%" MAX_SIGV4_LEN_TXT "[^:]" + ":%" MAX_SIGV4_LEN_TXT "[^:]" + ":%" MAX_SIGV4_LEN_TXT "s", + provider0, provider1, region, service); + if(!provider0[0]) { + failf(data, "first provider can't be empty"); ret = CURLE_BAD_FUNCTION_ARGUMENT; goto fail; } - provider0_low = malloc(len + 1); - provider0_up = malloc(len + 1); - if(!provider0_low || !provider0_up) { - goto fail; - } - Curl_strntolower(provider0_low, tmp0, len); - provider0_low[len] = '\0'; - Curl_strntoupper(provider0_up, tmp0, len); - provider0_up[len] = '\0'; - - if(tmp1) { - tmp0 = tmp1 + 1; - tmp1 = strchr(tmp0, ':'); - len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0); - if(len < 1) { - infof(data, "second provider can't be empty"); - ret = CURLE_BAD_FUNCTION_ARGUMENT; - goto fail; - } - provider1_low = malloc(len + 1); - provider1_mid = malloc(len + 1); - if(!provider1_low || !provider1_mid) { - goto fail; - } - Curl_strntolower(provider1_low, tmp0, len); - provider1_low[len] = '\0'; - Curl_strntolower(provider1_mid, tmp0, len); - provider1_mid[0] = Curl_raw_toupper(provider1_mid[0]); - provider1_mid[len] = '\0'; - - if(tmp1) { - tmp0 = tmp1 + 1; - tmp1 = strchr(tmp0, ':'); - len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0); - if(len < 1) { - infof(data, "region can't be empty"); - ret = CURLE_BAD_FUNCTION_ARGUMENT; - goto fail; - } - region = Curl_memdup(tmp0, len + 1); - if(!region) { - goto fail; - } - region[len] = '\0'; - - if(tmp1) { - tmp0 = tmp1 + 1; - service = strdup(tmp0); - if(!service) { - goto fail; - } - if(strlen(service) < 1) { - infof(data, "service can't be empty"); - ret = CURLE_BAD_FUNCTION_ARGUMENT; - goto fail; - } - } - } - } - else { - provider1_low = Curl_memdup(provider0_low, len + 1); - provider1_mid = Curl_memdup(provider0_low, len + 1); - if(!provider1_low || !provider1_mid) { - goto fail; - } - provider1_mid[0] = Curl_raw_toupper(provider1_mid[0]); - } + else if(!provider1[0]) + strcpy(provider1, provider0); - if(!service) { - tmp0 = hostname; - tmp1 = strchr(tmp0, '.'); - if(!tmp1) { - infof(data, "service missing in parameters or hostname"); + if(!service[0]) { + char *hostdot = strchr(hostname, '.'); + if(!hostdot) { + failf(data, "service missing in parameters and hostname"); ret = CURLE_URL_MALFORMAT; goto fail; } - len = tmp1 - tmp0; - service = Curl_memdup(tmp0, len + 1); - if(!service) { + len = hostdot - hostname; + if(len > MAX_SIGV4_LEN) { + failf(data, "service too long in hostname"); + ret = CURLE_URL_MALFORMAT; goto fail; } + strncpy(service, hostname, len); service[len] = '\0'; - if(!region) { - tmp0 = tmp1 + 1; - tmp1 = strchr(tmp0, '.'); - if(!tmp1) { - infof(data, "region missing in parameters or hostname"); + if(!region[0]) { + const char *reg = hostdot + 1; + const char *hostreg = strchr(reg, '.'); + if(!hostreg) { + failf(data, "region missing in parameters and hostname"); ret = CURLE_URL_MALFORMAT; goto fail; } - len = tmp1 - tmp0; - region = Curl_memdup(tmp0, len + 1); - if(!region) { + len = hostreg - reg; + if(len > MAX_SIGV4_LEN) { + failf(data, "region too long in hostname"); + ret = CURLE_URL_MALFORMAT; goto fail; } + strncpy(region, reg, len); region[len] = '\0'; } } #ifdef DEBUGBUILD - force_timestamp = getenv("CURL_FORCETIME"); - if(force_timestamp) - clock = 0; - else - time(&clock); + { + char *force_timestamp = getenv("CURL_FORCETIME"); + if(force_timestamp) + clock = 0; + else + time(&clock); + } #else time(&clock); #endif ret = Curl_gmtime(clock, &tm); - if(ret != CURLE_OK) { + if(ret) { goto fail; } if(!strftime(timestamp, sizeof(timestamp), "%Y%m%dT%H%M%SZ", &tm)) { + ret = CURLE_OUT_OF_MEMORY; goto fail; } + + ret = make_headers(data, hostname, timestamp, provider1, + &date_header, &canonical_headers, &signed_headers); + if(ret) + goto fail; + ret = CURLE_OUT_OF_MEMORY; + memcpy(date, timestamp, sizeof(date)); date[sizeof(date) - 1] = 0; - if(content_type) { - content_type = strchr(content_type, ':'); - if(!content_type) { - ret = CURLE_FAILED_INIT; - goto fail; - } - content_type++; - /* Skip whitespace now */ - while(*content_type == ' ' || *content_type == '\t') - ++content_type; - - canonical_headers = curl_maprintf("content-type:%s\n" - "host:%s\n" - "x-%s-date:%s\n", - content_type, - hostname, - provider1_low, timestamp); - signed_headers = curl_maprintf("content-type;host;x-%s-date", - provider1_low); - } - else { - canonical_headers = curl_maprintf("host:%s\n" - "x-%s-date:%s\n", - hostname, - provider1_low, timestamp); - signed_headers = curl_maprintf("host;x-%s-date", provider1_low); - } - - if(!canonical_headers || !signed_headers) { - goto fail; + if(post_data) { + if(data->set.postfieldsize < 0) + post_data_len = strlen(post_data); + else + post_data_len = (size_t)data->set.postfieldsize; } - - if(data->set.postfieldsize < 0) - post_data_len = strlen(post_data); - else - post_data_len = (size_t)data->set.postfieldsize; if(Curl_sha256it(sha_hash, (const unsigned char *) post_data, - post_data_len)) { + post_data_len)) goto fail; - } sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex)); - Curl_http_method(data, conn, &method, &httpreq); - - canonical_request = - curl_maprintf("%s\n" /* HTTPRequestMethod */ - "%s\n" /* CanonicalURI */ - "%s\n" /* CanonicalQueryString */ - "%s\n" /* CanonicalHeaders */ - "%s\n" /* SignedHeaders */ - "%s", /* HashedRequestPayload in hex */ - method, - data->state.up.path, - data->state.up.query ? data->state.up.query : "", - canonical_headers, - signed_headers, - sha_hex); - if(!canonical_request) { - goto fail; + { + Curl_HttpReq httpreq; + const char *method; + + Curl_http_method(data, conn, &method, &httpreq); + + canonical_request = + curl_maprintf("%s\n" /* HTTPRequestMethod */ + "%s\n" /* CanonicalURI */ + "%s\n" /* CanonicalQueryString */ + "%s\n" /* CanonicalHeaders */ + "%s\n" /* SignedHeaders */ + "%s", /* HashedRequestPayload in hex */ + method, + data->state.up.path, + data->state.up.query ? data->state.up.query : "", + Curl_dyn_ptr(&canonical_headers), + Curl_dyn_ptr(&signed_headers), + sha_hex); + if(!canonical_request) + goto fail; } - request_type = curl_maprintf("%s4_request", provider0_low); - if(!request_type) { + /* provider 0 lowercase */ + Curl_strntolower(provider0, provider0, strlen(provider0)); + request_type = curl_maprintf("%s4_request", provider0); + if(!request_type) goto fail; - } credential_scope = curl_maprintf("%s/%s/%s/%s", date, region, service, request_type); - if(!credential_scope) { + if(!credential_scope) goto fail; - } if(Curl_sha256it(sha_hash, (unsigned char *) canonical_request, - strlen(canonical_request))) { + strlen(canonical_request))) goto fail; - } sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex)); + /* provider 0 uppercase */ + Curl_strntoupper(provider0, provider0, strlen(provider0)); + /* - * Google allow to use rsa key instead of HMAC, so this code might change - * In the future, but for now we support only HMAC version + * Google allows using RSA key instead of HMAC, so this code might change + * in the future. For now we ony support HMAC. */ str_to_sign = curl_maprintf("%s4-HMAC-SHA256\n" /* Algorithm */ "%s\n" /* RequestDateTime */ "%s\n" /* CredentialScope */ "%s", /* HashedCanonicalRequest in hex */ - provider0_up, + provider0, timestamp, credential_scope, sha_hex); @@ -348,36 +474,33 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) goto fail; } - secret = curl_maprintf("%s4%s", provider0_up, passwd); - if(!secret) { + /* provider 0 uppercase */ + secret = curl_maprintf("%s4%s", provider0, + data->state.aptr.passwd ? + data->state.aptr.passwd : ""); + if(!secret) goto fail; - } - HMAC_SHA256(secret, strlen(secret), - date, strlen(date), tmp_sign0); - HMAC_SHA256(tmp_sign0, sizeof(tmp_sign0), - region, strlen(region), tmp_sign1); - HMAC_SHA256(tmp_sign1, sizeof(tmp_sign1), - service, strlen(service), tmp_sign0); - HMAC_SHA256(tmp_sign0, sizeof(tmp_sign0), - request_type, strlen(request_type), tmp_sign1); - HMAC_SHA256(tmp_sign1, sizeof(tmp_sign1), - str_to_sign, strlen(str_to_sign), tmp_sign0); + HMAC_SHA256(secret, strlen(secret), date, strlen(date), sign0); + HMAC_SHA256(sign0, sizeof(sign0), region, strlen(region), sign1); + HMAC_SHA256(sign1, sizeof(sign1), service, strlen(service), sign0); + HMAC_SHA256(sign0, sizeof(sign0), request_type, strlen(request_type), sign1); + HMAC_SHA256(sign1, sizeof(sign1), str_to_sign, strlen(str_to_sign), sign0); - sha256_to_hex(sha_hex, tmp_sign0, sizeof(sha_hex)); + sha256_to_hex(sha_hex, sign0, sizeof(sha_hex)); + /* provider 0 uppercase */ auth_headers = curl_maprintf("Authorization: %s4-HMAC-SHA256 " "Credential=%s/%s, " "SignedHeaders=%s, " "Signature=%s\r\n" - "X-%s-Date: %s\r\n", - provider0_up, + "%s\r\n", + provider0, user, credential_scope, - signed_headers, + Curl_dyn_ptr(&signed_headers), sha_hex, - provider1_mid, - timestamp); + date_header); if(!auth_headers) { goto fail; } @@ -388,19 +511,14 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) ret = CURLE_OK; fail: - free(provider0_low); - free(provider0_up); - free(provider1_low); - free(provider1_mid); - free(region); - free(service); - free(canonical_headers); - free(signed_headers); + Curl_dyn_free(&canonical_headers); + Curl_dyn_free(&signed_headers); free(canonical_request); free(request_type); free(credential_scope); free(str_to_sign); free(secret); + free(date_header); return ret; } diff --git a/libs/libcurl/src/http_chunks.c b/libs/libcurl/src/http_chunks.c index 2aeb753939..0b836851ac 100644 --- a/libs/libcurl/src/http_chunks.c +++ b/libs/libcurl/src/http_chunks.c @@ -100,7 +100,7 @@ void Curl_httpchunk_init(struct Curl_easy *data) CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, char *datap, ssize_t datalen, - ssize_t *wrotep, + ssize_t *wrote, CURLcode *extrap) { CURLcode result = CURLE_OK; @@ -109,7 +109,6 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, struct SingleRequest *k = &data->req; size_t piece; curl_off_t length = (curl_off_t)datalen; - size_t *wrote = (size_t *)wrotep; *wrote = 0; /* nothing's written yet */ @@ -126,7 +125,7 @@ CHUNKcode Curl_httpchunk_read(struct Curl_easy *data, while(length) { switch(ch->state) { case CHUNK_HEX: - if(isxdigit_ascii(*datap)) { + if(ISXDIGIT(*datap)) { if(ch->hexindex < CHUNK_MAXNUM_LEN) { ch->hexbuffer[ch->hexindex] = *datap; datap++; diff --git a/libs/libcurl/src/http_digest.c b/libs/libcurl/src/http_digest.c index c2472e103b..a71c6b7cfb 100644 --- a/libs/libcurl/src/http_digest.c +++ b/libs/libcurl/src/http_digest.c @@ -58,11 +58,11 @@ CURLcode Curl_input_digest(struct Curl_easy *data, digest = &data->state.digest; } - if(!checkprefix("Digest", header) || !ISSPACE(header[6])) + if(!checkprefix("Digest", header) || !ISBLANK(header[6])) return CURLE_BAD_CONTENT_ENCODING; header += strlen("Digest"); - while(*header && ISSPACE(*header)) + while(*header && ISBLANK(*header)) header++; return Curl_auth_decode_digest_http_message(header, digest); diff --git a/libs/libcurl/src/http_negotiate.c b/libs/libcurl/src/http_negotiate.c index 0ac4ead097..5909f85b0d 100644 --- a/libs/libcurl/src/http_negotiate.c +++ b/libs/libcurl/src/http_negotiate.c @@ -84,7 +84,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, /* Obtain the input token, if any */ header += strlen("Negotiate"); - while(*header && ISSPACE(*header)) + while(*header && ISBLANK(*header)) header++; len = strlen(header); diff --git a/libs/libcurl/src/http_ntlm.c b/libs/libcurl/src/http_ntlm.c index a1f0f20cbb..5a6a977905 100644 --- a/libs/libcurl/src/http_ntlm.c +++ b/libs/libcurl/src/http_ntlm.c @@ -29,7 +29,7 @@ /* * NTLM details: * - * https://davenport.sourceforge.io/ntlm.html + * https://davenport.sourceforge.net/ntlm.html * https://www.innovation.ch/java/ntlm.html */ diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c index a69cff2b3c..cc20b3a801 100644 --- a/libs/libcurl/src/http_proxy.c +++ b/libs/libcurl/src/http_proxy.c @@ -212,10 +212,8 @@ void Curl_connect_done(struct Curl_easy *data) Curl_dyn_free(&s->rcvbuf); Curl_dyn_free(&s->req); - /* restore the protocol pointer, if not already done */ - if(s->prot_save) - data->req.p.http = s->prot_save; - s->prot_save = NULL; + /* restore the protocol pointer */ + data->req.p.http = s->prot_save; data->info.httpcode = 0; /* clear it as it might've been used for the proxy */ data->req.ignorebody = FALSE; @@ -393,8 +391,8 @@ static CURLcode CONNECT(struct Curl_easy *data, if(!result) /* send to debug callback! */ - result = Curl_debug(data, CURLINFO_HEADER_OUT, - k->upload_fromhere, bytes_written); + Curl_debug(data, CURLINFO_HEADER_OUT, + k->upload_fromhere, bytes_written); s->nsend -= bytes_written; k->upload_fromhere += bytes_written; diff --git a/libs/libcurl/src/idn_win32.c b/libs/libcurl/src/idn_win32.c index dacba01d7a..2433d927ee 100644 --- a/libs/libcurl/src/idn_win32.c +++ b/libs/libcurl/src/idn_win32.c @@ -67,10 +67,10 @@ WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags, #define IDN_MAX_LENGTH 255 -bool curl_win32_idn_to_ascii(const char *in, char **out); -bool curl_win32_ascii_to_idn(const char *in, char **out); +bool Curl_win32_idn_to_ascii(const char *in, char **out); +bool Curl_win32_ascii_to_idn(const char *in, char **out); -bool curl_win32_idn_to_ascii(const char *in, char **out) +bool Curl_win32_idn_to_ascii(const char *in, char **out) { bool success = FALSE; @@ -93,7 +93,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out) return success; } -bool curl_win32_ascii_to_idn(const char *in, char **out) +bool Curl_win32_ascii_to_idn(const char *in, char **out) { bool success = FALSE; diff --git a/libs/libcurl/src/imap.c b/libs/libcurl/src/imap.c index 4b46ef1eff..ffa08bf7a4 100644 --- a/libs/libcurl/src/imap.c +++ b/libs/libcurl/src/imap.c @@ -83,6 +83,7 @@ #include "bufref.h" #include "curl_sasl.h" #include "warnless.h" +#include "curl_ctype.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -1885,22 +1886,17 @@ static char *imap_atom(const char *str, bool escape_only) */ static bool imap_is_bchar(char ch) { + /* Performing the alnum check with this macro is faster because of ASCII + arithmetic */ + if(ISALNUM(ch)) + return true; + switch(ch) { /* bchar */ case ':': case '@': case '/': /* bchar -> achar */ case '&': case '=': - /* bchar -> achar -> uchar -> unreserved */ - case '0': case '1': case '2': case '3': case '4': case '5': case '6': - case '7': case '8': case '9': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': - case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': - case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': - case 'V': case 'W': case 'X': case 'Y': case 'Z': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': - case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': - case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': - case 'v': case 'w': case 'x': case 'y': case 'z': + /* bchar -> achar -> uchar -> unreserved (without alphanumeric) */ case '-': case '.': case '_': case '~': /* bchar -> achar -> uchar -> sub-delims-sh */ case '!': case '$': case '\'': case '(': case ')': case '*': diff --git a/libs/libcurl/src/ldap.c b/libs/libcurl/src/ldap.c index 51a32dc964..b073349042 100644 --- a/libs/libcurl/src/ldap.c +++ b/libs/libcurl/src/ldap.c @@ -37,6 +37,18 @@ * OpenLDAP library versions, USE_OPENLDAP shall not be defined. */ +/* Wincrypt must be included before anything that could include OpenSSL. */ +#if defined(USE_WIN32_CRYPTO) +#include <wincrypt.h> +/* Undefine wincrypt conflicting symbols for BoringSSL. */ +#undef X509_NAME +#undef X509_EXTENSIONS +#undef PKCS7_ISSUER_AND_SERIAL +#undef PKCS7_SIGNER_INFO +#undef OCSP_REQUEST +#undef OCSP_RESPONSE +#endif + #ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */ # include <winldap.h> # ifndef LDAP_VENDOR_NAME @@ -344,7 +356,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) #ifdef HAVE_LDAP_SSL #ifdef USE_WIN32_LDAP /* Win32 LDAP SDK doesn't support insecure mode without CA! */ - server = ldap_sslinit(host, (int)conn->port, 1); + server = ldap_sslinit(host, conn->port, 1); ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON); #else int ldap_option; @@ -390,9 +402,9 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) result = CURLE_SSL_CERTPROBLEM; goto quit; } - server = ldapssl_init(host, (int)conn->port, 1); + server = ldapssl_init(host, conn->port, 1); if(!server) { - failf(data, "LDAP local: Cannot connect to %s:%ld", + failf(data, "LDAP local: Cannot connect to %s:%u", conn->host.dispname, conn->port); result = CURLE_COULDNT_CONNECT; goto quit; @@ -431,9 +443,9 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) result = CURLE_SSL_CERTPROBLEM; goto quit; } - server = ldap_init(host, (int)conn->port); + server = ldap_init(host, conn->port); if(!server) { - failf(data, "LDAP local: Cannot connect to %s:%ld", + failf(data, "LDAP local: Cannot connect to %s:%u", conn->host.dispname, conn->port); result = CURLE_COULDNT_CONNECT; goto quit; @@ -472,9 +484,9 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) goto quit; } else { - server = ldap_init(host, (int)conn->port); + server = ldap_init(host, conn->port); if(!server) { - failf(data, "LDAP local: Cannot connect to %s:%ld", + failf(data, "LDAP local: Cannot connect to %s:%u", conn->host.dispname, conn->port); result = CURLE_COULDNT_CONNECT; goto quit; diff --git a/libs/libcurl/src/libcurl.plist b/libs/libcurl/src/libcurl.plist index c8bd1ea886..fee5827e48 100644 --- a/libs/libcurl/src/libcurl.plist +++ b/libs/libcurl/src/libcurl.plist @@ -15,7 +15,7 @@ <string>se.curl.libcurl</string> <key>CFBundleVersion</key> - <string>7.84.0-DEV</string> + <string>7.86.0-DEV</string> <key>CFBundleName</key> <string>libcurl</string> @@ -27,9 +27,9 @@ <string>????</string> <key>CFBundleShortVersionString</key> - <string>libcurl 7.84.0-DEV</string> + <string>libcurl 7.86.0-DEV</string> <key>CFBundleGetInfoString</key> - <string>libcurl.plist 7.84.0-DEV</string> + <string>libcurl.plist 7.86.0-DEV</string> </dict> </plist> diff --git a/libs/libcurl/src/makefile.amiga b/libs/libcurl/src/makefile.amiga index b09fee9086..d5c8fe615e 100644 --- a/libs/libcurl/src/makefile.amiga +++ b/libs/libcurl/src/makefile.amiga @@ -31,7 +31,7 @@ ATCPSDKI= /GG/netinclude CC = m68k-amigaos-gcc -CFLAGS = -I$(ATCPSDKI) -m68020-60 -O2 -msoft-float -noixemul -g -I. -I../include -W -Wall +CFLAGS = -I$(ATCPSDKI) -m68020-60 -O2 -msoft-float -noixemul -g -I. -I../include -W -Wall -DUSE_OPENSSL -DHAVE_LIBZ include Makefile.inc OBJS = $(CSOURCES:.c=.o) diff --git a/libs/libcurl/src/md4.c b/libs/libcurl/src/md4.c index 63bade00df..e976fe7bdc 100644 --- a/libs/libcurl/src/md4.c +++ b/libs/libcurl/src/md4.c @@ -32,7 +32,8 @@ #ifdef USE_OPENSSL #include <openssl/opensslconf.h> -#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) +#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) && \ + !defined(USE_AMISSL) /* OpenSSL 3.0.0 marks the MD4 functions as deprecated */ #define OPENSSL_NO_MD4 #endif diff --git a/libs/libcurl/src/md5.c b/libs/libcurl/src/md5.c index 2164e15ff2..5be639929d 100644 --- a/libs/libcurl/src/md5.c +++ b/libs/libcurl/src/md5.c @@ -41,7 +41,7 @@ #endif #endif /* USE_MBEDTLS */ -#if defined(USE_OPENSSL) && !defined(USE_AMISSL) +#ifdef USE_OPENSSL #include <openssl/opensslconf.h> #if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_DEPRECATED_3_0) #define USE_OPENSSL_MD5 diff --git a/libs/libcurl/src/memdebug.c b/libs/libcurl/src/memdebug.c index f35a55fe22..15fb491559 100644 --- a/libs/libcurl/src/memdebug.c +++ b/libs/libcurl/src/memdebug.c @@ -129,7 +129,8 @@ static bool countcheck(const char *func, int line, const char *source) return FALSE; /* allow this */ } -void *curl_dbg_malloc(size_t wantedsize, int line, const char *source) +ALLOC_FUNC void *curl_dbg_malloc(size_t wantedsize, + int line, const char *source) { struct memdebug *mem; size_t size; @@ -155,8 +156,8 @@ void *curl_dbg_malloc(size_t wantedsize, int line, const char *source) return (mem ? mem->mem : NULL); } -void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, - int line, const char *source) +ALLOC_FUNC void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, + int line, const char *source) { struct memdebug *mem; size_t size, user_size; @@ -183,7 +184,8 @@ void *curl_dbg_calloc(size_t wanted_elements, size_t wanted_size, return (mem ? mem->mem : NULL); } -char *curl_dbg_strdup(const char *str, int line, const char *source) +ALLOC_FUNC char *curl_dbg_strdup(const char *str, + int line, const char *source) { char *mem; size_t len; @@ -207,7 +209,8 @@ char *curl_dbg_strdup(const char *str, int line, const char *source) } #if defined(WIN32) && defined(UNICODE) -wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, const char *source) +ALLOC_FUNC wchar_t *curl_dbg_wcsdup(const wchar_t *str, + int line, const char *source) { wchar_t *mem; size_t wsiz, bsiz; @@ -410,8 +413,8 @@ int curl_dbg_sclose(curl_socket_t sockfd, int line, const char *source) return res; } -FILE *curl_dbg_fopen(const char *file, const char *mode, - int line, const char *source) +ALLOC_FUNC FILE *curl_dbg_fopen(const char *file, const char *mode, + int line, const char *source) { FILE *res = fopen(file, mode); @@ -422,8 +425,8 @@ FILE *curl_dbg_fopen(const char *file, const char *mode, return res; } -FILE *curl_dbg_fdopen(int filedes, const char *mode, - int line, const char *source) +ALLOC_FUNC FILE *curl_dbg_fdopen(int filedes, const char *mode, + int line, const char *source) { FILE *res = fdopen(filedes, mode); if(source) diff --git a/libs/libcurl/src/memdebug.h b/libs/libcurl/src/memdebug.h index 3e41571e27..7fc90e83a0 100644 --- a/libs/libcurl/src/memdebug.h +++ b/libs/libcurl/src/memdebug.h @@ -30,21 +30,44 @@ * as well as the library. Do not mix with library internals! */ +#include <curl/curl.h> +#include "functypes.h" + +#if defined(__GNUC__) && __GNUC__ >= 3 +# define ALLOC_FUNC __attribute__((malloc)) +# define ALLOC_SIZE(s) __attribute__((alloc_size(s))) +# define ALLOC_SIZE2(n, s) __attribute__((alloc_size(n, s))) +#elif defined(_MSC_VER) +# define ALLOC_FUNC __declspec(restrict) +# define ALLOC_SIZE(s) +# define ALLOC_SIZE2(n, s) +#else +# define ALLOC_FUNC +# define ALLOC_SIZE(s) +# define ALLOC_SIZE2(n, s) +#endif + #define CURL_MT_LOGFNAME_BUFSIZE 512 extern FILE *curl_dbg_logfile; /* memory functions */ -CURL_EXTERN void *curl_dbg_malloc(size_t size, int line, const char *source); -CURL_EXTERN void *curl_dbg_calloc(size_t elements, size_t size, int line, - const char *source); -CURL_EXTERN void *curl_dbg_realloc(void *ptr, size_t size, int line, - const char *source); +CURL_EXTERN ALLOC_FUNC ALLOC_SIZE(1) void *curl_dbg_malloc(size_t size, + int line, + const char *source); +CURL_EXTERN ALLOC_FUNC ALLOC_SIZE2(1, 2) void *curl_dbg_calloc(size_t elements, + size_t size, int line, const char *source); +CURL_EXTERN ALLOC_SIZE(2) void *curl_dbg_realloc(void *ptr, + size_t size, + int line, + const char *source); CURL_EXTERN void curl_dbg_free(void *ptr, int line, const char *source); -CURL_EXTERN char *curl_dbg_strdup(const char *str, int line, const char *src); +CURL_EXTERN ALLOC_FUNC char *curl_dbg_strdup(const char *str, int line, + const char *src); #if defined(WIN32) && defined(UNICODE) -CURL_EXTERN wchar_t *curl_dbg_wcsdup(const wchar_t *str, int line, - const char *source); +CURL_EXTERN ALLOC_FUNC wchar_t *curl_dbg_wcsdup(const wchar_t *str, + int line, + const char *source); #endif CURL_EXTERN void curl_dbg_memdebug(const char *logname); @@ -79,10 +102,10 @@ CURL_EXTERN RECV_TYPE_RETV curl_dbg_recv(RECV_TYPE_ARG1 sockfd, const char *source); /* FILE functions */ -CURL_EXTERN FILE *curl_dbg_fopen(const char *file, const char *mode, int line, - const char *source); -CURL_EXTERN FILE *curl_dbg_fdopen(int filedes, const char *mode, +CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_fopen(const char *file, const char *mode, int line, const char *source); +CURL_EXTERN ALLOC_FUNC FILE *curl_dbg_fdopen(int filedes, const char *mode, + int line, const char *source); CURL_EXTERN int curl_dbg_fclose(FILE *file, int line, const char *source); diff --git a/libs/libcurl/src/mime.c b/libs/libcurl/src/mime.c index 11e614dc32..042141fc80 100644 --- a/libs/libcurl/src/mime.c +++ b/libs/libcurl/src/mime.c @@ -31,8 +31,9 @@ #include "urldata.h" #include "sendf.h" -#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \ - !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) +#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \ + !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_IMAP)) #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) #include <libgen.h> @@ -1924,8 +1925,8 @@ void Curl_mime_unpause(curl_mimepart *part) } -#else /* !CURL_DISABLE_HTTP && !CURL_DISABLE_MIME || - !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */ +#else /* !CURL_DISABLE_MIME && (!CURL_DISABLE_HTTP || + !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP) */ /* Mime not compiled in: define stubs for externally-referenced functions. */ curl_mime *curl_mime_init(CURL *easy) diff --git a/libs/libcurl/src/mime.h b/libs/libcurl/src/mime.h index fe1a61c060..bafde29f40 100644 --- a/libs/libcurl/src/mime.h +++ b/libs/libcurl/src/mime.h @@ -134,8 +134,9 @@ struct curl_mimepart { CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...); -#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \ - !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) +#if !defined(CURL_DISABLE_MIME) && (!defined(CURL_DISABLE_HTTP) || \ + !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_IMAP)) /* Prototypes. */ void Curl_mime_initpart(struct curl_mimepart *part, struct Curl_easy *easy); diff --git a/libs/libcurl/src/mprintf.c b/libs/libcurl/src/mprintf.c index f0401a881a..8a7c17a7ff 100644 --- a/libs/libcurl/src/mprintf.c +++ b/libs/libcurl/src/mprintf.c @@ -318,6 +318,11 @@ static int dprintf_Pass1(const char *format, struct va_stack *vto, flags |= FLAGS_PREC; precision = strtol(fmt, &fmt, 10); } + if((flags & (FLAGS_PREC | FLAGS_PRECPARAM)) == + (FLAGS_PREC | FLAGS_PRECPARAM)) + /* it is not permitted to use both kinds of precision for the same + argument */ + return 1; break; case 'h': flags |= FLAGS_SHORT; @@ -594,7 +599,7 @@ static int dprintf_formatf( /* Do the actual %-code parsing */ if(dprintf_Pass1(format, vto, endpos, ap_save)) - return -1; + return 0; end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1() created for us */ @@ -956,7 +961,7 @@ static int dprintf_formatf( else *fptr++ = 'f'; - *fptr = 0; /* and a final zero termination */ + *fptr = 0; /* and a final null-termination */ #ifdef __clang__ #pragma clang diagnostic push @@ -964,7 +969,11 @@ static int dprintf_formatf( #endif /* NOTE NOTE NOTE!! Not all sprintf implementations return number of output characters */ +#ifdef HAVE_SNPRINTF + (snprintf)(work, sizeof(work), formatbuf, p->data.dnum); +#else (sprintf)(work, formatbuf, p->data.dnum); +#endif #ifdef __clang__ #pragma clang diagnostic pop #endif @@ -1025,11 +1034,12 @@ int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, info.max = maxlength; retcode = dprintf_formatf(&info, addbyter, format, ap_save); - if((retcode != -1) && info.max) { + if(info.max) { /* we terminate this with a zero byte */ if(info.max == info.length) { /* we're at maximum, scrap the last letter */ info.buffer[-1] = 0; + DEBUGASSERT(retcode); retcode--; /* don't count the nul byte */ } else @@ -1067,13 +1077,12 @@ extern int Curl_dyn_vprintf(struct dynbuf *dyn, /* appends the formatted string, returns 0 on success, 1 on error */ int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save) { - int retcode; struct asprintf info; info.b = dyn; info.fail = 0; - retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - if((-1 == retcode) || info.fail) { + (void)dprintf_formatf(&info, alloc_addbyter, format, ap_save); + if(info.fail) { Curl_dyn_free(info.b); return 1; } @@ -1082,15 +1091,14 @@ int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save) char *curl_mvaprintf(const char *format, va_list ap_save) { - int retcode; struct asprintf info; struct dynbuf dyn; info.b = &dyn; Curl_dyn_init(info.b, DYN_APRINTF); info.fail = 0; - retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - if((-1 == retcode) || info.fail) { + (void)dprintf_formatf(&info, alloc_addbyter, format, ap_save); + if(info.fail) { Curl_dyn_free(info.b); return NULL; } diff --git a/libs/libcurl/src/mqtt.c b/libs/libcurl/src/mqtt.c index 7320747af0..4f3d14386f 100644 --- a/libs/libcurl/src/mqtt.c +++ b/libs/libcurl/src/mqtt.c @@ -186,7 +186,7 @@ static int add_passwd(const char *passwd, const size_t plen, return 0; } -/* add user to the CONN packet */ +/* add user to the CONNECT packet */ static int add_user(const char *username, const size_t ulen, unsigned char *pkt, const size_t start, int remain_pos) { @@ -204,7 +204,7 @@ static int add_user(const char *username, const size_t ulen, return 0; } -/* add client ID to the CONN packet */ +/* add client ID to the CONNECT packet */ static int add_client_id(const char *client_id, const size_t client_id_len, char *pkt, const size_t start) { @@ -216,7 +216,7 @@ static int add_client_id(const char *client_id, const size_t client_id_len, return 0; } -/* Set initial values of CONN packet */ +/* Set initial values of CONNECT packet */ static int init_connpack(char *packet, char *remain, int remain_pos) { /* Fixed header starts */ @@ -293,7 +293,7 @@ static CURLcode mqtt_connect(struct Curl_easy *data) return CURLE_OUT_OF_MEMORY; memset(packet, 0, packetlen); - /* set initial values for CONN pack */ + /* set initial values for the CONNECT packet */ pos = init_connpack(packet, remain, remain_pos); result = Curl_rand_hex(data, (unsigned char *)&client_id[clen], @@ -389,10 +389,18 @@ static CURLcode mqtt_get_topic(struct Curl_easy *data, char **topic, size_t *topiclen) { char *path = data->state.up.path; - if(strlen(path) > 1) - return Curl_urldecode(path + 1, 0, topic, topiclen, REJECT_NADA); - failf(data, "No MQTT topic found. Forgot to URL encode it?"); - return CURLE_URL_MALFORMAT; + CURLcode result = CURLE_URL_MALFORMAT; + if(strlen(path) > 1) { + result = Curl_urldecode(path + 1, 0, topic, topiclen, REJECT_NADA); + if(!result && (*topiclen > 0xffff)) { + failf(data, "Too long MQTT topic"); + result = CURLE_URL_MALFORMAT; + } + } + else + failf(data, "No MQTT topic found. Forgot to URL encode it?"); + + return result; } static CURLcode mqtt_subscribe(struct Curl_easy *data) @@ -690,7 +698,7 @@ static CURLcode mqtt_do(struct Curl_easy *data, bool *done) result = mqtt_connect(data); if(result) { - failf(data, "Error %d sending MQTT CONN request", result); + failf(data, "Error %d sending MQTT CONNECT request", result); return result; } mqstate(data, MQTT_FIRST, MQTT_CONNACK); diff --git a/libs/libcurl/src/multi.c b/libs/libcurl/src/multi.c index e0280447c2..51acba73ac 100644 --- a/libs/libcurl/src/multi.c +++ b/libs/libcurl/src/multi.c @@ -45,7 +45,6 @@ #include "multihandle.h" #include "sigpipe.h" #include "vtls/vtls.h" -#include "connect.h" #include "http_proxy.h" #include "http2.h" #include "socketpair.h" @@ -55,6 +54,22 @@ #include "curl_memory.h" #include "memdebug.h" +#ifdef __APPLE__ + +#define wakeup_write write +#define wakeup_read read +#define wakeup_close close +#define wakeup_create pipe + +#else /* __APPLE__ */ + +#define wakeup_write swrite +#define wakeup_read sread +#define wakeup_close sclose +#define wakeup_create(p) Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, p) + +#endif /* __APPLE__ */ + /* CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97 to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every @@ -68,6 +83,10 @@ #define CURL_CONNECTION_HASH_SIZE 97 #endif +#ifndef CURL_DNS_HASH_SIZE +#define CURL_DNS_HASH_SIZE 71 +#endif + #define CURL_MULTI_HANDLE 0x000bab1e #define GOOD_MULTI_HANDLE(x) \ @@ -372,7 +391,8 @@ static CURLMcode multi_addmsg(struct Curl_multi *multi, } struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ - int chashsize) /* connection hash */ + int chashsize, /* connection hash */ + int dnssize) /* dns hash */ { struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi)); @@ -381,7 +401,7 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ multi->magic = CURL_MULTI_HANDLE; - Curl_init_dnscache(&multi->hostcache); + Curl_init_dnscache(&multi->hostcache, dnssize); sh_init(&multi->sockhash, hashsize); @@ -396,7 +416,6 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ /* -1 means it not set by user, use the default value */ multi->maxconnects = -1; multi->max_concurrent_streams = 100; - multi->ipv6_works = Curl_ipv6works(NULL); #ifdef USE_WINSOCK multi->wsa_event = WSACreateEvent(); @@ -404,14 +423,14 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ goto error; #else #ifdef ENABLE_WAKEUP - if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, multi->wakeup_pair) < 0) { + if(wakeup_create(multi->wakeup_pair) < 0) { multi->wakeup_pair[0] = CURL_SOCKET_BAD; multi->wakeup_pair[1] = CURL_SOCKET_BAD; } else if(curlx_nonblock(multi->wakeup_pair[0], TRUE) < 0 || curlx_nonblock(multi->wakeup_pair[1], TRUE) < 0) { - sclose(multi->wakeup_pair[0]); - sclose(multi->wakeup_pair[1]); + wakeup_close(multi->wakeup_pair[0]); + wakeup_close(multi->wakeup_pair[1]); multi->wakeup_pair[0] = CURL_SOCKET_BAD; multi->wakeup_pair[1] = CURL_SOCKET_BAD; } @@ -435,7 +454,8 @@ struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ struct Curl_multi *curl_multi_init(void) { return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE, - CURL_CONNECTION_HASH_SIZE); + CURL_CONNECTION_HASH_SIZE, + CURL_DNS_HASH_SIZE); } CURLMcode curl_multi_add_handle(struct Curl_multi *multi, @@ -629,7 +649,7 @@ static CURLcode multi_done(struct Curl_easy *data, if(CURLE_ABORTED_BY_CALLBACK != result) { /* avoid this if we already aborted by callback to avoid this calling another callback */ - CURLcode rc = Curl_pgrsDone(data); + int rc = Curl_pgrsDone(data); if(!result && rc) result = CURLE_ABORTED_BY_CALLBACK; } @@ -731,7 +751,7 @@ static int close_connect_only(struct Curl_easy *data, if(data->state.lastconnect_id != conn->connection_id) return 0; - if(!conn->bits.connect_only) + if(!conn->connect_only) return 1; connclose(conn, "Removing connect-only easy handle"); @@ -828,6 +848,24 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi, /* Remove the association between the connection and the handle */ Curl_detach_connection(data); + if(data->set.connect_only && !data->multi_easy) { + /* This removes a handle that was part the multi interface that used + CONNECT_ONLY, that connection is now left alive but since this handle + has bits.close set nothing can use that transfer anymore and it is + forbidden from reuse. And this easy handle cannot find the connection + anymore once removed from the multi handle + + Better close the connection here, at once. + */ + struct connectdata *c; + curl_socket_t s; + s = Curl_getconnectinfo(data, &c); + if((s != CURL_SOCKET_BAD) && c) { + Curl_conncache_remove_conn(data, c, TRUE); + Curl_disconnect(data, c, TRUE); + } + } + if(data->state.lastconnect_id != -1) { /* Mark any connect-only connection for closure */ Curl_conncache_foreach(data, data->state.conn_cache, @@ -1309,8 +1347,6 @@ static CURLMcode multi_wait(struct Curl_multi *multi, pollrc = Curl_poll(ufds, nfds, 0); /* just pre-check with WinSock */ else pollrc = 0; - if(pollrc <= 0) /* now wait... if not ready during the pre-check above */ - WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE); #else pollrc = Curl_poll(ufds, nfds, timeout_ms); /* wait... */ #endif @@ -1321,6 +1357,9 @@ static CURLMcode multi_wait(struct Curl_multi *multi, retcode = pollrc; #ifdef USE_WINSOCK } + else { /* now wait... if not ready during the pre-check (pollrc == 0) */ + WSAWaitForMultipleEvents(1, &multi->wsa_event, FALSE, timeout_ms, FALSE); + } /* With WinSock, we have to run the following section unconditionally to call WSAEventSelect(fd, event, 0) on all the sockets */ { @@ -1332,20 +1371,23 @@ static CURLMcode multi_wait(struct Curl_multi *multi, unsigned r = ufds[curlfds + i].revents; unsigned short mask = 0; #ifdef USE_WINSOCK + curl_socket_t s = extra_fds[i].fd; wsa_events.lNetworkEvents = 0; - if(WSAEnumNetworkEvents(extra_fds[i].fd, NULL, &wsa_events) == 0) { + if(WSAEnumNetworkEvents(s, NULL, &wsa_events) == 0) { if(wsa_events.lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE)) mask |= CURL_WAIT_POLLIN; if(wsa_events.lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE)) mask |= CURL_WAIT_POLLOUT; if(wsa_events.lNetworkEvents & FD_OOB) mask |= CURL_WAIT_POLLPRI; - if(ret && pollrc <= 0 && wsa_events.lNetworkEvents) + if(ret && !pollrc && wsa_events.lNetworkEvents) retcode++; } - WSAEventSelect(extra_fds[i].fd, multi->wsa_event, 0); - if(pollrc <= 0) + WSAEventSelect(s, multi->wsa_event, 0); + if(!pollrc) { + extra_fds[i].revents = mask; continue; + } #endif if(r & POLLIN) mask |= CURL_WAIT_POLLIN; @@ -1368,7 +1410,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, if(bitmap & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))) { wsa_events.lNetworkEvents = 0; if(WSAEnumNetworkEvents(sockbunch[i], NULL, &wsa_events) == 0) { - if(ret && pollrc <= 0 && wsa_events.lNetworkEvents) + if(ret && !pollrc && wsa_events.lNetworkEvents) retcode++; } WSAEventSelect(sockbunch[i], multi->wsa_event, 0); @@ -1395,7 +1437,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, 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. */ - nread = sread(multi->wakeup_pair[0], buf, sizeof(buf)); + nread = wakeup_read(multi->wakeup_pair[0], buf, sizeof(buf)); if(nread <= 0) { if(nread < 0 && EINTR == SOCKERRNO) continue; @@ -1488,7 +1530,7 @@ CURLMcode curl_multi_wakeup(struct Curl_multi *multi) that will call curl_multi_wait(). If swrite() returns that it would block, it's considered successful because it means that previous calls to this function will wake up the poll(). */ - if(swrite(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) { + if(wakeup_write(multi->wakeup_pair[1], buf, sizeof(buf)) < 0) { int err = SOCKERRNO; int return_success; #ifdef USE_WINSOCK @@ -2100,7 +2142,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } } - if(data->set.connect_only) { + if(data->set.connect_only == 1) { /* keep connection open for application to use the socket */ connkeep(data->conn, "CONNECT_ONLY"); multistate(data, MSTATE_DONE); @@ -2724,8 +2766,8 @@ CURLMcode curl_multi_cleanup(struct Curl_multi *multi) WSACloseEvent(multi->wsa_event); #else #ifdef ENABLE_WAKEUP - sclose(multi->wakeup_pair[0]); - sclose(multi->wakeup_pair[1]); + wakeup_close(multi->wakeup_pair[0]); + wakeup_close(multi->wakeup_pair[1]); #endif #endif free(multi); diff --git a/libs/libcurl/src/multihandle.h b/libs/libcurl/src/multihandle.h index 76a67a89a0..a997784ea3 100644 --- a/libs/libcurl/src/multihandle.h +++ b/libs/libcurl/src/multihandle.h @@ -150,11 +150,13 @@ struct Curl_multi { 0 is used for read, 1 is used for write */ #endif #endif - /* multiplexing wanted */ - bool multiplexing; - bool recheckstate; /* see Curl_multi_connchanged */ +#define IPV6_UNKNOWN 0 +#define IPV6_DEAD 1 +#define IPV6_WORKS 2 + unsigned char ipv6_up; /* IPV6_* defined */ + bool multiplexing; /* multiplexing wanted */ + bool recheckstate; /* see Curl_multi_connchanged */ bool in_callback; /* true while executing a callback */ - bool ipv6_works; #ifdef USE_OPENSSL bool ssl_seeded; #endif diff --git a/libs/libcurl/src/multiif.h b/libs/libcurl/src/multiif.h index e0aa00b05e..0cb9d4f7f2 100644 --- a/libs/libcurl/src/multiif.h +++ b/libs/libcurl/src/multiif.h @@ -42,8 +42,9 @@ bool Curl_is_in_callback(struct Curl_easy *easy); CURLcode Curl_preconnect(struct Curl_easy *data); /* Internal version of curl_multi_init() accepts size parameters for the - socket and connection hashes */ -struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize); + socket, connection and dns hashes */ +struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize, + int dnssize); /* the write bits start at bit 16 for the *getsock() bitmap */ #define GETSOCK_WRITEBITSTART 16 diff --git a/libs/libcurl/src/netrc.c b/libs/libcurl/src/netrc.c index 83fe6a7e09..4461b8492f 100644 --- a/libs/libcurl/src/netrc.c +++ b/libs/libcurl/src/netrc.c @@ -33,6 +33,7 @@ #include "netrc.h" #include "strtok.h" #include "strcase.h" +#include "curl_get_line.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -58,8 +59,6 @@ enum host_lookup_state { static int parsenetrc(const char *host, char **loginp, char **passwordp, - bool *login_changed, - bool *password_changed, char *netrcfile) { FILE *file; @@ -73,8 +72,8 @@ static int parsenetrc(const char *host, char state_login = 0; /* Found a login keyword */ char state_password = 0; /* Found a password keyword */ - int state_our_login = FALSE; /* With specific_login, found *our* login - name */ + int state_our_login = TRUE; /* With specific_login, found *our* login + name (or login-less line) */ DEBUGASSERT(netrcfile); @@ -84,7 +83,7 @@ static int parsenetrc(const char *host, char netrcbuffer[4096]; int netrcbuffsize = (int)sizeof(netrcbuffer); - while(!done && fgets(netrcbuffer, netrcbuffsize, file)) { + while(!done && Curl_get_line(netrcbuffer, netrcbuffsize, file)) { char *tok; char *tok_end; bool quoted; @@ -96,7 +95,7 @@ static int parsenetrc(const char *host, } tok = netrcbuffer; while(tok) { - while(ISSPACE(*tok)) + while(ISBLANK(*tok)) tok++; /* tok is first non-space letter */ if(!*tok || (*tok == '#')) @@ -198,9 +197,9 @@ static int parsenetrc(const char *host, /* we are now parsing sub-keywords concerning "our" host */ if(state_login) { if(specific_login) { - state_our_login = strcasecompare(login, tok); + state_our_login = !Curl_timestrcmp(login, tok); } - else if(!login || strcmp(login, tok)) { + else if(!login || Curl_timestrcmp(login, tok)) { if(login_alloc) { free(login); login_alloc = FALSE; @@ -216,7 +215,7 @@ static int parsenetrc(const char *host, } else if(state_password) { if((state_our_login || !specific_login) - && (!password || strcmp(password, tok))) { + && (!password || Curl_timestrcmp(password, tok))) { if(password_alloc) { free(password); password_alloc = FALSE; @@ -243,24 +242,20 @@ static int parsenetrc(const char *host, } /* switch (state) */ tok = ++tok_end; } - } /* while fgets() */ + } /* while Curl_get_line() */ out: if(!retcode) { /* success */ - *login_changed = FALSE; - *password_changed = FALSE; if(login_alloc) { if(*loginp) free(*loginp); *loginp = login; - *login_changed = TRUE; } if(password_alloc) { if(*passwordp) free(*passwordp); *passwordp = password; - *password_changed = TRUE; } } else { @@ -281,11 +276,7 @@ static int parsenetrc(const char *host, * *loginp and *passwordp MUST be allocated if they aren't NULL when passed * in. */ -int Curl_parsenetrc(const char *host, - char **loginp, - char **passwordp, - bool *login_changed, - bool *password_changed, +int Curl_parsenetrc(const char *host, char **loginp, char **passwordp, char *netrcfile) { int retcode = 1; @@ -334,8 +325,7 @@ int Curl_parsenetrc(const char *host, free(homea); return -1; } - retcode = parsenetrc(host, loginp, passwordp, login_changed, - password_changed, filealloc); + retcode = parsenetrc(host, loginp, passwordp, filealloc); free(filealloc); #ifdef WIN32 if(retcode == NETRC_FILE_MISSING) { @@ -345,16 +335,14 @@ int Curl_parsenetrc(const char *host, free(homea); return -1; } - retcode = parsenetrc(host, loginp, passwordp, login_changed, - password_changed, filealloc); + retcode = parsenetrc(host, loginp, passwordp, filealloc); free(filealloc); } #endif free(homea); } else - retcode = parsenetrc(host, loginp, passwordp, login_changed, - password_changed, netrcfile); + retcode = parsenetrc(host, loginp, passwordp, netrcfile); return retcode; } diff --git a/libs/libcurl/src/netrc.h b/libs/libcurl/src/netrc.h index 53e315b61a..53d0056721 100644 --- a/libs/libcurl/src/netrc.h +++ b/libs/libcurl/src/netrc.h @@ -28,12 +28,8 @@ #ifndef CURL_DISABLE_NETRC /* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */ -int Curl_parsenetrc(const char *host, - char **loginp, - char **passwordp, - bool *login_changed, - bool *password_changed, - char *filename); +int Curl_parsenetrc(const char *host, char **loginp, + char **passwordp, char *filename); /* Assume: (*passwordp)[0]=0, host[0] != 0. * If (*loginp)[0] = 0, search for login and password within a machine * section in the netrc. diff --git a/libs/libcurl/src/noproxy.c b/libs/libcurl/src/noproxy.c new file mode 100644 index 0000000000..81f1e09934 --- /dev/null +++ b/libs/libcurl/src/noproxy.c @@ -0,0 +1,222 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ + +#include "curl_setup.h" + +#ifndef CURL_DISABLE_PROXY + +#include "inet_pton.h" +#include "strcase.h" +#include "noproxy.h" + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +/* + * Curl_cidr4_match() returns TRUE if the given IPv4 address is within the + * specified CIDR address range. + */ +UNITTEST bool Curl_cidr4_match(const char *ipv4, /* 1.2.3.4 address */ + const char *network, /* 1.2.3.4 address */ + unsigned int bits) +{ + unsigned int address = 0; + unsigned int check = 0; + + if(bits > 32) + /* strange input */ + return FALSE; + + if(1 != Curl_inet_pton(AF_INET, ipv4, &address)) + return FALSE; + if(1 != Curl_inet_pton(AF_INET, network, &check)) + return FALSE; + + if(bits && (bits != 32)) { + unsigned int mask = 0xffffffff << (32 - bits); + unsigned int haddr = htonl(address); + unsigned int hcheck = htonl(check); +#if 0 + fprintf(stderr, "Host %s (%x) network %s (%x) bits %u mask %x => %x\n", + ipv4, haddr, network, hcheck, bits, mask, + (haddr ^ hcheck) & mask); +#endif + if((haddr ^ hcheck) & mask) + return FALSE; + return TRUE; + } + return (address == check); +} + +UNITTEST bool Curl_cidr6_match(const char *ipv6, + const char *network, + unsigned int bits) +{ +#ifdef ENABLE_IPV6 + int bytes; + int rest; + unsigned char address[16]; + unsigned char check[16]; + + if(!bits) + bits = 128; + + bytes = bits/8; + rest = bits & 0x07; + if(1 != Curl_inet_pton(AF_INET6, ipv6, address)) + return FALSE; + if(1 != Curl_inet_pton(AF_INET6, network, check)) + return FALSE; + if((bytes > 16) || ((bytes == 16) && rest)) + return FALSE; + if(bytes && memcmp(address, check, bytes)) + return FALSE; + if(rest && !((address[bytes] ^ check[bytes]) & (0xff << (8 - rest)))) + return FALSE; + + return TRUE; +#else + (void)ipv6; + (void)network; + (void)bits; + return FALSE; +#endif +} + +enum nametype { + TYPE_HOST, + TYPE_IPV4, + TYPE_IPV6 +}; + +/**************************************************************** +* Checks if the host is in the noproxy list. returns TRUE if it matches and +* therefore the proxy should NOT be used. +****************************************************************/ +bool Curl_check_noproxy(const char *name, const char *no_proxy) +{ + /* no_proxy=domain1.dom,host.domain2.dom + * (a comma-separated list of hosts which should + * not be proxied, or an asterisk to override + * all proxy variables) + */ + if(no_proxy && no_proxy[0]) { + const char *p = no_proxy; + size_t namelen; + enum nametype type = TYPE_HOST; + char hostip[128]; + if(!strcmp("*", no_proxy)) + return TRUE; + + /* NO_PROXY was specified and it wasn't just an asterisk */ + + if(name[0] == '[') { + char *endptr; + /* IPv6 numerical address */ + endptr = strchr(name, ']'); + if(!endptr) + return FALSE; + name++; + namelen = endptr - name; + if(namelen >= sizeof(hostip)) + return FALSE; + memcpy(hostip, name, namelen); + hostip[namelen] = 0; + name = hostip; + type = TYPE_IPV6; + } + else { + unsigned int address; + if(1 == Curl_inet_pton(AF_INET, name, &address)) + type = TYPE_IPV4; + namelen = strlen(name); + } + + while(*p) { + const char *token; + size_t tokenlen = 0; + bool match = FALSE; + + /* pass blanks */ + while(*p && ISBLANK(*p)) + p++; + + token = p; + /* pass over the pattern */ + while(*p && !ISBLANK(*p) && (*p != ',')) { + p++; + tokenlen++; + } + + if(tokenlen) { + switch(type) { + case TYPE_HOST: + if(*token == '.') { + ++token; + --tokenlen; + /* tailmatch */ + match = (tokenlen <= namelen) && + strncasecompare(token, name + (namelen - tokenlen), namelen); + } + else + match = (tokenlen == namelen) && + strncasecompare(token, name, namelen); + break; + case TYPE_IPV4: + /* FALLTHROUGH */ + case TYPE_IPV6: { + const char *check = token; + char *slash = strchr(check, '/'); + unsigned int bits = 0; + char checkip[128]; + /* if the slash is part of this token, use it */ + if(slash && (slash < &check[tokenlen])) { + bits = atoi(slash + 1); + /* copy the check name to a temp buffer */ + if(tokenlen >= sizeof(checkip)) + break; + memcpy(checkip, check, tokenlen); + checkip[ slash - check ] = 0; + check = checkip; + } + if(type == TYPE_IPV6) + match = Curl_cidr6_match(name, check, bits); + else + match = Curl_cidr4_match(name, check, bits); + break; + } + } + if(match) + return TRUE; + } /* if(tokenlen) */ + while(*p == ',') + p++; + } /* while(*p) */ + } /* NO_PROXY was specified and it wasn't just an asterisk */ + + return FALSE; +} + +#endif /* CURL_DISABLE_PROXY */ diff --git a/libs/libcurl/src/dotdot.h b/libs/libcurl/src/noproxy.h index 4ffe72de83..8800a21276 100644 --- a/libs/libcurl/src/dotdot.h +++ b/libs/libcurl/src/noproxy.h @@ -1,5 +1,5 @@ -#ifndef HEADER_CURL_DOTDOT_H -#define HEADER_CURL_DOTDOT_H +#ifndef HEADER_CURL_NOPROXY_H +#define HEADER_CURL_NOPROXY_H /*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | @@ -23,5 +23,22 @@ * SPDX-License-Identifier: curl * ***************************************************************************/ -char *Curl_dedotdotify(const char *input); -#endif /* HEADER_CURL_DOTDOT_H */ +#include "curl_setup.h" + +#ifndef CURL_DISABLE_PROXY + +#ifdef DEBUGBUILD + +UNITTEST bool Curl_cidr4_match(const char *ipv4, /* 1.2.3.4 address */ + const char *network, /* 1.2.3.4 address */ + unsigned int bits); +UNITTEST bool Curl_cidr6_match(const char *ipv6, + const char *network, + unsigned int bits); +#endif + +bool Curl_check_noproxy(const char *name, const char *no_proxy); + +#endif + +#endif /* HEADER_CURL_NOPROXY_H */ diff --git a/libs/libcurl/src/openldap.c b/libs/libcurl/src/openldap.c index 19f2ad9f08..3a93b6728d 100644 --- a/libs/libcurl/src/openldap.c +++ b/libs/libcurl/src/openldap.c @@ -1068,8 +1068,8 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf, if(!binary) { /* check for leading or trailing whitespace */ - if(ISSPACE(bvals[i].bv_val[0]) || - ISSPACE(bvals[i].bv_val[bvals[i].bv_len - 1])) + if(ISBLANK(bvals[i].bv_val[0]) || + ISBLANK(bvals[i].bv_val[bvals[i].bv_len - 1])) binval = 1; else { /* check for unprintable characters */ diff --git a/libs/libcurl/src/pingpong.c b/libs/libcurl/src/pingpong.c index cd55173261..d4e6be98c4 100644 --- a/libs/libcurl/src/pingpong.c +++ b/libs/libcurl/src/pingpong.c @@ -330,7 +330,7 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, else if(gotbytes <= 0) { keepon = FALSE; result = CURLE_RECV_ERROR; - failf(data, "response reading failed"); + failf(data, "response reading failed (errno: %d)", SOCKERRNO); } else { /* we got a whole chunk of data, which can be anything from one @@ -398,7 +398,8 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, } else if(keepon) { - if((perline == gotbytes) && (gotbytes > data->set.buffer_size/2)) { + if((perline == gotbytes) && + (gotbytes > (ssize_t)data->set.buffer_size/2)) { /* We got an excessive line without newlines and we need to deal with it. We keep the first bytes of the line then we throw away the rest. */ diff --git a/libs/libcurl/src/rand.c b/libs/libcurl/src/rand.c index dd02f52680..2e7e7e8238 100644 --- a/libs/libcurl/src/rand.c +++ b/libs/libcurl/src/rand.c @@ -38,6 +38,64 @@ #include "curl_memory.h" #include "memdebug.h" +#ifdef WIN32 + +#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) +# define HAVE_MINGW_ORIGINAL +#endif + +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x600 && \ + !defined(HAVE_MINGW_ORIGINAL) +# define HAVE_WIN_BCRYPTGENRANDOM +# include <bcrypt.h> +# ifdef _MSC_VER +# pragma comment(lib, "bcrypt.lib") +# endif +# ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG +# define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002 +# endif +# ifndef STATUS_SUCCESS +# define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +# endif +#elif defined(USE_WIN32_CRYPTO) +# include <wincrypt.h> +# ifdef _MSC_VER +# pragma comment(lib, "advapi32.lib") +# endif +#endif + +CURLcode Curl_win32_random(unsigned char *entropy, size_t length) +{ + memset(entropy, 0, length); + +#if defined(HAVE_WIN_BCRYPTGENRANDOM) + if(BCryptGenRandom(NULL, entropy, (ULONG)length, + BCRYPT_USE_SYSTEM_PREFERRED_RNG) != STATUS_SUCCESS) + return CURLE_FAILED_INIT; + + return CURLE_OK; +#elif defined(USE_WIN32_CRYPTO) + { + HCRYPTPROV hCryptProv = 0; + + if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + return CURLE_FAILED_INIT; + + if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) { + CryptReleaseContext(hCryptProv, 0UL); + return CURLE_FAILED_INIT; + } + + CryptReleaseContext(hCryptProv, 0UL); + } + return CURLE_OK; +#else + return CURLE_NOT_BUILT_IN; +#endif +} +#endif + static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) { unsigned int r; @@ -73,6 +131,14 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) /* ---- non-cryptographic version following ---- */ +#ifdef WIN32 + if(!seeded) { + result = Curl_win32_random((unsigned char *)rnd, sizeof(*rnd)); + if(result != CURLE_NOT_BUILT_IN) + return result; + } +#endif + #if defined(RANDOM_FILE) && !defined(WIN32) if(!seeded) { /* if there's a random file to read a seed from, use it */ @@ -146,7 +212,7 @@ CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num) /* * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random - * hexadecimal digits PLUS a zero terminating byte. It must be an odd number + * hexadecimal digits PLUS a null-terminating byte. It must be an odd number * size. */ @@ -169,7 +235,7 @@ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, /* make sure it fits in the local buffer and that it is an odd number! */ return CURLE_BAD_FUNCTION_ARGUMENT; - num--; /* save one for zero termination */ + num--; /* save one for null-termination */ result = Curl_rand(data, buffer, num/2); if(result) diff --git a/libs/libcurl/src/rand.h b/libs/libcurl/src/rand.h index 2f442f5816..30fc29615a 100644 --- a/libs/libcurl/src/rand.h +++ b/libs/libcurl/src/rand.h @@ -42,10 +42,16 @@ CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num); /* * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random - * hexadecimal digits PLUS a zero terminating byte. It must be an odd number + * hexadecimal digits PLUS a null-terminating byte. It must be an odd number * size. */ CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd, size_t num); +#ifdef WIN32 +/* Random generator shared between the Schannel vtls and Curl_rand*() + functions */ +CURLcode Curl_win32_random(unsigned char *entropy, size_t length); +#endif + #endif /* HEADER_CURL_RAND_H */ diff --git a/libs/libcurl/src/rtsp.c b/libs/libcurl/src/rtsp.c index 5a6644b26c..6d3bf97e6c 100644 --- a/libs/libcurl/src/rtsp.c +++ b/libs/libcurl/src/rtsp.c @@ -794,7 +794,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, char *header) /* Find the first non-space letter */ start = header + 8; - while(*start && ISSPACE(*start)) + while(*start && ISBLANK(*start)) start++; if(!*start) { diff --git a/libs/libcurl/src/select.c b/libs/libcurl/src/select.c index c16358d56c..2ac0746772 100644 --- a/libs/libcurl/src/select.c +++ b/libs/libcurl/src/select.c @@ -310,8 +310,12 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, timediff_t timeout_ms) else pending_ms = 0; r = poll(ufds, nfds, pending_ms); - if(r <= 0) + if(r <= 0) { + if((r == -1) && (SOCKERRNO == EINTR)) + /* make EINTR from select or poll not a "lethal" error */ + r = 0; return r; + } for(i = 0; i < nfds; i++) { if(ufds[i].fd == CURL_SOCKET_BAD) diff --git a/libs/libcurl/src/select.h b/libs/libcurl/src/select.h index eaff7d9b1c..f2cf8bbd9f 100644 --- a/libs/libcurl/src/select.h +++ b/libs/libcurl/src/select.h @@ -36,8 +36,7 @@ * Definition of pollfd struct and constants for platforms lacking them. */ -#if !defined(HAVE_STRUCT_POLLFD) && \ - !defined(HAVE_SYS_POLL_H) && \ +#if !defined(HAVE_SYS_POLL_H) && \ !defined(HAVE_POLL_H) && \ !defined(POLLIN) diff --git a/libs/libcurl/src/sendf.c b/libs/libcurl/src/sendf.c index a210284579..d26b7e7cd7 100644 --- a/libs/libcurl/src/sendf.c +++ b/libs/libcurl/src/sendf.c @@ -48,6 +48,7 @@ #include "strdup.h" #include "http2.h" #include "headers.h" +#include "ws.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -245,7 +246,7 @@ void Curl_infof(struct Curl_easy *data, const char *fmt, ...) DEBUGASSERT(!strchr(fmt, '\n')); if(data && data->set.verbose) { va_list ap; - size_t len; + int len; char buffer[MAXINFO + 2]; va_start(ap, fmt); len = mvsnprintf(buffer, MAXINFO, fmt, ap); @@ -265,7 +266,7 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...) DEBUGASSERT(!strchr(fmt, '\n')); if(data->set.verbose || data->set.errorbuffer) { va_list ap; - size_t len; + int len; char error[CURL_ERROR_SIZE + 2]; va_start(ap, fmt); len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap); @@ -496,6 +497,9 @@ static CURLcode pausewrite(struct Curl_easy *data, } } DEBUGASSERT(i < 3); + if(i >= 3) + /* There are more types to store than what fits: very bad */ + return CURLE_OUT_OF_MEMORY; } else i = 0; @@ -531,6 +535,7 @@ static CURLcode chop_write(struct Curl_easy *data, curl_write_callback writebody = NULL; char *ptr = optr; size_t len = olen; + void *writebody_ptr = data->set.out; if(!len) return CURLE_OK; @@ -541,8 +546,18 @@ static CURLcode chop_write(struct Curl_easy *data, return pausewrite(data, type, ptr, len); /* Determine the callback(s) to use. */ - if(type & CLIENTWRITE_BODY) + if(type & CLIENTWRITE_BODY) { +#ifdef USE_WEBSOCKETS + if(conn->handler->protocol & (CURLPROTO_WS|CURLPROTO_WSS)) { + struct HTTP *ws = data->req.p.http; + writebody = Curl_ws_writecb; + ws->ws.data = data; + writebody_ptr = ws; + } + else +#endif writebody = data->set.fwrite_func; + } if((type & CLIENTWRITE_HEADER) && (data->set.fwrite_header || data->set.writeheader)) { /* @@ -560,7 +575,7 @@ static CURLcode chop_write(struct Curl_easy *data, if(writebody) { size_t wrote; Curl_set_in_callback(data, true); - wrote = writebody(ptr, 1, chunklen, data->set.out); + wrote = writebody(ptr, 1, chunklen, writebody_ptr); Curl_set_in_callback(data, false); if(CURL_WRITEFUNC_PAUSE == wrote) { @@ -583,18 +598,20 @@ static CURLcode chop_write(struct Curl_easy *data, len -= chunklen; } +#ifndef CURL_DISABLE_HTTP /* HTTP header, but not status-line */ if((conn->handler->protocol & PROTO_FAMILY_HTTP) && (type & CLIENTWRITE_HEADER) && !(type & CLIENTWRITE_STATUS) ) { - CURLcode result = - Curl_headers_push(data, optr, - type & CLIENTWRITE_CONNECT ? CURLH_CONNECT : - (type & CLIENTWRITE_1XX ? CURLH_1XX : - (type & CLIENTWRITE_TRAILER ? CURLH_TRAILER : - CURLH_HEADER))); + unsigned char htype = (unsigned char) + (type & CLIENTWRITE_CONNECT ? CURLH_CONNECT : + (type & CLIENTWRITE_1XX ? CURLH_1XX : + (type & CLIENTWRITE_TRAILER ? CURLH_TRAILER : + CURLH_HEADER))); + CURLcode result = Curl_headers_push(data, optr, htype); if(result) return result; } +#endif if(writeheader) { size_t wrote; @@ -607,8 +624,10 @@ static CURLcode chop_write(struct Curl_easy *data, /* here we pass in the HEADER bit only since if this was body as well then it was passed already and clearly that didn't trigger the pause, so this is saved for later with the HEADER bit only */ - return pausewrite(data, CLIENTWRITE_HEADER, optr, olen); - + return pausewrite(data, CLIENTWRITE_HEADER | + (type & (CLIENTWRITE_STATUS|CLIENTWRITE_CONNECT| + CLIENTWRITE_1XX|CLIENTWRITE_TRAILER)), + optr, olen); if(wrote != olen) { failf(data, "Failed writing header"); return CURLE_WRITE_ERROR; @@ -709,17 +728,17 @@ CURLcode Curl_read(struct Curl_easy *data, /* transfer */ } /* return 0 on success */ -int Curl_debug(struct Curl_easy *data, curl_infotype type, - char *ptr, size_t size) +void Curl_debug(struct Curl_easy *data, curl_infotype type, + char *ptr, size_t size) { - int rc = 0; if(data->set.verbose) { static const char s_infotype[CURLINFO_END][3] = { "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; if(data->set.fdebug) { + bool inCallback = Curl_is_in_callback(data); Curl_set_in_callback(data, true); - rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata); - Curl_set_in_callback(data, false); + (void)(*data->set.fdebug)(data, type, ptr, size, data->set.debugdata); + Curl_set_in_callback(data, inCallback); } else { switch(type) { @@ -734,5 +753,4 @@ int Curl_debug(struct Curl_easy *data, curl_infotype type, } } } - return rc; } diff --git a/libs/libcurl/src/sendf.h b/libs/libcurl/src/sendf.h index 075d70eaad..7c4c1280a0 100644 --- a/libs/libcurl/src/sendf.h +++ b/libs/libcurl/src/sendf.h @@ -89,8 +89,8 @@ CURLcode Curl_write_plain(struct Curl_easy *data, ssize_t *written); /* the function used to output verbose information */ -int Curl_debug(struct Curl_easy *data, curl_infotype type, - char *ptr, size_t size); +void Curl_debug(struct Curl_easy *data, curl_infotype type, + char *ptr, size_t size); #endif /* HEADER_CURL_SENDF_H */ diff --git a/libs/libcurl/src/setopt.c b/libs/libcurl/src/setopt.c index 6b16e1c7c8..5b5975485c 100644 --- a/libs/libcurl/src/setopt.c +++ b/libs/libcurl/src/setopt.c @@ -148,6 +148,40 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) #define C_SSLVERSION_VALUE(x) (x & 0xffff) #define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000) +static CURLcode protocol2num(const char *str, curl_prot_t *val) +{ + if(!str) + return CURLE_BAD_FUNCTION_ARGUMENT; + + if(curl_strequal(str, "all")) { + *val = ~(curl_prot_t) 0; + return CURLE_OK; + } + + *val = 0; + + do { + const char *token = str; + size_t tlen; + + str = strchr(str, ','); + tlen = str? (size_t) (str - token): strlen(token); + if(tlen) { + const struct Curl_handler *h = Curl_builtin_scheme(token, tlen); + + if(!h) + return CURLE_UNSUPPORTED_PROTOCOL; + + *val |= h->protocol; + } + } while(str++); + + if(!*val) + /* no protocol listed */ + return CURLE_BAD_FUNCTION_ARGUMENT; + return CURLE_OK; +} + /* * Do not make Curl_vsetopt() static: it is called from * packages/OS400/ccsidcurl.c. @@ -157,9 +191,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) char *argptr; CURLcode result = CURLE_OK; long arg; -#ifdef ENABLE_IPV6 unsigned long uarg; -#endif curl_off_t bigsize; switch(option) { @@ -167,7 +199,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) arg = va_arg(param, long); if(arg < -1) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.dns_cache_timeout = arg; + else if(arg > INT_MAX) + arg = INT_MAX; + + data->set.dns_cache_timeout = (int)arg; break; case CURLOPT_DNS_USE_GLOBAL_CACHE: /* deprecated */ @@ -314,7 +349,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ arg = va_arg(param, long); if((arg >= 0) && (arg <= (INT_MAX/1000))) - data->set.server_response_timeout = arg * 1000; + data->set.server_response_timeout = (unsigned int)arg * 1000; else return CURLE_BAD_FUNCTION_ARGUMENT; break; @@ -344,7 +379,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) arg = va_arg(param, long); if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.use_netrc = (enum CURL_NETRC_OPTION)arg; + data->set.use_netrc = (unsigned char)arg; break; case CURLOPT_NETRC_FILE: /* @@ -616,8 +651,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) } else data->set.method = HTTPREQ_GET; + data->set.upload = FALSE; break; +#ifndef CURL_DISABLE_MIME case CURLOPT_HTTPPOST: /* * Set to make us do HTTP POST @@ -626,6 +663,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.method = HTTPREQ_POST_FORM; data->set.opt_no_body = FALSE; /* this is implied */ break; +#endif case CURLOPT_AWS_SIGV4: /* @@ -641,18 +679,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.httpauth = CURLAUTH_AWS_SIGV4; break; - case CURLOPT_MIMEPOST: - /* - * Set to make us do MIME/form POST - */ - result = Curl_mime_set_subparts(&data->set.mimepost, - va_arg(param, curl_mime *), FALSE); - if(!result) { - data->set.method = HTTPREQ_POST_MIME; - data->set.opt_no_body = FALSE; /* this is implied */ - } - break; - case CURLOPT_REFERER: /* * String to set in the HTTP Referer: field. @@ -674,13 +700,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) va_arg(param, char *)); break; - case CURLOPT_HTTPHEADER: - /* - * Set a list with HTTP headers to use (or replace internals with) - */ - data->set.headers = va_arg(param, struct curl_slist *); - break; - #ifndef CURL_DISABLE_PROXY case CURLOPT_PROXYHEADER: /* @@ -918,6 +937,36 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #endif /* CURL_DISABLE_HTTP */ +#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \ + !defined(CURL_DISABLE_IMAP) +# if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MIME) + case CURLOPT_HTTPHEADER: + /* + * Set a list with HTTP headers to use (or replace internals with) + */ + data->set.headers = va_arg(param, struct curl_slist *); + break; +# endif + +# ifndef CURL_DISABLE_MIME + case CURLOPT_MIMEPOST: + /* + * Set to make us do MIME POST + */ + result = Curl_mime_set_subparts(&data->set.mimepost, + va_arg(param, curl_mime *), FALSE); + if(!result) { + data->set.method = HTTPREQ_POST_MIME; + data->set.opt_no_body = FALSE; /* this is implied */ + } + break; + + case CURLOPT_MIME_OPTIONS: + data->set.mime_options = (unsigned int)va_arg(param, long); + break; +# endif +#endif + case CURLOPT_HTTPAUTH: /* * Set HTTP Authentication type BITMASK. @@ -1262,7 +1311,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) (arg > CURLFTP_CREATE_DIR_RETRY)) result = CURLE_BAD_FUNCTION_ARGUMENT; else - data->set.ftp_create_missing_dirs = (int)arg; + data->set.ftp_create_missing_dirs = (unsigned char)arg; break; case CURLOPT_READDATA: /* @@ -1352,12 +1401,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_PORT: /* - * The port number to use when getting the URL + * The port number to use when getting the URL. 0 disables it. */ arg = va_arg(param, long); if((arg < 0) || (arg > 65535)) return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.use_port = arg; + data->set.use_port = (unsigned short)arg; break; case CURLOPT_TIMEOUT: /* @@ -1366,16 +1415,16 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ arg = va_arg(param, long); if((arg >= 0) && (arg <= (INT_MAX/1000))) - data->set.timeout = arg * 1000; + data->set.timeout = (unsigned int)arg * 1000; else return CURLE_BAD_FUNCTION_ARGUMENT; break; case CURLOPT_TIMEOUT_MS: - arg = va_arg(param, long); - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.timeout = arg; + uarg = va_arg(param, unsigned long); + if(uarg >= UINT_MAX) + uarg = UINT_MAX; + data->set.timeout = (unsigned int)uarg; break; case CURLOPT_CONNECTTIMEOUT: @@ -1384,16 +1433,16 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) */ arg = va_arg(param, long); if((arg >= 0) && (arg <= (INT_MAX/1000))) - data->set.connecttimeout = arg * 1000; + data->set.connecttimeout = (unsigned int)arg * 1000; else return CURLE_BAD_FUNCTION_ARGUMENT; break; case CURLOPT_CONNECTTIMEOUT_MS: - arg = va_arg(param, long); - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.connecttimeout = arg; + uarg = va_arg(param, unsigned long); + if(uarg >= UINT_MAX) + uarg = UINT_MAX; + data->set.connecttimeout = (unsigned int)uarg; break; #ifndef CURL_DISABLE_FTP @@ -1401,10 +1450,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) /* * The maximum time for curl to wait for FTP server connect */ - arg = va_arg(param, long); - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.accepttimeout = arg; + uarg = va_arg(param, unsigned long); + if(uarg >= UINT_MAX) + uarg = UINT_MAX; + data->set.accepttimeout = (unsigned int)uarg; break; #endif @@ -2156,7 +2205,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) else if(arg < READBUFFER_MIN) arg = READBUFFER_MIN; - data->set.buffer_size = arg; + data->set.buffer_size = (int)arg; break; case CURLOPT_UPLOAD_BUFFERSIZE: @@ -2350,9 +2399,14 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_CONNECT_ONLY: /* - * No data transfer, set up connection and let application use the socket + * No data transfer. + * (1) - only do connection + * (2) - do first get request but get no content */ - data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE; + arg = va_arg(param, long); + if(arg > 2) + return CURLE_BAD_FUNCTION_ARGUMENT; + data->set.connect_only = (unsigned char)arg; break; case CURLOPT_SOCKOPTFUNCTION: @@ -2560,16 +2614,36 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) transfer, which thus helps the app which takes URLs from users or other external inputs and want to restrict what protocol(s) to deal with. Defaults to CURLPROTO_ALL. */ - data->set.allowed_protocols = (unsigned int)va_arg(param, long); + data->set.allowed_protocols = (curl_prot_t)va_arg(param, long); break; case CURLOPT_REDIR_PROTOCOLS: /* set the bitmask for the protocols that libcurl is allowed to follow to, as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs to be set in both bitmasks to be allowed to get redirected to. */ - data->set.redir_protocols = (unsigned int)va_arg(param, long); + data->set.redir_protocols = (curl_prot_t)va_arg(param, long); break; + case CURLOPT_PROTOCOLS_STR: { + curl_prot_t prot; + argptr = va_arg(param, char *); + result = protocol2num(argptr, &prot); + if(result) + return result; + data->set.allowed_protocols = prot; + break; + } + + case CURLOPT_REDIR_PROTOCOLS_STR: { + curl_prot_t prot; + argptr = va_arg(param, char *); + result = protocol2num(argptr, &prot); + if(result) + return result; + data->set.redir_protocols = prot; + break; + } + case CURLOPT_DEFAULT_PROTOCOL: /* Set the protocol to use when the URL doesn't include any protocol */ result = Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL], @@ -2598,13 +2672,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; #endif -#if (!defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_MIME)) || \ - !defined(CURL_DISABLE_SMTP) || !defined(CURL_DISABLE_IMAP) - case CURLOPT_MIME_OPTIONS: - data->set.mime_options = (unsigned int)va_arg(param, long); - break; -#endif - case CURLOPT_SASL_AUTHZID: /* Authorization identity (identity to act as) */ result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID], @@ -2856,7 +2923,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) #endif break; case CURLOPT_SSL_ENABLE_NPN: - data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE; break; case CURLOPT_SSL_ENABLE_ALPN: data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE; @@ -2912,10 +2978,10 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE; break; case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS: - arg = va_arg(param, long); - if(arg < 0) - return CURLE_BAD_FUNCTION_ARGUMENT; - data->set.happy_eyeballs_timeout = arg; + uarg = va_arg(param, unsigned long); + if(uarg >= UINT_MAX) + uarg = UINT_MAX; + data->set.happy_eyeballs_timeout = (unsigned int)uarg; break; #ifndef CURL_DISABLE_SHUFFLE_DNS case CURLOPT_DNS_SHUFFLE_ADDRESSES: @@ -3032,6 +3098,15 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) case CURLOPT_PREREQDATA: data->set.prereq_userp = va_arg(param, void *); break; +#ifdef USE_WEBSOCKETS + case CURLOPT_WS_OPTIONS: { + bool raw; + arg = va_arg(param, long); + raw = (arg & CURLWS_RAW_MODE); + data->set.ws_raw_mode = raw; + break; + } +#endif default: /* unknown tag and its companion, just ignore: */ result = CURLE_UNKNOWN_OPTION; diff --git a/libs/libcurl/src/setup-win32.h b/libs/libcurl/src/setup-win32.h index c16928db90..bc5f8efc3c 100644 --- a/libs/libcurl/src/setup-win32.h +++ b/libs/libcurl/src/setup-win32.h @@ -37,10 +37,21 @@ #ifdef HAVE_WINDOWS_H # if defined(UNICODE) && !defined(_UNICODE) -# define _UNICODE +# error "UNICODE is defined but _UNICODE is not defined" # endif # if defined(_UNICODE) && !defined(UNICODE) -# define UNICODE +# error "_UNICODE is defined but UNICODE is not defined" +# endif +/* + * Don't include unneeded stuff in Windows headers to avoid compiler + * warnings and macro clashes. + * Make sure to define this macro before including any Windows headers. + */ +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# ifndef NOGDI +# define NOGDI # endif # include <winerror.h> # include <windows.h> diff --git a/libs/libcurl/src/share.c b/libs/libcurl/src/share.c index 8b18360624..1a083e72a0 100644 --- a/libs/libcurl/src/share.c +++ b/libs/libcurl/src/share.c @@ -41,7 +41,7 @@ curl_share_init(void) if(share) { share->magic = CURL_GOOD_SHARE; share->specifier |= (1<<CURL_LOCK_DATA_SHARE); - Curl_init_dnscache(&share->hostcache); + Curl_init_dnscache(&share->hostcache, 23); } return share; diff --git a/libs/libcurl/src/smb.c b/libs/libcurl/src/smb.c index 039d680041..a62e858143 100644 --- a/libs/libcurl/src/smb.c +++ b/libs/libcurl/src/smb.c @@ -34,7 +34,7 @@ #include <process.h> #ifdef CURL_WINDOWS_APP #define getpid GetCurrentProcessId -#elif !defined(MSDOS) +#elif defined(WIN32) #define getpid _getpid #endif #endif diff --git a/libs/libcurl/src/socketpair.h b/libs/libcurl/src/socketpair.h index f91a3c6511..de70df673a 100644 --- a/libs/libcurl/src/socketpair.h +++ b/libs/libcurl/src/socketpair.h @@ -26,6 +26,8 @@ #include "curl_setup.h" #ifndef HAVE_SOCKETPAIR +#include <curl/curl.h> + int Curl_socketpair(int domain, int type, int protocol, curl_socket_t socks[2]); #else diff --git a/libs/libcurl/src/splay.c b/libs/libcurl/src/splay.c index e7d86f1aac..33b44aa1c6 100644 --- a/libs/libcurl/src/splay.c +++ b/libs/libcurl/src/splay.c @@ -103,7 +103,7 @@ struct Curl_tree *Curl_splayinsert(struct curltime i, struct Curl_tree *node) { static const struct curltime KEY_NOTUSED = { - (time_t)-1, (unsigned int)-1 + ~0, -1 }; /* will *NEVER* appear */ if(!node) @@ -213,7 +213,7 @@ int Curl_splayremove(struct Curl_tree *t, struct Curl_tree **newroot) { static const struct curltime KEY_NOTUSED = { - (time_t)-1, (unsigned int)-1 + ~0, -1 }; /* will *NEVER* appear */ struct Curl_tree *x; diff --git a/libs/libcurl/src/strcase.c b/libs/libcurl/src/strcase.c index f932485204..09d2a8a961 100644 --- a/libs/libcurl/src/strcase.c +++ b/libs/libcurl/src/strcase.c @@ -28,8 +28,6 @@ #include "strcase.h" -static char raw_tolower(char in); - /* Mapping table to go from lowercase to uppercase for plain ASCII.*/ static const unsigned char touppermap[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, @@ -79,7 +77,7 @@ char Curl_raw_toupper(char in) /* Portable, consistent tolower. Do not use tolower() because its behavior is altered by the current locale. */ -static char raw_tolower(char in) +char Curl_raw_tolower(char in) { return tolowermap[(unsigned char) in]; } @@ -165,7 +163,7 @@ void Curl_strntolower(char *dest, const char *src, size_t n) return; do { - *dest++ = raw_tolower(*src); + *dest++ = Curl_raw_tolower(*src); } while(*src++ && --n); } @@ -179,6 +177,28 @@ bool Curl_safecmp(char *a, char *b) return !a && !b; } +/* + * Curl_timestrcmp() returns 0 if the two strings are identical. The time this + * function spends is a function of the shortest string, not of the contents. + */ +int Curl_timestrcmp(const char *a, const char *b) +{ + int match = 0; + int i = 0; + + if(a && b) { + while(1) { + match |= a[i]^b[i]; + if(!a[i] || !b[i]) + break; + i++; + } + } + else + return a || b; + return match; +} + /* --- public functions --- */ int curl_strequal(const char *first, const char *second) diff --git a/libs/libcurl/src/strcase.h b/libs/libcurl/src/strcase.h index d245929227..65a575385d 100644 --- a/libs/libcurl/src/strcase.h +++ b/libs/libcurl/src/strcase.h @@ -43,6 +43,7 @@ int Curl_safe_strcasecompare(const char *first, const char *second); int Curl_strncasecompare(const char *first, const char *second, size_t max); char Curl_raw_toupper(char in); +char Curl_raw_tolower(char in); /* checkprefix() is a shorter version of the above, used when the first argument is the string literal */ @@ -52,5 +53,6 @@ void Curl_strntoupper(char *dest, const char *src, size_t n); void Curl_strntolower(char *dest, const char *src, size_t n); bool Curl_safecmp(char *a, char *b); +int Curl_timestrcmp(const char *first, const char *second); #endif /* HEADER_CURL_STRCASE_H */ diff --git a/libs/libcurl/src/strerror.c b/libs/libcurl/src/strerror.c index be43fd6c84..b9a51e26b9 100644 --- a/libs/libcurl/src/strerror.c +++ b/libs/libcurl/src/strerror.c @@ -265,9 +265,6 @@ curl_easy_strerror(CURLcode error) case CURLE_TFTP_NOSUCHUSER: return "TFTP: No such user"; - case CURLE_CONV_FAILED: - return "Conversion failed"; - case CURLE_REMOTE_FILE_NOT_FOUND: return "Remote file not found"; @@ -334,6 +331,7 @@ curl_easy_strerror(CURLcode error) case CURLE_OBSOLETE51: case CURLE_OBSOLETE57: case CURLE_OBSOLETE62: + case CURLE_OBSOLETE75: case CURLE_OBSOLETE76: case CURL_LAST: break; @@ -478,7 +476,7 @@ curl_url_strerror(CURLUcode error) return "Port number was not a decimal number between 0 and 65535"; case CURLUE_UNSUPPORTED_SCHEME: - return "This libcurl build doesn't support the given URL scheme"; + return "Unsupported URL scheme"; case CURLUE_URLDECODE: return "URL decode error, most likely because of rubbish in the input"; @@ -532,7 +530,7 @@ curl_url_strerror(CURLUcode error) return "Bad file:// URL"; case CURLUE_BAD_SLASHES: - return "Unsupported number of slashes"; + return "Unsupported number of slashes following scheme"; case CURLUE_BAD_SCHEME: return "Bad scheme"; diff --git a/libs/libcurl/src/strtoofft.c b/libs/libcurl/src/strtoofft.c index 30908fdd92..30deb8c05b 100644 --- a/libs/libcurl/src/strtoofft.c +++ b/libs/libcurl/src/strtoofft.c @@ -87,7 +87,7 @@ static curl_off_t strtooff(const char *nptr, char **endptr, int base) /* Skip leading whitespace. */ end = (char *)nptr; - while(ISSPACE(end[0])) { + while(ISBLANK(end[0])) { end++; } @@ -222,9 +222,9 @@ CURLofft curlx_strtoofft(const char *str, char **endp, int base, errno = 0; *num = 0; /* clear by default */ - while(*str && ISSPACE(*str)) + while(*str && ISBLANK(*str)) str++; - if('-' == *str) { + if(('-' == *str) || (ISSPACE(*str))) { if(endp) *endp = (char *)str; /* didn't actually move */ return CURL_OFFT_INVAL; /* nothing parsed */ diff --git a/libs/libcurl/src/timediff.c b/libs/libcurl/src/timediff.c index 27fd911638..c5893187dd 100644 --- a/libs/libcurl/src/timediff.c +++ b/libs/libcurl/src/timediff.c @@ -24,6 +24,8 @@ #include "timediff.h" +#include <limits.h> + /* * Converts number of milliseconds into a timeval structure. * diff --git a/libs/libcurl/src/transfer.c b/libs/libcurl/src/transfer.c index 1720b24b12..441da73429 100644 --- a/libs/libcurl/src/transfer.c +++ b/libs/libcurl/src/transfer.c @@ -539,6 +539,13 @@ static CURLcode readwrite_data(struct Curl_easy *data, bool is_http2 = ((conn->handler->protocol & PROTO_FAMILY_HTTP) && (conn->httpversion == 20)); #endif + bool is_http3 = +#ifdef ENABLE_QUIC + ((conn->handler->protocol & PROTO_FAMILY_HTTP) && + (conn->httpversion == 30)); +#else + FALSE; +#endif if( #ifdef USE_NGHTTP2 @@ -549,6 +556,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, for a particular stream. */ !is_http2 && #endif + !is_http3 && /* Same reason mentioned above. */ k->size != -1 && !k->header) { /* make sure we don't read too much */ curl_off_t totalleft = k->size - k->bytecount; @@ -596,6 +604,9 @@ static CURLcode readwrite_data(struct Curl_easy *data, DEBUGF(infof(data, "nread == 0, stream closed, bailing")); else #endif + if(is_http3 && !nread) + DEBUGF(infof(data, "nread == 0, stream closed, bailing")); + else DEBUGF(infof(data, "nread <= 0, server closed connection, bailing")); k->keepon &= ~KEEP_RECV; break; @@ -753,7 +764,13 @@ static CURLcode readwrite_data(struct Curl_easy *data, if(nread < 0) /* this should be unusual */ nread = 0; - k->keepon &= ~KEEP_RECV; /* we're done reading */ + /* HTTP/3 over QUIC should keep reading until QUIC connection + is closed. In contrast to HTTP/2 which can stop reading + from TCP connection, HTTP/3 over QUIC needs ACK from server + to ensure stream closure. It should keep reading. */ + if(!is_http3) { + k->keepon &= ~KEEP_RECV; /* we're done reading */ + } } k->bytecount += nread; @@ -1422,6 +1439,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) if(result) return result; + data->state.requests = 0; data->state.followlocation = 0; /* reset the location-follow counter */ data->state.this_is_a_follow = FALSE; /* reset this */ data->state.errorbuf = FALSE; /* no error has occurred */ @@ -1619,7 +1637,7 @@ CURLcode Curl_follow(struct Curl_easy *data, if((type != FOLLOW_RETRY) && (data->req.httpcode != 401) && (data->req.httpcode != 407) && - Curl_is_absolute_url(newurl, NULL, 0)) + Curl_is_absolute_url(newurl, NULL, 0, FALSE)) /* If this is not redirect due to a 401 or 407 response and an absolute URL: don't allow a custom port number */ disallowport = TRUE; @@ -1631,8 +1649,11 @@ CURLcode Curl_follow(struct Curl_easy *data, CURLU_ALLOW_SPACE | (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)); if(uc) { - if(type != FOLLOW_FAKE) + if(type != FOLLOW_FAKE) { + failf(data, "The redirect target URL could not be parsed: %s", + curl_url_strerror(uc)); return Curl_uc_to_curlcode(uc); + } /* the URL could not be parsed for some reason, but since this is FAKE mode, just duplicate the field as-is */ @@ -1679,7 +1700,7 @@ CURLcode Curl_follow(struct Curl_easy *data, return Curl_uc_to_curlcode(uc); } - p = Curl_builtin_scheme(scheme); + p = Curl_builtin_scheme(scheme, CURL_ZERO_TERMINATED); if(p && (p->protocol != data->info.conn_protocol)) { infof(data, "Clear auth, redirects scheme from %s to %s", data->info.conn_scheme, scheme); diff --git a/libs/libcurl/src/url.c b/libs/libcurl/src/url.c index 1114c6c12e..be5ffca2d8 100644 --- a/libs/libcurl/src/url.c +++ b/libs/libcurl/src/url.c @@ -73,10 +73,11 @@ #endif #elif defined(USE_WIN32_IDN) -/* prototype for curl_win32_idn_to_ascii() */ -bool curl_win32_idn_to_ascii(const char *in, char **out); +/* prototype for Curl_win32_idn_to_ascii() */ +bool Curl_win32_idn_to_ascii(const char *in, char **out); #endif /* USE_LIBIDN2 */ +#include "doh.h" #include "urldata.h" #include "netrc.h" @@ -105,6 +106,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "urlapi-int.h" #include "system_win32.h" #include "hsts.h" +#include "noproxy.h" /* And now for the protocols */ #include "ftp.h" @@ -127,7 +129,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "http_proxy.h" #include "conncache.h" #include "multihandle.h" -#include "dotdot.h" #include "strdup.h" #include "setopt.h" #include "altsvc.h" @@ -153,6 +154,9 @@ static void conn_free(struct connectdata *conn); #define UNIX_SOCKET_PREFIX "localhost" #endif +/* Reject URLs exceeding this length */ +#define MAX_URL_LEN 0xffff + /* * get_protocol_family() * @@ -164,7 +168,7 @@ static void conn_free(struct connectdata *conn); * * Returns the family as a single bit protocol identifier. */ -static unsigned int get_protocol_family(const struct Curl_handler *h) +static curl_prot_t get_protocol_family(const struct Curl_handler *h) { DEBUGASSERT(h); DEBUGASSERT(h->family); @@ -188,6 +192,16 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_http, #endif +#ifdef USE_WEBSOCKETS +#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) + &Curl_handler_wss, +#endif + +#ifndef CURL_DISABLE_HTTP + &Curl_handler_ws, +#endif +#endif + #ifndef CURL_DISABLE_FTP &Curl_handler_ftp, #endif @@ -439,6 +453,7 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_safefree(data->info.wouldredirect); /* this destroys the channel and we cannot use it anymore after this */ + Curl_resolver_cancel(data); Curl_resolver_cleanup(data->state.async.resolver); Curl_http2_cleanup_dependencies(data); @@ -563,11 +578,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->new_file_perms = 0644; /* Default permissions */ set->new_directory_perms = 0755; /* Default permissions */ - - /* for the *protocols fields we don't use the CURLPROTO_ALL convenience - define since we internally only use the lower 16 bits for the passed - in bitmask to not conflict with the private bits */ - set->allowed_protocols = (unsigned int)CURLPROTO_ALL; + set->allowed_protocols = (curl_prot_t) CURLPROTO_ALL; set->redir_protocols = CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | CURLPROTO_FTPS; @@ -618,7 +629,6 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->tcp_keepidle = 60; set->tcp_fastopen = FALSE; set->tcp_nodelay = TRUE; - set->ssl_enable_npn = TRUE; set->ssl_enable_alpn = TRUE; set->expect_100_timeout = 1000L; /* Wait for a second by default. */ set->sep_headers = TRUE; /* separated header lists by default */ @@ -741,15 +751,6 @@ static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn) DEBUGASSERT(data); infof(data, "Closing connection %ld", conn->connection_id); -#ifndef USE_HYPER - if(conn->connect_state && conn->connect_state->prot_save) { - /* If this was closed with a CONNECT in progress, cleanup this temporary - struct arrangement */ - data->req.p.http = NULL; - Curl_safefree(conn->connect_state->prot_save); - } -#endif - /* possible left-overs from the async name resolvers */ Curl_resolver_cancel(data); @@ -864,7 +865,7 @@ void Curl_disconnect(struct Curl_easy *data, /* Cleanup NEGOTIATE connection-related data */ Curl_http_auth_cleanup_negotiate(conn); - if(conn->bits.connect_only) + if(conn->connect_only) /* treat the connection as dead in CONNECT_ONLY situations */ dead_connection = TRUE; @@ -948,19 +949,11 @@ socks_proxy_info_matches(const struct proxy_info *data, /* the user information is case-sensitive or at least it is not defined as case-insensitive see https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1 */ - if(!data->user != !needle->user) - return FALSE; - /* curl_strequal does a case insentive comparison, so do not use it here! */ - if(data->user && - needle->user && - strcmp(data->user, needle->user) != 0) - return FALSE; - if(!data->passwd != !needle->passwd) - return FALSE; - /* curl_strequal does a case insentive comparison, so do not use it here! */ - if(data->passwd && - needle->passwd && - strcmp(data->passwd, needle->passwd) != 0) + + /* curl_strequal does a case insensitive comparison, + so do not use it here! */ + if(Curl_timestrcmp(data->user, needle->user) || + Curl_timestrcmp(data->passwd, needle->passwd)) return FALSE; return TRUE; } @@ -1210,7 +1203,7 @@ ConnectionExists(struct Curl_easy *data, check = curr->ptr; curr = curr->next; - if(check->bits.connect_only || check->bits.close) + if(check->connect_only || check->bits.close) /* connect-only or to-be-closed connections will not be reused */ continue; @@ -1362,10 +1355,10 @@ ConnectionExists(struct Curl_easy *data, if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) { /* This protocol requires credentials per connection, so verify that we're using the same name and password as well */ - if(strcmp(needle->user, check->user) || - strcmp(needle->passwd, check->passwd) || - !Curl_safecmp(needle->sasl_authzid, check->sasl_authzid) || - !Curl_safecmp(needle->oauth_bearer, check->oauth_bearer)) { + if(Curl_timestrcmp(needle->user, check->user) || + Curl_timestrcmp(needle->passwd, check->passwd) || + Curl_timestrcmp(needle->sasl_authzid, check->sasl_authzid) || + Curl_timestrcmp(needle->oauth_bearer, check->oauth_bearer)) { /* one of them was different */ continue; } @@ -1441,8 +1434,8 @@ ConnectionExists(struct Curl_easy *data, possible. (Especially we must not reuse the same connection if partway through a handshake!) */ if(wantNTLMhttp) { - if(strcmp(needle->user, check->user) || - strcmp(needle->passwd, check->passwd)) { + if(Curl_timestrcmp(needle->user, check->user) || + Curl_timestrcmp(needle->passwd, check->passwd)) { /* we prefer a credential match, but this is at least a connection that can be reused and "upgraded" to NTLM */ @@ -1464,8 +1457,10 @@ ConnectionExists(struct Curl_easy *data, if(!check->http_proxy.user || !check->http_proxy.passwd) continue; - if(strcmp(needle->http_proxy.user, check->http_proxy.user) || - strcmp(needle->http_proxy.passwd, check->http_proxy.passwd)) + if(Curl_timestrcmp(needle->http_proxy.user, + check->http_proxy.user) || + Curl_timestrcmp(needle->http_proxy.passwd, + check->http_proxy.passwd)) continue; } else if(check->proxy_ntlm_state != NTLMSTATE_NONE) { @@ -1637,7 +1632,7 @@ CURLcode Curl_idnconvert_hostname(struct Curl_easy *data, #elif defined(USE_WIN32_IDN) char *ace_hostname = NULL; - if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) { + if(Curl_win32_idn_to_ascii(host->name, &ace_hostname)) { host->encalloc = ace_hostname; /* change the name pointer to point to the encoded hostname */ host->name = host->encalloc; @@ -1668,7 +1663,7 @@ void Curl_free_idnconverted_hostname(struct hostname *host) } #elif defined(USE_WIN32_IDN) free(host->encalloc); /* must be freed with free() since this was - allocated by curl_win32_idn_to_ascii */ + allocated by Curl_win32_idn_to_ascii */ host->encalloc = NULL; #else (void)host; @@ -1794,7 +1789,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->proxy_ssl_config.ssl_options = data->set.proxy_ssl.primary.ssl_options; #endif conn->ip_version = data->set.ipver; - conn->bits.connect_only = data->set.connect_only; + conn->connect_only = data->set.connect_only; conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */ #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ @@ -1838,15 +1833,18 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) } /* returns the handler if the given scheme is built-in */ -const struct Curl_handler *Curl_builtin_scheme(const char *scheme) +const struct Curl_handler *Curl_builtin_scheme(const char *scheme, + size_t schemelen) { const struct Curl_handler * const *pp; const struct Curl_handler *p; /* Scan protocol handler table and match against 'scheme'. The handler may be changed later when the protocol specific setup function is called. */ + if(schemelen == CURL_ZERO_TERMINATED) + schemelen = strlen(scheme); for(pp = protocols; (p = *pp) != NULL; pp++) - if(strcasecompare(p->scheme, scheme)) - /* Protocol found in table. Check if allowed */ + if(strncasecompare(p->scheme, scheme, schemelen) && !p->scheme[schemelen]) + /* Protocol found in table. */ return p; return NULL; /* not found */ } @@ -1856,7 +1854,8 @@ static CURLcode findprotocol(struct Curl_easy *data, struct connectdata *conn, const char *protostr) { - const struct Curl_handler *p = Curl_builtin_scheme(protostr); + const struct Curl_handler *p = Curl_builtin_scheme(protostr, + CURL_ZERO_TERMINATED); if(p && /* Protocol found in table. Check if allowed */ (data->set.allowed_protocols & p->protocol)) { @@ -1980,7 +1979,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; if(data->set.str[STRING_DEFAULT_PROTOCOL] && - !Curl_is_absolute_url(data->state.url, NULL, 0)) { + !Curl_is_absolute_url(data->state.url, NULL, 0, TRUE)) { char *url = aprintf("%s://%s", data->set.str[STRING_DEFAULT_PROTOCOL], data->state.url); if(!url) @@ -2024,10 +2023,60 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, if(!strcasecompare("file", data->state.up.scheme)) return CURLE_OUT_OF_MEMORY; } + else if(strlen(data->state.up.hostname) > MAX_URL_LEN) { + failf(data, "Too long host name (maximum is %d)", MAX_URL_LEN); + return CURLE_URL_MALFORMAT; + } + hostname = data->state.up.hostname; + + if(hostname && hostname[0] == '[') { + /* This looks like an IPv6 address literal. See if there is an address + scope. */ + size_t hlen; + conn->bits.ipv6_ip = TRUE; + /* cut off the brackets! */ + hostname++; + hlen = strlen(hostname); + hostname[hlen - 1] = 0; + + zonefrom_url(uh, data, conn); + } + + /* make sure the connect struct gets its own copy of the host name */ + conn->host.rawalloc = strdup(hostname ? hostname : ""); + if(!conn->host.rawalloc) + return CURLE_OUT_OF_MEMORY; + conn->host.name = conn->host.rawalloc; + + /************************************************************* + * IDN-convert the hostnames + *************************************************************/ + result = Curl_idnconvert_hostname(data, &conn->host); + if(result) + return result; + if(conn->bits.conn_to_host) { + result = Curl_idnconvert_hostname(data, &conn->conn_to_host); + if(result) + return result; + } +#ifndef CURL_DISABLE_PROXY + if(conn->bits.httpproxy) { + result = Curl_idnconvert_hostname(data, &conn->http_proxy.host); + if(result) + return result; + } + if(conn->bits.socksproxy) { + result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host); + if(result) + return result; + } +#endif #ifndef CURL_DISABLE_HSTS + /* HSTS upgrade */ if(data->hsts && strcasecompare("http", data->state.up.scheme)) { - if(Curl_hsts(data->hsts, data->state.up.hostname, TRUE)) { + /* This MUST use the IDN decoded name */ + if(Curl_hsts(data->hsts, conn->host.name, TRUE)) { char *url; Curl_safefree(data->state.up.scheme); uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0); @@ -2078,7 +2127,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, return Curl_uc_to_curlcode(uc); } - if(!data->state.aptr.user) { + if(!data->set.str[STRING_USERNAME]) { /* we don't use the URL API's URL decoder option here since it rejects control codes and we want to allow them for some schemes in the user and password fields */ @@ -2128,31 +2177,11 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, unsigned long port = strtoul(data->state.up.port, NULL, 10); conn->port = conn->remote_port = (data->set.use_port && data->state.allow_port) ? - (int)data->set.use_port : curlx_ultous(port); + data->set.use_port : curlx_ultous(port); } (void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0); - hostname = data->state.up.hostname; - if(hostname && hostname[0] == '[') { - /* This looks like an IPv6 address literal. See if there is an address - scope. */ - size_t hlen; - conn->bits.ipv6_ip = TRUE; - /* cut off the brackets! */ - hostname++; - hlen = strlen(hostname); - hostname[hlen - 1] = 0; - - zonefrom_url(uh, data, conn); - } - - /* make sure the connect struct gets its own copy of the host name */ - conn->host.rawalloc = strdup(hostname ? hostname : ""); - if(!conn->host.rawalloc) - return CURLE_OUT_OF_MEMORY; - conn->host.name = conn->host.rawalloc; - #ifdef ENABLE_IPV6 if(data->set.scope_id) /* Override any scope that was set above. */ @@ -2250,83 +2279,6 @@ void Curl_free_request_state(struct Curl_easy *data) #ifndef CURL_DISABLE_PROXY -/**************************************************************** -* Checks if the host is in the noproxy list. returns true if it matches -* and therefore the proxy should NOT be used. -****************************************************************/ -static bool check_noproxy(const char *name, const char *no_proxy) -{ - /* no_proxy=domain1.dom,host.domain2.dom - * (a comma-separated list of hosts which should - * not be proxied, or an asterisk to override - * all proxy variables) - */ - if(no_proxy && no_proxy[0]) { - size_t tok_start; - size_t tok_end; - const char *separator = ", "; - size_t no_proxy_len; - size_t namelen; - char *endptr; - if(strcasecompare("*", no_proxy)) { - return TRUE; - } - - /* NO_PROXY was specified and it wasn't just an asterisk */ - - no_proxy_len = strlen(no_proxy); - if(name[0] == '[') { - /* IPv6 numerical address */ - endptr = strchr(name, ']'); - if(!endptr) - return FALSE; - name++; - namelen = endptr - name; - } - else - namelen = strlen(name); - - for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) { - while(tok_start < no_proxy_len && - strchr(separator, no_proxy[tok_start]) != NULL) { - /* Look for the beginning of the token. */ - ++tok_start; - } - - if(tok_start == no_proxy_len) - break; /* It was all trailing separator chars, no more tokens. */ - - for(tok_end = tok_start; tok_end < no_proxy_len && - strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end) - /* Look for the end of the token. */ - ; - - /* To match previous behavior, where it was necessary to specify - * ".local.com" to prevent matching "notlocal.com", we will leave - * the '.' off. - */ - if(no_proxy[tok_start] == '.') - ++tok_start; - - if((tok_end - tok_start) <= namelen) { - /* Match the last part of the name to the domain we are checking. */ - const char *checkn = name + namelen - (tok_end - tok_start); - if(strncasecompare(no_proxy + tok_start, checkn, - tok_end - tok_start)) { - if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') { - /* We either have an exact match, or the previous character is a . - * so it is within the same domain, so no proxy for this host. - */ - return TRUE; - } - } - } /* if((tok_end - tok_start) <= namelen) */ - } /* for(tok_start = 0; tok_start < no_proxy_len; - tok_start = tok_end + 1) */ - } /* NO_PROXY was specified and it wasn't just an asterisk */ - - return FALSE; -} #ifndef CURL_DISABLE_HTTP /**************************************************************** @@ -2366,7 +2318,7 @@ static char *detect_proxy(struct Curl_easy *data, /* Now, build <protocol>_proxy and check for such a one to use */ while(*protop) - *envp++ = (char)tolower((int)*protop++); + *envp++ = Curl_raw_tolower(*protop++); /* append _proxy */ strcpy(envp, "_proxy"); @@ -2695,8 +2647,8 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, } } - if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ? - data->set.str[STRING_NOPROXY] : no_proxy)) { + if(Curl_check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ? + data->set.str[STRING_NOPROXY] : no_proxy)) { Curl_safefree(proxy); Curl_safefree(socksproxy); } @@ -2734,16 +2686,16 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, * connection that may exist registered to the same proxy host. ***********************************************************************/ if(proxy || socksproxy) { + curl_proxytype ptype = (curl_proxytype)conn->http_proxy.proxytype; if(proxy) { - result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype); + result = parse_proxy(data, conn, proxy, ptype); Curl_safefree(proxy); /* parse_proxy copies the proxy string */ if(result) goto out; } if(socksproxy) { - result = parse_proxy(data, conn, socksproxy, - conn->socks_proxy.proxytype); + result = parse_proxy(data, conn, socksproxy, ptype); /* parse_proxy copies the socks proxy string */ Curl_safefree(socksproxy); if(result) @@ -2893,15 +2845,15 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len, (psep && psep > osep ? (size_t)(psep - osep) : (size_t)(login + len - osep)) - 1 : 0); - /* Allocate the user portion buffer */ - if(userp && ulen) { + /* Allocate the user portion buffer, which can be zero length */ + if(userp) { ubuf = malloc(ulen + 1); if(!ubuf) result = CURLE_OUT_OF_MEMORY; } /* Allocate the password portion buffer */ - if(!result && passwdp && plen) { + if(!result && passwdp && psep) { pbuf = malloc(plen + 1); if(!pbuf) { free(ubuf); @@ -2964,7 +2916,7 @@ static CURLcode parse_remote_port(struct Curl_easy *data, /* if set, we use this instead of the port possibly given in the URL */ char portbuf[16]; CURLUcode uc; - conn->remote_port = (unsigned short)data->set.use_port; + conn->remote_port = data->set.use_port; msnprintf(portbuf, sizeof(portbuf), "%d", conn->remote_port); uc = curl_url_set(data->state.uh, CURLUPART_PORT, portbuf, 0); if(uc) @@ -2986,14 +2938,6 @@ static CURLcode override_login(struct Curl_easy *data, char **passwdp = &conn->passwd; char **optionsp = &conn->options; -#ifndef CURL_DISABLE_NETRC - if(data->set.use_netrc == CURL_NETRC_REQUIRED && data->state.aptr.user) { - Curl_safefree(*userp); - Curl_safefree(*passwdp); - Curl_safefree(data->state.aptr.user); /* disable user+password */ - } -#endif - if(data->set.str[STRING_OPTIONS]) { free(*optionsp); *optionsp = strdup(data->set.str[STRING_OPTIONS]); @@ -3002,22 +2946,23 @@ static CURLcode override_login(struct Curl_easy *data, } #ifndef CURL_DISABLE_NETRC + if(data->set.use_netrc == CURL_NETRC_REQUIRED) { + Curl_safefree(*userp); + Curl_safefree(*passwdp); + } conn->bits.netrc = FALSE; if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) { - bool netrc_user_changed = FALSE; - bool netrc_passwd_changed = FALSE; int ret; bool url_provided = FALSE; - if(data->state.up.user) { - /* there was a user name in the URL */ - userp = &data->state.up.user; + if(data->state.aptr.user) { + /* there was a user name in the URL. Use the URL decoded version */ + userp = &data->state.aptr.user; url_provided = TRUE; } ret = Curl_parsenetrc(conn->host.name, userp, passwdp, - &netrc_user_changed, &netrc_passwd_changed, data->set.str[STRING_NETRC_FILE]); if(ret > 0) { infof(data, "Couldn't find host %s in the %s file; using defaults", @@ -3038,29 +2983,35 @@ static CURLcode override_login(struct Curl_easy *data, conn->user = strdup(*userp); if(!conn->user) return CURLE_OUT_OF_MEMORY; - /* don't update the user name below */ - userp = NULL; + } + /* no user was set but a password, set a blank user */ + if(userp && !*userp && *passwdp) { + *userp = strdup(""); + if(!*userp) + return CURLE_OUT_OF_MEMORY; } } #endif /* for updated strings, we update them in the URL */ - if(userp) { - if(*userp) { - CURLcode result = Curl_setstropt(&data->state.aptr.user, *userp); + if(*userp) { + CURLcode result; + if(data->state.aptr.user != *userp) { + /* nothing to do then */ + result = Curl_setstropt(&data->state.aptr.user, *userp); if(result) return result; } - if(data->state.aptr.user) { - uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user, - CURLU_URLENCODE); - if(uc) - return Curl_uc_to_curlcode(uc); - if(!*userp) { - *userp = strdup(data->state.aptr.user); - if(!*userp) - return CURLE_OUT_OF_MEMORY; - } + } + if(data->state.aptr.user) { + uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user, + CURLU_URLENCODE); + if(uc) + return Curl_uc_to_curlcode(uc); + if(!*userp) { + *userp = strdup(data->state.aptr.user); + if(!*userp) + return CURLE_OUT_OF_MEMORY; } } if(*passwdp) { @@ -3413,141 +3364,166 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, return result; } -/************************************************************* - * Resolve the address of the server or proxy - *************************************************************/ -static CURLcode resolve_server(struct Curl_easy *data, - struct connectdata *conn, - bool *async) +#ifdef USE_UNIX_SOCKETS +static CURLcode resolve_unix(struct Curl_easy *data, + struct connectdata *conn, + char *unix_path) { - CURLcode result = CURLE_OK; - timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + struct Curl_dns_entry *hostaddr = NULL; + bool longpath = FALSE; - DEBUGASSERT(conn); - DEBUGASSERT(data); - /************************************************************* - * Resolve the name of the server or proxy - *************************************************************/ - if(conn->bits.reuse) - /* We're reusing the connection - no need to resolve anything, and - idnconvert_hostname() was called already in create_conn() for the re-use - case. */ - *async = FALSE; + DEBUGASSERT(unix_path); + DEBUGASSERT(conn->dns_entry == NULL); - else { - /* this is a fresh connect */ - int rc; - struct Curl_dns_entry *hostaddr = NULL; + /* Unix domain sockets are local. The host gets ignored, just use the + * specified domain socket address. Do not cache "DNS entries". There is + * no DNS involved and we already have the filesystem path available. */ + hostaddr = calloc(1, sizeof(struct Curl_dns_entry)); + if(!hostaddr) + return CURLE_OUT_OF_MEMORY; -#ifdef USE_UNIX_SOCKETS - char *unix_path = NULL; + hostaddr->addr = Curl_unix2addr(unix_path, &longpath, + conn->bits.abstract_unix_socket); + if(!hostaddr->addr) { + if(longpath) + /* Long paths are not supported for now */ + failf(data, "Unix socket path too long: '%s'", unix_path); + free(hostaddr); + return longpath ? CURLE_COULDNT_RESOLVE_HOST : CURLE_OUT_OF_MEMORY; + } - if(conn->unix_domain_socket) - unix_path = conn->unix_domain_socket; -#ifndef CURL_DISABLE_PROXY - else if(conn->socks_proxy.host.name - && !strncmp(UNIX_SOCKET_PREFIX"/", - conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX))) - unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1; + hostaddr->inuse++; + conn->dns_entry = hostaddr; + return CURLE_OK; +} #endif - if(unix_path) { - /* Unix domain sockets are local. The host gets ignored, just use the - * specified domain socket address. Do not cache "DNS entries". There is - * no DNS involved and we already have the filesystem path available */ +#ifndef CURL_DISABLE_PROXY +static CURLcode resolve_proxy(struct Curl_easy *data, + struct connectdata *conn, + bool *async) +{ + struct Curl_dns_entry *hostaddr = NULL; + struct hostname *host; + timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + int rc; - hostaddr = calloc(1, sizeof(struct Curl_dns_entry)); - if(!hostaddr) - result = CURLE_OUT_OF_MEMORY; - else { - bool longpath = FALSE; - hostaddr->addr = Curl_unix2addr(unix_path, &longpath, - conn->bits.abstract_unix_socket); - if(hostaddr->addr) - hostaddr->inuse++; - else { - /* Long paths are not supported for now */ - if(longpath) { - failf(data, "Unix socket path too long: '%s'", unix_path); - result = CURLE_COULDNT_RESOLVE_HOST; - } - else - result = CURLE_OUT_OF_MEMORY; - free(hostaddr); - hostaddr = NULL; - } - } - } - else + DEBUGASSERT(conn->dns_entry == NULL); + + host = conn->bits.socksproxy ? &conn->socks_proxy.host : + &conn->http_proxy.host; + + conn->hostname_resolve = strdup(host->name); + if(!conn->hostname_resolve) + return CURLE_OUT_OF_MEMORY; + + rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port, + &hostaddr, timeout_ms); + conn->dns_entry = hostaddr; + if(rc == CURLRESOLV_PENDING) + *async = TRUE; + else if(rc == CURLRESOLV_TIMEDOUT) + return CURLE_OPERATION_TIMEDOUT; + else if(!hostaddr) { + failf(data, "Couldn't resolve proxy '%s'", host->dispname); + return CURLE_COULDNT_RESOLVE_PROXY; + } + + return CURLE_OK; +} #endif - if(!CONN_IS_PROXIED(conn)) { - struct hostname *connhost; - if(conn->bits.conn_to_host) - connhost = &conn->conn_to_host; - else - connhost = &conn->host; +static CURLcode resolve_host(struct Curl_easy *data, + struct connectdata *conn, + bool *async) +{ + struct Curl_dns_entry *hostaddr = NULL; + struct hostname *connhost; + timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE); + int rc; - /* If not connecting via a proxy, extract the port from the URL, if it is - * there, thus overriding any defaults that might have been set above. */ - if(conn->bits.conn_to_port) - conn->port = conn->conn_to_port; - else - conn->port = conn->remote_port; + DEBUGASSERT(conn->dns_entry == NULL); - /* Resolve target host right on */ - conn->hostname_resolve = strdup(connhost->name); - if(!conn->hostname_resolve) - return CURLE_OUT_OF_MEMORY; - rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port, - &hostaddr, timeout_ms); - if(rc == CURLRESOLV_PENDING) - *async = TRUE; - - else if(rc == CURLRESOLV_TIMEDOUT) { - failf(data, "Failed to resolve host '%s' with timeout after %ld ms", - connhost->dispname, - Curl_timediff(Curl_now(), data->progress.t_startsingle)); - result = CURLE_OPERATION_TIMEDOUT; - } - else if(!hostaddr) { - failf(data, "Could not resolve host: %s", connhost->dispname); - result = CURLE_COULDNT_RESOLVE_HOST; - /* don't return yet, we need to clean up the timeout first */ - } - } -#ifndef CURL_DISABLE_PROXY - else { - /* This is a proxy that hasn't been resolved yet. */ + connhost = conn->bits.conn_to_host ? &conn->conn_to_host : &conn->host; - struct hostname * const host = conn->bits.socksproxy ? - &conn->socks_proxy.host : &conn->http_proxy.host; + /* If not connecting via a proxy, extract the port from the URL, if it is + * there, thus overriding any defaults that might have been set above. */ + conn->port = conn->bits.conn_to_port ? conn->conn_to_port : + conn->remote_port; - /* resolve proxy */ - conn->hostname_resolve = strdup(host->name); - if(!conn->hostname_resolve) - return CURLE_OUT_OF_MEMORY; - rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port, - &hostaddr, timeout_ms); + /* Resolve target host right on */ + conn->hostname_resolve = strdup(connhost->name); + if(!conn->hostname_resolve) + return CURLE_OUT_OF_MEMORY; - if(rc == CURLRESOLV_PENDING) - *async = TRUE; + rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port, + &hostaddr, timeout_ms); + conn->dns_entry = hostaddr; + if(rc == CURLRESOLV_PENDING) + *async = TRUE; + else if(rc == CURLRESOLV_TIMEDOUT) { + failf(data, "Failed to resolve host '%s' with timeout after %ld ms", + connhost->dispname, + Curl_timediff(Curl_now(), data->progress.t_startsingle)); + return CURLE_OPERATION_TIMEDOUT; + } + else if(!hostaddr) { + failf(data, "Could not resolve host: %s", connhost->dispname); + return CURLE_COULDNT_RESOLVE_HOST; + } - else if(rc == CURLRESOLV_TIMEDOUT) - result = CURLE_OPERATION_TIMEDOUT; + return CURLE_OK; +} - else if(!hostaddr) { - failf(data, "Couldn't resolve proxy '%s'", host->dispname); - result = CURLE_COULDNT_RESOLVE_PROXY; - /* don't return yet, we need to clean up the timeout first */ - } - } +/* Perform a fresh resolve */ +static CURLcode resolve_fresh(struct Curl_easy *data, + struct connectdata *conn, + bool *async) +{ +#ifdef USE_UNIX_SOCKETS + char *unix_path = conn->unix_domain_socket; + +#ifndef CURL_DISABLE_PROXY + if(!unix_path && conn->socks_proxy.host.name && + !strncmp(UNIX_SOCKET_PREFIX"/", + conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX))) + unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1; #endif - DEBUGASSERT(conn->dns_entry == NULL); - conn->dns_entry = hostaddr; + + if(unix_path) { + conn->transport = TRNSPRT_UNIX; + return resolve_unix(data, conn, unix_path); } +#endif - return result; +#ifndef CURL_DISABLE_PROXY + if(CONN_IS_PROXIED(conn)) + return resolve_proxy(data, conn, async); +#endif + + return resolve_host(data, conn, async); +} + +/************************************************************* + * Resolve the address of the server or proxy + *************************************************************/ +static CURLcode resolve_server(struct Curl_easy *data, + struct connectdata *conn, + bool *async) +{ + DEBUGASSERT(conn); + DEBUGASSERT(data); + + /* Resolve the name of the server or proxy */ + if(conn->bits.reuse) { + /* We're reusing the connection - no need to resolve anything, and + idnconvert_hostname() was called already in create_conn() for the re-use + case. */ + *async = FALSE; + return CURLE_OK; + } + + return resolve_fresh(data, conn, async); } /* @@ -3754,29 +3730,6 @@ static CURLcode create_conn(struct Curl_easy *data, if(result) goto out; - /************************************************************* - * IDN-convert the hostnames - *************************************************************/ - result = Curl_idnconvert_hostname(data, &conn->host); - if(result) - goto out; - if(conn->bits.conn_to_host) { - result = Curl_idnconvert_hostname(data, &conn->conn_to_host); - if(result) - goto out; - } -#ifndef CURL_DISABLE_PROXY - if(conn->bits.httpproxy) { - result = Curl_idnconvert_hostname(data, &conn->http_proxy.host); - if(result) - goto out; - } - if(conn->bits.socksproxy) { - result = Curl_idnconvert_hostname(data, &conn->socks_proxy.host); - if(result) - goto out; - } -#endif /************************************************************* * Check whether the host and the "connect to host" are equal. @@ -3989,13 +3942,11 @@ static CURLcode create_conn(struct Curl_easy *data, be able to do that if we have reached the limit of how many connections we are allowed to open. */ - if(conn->handler->flags & PROTOPT_ALPN_NPN) { + if(conn->handler->flags & PROTOPT_ALPN) { /* The protocol wants it, so set the bits if enabled in the easy handle (default) */ if(data->set.ssl_enable_alpn) conn->bits.tls_enable_alpn = TRUE; - if(data->set.ssl_enable_npn) - conn->bits.tls_enable_npn = TRUE; } if(waitpipe) diff --git a/libs/libcurl/src/url.h b/libs/libcurl/src/url.h index e3b2940305..ba4270d523 100644 --- a/libs/libcurl/src/url.h +++ b/libs/libcurl/src/url.h @@ -46,7 +46,8 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len, char **userptr, char **passwdptr, char **optionsptr); -const struct Curl_handler *Curl_builtin_scheme(const char *scheme); +const struct Curl_handler *Curl_builtin_scheme(const char *scheme, + size_t schemelen); bool Curl_is_ASCII_name(const char *hostname); CURLcode Curl_idnconvert_hostname(struct Curl_easy *data, diff --git a/libs/libcurl/src/urlapi-int.h b/libs/libcurl/src/urlapi-int.h index a03aa888af..43a83ef6e4 100644 --- a/libs/libcurl/src/urlapi-int.h +++ b/libs/libcurl/src/urlapi-int.h @@ -25,10 +25,12 @@ ***************************************************************************/ #include "curl_setup.h" -bool Curl_is_absolute_url(const char *url, char *scheme, size_t buflen); +size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen, + bool guess_scheme); #ifdef DEBUGBUILD -CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, bool); +CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host, + bool has_scheme); #endif #endif /* HEADER_CURL_URLAPI_INT_H */ diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c index dee4b5aa09..7dac81c85c 100644 --- a/libs/libcurl/src/urlapi.c +++ b/libs/libcurl/src/urlapi.c @@ -27,12 +27,12 @@ #include "urldata.h" #include "urlapi-int.h" #include "strcase.h" -#include "dotdot.h" #include "url.h" #include "escape.h" #include "curl_ctype.h" #include "inet_pton.h" #include "inet_ntop.h" +#include "strdup.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -68,9 +68,6 @@ struct Curl_URL { char *path; char *query; char *fragment; - - char *scratch; /* temporary scratch area */ - char *temppath; /* temporary path pointer */ long portnum; /* the numerical version */ }; @@ -88,8 +85,6 @@ static void free_urlhandle(struct Curl_URL *u) free(u->path); free(u->query); free(u->fragment); - free(u->scratch); - free(u->temppath); } /* @@ -121,95 +116,50 @@ static const char *find_host_sep(const char *url) } /* - * Decide in an encoding-independent manner whether a character in an - * URL must be escaped. The same criterion must be used in strlen_url() - * and strcpy_url(). + * Decide in an encoding-independent manner whether a character in a URL must + * be escaped. This is used in urlencode_str(). */ static bool urlchar_needs_escaping(int c) { return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)); } -/* - * strlen_url() returns the length of the given URL if the spaces within the - * URL were properly URL encoded. - * URL encoding should be skipped for host names, otherwise IDN resolution - * will fail. - */ -static size_t strlen_url(const char *url, bool relative) -{ - const unsigned char *ptr; - size_t newlen = 0; - bool left = TRUE; /* left side of the ? */ - const unsigned char *host_sep = (const unsigned char *) url; - - if(!relative) - host_sep = (const unsigned char *) find_host_sep(url); - - for(ptr = (unsigned char *)url; *ptr; ptr++) { - - if(ptr < host_sep) { - ++newlen; - continue; - } - - if(*ptr == ' ') { - if(left) - newlen += 3; - else - newlen++; - continue; - } - - if (*ptr == '?') - left = FALSE; - - if(urlchar_needs_escaping(*ptr)) - newlen += 2; - - newlen++; - } - - return newlen; -} - -/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in - * the source URL accordingly. +/* urlencode_str() writes data into an output dynbuf and URL-encodes the + * spaces in the source URL accordingly. + * * URL encoding should be skipped for host names, otherwise IDN resolution * will fail. - * - * Returns TRUE if something was updated. */ -static bool strcpy_url(char *output, const char *url, bool relative) +static CURLUcode urlencode_str(struct dynbuf *o, const char *url, + size_t len, bool relative, + bool query) { /* we must add this with whitespace-replacing */ - bool left = TRUE; + bool left = !query; const unsigned char *iptr; - char *optr = output; const unsigned char *host_sep = (const unsigned char *) url; - bool changed = FALSE; if(!relative) host_sep = (const unsigned char *) find_host_sep(url); for(iptr = (unsigned char *)url; /* read from here */ - *iptr; /* until zero byte */ - iptr++) { + len; iptr++, len--) { if(iptr < host_sep) { - *optr++ = *iptr; + if(Curl_dyn_addn(o, iptr, 1)) + return CURLUE_OUT_OF_MEMORY; continue; } if(*iptr == ' ') { if(left) { - *optr++='%'; /* add a '%' */ - *optr++='2'; /* add a '2' */ - *optr++='0'; /* add a '0' */ + if(Curl_dyn_addn(o, "%20", 3)) + return CURLUE_OUT_OF_MEMORY; + } + else { + if(Curl_dyn_addn(o, "+", 1)) + return CURLUE_OUT_OF_MEMORY; } - else - *optr++='+'; /* add a '+' here */ - changed = TRUE; continue; } @@ -217,24 +167,28 @@ static bool strcpy_url(char *output, const char *url, bool relative) left = FALSE; if(urlchar_needs_escaping(*iptr)) { - msnprintf(optr, 4, "%%%02x", *iptr); - changed = TRUE; - optr += 3; + if(Curl_dyn_addf(o, "%%%02x", *iptr)) + return CURLUE_OUT_OF_MEMORY; + } + else { + if(Curl_dyn_addn(o, iptr, 1)) + return CURLUE_OUT_OF_MEMORY; } - else - *optr++ = *iptr; } - *optr = 0; /* null-terminate output buffer */ - return changed; + return CURLUE_OK; } /* - * Returns true if the given URL is absolute (as opposed to relative). Returns - * the scheme in the buffer if TRUE and 'buf' is non-NULL. The buflen must - * be larger than MAX_SCHEME_LEN if buf is set. + * Returns the length of the scheme if the given URL is absolute (as opposed + * to relative). Stores the scheme in the buffer if TRUE and 'buf' is + * non-NULL. The buflen must be larger than MAX_SCHEME_LEN if buf is set. + * + * If 'guess_scheme' is TRUE, it means the URL might be provided without + * scheme. */ -bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) +size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen, + bool guess_scheme) { int i; DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN)); @@ -242,8 +196,8 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) if(buf) buf[0] = 0; /* always leave a defined value in buf */ #ifdef WIN32 - if(STARTS_WITH_DRIVE_PREFIX(url)) - return FALSE; + if(guess_scheme && STARTS_WITH_DRIVE_PREFIX(url)) + return 0; #endif for(i = 0; i < MAX_SCHEME_LEN; ++i) { char s = url[i]; @@ -256,16 +210,22 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) break; } } - if(i && (url[i] == ':') && (url[i + 1] == '/')) { + if(i && (url[i] == ':') && ((url[i + 1] == '/') || !guess_scheme)) { + /* If this does not guess scheme, the scheme always ends with the colon so + that this also detects data: URLs etc. In guessing mode, data: could + be the host name "data" with a specified port number. */ + + /* the length of the scheme is the name part only */ + size_t len = i; if(buf) { buf[i] = 0; while(i--) { - buf[i] = (char)TOLOWER(url[i]); + buf[i] = Curl_raw_tolower(url[i]); } } - return TRUE; + return len; } - return FALSE; + return 0; } /* @@ -273,34 +233,26 @@ bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen) * URL-encodes any spaces. * The returned pointer must be freed by the caller unless NULL * (returns NULL on out of memory). + * + * Note that this function destroys the 'base' string. */ -static char *concat_url(const char *base, const char *relurl) +static char *concat_url(char *base, const char *relurl) { /*** TRY to append this new path to the old URL to the right of the host part. Oh crap, this is doomed to cause problems in the future... */ - char *newest; + struct dynbuf newest; char *protsep; char *pathsep; - size_t newlen; bool host_changed = FALSE; - const char *useurl = relurl; - size_t urllen; - - /* we must make our own copy of the URL to play with, as it may - point to read-only data */ - char *url_clone = strdup(base); - - if(!url_clone) - return NULL; /* skip out of this NOW */ /* protsep points to the start of the host name */ - protsep = strstr(url_clone, "//"); + protsep = strstr(base, "//"); if(!protsep) - protsep = url_clone; + protsep = base; else protsep += 2; /* pass the slashes */ @@ -393,38 +345,24 @@ static char *concat_url(const char *base, const char *relurl) } } - /* If the new part contains a space, this is a mighty stupid redirect - but we still make an effort to do "right". To the left of a '?' - letter we replace each space with %20 while it is replaced with '+' - on the right side of the '?' letter. - */ - newlen = strlen_url(useurl, !host_changed); - - urllen = strlen(url_clone); - - newest = malloc(urllen + 1 + /* possible slash */ - newlen + 1 /* zero byte */); - - if(!newest) { - free(url_clone); /* don't leak this */ - return NULL; - } + Curl_dyn_init(&newest, CURL_MAX_INPUT_LENGTH); /* copy over the root url part */ - memcpy(newest, url_clone, urllen); + if(Curl_dyn_add(&newest, base)) + return NULL; /* check if we need to append a slash */ if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0])) ; - else - newest[urllen++]='/'; + else { + if(Curl_dyn_addn(&newest, "/", 1)) + return NULL; + } /* then append the new piece on the right side */ - strcpy_url(&newest[urllen], useurl, !host_changed); + urlencode_str(&newest, useurl, strlen(useurl), !host_changed, FALSE); - free(url_clone); - - return newest; + return Curl_dyn_ptr(&newest); } /* scan for byte values < 31 or 127 */ @@ -458,7 +396,7 @@ static bool junkscan(const char *part, unsigned int flags) * */ static CURLUcode parse_hostname_login(struct Curl_URL *u, - char **hostname, + struct dynbuf *host, unsigned int flags) { CURLUcode result = CURLUE_OK; @@ -468,27 +406,31 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u, char *optionsp = NULL; const struct Curl_handler *h = NULL; - /* At this point, we're hoping all the other special cases have - * been taken care of, so conn->host.name is at most - * [user[:password][;options]]@]hostname + /* At this point, we assume all the other special cases have been taken + * care of, so the host is at most + * + * [user[:password][;options]]@]hostname * * We need somewhere to put the embedded details, so do that first. */ - char *ptr = strchr(*hostname, '@'); - char *login = *hostname; + char *login = Curl_dyn_ptr(host); + char *ptr; + + DEBUGASSERT(login); + ptr = strchr(login, '@'); if(!ptr) goto out; /* We will now try to extract the * possible login information in a string like: * ftp://user:password@ftp.my.site:8021/README */ - *hostname = ++ptr; + ptr++; /* if this is a known scheme, get some details */ if(u->scheme) - h = Curl_builtin_scheme(u->scheme); + h = Curl_builtin_scheme(u->scheme, CURL_ZERO_TERMINATED); /* We could use the login information in the URL so extract it. Only parse options if the handler says we should. Note that 'h' might be NULL! */ @@ -530,6 +472,10 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u, u->options = optionsp; } + /* move the name to the start of the host buffer */ + if(Curl_dyn_tail(host, strlen(ptr))) + return CURLUE_OUT_OF_MEMORY; + return CURLUE_OK; out: @@ -543,13 +489,13 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u, return result; } -UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, +UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host, bool has_scheme) { char *portptr = NULL; char endbracket; int len; - + char *hostname = Curl_dyn_ptr(host); /* * Find the end of an IPv6 address, either on the ']' ending bracket or * a percent-encoded zone index. @@ -586,6 +532,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, char *rest; long port; char portbuf[7]; + size_t keep = portptr - hostname; /* Browser behavior adaptation. If there's a colon with no digits after, just cut off the name there which makes us ignore the colon and just @@ -594,15 +541,15 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, Don't do it if the URL has no scheme, to make something that looks like a scheme not work! */ - if(!portptr[1]) { - *portptr = '\0'; + Curl_dyn_setlen(host, keep); + portptr++; + if(!*portptr) return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER; - } - if(!ISDIGIT(portptr[1])) + if(!ISDIGIT(*portptr)) return CURLUE_BAD_PORT_NUMBER; - port = strtol(portptr + 1, &rest, 10); /* Port number must be decimal */ + port = strtol(portptr, &rest, 10); /* Port number must be decimal */ if(port > 0xffff) return CURLUE_BAD_PORT_NUMBER; @@ -610,7 +557,6 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, if(rest[0]) return CURLUE_BAD_PORT_NUMBER; - *portptr++ = '\0'; /* cut off the name there */ *rest = 0; /* generate a new port number string to get rid of leading zeroes etc */ msnprintf(portbuf, sizeof(portbuf), "%ld", port); @@ -623,12 +569,15 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, return CURLUE_OK; } -static CURLUcode hostname_check(struct Curl_URL *u, char *hostname) +static CURLUcode hostname_check(struct Curl_URL *u, char *hostname, + size_t hlen) /* length of hostname */ { size_t len; - size_t hlen = strlen(hostname); + DEBUGASSERT(hostname); - if(hostname[0] == '[') { + if(!hostname[0]) + return CURLUE_NO_HOST; + else if(hostname[0] == '[') { const char *l = "0123456789abcdefABCDEF:."; if(hlen < 4) /* '[::]' is the shortest possible valid string */ return CURLUE_BAD_IPV6; @@ -687,13 +636,11 @@ static CURLUcode hostname_check(struct Curl_URL *u, char *hostname) } else { /* letters from the second string are not ok */ - len = strcspn(hostname, " \r\n\t/:#?!@"); + len = strcspn(hostname, " \r\n\t/:#?!@{}[]\\$\'\"^`*<>=;,"); if(hlen != len) /* hostname with bad content */ return CURLUE_BAD_HOSTNAME; } - if(!hostname[0]) - return CURLUE_NO_HOST; return CURLUE_OK; } @@ -787,79 +734,230 @@ static bool ipv4_normalize(const char *hostname, char *outp, size_t olen) return TRUE; } -/* return strdup'ed version in 'outp', possibly percent decoded */ -static CURLUcode decode_host(char *hostname, char **outp) +/* if necessary, replace the host content with a URL decoded version */ +static CURLUcode decode_host(struct dynbuf *host) { char *per = NULL; - if(hostname[0] != '[') + const char *hostname = Curl_dyn_ptr(host); + if(hostname[0] == '[') /* only decode if not an ipv6 numerical */ - per = strchr(hostname, '%'); - if(!per) { - *outp = strdup(hostname); - if(!*outp) - return CURLUE_OUT_OF_MEMORY; - } + return CURLUE_OK; + per = strchr(hostname, '%'); + if(!per) + /* nothing to decode */ + return CURLUE_OK; else { - /* might be encoded */ + /* encoded */ size_t dlen; - CURLcode result = Curl_urldecode(hostname, 0, outp, &dlen, REJECT_CTRL); + char *decoded; + CURLcode result = Curl_urldecode(hostname, 0, &decoded, &dlen, + REJECT_CTRL); if(result) return CURLUE_BAD_HOSTNAME; + Curl_dyn_reset(host); + result = Curl_dyn_addn(host, decoded, dlen); + free(decoded); + if(result) + return CURLUE_OUT_OF_MEMORY; } return CURLUE_OK; } -static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) +/* + * "Remove Dot Segments" + * https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4 + */ + +/* + * dedotdotify() + * @unittest: 1395 + * + * This function gets a null-terminated path with dot and dotdot sequences + * passed in and strips them off according to the rules in RFC 3986 section + * 5.2.4. + * + * The function handles a query part ('?' + stuff) appended but it expects + * that fragments ('#' + stuff) have already been cut off. + * + * RETURNS + * + * an allocated dedotdotified output string + */ +UNITTEST char *dedotdotify(const char *input, size_t clen); +UNITTEST char *dedotdotify(const char *input, size_t clen) { - char *path; - bool path_alloced = FALSE; + char *out = malloc(clen + 1); + char *outptr; + const char *orginput = input; + char *queryp; + if(!out) + return NULL; /* out of memory */ + + *out = 0; /* null-terminates, for inputs like "./" */ + outptr = out; + + if(!*input) + /* zero length input string, return that */ + return out; + + /* + * To handle query-parts properly, we must find it and remove it during the + * dotdot-operation and then append it again at the end to the output + * string. + */ + queryp = strchr(input, '?'); + + do { + bool dotdot = TRUE; + if(*input == '.') { + /* A. If the input buffer begins with a prefix of "../" or "./", then + remove that prefix from the input buffer; otherwise, */ + + if(!strncmp("./", input, 2)) { + input += 2; + clen -= 2; + } + else if(!strncmp("../", input, 3)) { + input += 3; + clen -= 3; + } + /* D. if the input buffer consists only of "." or "..", then remove + that from the input buffer; otherwise, */ + + else if(!strcmp(".", input) || !strcmp("..", input) || + !strncmp(".?", input, 2) || !strncmp("..?", input, 3)) { + *out = 0; + break; + } + else + dotdot = FALSE; + } + else if(*input == '/') { + /* B. if the input buffer begins with a prefix of "/./" or "/.", where + "." is a complete path segment, then replace that prefix with "/" in + the input buffer; otherwise, */ + if(!strncmp("/./", input, 3)) { + input += 2; + clen -= 2; + } + else if(!strcmp("/.", input) || !strncmp("/.?", input, 3)) { + *outptr++ = '/'; + *outptr = 0; + break; + } + + /* C. if the input buffer begins with a prefix of "/../" or "/..", + where ".." is a complete path segment, then replace that prefix with + "/" in the input buffer and remove the last segment and its + preceding "/" (if any) from the output buffer; otherwise, */ + + else if(!strncmp("/../", input, 4)) { + input += 3; + clen -= 3; + /* remove the last segment from the output buffer */ + while(outptr > out) { + outptr--; + if(*outptr == '/') + break; + } + *outptr = 0; /* null-terminate where it stops */ + } + else if(!strcmp("/..", input) || !strncmp("/..?", input, 4)) { + /* remove the last segment from the output buffer */ + while(outptr > out) { + outptr--; + if(*outptr == '/') + break; + } + *outptr++ = '/'; + *outptr = 0; /* null-terminate where it stops */ + break; + } + else + dotdot = FALSE; + } + else + dotdot = FALSE; + + if(!dotdot) { + /* E. move the first path segment in the input buffer to the end of + the output buffer, including the initial "/" character (if any) and + any subsequent characters up to, but not including, the next "/" + character or the end of the input buffer. */ + + do { + *outptr++ = *input++; + clen--; + } while(*input && (*input != '/') && (*input != '?')); + *outptr = 0; + } + + /* continue until end of input string OR, if there is a terminating + query part, stop there */ + } while(*input && (!queryp || (input < queryp))); + + if(queryp) { + size_t qlen; + /* There was a query part, append that to the output. */ + size_t oindex = queryp - orginput; + qlen = strlen(&orginput[oindex]); + memcpy(outptr, &orginput[oindex], qlen + 1); /* include zero byte */ + } + + return out; +} + +static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) +{ + const char *path; + size_t pathlen; bool uncpath = FALSE; - char *hostname; char *query = NULL; char *fragment = NULL; - CURLUcode result; - bool url_has_scheme = FALSE; char schemebuf[MAX_SCHEME_LEN + 1]; const char *schemep = NULL; size_t schemelen = 0; size_t urllen; + CURLUcode result = CURLUE_OK; + size_t fraglen = 0; + struct dynbuf host; DEBUGASSERT(url); + Curl_dyn_init(&host, CURL_MAX_INPUT_LENGTH); + /************************************************************* * Parse the URL. ************************************************************/ /* allocate scratch area */ urllen = strlen(url); - if(urllen > CURL_MAX_INPUT_LENGTH) + if(urllen > CURL_MAX_INPUT_LENGTH) { /* excessive input length */ - return CURLUE_MALFORMED_INPUT; - - path = u->scratch = malloc(urllen * 2 + 2); - if(!path) - return CURLUE_OUT_OF_MEMORY; - - hostname = &path[urllen + 1]; - hostname[0] = 0; - - if(Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf))) { - url_has_scheme = TRUE; - schemelen = strlen(schemebuf); + result = CURLUE_MALFORMED_INPUT; + goto fail; } + schemelen = Curl_is_absolute_url(url, schemebuf, sizeof(schemebuf), + flags & (CURLU_GUESS_SCHEME| + CURLU_DEFAULT_SCHEME)); + /* handle the file: scheme */ - if(url_has_scheme && !strcmp(schemebuf, "file")) { - if(urllen <= 6) + if(schemelen && !strcmp(schemebuf, "file")) { + if(urllen <= 6) { /* file:/ is not enough to actually be a complete file: URL */ - return CURLUE_BAD_FILE_URL; + result = CURLUE_BAD_FILE_URL; + goto fail; + } /* path has been allocated large enough to hold this */ - strcpy(path, &url[5]); + path = (char *)&url[5]; - u->scheme = strdup("file"); - if(!u->scheme) - return CURLUE_OUT_OF_MEMORY; + schemep = u->scheme = strdup("file"); + if(!u->scheme) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } /* Extra handling URLs with an authority component (i.e. that start with * "file://") @@ -869,7 +967,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) */ if(path[0] == '/' && path[1] == '/') { /* swallow the two slashes */ - char *ptr = &path[2]; + const char *ptr = &path[2]; /* * According to RFC 8089, a file: URL can be reliably dereferenced if: @@ -905,13 +1003,17 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) chars, and the delimiting slash character must be appended to the host name */ path = strpbrk(ptr, "/\\:*?\"<>|"); - if(!path || *path != '/') - return CURLUE_BAD_FILE_URL; + if(!path || *path != '/') { + result = CURLUE_BAD_FILE_URL; + goto fail; + } len = path - ptr; if(len) { - memcpy(hostname, ptr, len); - hostname[len] = 0; + if(Curl_dyn_addn(&host, ptr, len)) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } uncpath = TRUE; } @@ -919,7 +1021,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) #else /* Invalid file://hostname/, expected localhost or 127.0.0.1 or none */ - return CURLUE_BAD_FILE_URL; + result = CURLUE_BAD_FILE_URL; + goto fail; #endif } } @@ -928,7 +1031,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) } if(!uncpath) - hostname = NULL; /* no host for file: URLs by default */ + /* no host for file: URLs by default */ + Curl_dyn_reset(&host); #if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__) /* Don't allow Windows drive letters when not in Windows. @@ -936,13 +1040,14 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) || STARTS_WITH_URL_DRIVE_PREFIX(path)) { /* File drive letters are only accepted in MSDOS/Windows */ - return CURLUE_BAD_FILE_URL; + result = CURLUE_BAD_FILE_URL; + goto fail; } #else /* If the path starts with a slash and a drive letter, ditch the slash */ if('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) { /* This cannot be done with strcpy, as the memory chunks overlap! */ - memmove(path, &path[1], strlen(&path[1]) + 1); + path++; } #endif @@ -952,32 +1057,39 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) const char *p; const char *hostp; size_t len; - path[0] = 0; - if(url_has_scheme) { + if(schemelen) { int i = 0; p = &url[schemelen + 1]; while(p && (*p == '/') && (i < 4)) { p++; i++; } - if((i < 1) || (i>3)) - /* less than one or more than three slashes */ - return CURLUE_BAD_SLASHES; schemep = schemebuf; - if(!Curl_builtin_scheme(schemep) && - !(flags & CURLU_NON_SUPPORT_SCHEME)) - return CURLUE_UNSUPPORTED_SCHEME; + if(!Curl_builtin_scheme(schemep, CURL_ZERO_TERMINATED) && + !(flags & CURLU_NON_SUPPORT_SCHEME)) { + result = CURLUE_UNSUPPORTED_SCHEME; + goto fail; + } - if(junkscan(schemep, flags)) - return CURLUE_BAD_SCHEME; + if((i < 1) || (i>3)) { + /* less than one or more than three slashes */ + result = CURLUE_BAD_SLASHES; + goto fail; + } + if(junkscan(schemep, flags)) { + result = CURLUE_BAD_SCHEME; + goto fail; + } } else { /* no scheme! */ - if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME))) - return CURLUE_BAD_SCHEME; + if(!(flags & (CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME))) { + result = CURLUE_BAD_SCHEME; + goto fail; + } if(flags & CURLU_DEFAULT_SCHEME) schemep = DEFAULT_SCHEME; @@ -994,122 +1106,169 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) len = p - hostp; if(len) { - memcpy(hostname, hostp, len); - hostname[len] = 0; + if(Curl_dyn_addn(&host, hostp, len)) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } } else { - if(!(flags & CURLU_NO_AUTHORITY)) - return CURLUE_NO_HOST; + if(!(flags & CURLU_NO_AUTHORITY)) { + result = CURLUE_NO_HOST; + goto fail; + } } - strcpy(path, p); + path = (char *)p; if(schemep) { u->scheme = strdup(schemep); - if(!u->scheme) - return CURLUE_OUT_OF_MEMORY; + if(!u->scheme) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } } } - if((flags & CURLU_URLENCODE) && path[0]) { - /* worst case output length is 3x the original! */ - char *newp = malloc(strlen(path) * 3); - if(!newp) - return CURLUE_OUT_OF_MEMORY; - path_alloced = TRUE; - strcpy_url(newp, path, TRUE); /* consider it relative */ - u->temppath = path = newp; - } - fragment = strchr(path, '#'); if(fragment) { - *fragment++ = 0; - if(junkscan(fragment, flags)) - return CURLUE_BAD_FRAGMENT; - if(fragment[0]) { - u->fragment = strdup(fragment); - if(!u->fragment) - return CURLUE_OUT_OF_MEMORY; + fraglen = strlen(fragment); + if(fraglen > 1) { + /* skip the leading '#' in the copy but include the terminating null */ + u->fragment = Curl_memdup(fragment + 1, fraglen); + if(!u->fragment) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } + + if(junkscan(u->fragment, flags)) { + result = CURLUE_BAD_FRAGMENT; + goto fail; + } } } query = strchr(path, '?'); - if(query) { - *query++ = 0; - if(junkscan(query, flags)) - return CURLUE_BAD_QUERY; - /* done even if the query part is a blank string */ - u->query = strdup(query); - if(!u->query) - return CURLUE_OUT_OF_MEMORY; - } + if(query && (!fragment || (query < fragment))) { + size_t qlen = strlen(query) - fraglen; /* includes '?' */ + pathlen = strlen(path) - qlen - fraglen; + if(qlen > 1) { + if(qlen && (flags & CURLU_URLENCODE)) { + struct dynbuf enc; + Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); + /* skip the leading question mark */ + if(urlencode_str(&enc, query + 1, qlen - 1, TRUE, TRUE)) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } + u->query = Curl_dyn_ptr(&enc); + } + else { + u->query = Curl_memdup(query + 1, qlen); + if(!u->query) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } + u->query[qlen - 1] = 0; + } - if(junkscan(path, flags)) - return CURLUE_BAD_PATH; + if(junkscan(u->query, flags)) { + result = CURLUE_BAD_QUERY; + goto fail; + } + } + else { + /* single byte query */ + u->query = strdup(""); + if(!u->query) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } + } + } + else + pathlen = strlen(path) - fraglen; + + if(pathlen && (flags & CURLU_URLENCODE)) { + struct dynbuf enc; + Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); + if(urlencode_str(&enc, path, pathlen, TRUE, FALSE)) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } + pathlen = Curl_dyn_len(&enc); + path = u->path = Curl_dyn_ptr(&enc); + } - if(!path[0]) - /* if there's no path left set, unset */ + if(!pathlen) { + /* there is no path left, unset */ path = NULL; + } else { + if(!u->path) { + u->path = Curl_memdup(path, pathlen + 1); + if(!u->path) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } + u->path[pathlen] = 0; + path = u->path; + } + else if(flags & CURLU_URLENCODE) + /* it might have encoded more than just the path so cut it */ + u->path[pathlen] = 0; + + if(junkscan(u->path, flags)) { + result = CURLUE_BAD_PATH; + goto fail; + } + if(!(flags & CURLU_PATH_AS_IS)) { /* remove ../ and ./ sequences according to RFC3986 */ - char *newp = Curl_dedotdotify(path); - if(!newp) - return CURLUE_OUT_OF_MEMORY; - - if(strcmp(newp, path)) { - /* if we got a new version */ - if(path_alloced) - Curl_safefree(u->temppath); - u->temppath = path = newp; - path_alloced = TRUE; + char *newp = dedotdotify((char *)path, pathlen); + if(!newp) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; } - else - free(newp); + free(u->path); + u->path = newp; } - - u->path = path_alloced?path:strdup(path); - if(!u->path) - return CURLUE_OUT_OF_MEMORY; - u->temppath = NULL; /* used now */ } - if(hostname) { + if(Curl_dyn_len(&host)) { char normalized_ipv4[sizeof("255.255.255.255") + 1]; /* * Parse the login details and strip them out of the host name. */ - result = parse_hostname_login(u, &hostname, flags); - if(result) - return result; - - result = Curl_parse_port(u, hostname, url_has_scheme); + result = parse_hostname_login(u, &host, flags); + if(!result) + result = Curl_parse_port(u, &host, schemelen); if(result) - return result; + goto fail; - if(junkscan(hostname, flags)) - return CURLUE_BAD_HOSTNAME; + if(junkscan(Curl_dyn_ptr(&host), flags)) { + result = CURLUE_BAD_HOSTNAME; + goto fail; + } - if(0 == strlen(hostname) && (flags & CURLU_NO_AUTHORITY)) { - /* Skip hostname check, it's allowed to be empty. */ - u->host = strdup(""); + if(ipv4_normalize(Curl_dyn_ptr(&host), + normalized_ipv4, sizeof(normalized_ipv4))) { + Curl_dyn_reset(&host); + if(Curl_dyn_add(&host, normalized_ipv4)) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } } else { - if(ipv4_normalize(hostname, normalized_ipv4, sizeof(normalized_ipv4))) - u->host = strdup(normalized_ipv4); - else { - result = decode_host(hostname, &u->host); - if(result) - return result; - result = hostname_check(u, u->host); - if(result) - return result; - } + result = decode_host(&host); + if(!result) + result = hostname_check(u, Curl_dyn_ptr(&host), Curl_dyn_len(&host)); + if(result) + goto fail; } - if(!u->host) - return CURLUE_OUT_OF_MEMORY; + if((flags & CURLU_GUESS_SCHEME) && !schemep) { + const char *hostname = Curl_dyn_ptr(&host); /* legacy curl-style guess based on host name */ if(checkprefix("ftp.", hostname)) schemep = "ftp"; @@ -1127,27 +1286,26 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) schemep = "http"; u->scheme = strdup(schemep); - if(!u->scheme) - return CURLUE_OUT_OF_MEMORY; + if(!u->scheme) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; + } + } + } + else if(flags & CURLU_NO_AUTHORITY) { + /* allowed to be empty. */ + if(Curl_dyn_add(&host, "")) { + result = CURLUE_OUT_OF_MEMORY; + goto fail; } } - Curl_safefree(u->scratch); - Curl_safefree(u->temppath); - - return CURLUE_OK; -} + u->host = Curl_dyn_ptr(&host); -/* - * Parse the URL and set the relevant members of the Curl_URL struct. - */ -static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) -{ - CURLUcode result = seturl(url, u, flags); - if(result) { - free_urlhandle(u); - memset(u, 0, sizeof(struct Curl_URL)); - } + return result; + fail: + Curl_dyn_free(&host); + free_urlhandle(u); return result; } @@ -1165,8 +1323,6 @@ static CURLUcode parseurl_and_replace(const char *url, CURLU *u, free_urlhandle(u); *u = tmpurl; } - else - free_urlhandle(&tmpurl); return result; } @@ -1265,7 +1421,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, /* there's no stored port number, but asked to deliver a default one for the scheme */ const struct Curl_handler *h = - Curl_builtin_scheme(u->scheme); + Curl_builtin_scheme(u->scheme, CURL_ZERO_TERMINATED); if(h) { msnprintf(portbuf, sizeof(portbuf), "%u", h->defport); ptr = portbuf; @@ -1275,7 +1431,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, /* there is a stored port number, but ask to inhibit if it matches the default one for the scheme */ const struct Curl_handler *h = - Curl_builtin_scheme(u->scheme); + Curl_builtin_scheme(u->scheme, CURL_ZERO_TERMINATED); if(h && (h->defport == u->portnum) && (flags & CURLU_NO_DEFAULT_PORT)) ptr = NULL; @@ -1321,7 +1477,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, else return CURLUE_NO_SCHEME; - h = Curl_builtin_scheme(scheme); + h = Curl_builtin_scheme(scheme, CURL_ZERO_TERMINATED); if(!port && (flags & CURLU_DEFAULT_PORT)) { /* there's no stored port number, but asked to deliver a default one for the scheme */ @@ -1344,14 +1500,13 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, if(u->host[0] == '[') { if(u->zoneid) { /* make it '[ host %25 zoneid ]' */ + struct dynbuf enc; size_t hostlen = strlen(u->host); - size_t alen = hostlen + 3 + strlen(u->zoneid) + 1; - allochost = malloc(alen); - if(!allochost) + Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); + if(Curl_dyn_addf(&enc, "%.*s%%25%s]", (int)hostlen - 1, u->host, + u->zoneid)) return CURLUE_OUT_OF_MEMORY; - memcpy(allochost, u->host, hostlen - 1); - msnprintf(&allochost[hostlen - 1], alen - hostlen + 1, - "%%25%s]", u->zoneid); + allochost = Curl_dyn_ptr(&enc); } } else if(urlencode) { @@ -1362,32 +1517,32 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, else { /* only encode '%' in output host name */ char *host = u->host; - size_t pcount = 0; + bool percent = FALSE; /* first, count number of percents present in the name */ while(*host) { - if(*host == '%') - pcount++; + if(*host == '%') { + percent = TRUE; + break; + } host++; } - /* if there were percents, encode the host name */ - if(pcount) { - size_t hostlen = strlen(u->host); - size_t alen = hostlen + 2 * pcount + 1; - char *o = allochost = malloc(alen); - if(!allochost) - return CURLUE_OUT_OF_MEMORY; - + /* if there were percent(s), encode the host name */ + if(percent) { + struct dynbuf enc; + CURLcode result; + Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); host = u->host; while(*host) { - if(*host == '%') { - memcpy(o, "%25", 3); - o += 3; - host++; - continue; - } - *o++ = *host++; + if(*host == '%') + result = Curl_dyn_addn(&enc, "%25", 3); + else + result = Curl_dyn_addn(&enc, host, 1); + if(result) + return CURLUE_OUT_OF_MEMORY; + host++; } - *o = '\0'; + free(u->host); + u->host = Curl_dyn_ptr(&enc); } } @@ -1420,13 +1575,15 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, break; } if(ptr) { - *part = strdup(ptr); + size_t partlen = strlen(ptr); + size_t i = 0; + *part = Curl_memdup(ptr, partlen + 1); if(!*part) return CURLUE_OUT_OF_MEMORY; if(plusdecode) { /* convert + to space */ - char *plus; - for(plus = *part; *plus; ++plus) { + char *plus = *part; + for(i = 0; i < partlen; ++plus, i++) { if(*plus == '+') *plus = ' '; } @@ -1443,18 +1600,16 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, return CURLUE_URLDECODE; } *part = decoded; + partlen = dlen; } if(urlencode) { - /* worst case output length is 3x the original! */ - char *newp = malloc(strlen(*part) * 3); - if(!newp) + struct dynbuf enc; + Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); + if(urlencode_str(&enc, *part, partlen, TRUE, + what == CURLUPART_QUERY)) return CURLUE_OUT_OF_MEMORY; - if(strcpy_url(newp, *part, TRUE)) { /* consider it relative */ - free(*part); - *part = newp; - } - else - free(newp); + free(*part); + *part = Curl_dyn_ptr(&enc); } return CURLUE_OK; @@ -1532,7 +1687,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, return CURLUE_BAD_SCHEME; if(!(flags & CURLU_NON_SUPPORT_SCHEME) && /* verify that it is a fine scheme */ - !Curl_builtin_scheme(part)) + !Curl_builtin_scheme(part, CURL_ZERO_TERMINATED)) return CURLUE_UNSUPPORTED_SCHEME; storep = &u->scheme; urlencode = FALSE; /* never */ @@ -1598,7 +1753,9 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, /* if the new thing is absolute or the old one is not * (we could not get an absolute url in 'oldurl'), * then replace the existing with the new. */ - if(Curl_is_absolute_url(part, NULL, 0) + if(Curl_is_absolute_url(part, NULL, 0, + flags & (CURLU_GUESS_SCHEME| + CURLU_DEFAULT_SCHEME)) || curl_url_get(u, CURLUPART_URL, &oldurl, flags)) { return parseurl_and_replace(part, u, flags); } @@ -1628,14 +1785,16 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, if(urlencode) { const unsigned char *i; - char *o; - char *enc = malloc(nalloc * 3 + 1); /* for worst case! */ - if(!enc) - return CURLUE_OUT_OF_MEMORY; - for(i = (const unsigned char *)part, o = enc; *i; i++) { + struct dynbuf enc; + + Curl_dyn_init(&enc, nalloc * 3 + 1); + + for(i = (const unsigned char *)part; *i; i++) { + CURLcode result; if((*i == ' ') && plusencode) { - *o = '+'; - o++; + result = Curl_dyn_addn(&enc, "+", 1); + if(result) + return CURLUE_OUT_OF_MEMORY; } else if(Curl_isunreserved(*i) || ((*i == '/') && urlskipslash) || @@ -1643,16 +1802,17 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, if((*i == '=') && equalsencode) /* only skip the first equals sign */ equalsencode = FALSE; - *o = *i; - o++; + result = Curl_dyn_addn(&enc, i, 1); + if(result) + return CURLUE_OUT_OF_MEMORY; } else { - msnprintf(o, 4, "%%%02x", *i); - o += 3; + result = Curl_dyn_addf(&enc, "%%%02x", *i); + if(result) + return CURLUE_OUT_OF_MEMORY; } } - *o = 0; /* null-terminate */ - newp = enc; + newp = Curl_dyn_ptr(&enc); } else { char *p; @@ -1664,8 +1824,8 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, /* make sure percent encoded are lower case */ if((*p == '%') && ISXDIGIT(p[1]) && ISXDIGIT(p[2]) && (ISUPPER(p[1]) || ISUPPER(p[2]))) { - p[1] = (char)TOLOWER(p[1]); - p[2] = (char)TOLOWER(p[2]); + p[1] = Curl_raw_tolower(p[1]); + p[2] = Curl_raw_tolower(p[2]); p += 3; } else @@ -1674,34 +1834,41 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, } if(appendquery) { - /* Append the string onto the old query. Add a '&' separator if none is - present at the end of the exsting query already */ + /* Append the 'newp' string onto the old query. Add a '&' separator if + none is present at the end of the existing query already */ + size_t querylen = u->query ? strlen(u->query) : 0; bool addamperand = querylen && (u->query[querylen -1] != '&'); if(querylen) { - size_t newplen = strlen(newp); - char *p = malloc(querylen + addamperand + newplen + 1); - if(!p) { - free((char *)newp); - return CURLUE_OUT_OF_MEMORY; + struct dynbuf enc; + Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); + + if(Curl_dyn_addn(&enc, u->query, querylen)) /* add original query */ + goto nomem; + + if(addamperand) { + if(Curl_dyn_addn(&enc, "&", 1)) + goto nomem; } - strcpy(p, u->query); /* original query */ - if(addamperand) - p[querylen] = '&'; /* ampersand */ - strcpy(&p[querylen + addamperand], newp); /* new suffix */ + if(Curl_dyn_add(&enc, newp)) + goto nomem; free((char *)newp); free(*storep); - *storep = p; + *storep = Curl_dyn_ptr(&enc); return CURLUE_OK; + nomem: + free((char *)newp); + return CURLUE_OUT_OF_MEMORY; } } if(what == CURLUPART_HOST) { - if(0 == strlen(newp) && (flags & CURLU_NO_AUTHORITY)) { + size_t n = strlen(newp); + if(!n && (flags & CURLU_NO_AUTHORITY)) { /* Skip hostname check, it's allowed to be empty. */ } else { - if(hostname_check(u, (char *)newp)) { + if(hostname_check(u, (char *)newp, n)) { free((char *)newp); return CURLUE_BAD_HOSTNAME; } diff --git a/libs/libcurl/src/urldata.h b/libs/libcurl/src/urldata.h index bcb4d460c2..1d430b5e88 100644 --- a/libs/libcurl/src/urldata.h +++ b/libs/libcurl/src/urldata.h @@ -53,6 +53,33 @@ #define PORT_GOPHER 70 #define PORT_MQTT 1883 +#ifdef USE_WEBSOCKETS +/* CURLPROTO_GOPHERS (29) is the highest publicly used protocol bit number, + * the rest are internal information. If we use higher bits we only do this on + * platforms that have a >= 64 bit type and then we use such a type for the + * protocol fields in the protocol handler. + */ +#define CURLPROTO_WS (1<<30) +#define CURLPROTO_WSS ((curl_prot_t)1<<31) +#else +#define CURLPROTO_WS 0 +#define CURLPROTO_WSS 0 +#endif + +/* This should be undefined once we need bit 32 or higher */ +#define PROTO_TYPE_SMALL + +#ifndef PROTO_TYPE_SMALL +typedef curl_off_t curl_prot_t; +#else +typedef unsigned int curl_prot_t; +#endif + +/* This mask is for all the old protocols that are provided and defined in the + public header and shall exclude protocols added since which are not exposed + in the API */ +#define CURLPROTO_MASK (0x3ffffff) + #define DICT_MATCH "/MATCH:" #define DICT_MATCH2 "/M:" #define DICT_MATCH3 "/FIND:" @@ -66,7 +93,8 @@ /* Convenience defines for checking protocols or their SSL based version. Each protocol handler should only ever have a single CURLPROTO_ in its protocol field. */ -#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS) +#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_WS| \ + CURLPROTO_WSS) #define PROTO_FAMILY_FTP (CURLPROTO_FTP|CURLPROTO_FTPS) #define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S) #define PROTO_FAMILY_SMB (CURLPROTO_SMB|CURLPROTO_SMBS) @@ -157,10 +185,10 @@ typedef CURLcode (*Curl_datastream)(struct Curl_easy *data, # endif #endif -#ifdef HAVE_LIBSSH2_H +#ifdef USE_LIBSSH2 #include <libssh2.h> #include <libssh2_sftp.h> -#endif /* HAVE_LIBSSH2_H */ +#endif /* USE_LIBSSH2 */ #define READBUFFER_SIZE CURL_MAX_WRITE_SIZE #define READBUFFER_MAX CURL_MAX_READ_SIZE @@ -318,11 +346,11 @@ struct digestdata { char *nonce; char *cnonce; char *realm; - int algo; char *opaque; char *qop; char *algorithm; int nc; /* nonce count */ + unsigned char algo; BIT(stale); /* set true for re-negotiation */ BIT(userhash); #endif @@ -507,9 +535,7 @@ struct ConnectBits { connection */ BIT(multiplex); /* connection is multiplexed */ BIT(tcp_fastopen); /* use TCP Fast Open */ - BIT(tls_enable_npn); /* TLS NPN extension? */ BIT(tls_enable_alpn); /* TLS ALPN extension? */ - BIT(connect_only); #ifndef CURL_DISABLE_DOH BIT(doh); #endif @@ -554,7 +580,7 @@ struct Curl_async { struct Curl_dns_entry *dns; struct thread_data *tdata; void *resolver; /* resolver state, if it is used in the URL state - - ares_channel f.e. */ + ares_channel e.g. */ int port; int status; /* if done is TRUE, this is the status from the callback */ BIT(done); /* set TRUE when the lookup is complete */ @@ -575,8 +601,9 @@ enum expect100 { enum upgrade101 { UPGR101_INIT, /* default state */ - UPGR101_REQUESTED, /* upgrade requested */ - UPGR101_RECEIVED, /* response received */ + UPGR101_WS, /* upgrade to WebSockets requested */ + UPGR101_H2, /* upgrade to HTTP/2 requested */ + UPGR101_RECEIVED, /* 101 response received */ UPGR101_WORKING /* talking upgraded protocol */ }; @@ -598,23 +625,6 @@ enum doh_slots { DOH_PROBE_SLOTS }; -/* one of these for each DoH request */ -struct dnsprobe { - CURL *easy; - int dnstype; - unsigned char dohbuffer[512]; - size_t dohlen; - struct dynbuf serverdoh; -}; - -struct dohdata { - struct curl_slist *headers; - struct dnsprobe probe[DOH_PROBE_SLOTS]; - unsigned int pending; /* still outstanding requests */ - int port; - const char *host; -}; - /* * Request specific data in the easy handle (Curl_easy). Previously, * these members were on the connectdata struct but since a conn struct may @@ -796,10 +806,10 @@ struct Curl_handler { void (*attach)(struct Curl_easy *data, struct connectdata *conn); int defport; /* Default port. */ - unsigned int protocol; /* See CURLPROTO_* - this needs to be the single - specific protocol bit */ - unsigned int family; /* single bit for protocol family; basically the - non-TLS name of the protocol this is */ + curl_prot_t protocol; /* See CURLPROTO_* - this needs to be the single + specific protocol bit */ + curl_prot_t family; /* single bit for protocol family; basically the + non-TLS name of the protocol this is */ unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */ }; @@ -820,7 +830,7 @@ struct Curl_handler { url query strings (?foo=bar) ! */ #define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per request instead of per connection */ -#define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */ +#define PROTOPT_ALPN (1<<8) /* set ALPN for this */ #define PROTOPT_STREAM (1<<9) /* a protocol with individual logical streams */ #define PROTOPT_URLOPTIONS (1<<10) /* allow options part in the userinfo field of the URL */ @@ -856,7 +866,8 @@ struct postponed_data { struct proxy_info { struct hostname host; long port; - curl_proxytype proxytype; /* what kind of proxy that is in use */ + unsigned char proxytype; /* curl_proxytype: what kind of proxy that is in + use */ char *user; /* proxy user name string, allocated */ char *passwd; /* proxy password string, allocated */ }; @@ -895,6 +906,11 @@ struct connstate { unsigned char *outp; /* send from this pointer */ }; +#define TRNSPRT_TCP 3 +#define TRNSPRT_UDP 4 +#define TRNSPRT_QUIC 5 +#define TRNSPRT_UNIX 6 + /* * The connectdata struct contains all fields and variables that should be * unique for an entire connection. @@ -932,15 +948,6 @@ struct connectdata { cache entry remains locked. It gets unlocked in multi_done() */ struct Curl_addrinfo *ip_addr; struct Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */ -#ifdef ENABLE_IPV6 - unsigned int scope_id; /* Scope id for IPv6 */ -#endif - - enum { - TRNSPRT_TCP = 3, - TRNSPRT_UDP = 4, - TRNSPRT_QUIC = 5 - } transport; #ifdef ENABLE_QUIC struct quicsocket hequic[2]; /* two, for happy eyeballs! */ @@ -956,13 +963,6 @@ struct connectdata { struct proxy_info socks_proxy; struct proxy_info http_proxy; #endif - int port; /* which port to use locally - to connect to */ - int remote_port; /* the remote port, not the proxy port! */ - int conn_to_port; /* the remote port to connect to. valid only if - bits.conn_to_port is set */ - unsigned short secondary_port; /* secondary socket remote port to connect to - (ftp) */ - /* 'primary_ip' and 'primary_port' get filled with peer's numerical ip address and port number whenever an outgoing connection is *attempted* from the primary socket to a remote address. When more @@ -971,14 +971,11 @@ struct connectdata { these are updated with data which comes directly from the socket. */ char primary_ip[MAX_IPADR_LEN]; - unsigned char ip_version; /* copied from the Curl_easy at creation time */ - char *user; /* user name string, allocated */ char *passwd; /* password string, allocated */ char *options; /* options string, allocated */ char *sasl_authzid; /* authorization identity string, allocated */ char *oauth_bearer; /* OAUTH2 bearer, allocated */ - unsigned char httpversion; /* the HTTP version*10 reported by the server */ struct curltime now; /* "current" time */ struct curltime created; /* creation time */ struct curltime lastused; /* when returned to the connection cache */ @@ -1005,8 +1002,6 @@ struct connectdata { #endif struct ConnectBits bits; /* various state-flags for this connection */ - /* The field below gets set in Curl_connecthost */ - int num_addr; /* number of addresses to try to connect to */ /* connecttime: when connect() is called on the current IP address. Used to be able to track when to move on to try next IP - but only when the multi interface is used. */ @@ -1034,9 +1029,9 @@ struct connectdata { #ifdef HAVE_GSSAPI BIT(sec_complete); /* if Kerberos is enabled for this connection */ - enum protection_level command_prot; - enum protection_level data_prot; - enum protection_level request_data_prot; + unsigned char command_prot; /* enum protection_level */ + unsigned char data_prot; /* enum protection_level */ + unsigned char request_data_prot; /* enum protection_level */ size_t buffer_size; struct krb5buffer in_buffer; void *app_data; @@ -1135,12 +1130,27 @@ struct connectdata { int localportrange; int cselect_bits; /* bitmask of socket events */ int waitfor; /* current READ/WRITE bits to wait for */ - int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */ - #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) int socks5_gssapi_enctype; #endif + /* The field below gets set in Curl_connecthost */ + int num_addr; /* number of addresses to try to connect to */ + int port; /* which port to use locally - to connect to */ + int remote_port; /* the remote port, not the proxy port! */ + int conn_to_port; /* the remote port to connect to. valid only if + bits.conn_to_port is set */ +#ifdef ENABLE_IPV6 + unsigned int scope_id; /* Scope id for IPv6 */ +#endif unsigned short localport; + unsigned short secondary_port; /* secondary socket remote port to connect to + (ftp) */ + unsigned char alpn; /* APLN TLS negotiated protocol, a CURL_HTTP_VERSION* + value */ + unsigned char transport; /* one of the TRNSPRT_* defines */ + unsigned char ip_version; /* copied from the Curl_easy at creation time */ + unsigned char httpversion; /* the HTTP version*10 reported by the server */ + unsigned char connect_only; }; /* The end of connectdata. */ @@ -1300,6 +1310,7 @@ typedef enum { EXPIRE_TIMEOUT, EXPIRE_TOOFAST, EXPIRE_QUIC, + EXPIRE_FTP_ACCEPT, EXPIRE_LAST /* not an actual timer, used as a marker only */ } expire_id; @@ -1353,7 +1364,7 @@ struct UrlState { This is strdup()ed data. */ char *first_host; int first_remote_port; - unsigned int first_remote_protocol; + curl_prot_t first_remote_protocol; int retrycount; /* number of retries on a new connection */ struct Curl_ssl_session *session; /* array of 'max_ssl_sessions' size */ @@ -1429,7 +1440,8 @@ struct UrlState { #endif CURLU *uh; /* URL handle for the current parsed URL */ struct urlpieces up; - Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */ + unsigned char httpreq; /* Curl_HttpReq; what kind of HTTP request (if any) + is this */ char *url; /* work URL, copied from UserDefined */ char *referer; /* referer string */ #ifndef CURL_DISABLE_COOKIES @@ -1649,7 +1661,7 @@ struct UserDefined { void *out; /* CURLOPT_WRITEDATA */ void *in_set; /* CURLOPT_READDATA */ void *writeheader; /* write the header to this if non-NULL */ - long use_port; /* which port to use (when not using default) */ + unsigned short use_port; /* which port to use (when not using default) */ unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */ unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */ #ifndef CURL_DISABLE_PROXY @@ -1695,10 +1707,10 @@ struct UserDefined { #endif void *progress_client; /* pointer to pass to the progress callback */ void *ioctl_client; /* pointer to pass to the ioctl callback */ - long timeout; /* in milliseconds, 0 means no timeout */ - long connecttimeout; /* in milliseconds, 0 means no timeout */ - long happy_eyeballs_timeout; /* in milliseconds, 0 is a valid value */ - long server_response_timeout; /* in milliseconds, 0 means no timeout */ + unsigned int timeout; /* ms, 0 means no timeout */ + unsigned int connecttimeout; /* ms, 0 means no timeout */ + unsigned int happy_eyeballs_timeout; /* ms, 0 is a valid value */ + unsigned int server_response_timeout; /* ms, 0 means no timeout */ long maxage_conn; /* in seconds, max idle time to allow a connection that is to be reused */ long maxlifetime_conn; /* in seconds, max time since creation to allow a @@ -1732,10 +1744,10 @@ struct UserDefined { DNS cache */ struct curl_slist *connect_to; /* list of host:port mappings to override the hostname and port to connect to */ - curl_TimeCond timecondition; /* kind of time/date comparison */ - curl_proxytype proxytype; /* what kind of proxy that is in use */ time_t timevalue; /* what time to compare with */ - Curl_HttpReq method; /* what kind of HTTP request (if any) is this */ + unsigned char timecondition; /* kind of time comparison: curl_TimeCond */ + unsigned char proxytype; /* what kind of proxy: curl_proxytype */ + unsigned char method; /* what kind of HTTP request: Curl_HttpReq */ unsigned char httpwant; /* when non-zero, a specific HTTP version requested to be used in the library's request(s) */ struct ssl_config_data ssl; /* user defined SSL stuff */ @@ -1743,8 +1755,8 @@ struct UserDefined { struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */ #endif struct ssl_general_config general_ssl; /* general user defined SSL stuff */ - long dns_cache_timeout; /* DNS cache timeout */ - long buffer_size; /* size of receive buffer to use */ + int dns_cache_timeout; /* DNS cache timeout (seconds) */ + unsigned int buffer_size; /* size of receive buffer to use */ unsigned int upload_buffer_size; /* size of upload buffer to use, keep it >= CURL_MAX_WRITE_SIZE */ void *private_data; /* application-private data */ @@ -1753,14 +1765,16 @@ struct UserDefined { file 0 - whatever, 1 - v2, 2 - v6 */ curl_off_t max_filesize; /* Maximum file size to download */ #ifndef CURL_DISABLE_FTP - curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */ - curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */ - curl_ftpccc ftp_ccc; /* FTP CCC options */ - long accepttimeout; /* in milliseconds, 0 means no timeout */ -#endif - int ftp_create_missing_dirs; /* 1 - create directories that don't exist - 2 - the same but also allow MKD to fail once - */ + unsigned char ftp_filemethod; /* how to get to a file: curl_ftpfile */ + unsigned char ftpsslauth; /* what AUTH XXX to try: curl_ftpauth */ + unsigned char ftp_ccc; /* FTP CCC options: curl_ftpccc */ + unsigned int accepttimeout; /* in milliseconds, 0 means no timeout */ +#endif + /* Desppie the name ftp_create_missing_dirs is for FTP(S) and SFTP + 1 - create directories that don't exist + 2 - the same but also allow MKD to fail once + */ + unsigned char ftp_create_missing_dirs; #ifdef USE_LIBSSH2 curl_sshhostkeycallback ssh_hostkeyfunc; /* hostkey check callback */ void *ssh_hostkeyfunc_userp; /* custom pointer to callback */ @@ -1769,8 +1783,7 @@ struct UserDefined { curl_sshkeycallback ssh_keyfunc; /* key matching callback */ void *ssh_keyfunc_userp; /* custom pointer to callback */ #ifndef CURL_DISABLE_NETRC - enum CURL_NETRC_OPTION - use_netrc; /* defined in include/curl.h */ + unsigned char use_netrc; /* enum CURL_NETRC_OPTION values */ #endif curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or IMAP or POP3 or others! */ @@ -1782,15 +1795,14 @@ struct UserDefined { #ifdef ENABLE_IPV6 unsigned int scope_id; /* Scope id for IPv6 */ #endif - unsigned int allowed_protocols; - unsigned int redir_protocols; + curl_prot_t allowed_protocols; + curl_prot_t redir_protocols; unsigned int mime_options; /* Mime option flags. */ #ifndef CURL_DISABLE_RTSP void *rtp_out; /* write RTP to this if non-NULL */ /* Common RTSP header options */ Curl_RtspReq rtspreq; /* RTSP request type */ - long rtspversion; /* like httpversion, for RTSP */ #endif #ifndef CURL_DISABLE_FTP curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer @@ -1833,6 +1845,8 @@ struct UserDefined { BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some recipients */ #endif + unsigned char connect_only; /* make connection/request, then let + application use the socket */ BIT(is_fread_set); /* has read callback been set to non-NULL? */ #ifndef CURL_DISABLE_TFTP BIT(tftp_no_options); /* do not send TFTP options requests */ @@ -1878,7 +1892,6 @@ struct UserDefined { BIT(no_signal); /* do not use any signal/alarm handler */ BIT(tcp_nodelay); /* whether to enable TCP_NODELAY or not */ BIT(ignorecl); /* ignore content length */ - BIT(connect_only); /* make connection, let application use the socket */ BIT(http_te_skip); /* pass the raw body data to the user, even when transfer-encoded (chunked, compressed) */ BIT(http_ce_skip); /* pass the raw body data to the user, even when @@ -1891,7 +1904,6 @@ struct UserDefined { BIT(sasl_ir); /* Enable/disable SASL initial response */ BIT(tcp_keepalive); /* use TCP keepalives */ BIT(tcp_fastopen); /* use TCP Fast Open */ - BIT(ssl_enable_npn); /* TLS NPN extension? */ BIT(ssl_enable_alpn);/* TLS ALPN extension? */ BIT(path_as_is); /* allow dotdots? */ BIT(pipewait); /* wait for multiplex status before starting a new @@ -1911,6 +1923,9 @@ struct UserDefined { BIT(doh_verifystatus); /* DoH certificate status verification */ #endif BIT(http09_allowed); /* allow HTTP/0.9 responses */ +#ifdef USE_WEBSOCKETS + BIT(ws_raw_mode); +#endif }; struct Names { diff --git a/libs/libcurl/src/vauth/digest.c b/libs/libcurl/src/vauth/digest.c index 355cd74a6e..f945e8b6c9 100644 --- a/libs/libcurl/src/vauth/digest.c +++ b/libs/libcurl/src/vauth/digest.c @@ -49,6 +49,15 @@ #include "curl_memory.h" #include "memdebug.h" +#define SESSION_ALGO 1 /* for algos with this bit set */ + +#define ALGO_MD5 0 +#define ALGO_MD5SESS (ALGO_MD5 | SESSION_ALGO) +#define ALGO_SHA256 2 +#define ALGO_SHA256SESS (ALGO_SHA256 | SESSION_ALGO) +#define ALGO_SHA512_256 4 +#define ALGO_SHA512_256SESS (ALGO_SHA512_256 | SESSION_ALGO) + #if !defined(USE_WINDOWS_SSPI) #define DIGEST_QOP_VALUE_AUTH (1 << 0) #define DIGEST_QOP_VALUE_AUTH_INT (1 << 1) @@ -373,7 +382,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, if(!(qop_values & DIGEST_QOP_VALUE_AUTH)) return CURLE_BAD_CONTENT_ENCODING; - /* Generate 32 random hex chars, 32 bytes + 1 zero termination */ + /* Generate 32 random hex chars, 32 bytes + 1 null-termination */ result = Curl_rand_hex(data, (unsigned char *)cnonce, sizeof(cnonce)); if(result) return result; @@ -512,7 +521,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, char content[DIGEST_MAX_CONTENT_LENGTH]; /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) + while(*chlg && ISBLANK(*chlg)) chlg++; /* Extract a value=content pair */ @@ -551,6 +560,9 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, token = strtok_r(tmp, ",", &tok_buf); while(token) { + /* Pass additional spaces here */ + while(*token && ISBLANK(*token)) + token++; if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) { foundAuth = TRUE; } @@ -583,17 +595,17 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, return CURLE_OUT_OF_MEMORY; if(strcasecompare(content, "MD5-sess")) - digest->algo = CURLDIGESTALGO_MD5SESS; + digest->algo = ALGO_MD5SESS; else if(strcasecompare(content, "MD5")) - digest->algo = CURLDIGESTALGO_MD5; + digest->algo = ALGO_MD5; else if(strcasecompare(content, "SHA-256")) - digest->algo = CURLDIGESTALGO_SHA256; + digest->algo = ALGO_SHA256; else if(strcasecompare(content, "SHA-256-SESS")) - digest->algo = CURLDIGESTALGO_SHA256SESS; + digest->algo = ALGO_SHA256SESS; else if(strcasecompare(content, "SHA-512-256")) - digest->algo = CURLDIGESTALGO_SHA512_256; + digest->algo = ALGO_SHA512_256; else if(strcasecompare(content, "SHA-512-256-SESS")) - digest->algo = CURLDIGESTALGO_SHA512_256SESS; + digest->algo = ALGO_SHA512_256SESS; else return CURLE_BAD_CONTENT_ENCODING; } @@ -610,7 +622,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, break; /* We're done here */ /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) + while(*chlg && ISBLANK(*chlg)) chlg++; /* Allow the list to be comma-separated */ @@ -628,6 +640,10 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, if(!digest->nonce) return CURLE_BAD_CONTENT_ENCODING; + /* "<algo>-sess" protocol versions require "auth" or "auth-int" qop */ + if(!digest->qop && (digest->algo & SESSION_ALGO)) + return CURLE_BAD_CONTENT_ENCODING; + return CURLE_OK; } @@ -726,9 +742,7 @@ static CURLcode auth_create_digest_http_message( free(hashthis); convert_to_ascii(hashbuf, ha1); - if(digest->algo == CURLDIGESTALGO_MD5SESS || - digest->algo == CURLDIGESTALGO_SHA256SESS || - digest->algo == CURLDIGESTALGO_SHA512_256SESS) { + if(digest->algo & SESSION_ALGO) { /* nonce and cnonce are OUTSIDE the hash */ tmp = aprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce); if(!tmp) @@ -843,10 +857,8 @@ static CURLcode auth_create_digest_http_message( digest->qop, request_digest); - if(strcasecompare(digest->qop, "auth")) - digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 - padded which tells to the server how many times you are - using the same nonce in the qop=auth mode */ + /* Increment nonce-count to use another nc value for the next request */ + digest->nc++; } else { response = aprintf("username=\"%s\", " @@ -875,8 +887,9 @@ static CURLcode auth_create_digest_http_message( free(response); return CURLE_OUT_OF_MEMORY; } - tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque); + tmp = aprintf("%s, opaque=\"%s\"", response, opaque_quoted); free(response); + free(opaque_quoted); if(!tmp) return CURLE_OUT_OF_MEMORY; @@ -938,28 +951,18 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, struct digestdata *digest, char **outptr, size_t *outlen) { - switch(digest->algo) { - case CURLDIGESTALGO_MD5: - case CURLDIGESTALGO_MD5SESS: + if(digest->algo <= ALGO_MD5SESS) return auth_create_digest_http_message(data, userp, passwdp, request, uripath, digest, outptr, outlen, auth_digest_md5_to_ascii, Curl_md5it); - - case CURLDIGESTALGO_SHA256: - case CURLDIGESTALGO_SHA256SESS: - case CURLDIGESTALGO_SHA512_256: - case CURLDIGESTALGO_SHA512_256SESS: - return auth_create_digest_http_message(data, userp, passwdp, - request, uripath, digest, - outptr, outlen, - auth_digest_sha256_to_ascii, - Curl_sha256it); - - default: - return CURLE_UNSUPPORTED_PROTOCOL; - } + DEBUGASSERT(digest->algo <= ALGO_SHA512_256SESS); + return auth_create_digest_http_message(data, userp, passwdp, + request, uripath, digest, + outptr, outlen, + auth_digest_sha256_to_ascii, + Curl_sha256it); } /* @@ -982,7 +985,7 @@ void Curl_auth_digest_cleanup(struct digestdata *digest) Curl_safefree(digest->algorithm); digest->nc = 0; - digest->algo = CURLDIGESTALGO_MD5; /* default algorithm */ + digest->algo = ALGO_MD5; /* default algorithm */ digest->stale = FALSE; /* default means normal, not stale */ digest->userhash = FALSE; } diff --git a/libs/libcurl/src/vauth/digest.h b/libs/libcurl/src/vauth/digest.h index 6a2f565894..d785bdd91b 100644 --- a/libs/libcurl/src/vauth/digest.h +++ b/libs/libcurl/src/vauth/digest.h @@ -31,15 +31,6 @@ #define DIGEST_MAX_VALUE_LENGTH 256 #define DIGEST_MAX_CONTENT_LENGTH 1024 -enum { - CURLDIGESTALGO_MD5, - CURLDIGESTALGO_MD5SESS, - CURLDIGESTALGO_SHA256, - CURLDIGESTALGO_SHA256SESS, - CURLDIGESTALGO_SHA512_256, - CURLDIGESTALGO_SHA512_256SESS -}; - /* This is used to extract the realm from a challenge message */ bool Curl_auth_digest_get_pair(const char *str, char *value, char *content, const char **endptr); diff --git a/libs/libcurl/src/vauth/digest_sspi.c b/libs/libcurl/src/vauth/digest_sspi.c index af463848a6..89a9db52c7 100644 --- a/libs/libcurl/src/vauth/digest_sspi.c +++ b/libs/libcurl/src/vauth/digest_sspi.c @@ -259,7 +259,7 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg, char content[DIGEST_MAX_CONTENT_LENGTH]; /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) + while(*chlg && ISBLANK(*chlg)) chlg++; /* Extract a value=content pair */ @@ -292,7 +292,7 @@ CURLcode Curl_override_sspi_http_realm(const char *chlg, break; /* We're done here */ /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) + while(*chlg && ISBLANK(*chlg)) chlg++; /* Allow the list to be comma-separated */ @@ -333,7 +333,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, char value[DIGEST_MAX_VALUE_LENGTH]; char content[DIGEST_MAX_CONTENT_LENGTH]; - while(*p && ISSPACE(*p)) + while(*p && ISBLANK(*p)) p++; if(!Curl_auth_digest_get_pair(p, value, content, &p)) @@ -345,7 +345,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, break; } - while(*p && ISSPACE(*p)) + while(*p && ISBLANK(*p)) p++; if(',' == *p) @@ -431,8 +431,8 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, has changed then delete that context. */ if((userp && !digest->user) || (!userp && digest->user) || (passwdp && !digest->passwd) || (!passwdp && digest->passwd) || - (userp && digest->user && strcmp(userp, digest->user)) || - (passwdp && digest->passwd && strcmp(passwdp, digest->passwd))) { + (userp && digest->user && Curl_timestrcmp(userp, digest->user)) || + (passwdp && digest->passwd && Curl_timestrcmp(passwdp, digest->passwd))) { if(digest->http_context) { s_pSecFn->DeleteSecurityContext(digest->http_context); Curl_safefree(digest->http_context); diff --git a/libs/libcurl/src/vauth/gsasl.c b/libs/libcurl/src/vauth/gsasl.c index 9d137b72ca..a73c644434 100644 --- a/libs/libcurl/src/vauth/gsasl.c +++ b/libs/libcurl/src/vauth/gsasl.c @@ -36,7 +36,8 @@ #include <gsasl.h> -/* The last #include files should be: */ +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" #include "curl_memory.h" #include "memdebug.h" diff --git a/libs/libcurl/src/vauth/ntlm.c b/libs/libcurl/src/vauth/ntlm.c index edaacbb9ed..c10fa6caaf 100644 --- a/libs/libcurl/src/vauth/ntlm.c +++ b/libs/libcurl/src/vauth/ntlm.c @@ -29,7 +29,7 @@ /* * NTLM details: * - * https://davenport.sourceforge.io/ntlm.html + * https://davenport.sourceforge.net/ntlm.html * https://www.innovation.ch/java/ntlm.html */ @@ -600,7 +600,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, /* A safer but less compatible alternative is: * Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp); - * See https://davenport.sourceforge.io/ntlm.html#ntlmVersion2 */ + * See https://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */ } if(unicode) { @@ -658,7 +658,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, /* LanManager response */ /* NT response */ - 0, /* zero termination */ + 0, /* null-termination */ 0, 0, 0, /* type-3 long, the 24 upper bits */ SHORTPAIR(0x18), /* LanManager response length, twice */ diff --git a/libs/libcurl/src/vauth/ntlm.h b/libs/libcurl/src/vauth/ntlm.h index 97325d975c..4dfda55453 100644 --- a/libs/libcurl/src/vauth/ntlm.h +++ b/libs/libcurl/src/vauth/ntlm.h @@ -34,7 +34,8 @@ /* Stuff only required for curl_ntlm_msgs.c */ #ifdef BUILDING_CURL_NTLM_MSGS_C -/* Flag bits definitions based on https://davenport.sourceforge.io/ntlm.html */ +/* Flag bits definitions based on + https://davenport.sourceforge.net/ntlm.html */ #define NTLMFLAG_NEGOTIATE_UNICODE (1<<0) /* Indicates that Unicode strings are supported for use in security buffer diff --git a/libs/libcurl/src/vauth/vauth.c b/libs/libcurl/src/vauth/vauth.c index 9d6363df07..58fe05139d 100644 --- a/libs/libcurl/src/vauth/vauth.c +++ b/libs/libcurl/src/vauth/vauth.c @@ -27,6 +27,8 @@ #include <curl/curl.h> #include "vauth.h" +#include "urldata.h" +#include "strcase.h" #include "curl_multibyte.h" #include "curl_printf.h" @@ -144,3 +146,18 @@ bool Curl_auth_user_contains_domain(const char *user) return valid; } + +/* + * Curl_auth_ollowed_to_host() tells if authentication, cookies or other + * "sensitive data" can (still) be sent to this host. + */ +bool Curl_auth_allowed_to_host(struct Curl_easy *data) +{ + struct connectdata *conn = data->conn; + return (!data->state.this_is_a_follow || + data->set.allow_auth_to_other_hosts || + (data->state.first_host && + strcasecompare(data->state.first_host, conn->host.name) && + (data->state.first_remote_port == conn->remote_port) && + (data->state.first_remote_protocol == conn->handler->protocol))); +} diff --git a/libs/libcurl/src/vauth/vauth.h b/libs/libcurl/src/vauth/vauth.h index 1c4b5b5dc6..af27f01dfb 100644 --- a/libs/libcurl/src/vauth/vauth.h +++ b/libs/libcurl/src/vauth/vauth.h @@ -54,6 +54,12 @@ struct gsasldata; #define GSS_ERROR(status) ((status) & 0x80000000) #endif +/* + * Curl_auth_allowed_to_host() tells if authentication, cookies or other + * "sensitive data" can (still) be sent to this host. + */ +bool Curl_auth_allowed_to_host(struct Curl_easy *data); + /* This is used to build a SPN string */ #if !defined(USE_WINDOWS_SSPI) char *Curl_auth_build_spn(const char *service, const char *host, @@ -224,7 +230,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, CURLcode Curl_auth_create_spnego_message(struct negotiatedata *nego, char **outptr, size_t *outlen); -/* This is used to clean up the SPNEGO specifiec data */ +/* This is used to clean up the SPNEGO specific data */ void Curl_auth_cleanup_spnego(struct negotiatedata *nego); #endif /* USE_SPNEGO */ diff --git a/libs/libcurl/src/version.c b/libs/libcurl/src/version.c index 4672182d50..f71f49e09a 100644 --- a/libs/libcurl/src/version.c +++ b/libs/libcurl/src/version.c @@ -53,7 +53,7 @@ #include <librtmp/rtmp.h> #endif -#ifdef HAVE_ZLIB_H +#ifdef HAVE_LIBZ #include <zlib.h> #endif @@ -338,6 +338,11 @@ static const char * const protocols[] = { #endif #ifdef USE_LIBRTMP "rtmp", + "rtmpe", + "rtmps", + "rtmpt", + "rtmpte", + "rtmpts", #endif #ifndef CURL_DISABLE_RTSP "rtsp", @@ -367,6 +372,12 @@ static const char * const protocols[] = { #ifndef CURL_DISABLE_TFTP "tftp", #endif +#ifdef USE_WEBSOCKETS + "ws", +#endif +#if defined(USE_SSL) && defined(USE_WEBSOCKETS) + "wss", +#endif NULL }; diff --git a/libs/libcurl/src/vquic/msh3.c b/libs/libcurl/src/vquic/msh3.c index 296943b22a..c3e58e726a 100644 --- a/libs/libcurl/src/vquic/msh3.c +++ b/libs/libcurl/src/vquic/msh3.c @@ -27,7 +27,6 @@ #ifdef USE_MSH3 #include "urldata.h" -#include "curl_printf.h" #include "timeval.h" #include "multiif.h" #include "sendf.h" @@ -35,6 +34,11 @@ #include "h2h3.h" #include "msh3.h" +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + /* #define DEBUG_HTTP3 1 */ #ifdef DEBUG_HTTP3 #define H3BUGF(x) x @@ -110,7 +114,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, socklen_t addrlen) { struct quicsocket *qs = &conn->hequic[sockindex]; - bool unsecure = !conn->ssl_config.verifypeer; + bool insecure = !conn->ssl_config.verifypeer; memset(qs, 0, sizeof(*qs)); (void)sockfd; @@ -128,7 +132,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, qs->conn = MsH3ConnectionOpen(qs->api, conn->host.name, (uint16_t)conn->remote_port, - unsecure); + insecure); if(!qs->conn) { failf(data, "can't create msh3 connection"); if(qs->api) { @@ -222,13 +226,8 @@ static unsigned int msh3_conncheck(struct Curl_easy *data, return CONNRESULT_NONE; } -static void msh3_cleanup(struct quicsocket *qs, struct HTTP *stream) +static void disconnect(struct quicsocket *qs) { - if(stream && stream->recv_buf) { - free(stream->recv_buf); - stream->recv_buf = ZERO_NULL; - msh3_lock_uninitialize(&stream->recv_lock); - } if(qs->conn) { MsH3ConnectionClose(qs->conn); qs->conn = ZERO_NULL; @@ -242,18 +241,20 @@ static void msh3_cleanup(struct quicsocket *qs, struct HTTP *stream) static CURLcode msh3_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead_connection) { + (void)data; (void)dead_connection; H3BUGF(infof(data, "disconnecting (msh3)")); - msh3_cleanup(conn->quic, data->req.p.http); + disconnect(conn->quic); return CURLE_OK; } void Curl_quic_disconnect(struct Curl_easy *data, struct connectdata *conn, int tempindex) { + (void)data; if(conn->transport == TRNSPRT_QUIC) { - H3BUGF(infof(data, "disconnecting (curl)")); - msh3_cleanup(&conn->hequic[tempindex], data->req.p.http); + H3BUGF(infof(data, "disconnecting QUIC index %u", tempindex)); + disconnect(&conn->hequic[tempindex]); } } @@ -288,7 +289,6 @@ static void MSH3_CALL msh3_header_received(MSH3_REQUEST *Request, struct HTTP *stream = IfContext; size_t total_len; (void)Request; - H3BUGF(printf("* msh3_header_received\n")); if(stream->recv_header_complete) { H3BUGF(printf("* ignoring header after data\n")); @@ -381,9 +381,6 @@ static void MSH3_CALL msh3_shutdown(MSH3_REQUEST *Request, void *IfContext) (void)stream; } -static_assert(sizeof(MSH3_HEADER) == sizeof(struct h2h3pseudo), - "Sizes must match for cast below to work"); - static ssize_t msh3_stream_send(struct Curl_easy *data, int sockindex, const void *mem, @@ -396,6 +393,9 @@ static ssize_t msh3_stream_send(struct Curl_easy *data, struct h2h3req *hreq; (void)sockindex; + /* Sizes must match for cast below to work" */ + DEBUGASSERT(sizeof(MSH3_HEADER) == sizeof(struct h2h3pseudo)); + H3BUGF(infof(data, "msh3_stream_send %zu", len)); if(!stream->req) { @@ -490,9 +490,19 @@ CURLcode Curl_quic_done_sending(struct Curl_easy *data) void Curl_quic_done(struct Curl_easy *data, bool premature) { - (void)data; + struct HTTP *stream = data->req.p.http; (void)premature; H3BUGF(infof(data, "Curl_quic_done")); + if(stream) { + if(stream->recv_buf) { + Curl_safefree(stream->recv_buf); + msh3_lock_uninitialize(&stream->recv_lock); + } + if(stream->req) { + MsH3RequestClose(stream->req); + stream->req = ZERO_NULL; + } + } } bool Curl_quic_data_pending(const struct Curl_easy *data) diff --git a/libs/libcurl/src/vquic/ngtcp2.c b/libs/libcurl/src/vquic/ngtcp2.c index ca9c388345..097cca44b0 100644 --- a/libs/libcurl/src/vquic/ngtcp2.c +++ b/libs/libcurl/src/vquic/ngtcp2.c @@ -38,6 +38,9 @@ #elif defined(USE_GNUTLS) #include <ngtcp2/ngtcp2_crypto_gnutls.h> #include "vtls/gtls.h" +#elif defined(USE_WOLFSSL) +#include <ngtcp2/ngtcp2_crypto_wolfssl.h> +#include "vtls/wolfssl.h" #endif #include "urldata.h" #include "sendf.h" @@ -101,6 +104,11 @@ struct h3out { "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \ "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \ "%DISABLE_TLS13_COMPAT_MODE" +#elif defined(USE_WOLFSSL) +#define QUIC_CIPHERS \ + "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_" \ + "POLY1305_SHA256:TLS_AES_128_CCM_SHA256" +#define QUIC_GROUPS "P-256:P-384:P-521" #endif /* ngtcp2 default congestion controller does not perform pacing. Limit @@ -113,7 +121,7 @@ static CURLcode ng_process_ingress(struct Curl_easy *data, static CURLcode ng_flush_egress(struct Curl_easy *data, int sockfd, struct quicsocket *qs); static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, - size_t datalen, void *user_data, + uint64_t datalen, void *user_data, void *stream_user_data); static ngtcp2_conn *get_conn(ngtcp2_crypto_conn_ref *conn_ref) @@ -202,6 +210,14 @@ static int keylog_callback(gnutls_session_t session, const char *label, Curl_tls_keylog_write(label, crandom.data, secret->data, secret->size); return 0; } +#elif defined(USE_WOLFSSL) +#if defined(HAVE_SECRET_CALLBACK) +static void keylog_callback(const WOLFSSL *ssl, const char *line) +{ + (void)ssl; + Curl_tls_keylog_write_line(line); +} +#endif #endif static int init_ngh3_conn(struct quicsocket *qs); @@ -395,7 +411,105 @@ static int quic_init_ssl(struct quicsocket *qs) gnutls_server_name_set(qs->ssl, GNUTLS_NAME_DNS, hostname, strlen(hostname)); return 0; } +#elif defined(USE_WOLFSSL) + +static WOLFSSL_CTX *quic_ssl_ctx(struct Curl_easy *data) +{ + struct connectdata *conn = data->conn; + WOLFSSL_CTX *ssl_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); + + if(ngtcp2_crypto_wolfssl_configure_client_context(ssl_ctx) != 0) { + failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed"); + return NULL; + } + + wolfSSL_CTX_set_default_verify_paths(ssl_ctx); + + if(wolfSSL_CTX_set_cipher_list(ssl_ctx, QUIC_CIPHERS) != 1) { + char error_buffer[256]; + ERR_error_string_n(ERR_get_error(), error_buffer, sizeof(error_buffer)); + failf(data, "SSL_CTX_set_ciphersuites: %s", error_buffer); + return NULL; + } + + if(wolfSSL_CTX_set1_groups_list(ssl_ctx, (char *)QUIC_GROUPS) != 1) { + failf(data, "SSL_CTX_set1_groups_list failed"); + return NULL; + } + + /* Open the file if a TLS or QUIC backend has not done this before. */ + Curl_tls_keylog_open(); + if(Curl_tls_keylog_enabled()) { +#if defined(HAVE_SECRET_CALLBACK) + wolfSSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback); +#else + failf(data, "wolfSSL was built without keylog callback"); + return NULL; #endif + } + + if(conn->ssl_config.verifypeer) { + const char * const ssl_cafile = conn->ssl_config.CAfile; + const char * const ssl_capath = conn->ssl_config.CApath; + + if(ssl_cafile || ssl_capath) { + wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + /* tell wolfSSL where to find CA certificates that are used to verify + the server's certificate. */ + if(!wolfSSL_CTX_load_verify_locations(ssl_ctx, ssl_cafile, ssl_capath)) { + /* Fail if we insist on successfully verifying the server. */ + failf(data, "error setting certificate verify locations:" + " CAfile: %s CApath: %s", + ssl_cafile ? ssl_cafile : "none", + ssl_capath ? ssl_capath : "none"); + return NULL; + } + infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none"); + infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none"); + } +#ifdef CURL_CA_FALLBACK + else { + /* verifying the peer without any CA certificates won't work so + use wolfssl's built-in default as fallback */ + wolfSSL_CTX_set_default_verify_paths(ssl_ctx); + } +#endif + } + else { + wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL); + } + + return ssl_ctx; +} + +/** SSL callbacks ***/ + +static int quic_init_ssl(struct quicsocket *qs) +{ + const uint8_t *alpn = NULL; + size_t alpnlen = 0; + /* this will need some attention when HTTPS proxy over QUIC get fixed */ + const char * const hostname = qs->conn->host.name; + + DEBUGASSERT(!qs->ssl); + qs->ssl = SSL_new(qs->sslctx); + + wolfSSL_set_app_data(qs->ssl, &qs->conn_ref); + wolfSSL_set_connect_state(qs->ssl); + wolfSSL_set_quic_use_legacy_codepoint(qs->ssl, 0); + + alpn = (const uint8_t *)H3_ALPN_H3_29 H3_ALPN_H3; + alpnlen = sizeof(H3_ALPN_H3_29) - 1 + sizeof(H3_ALPN_H3) - 1; + if(alpn) + wolfSSL_set_alpn_protos(qs->ssl, alpn, (int)alpnlen); + + /* set SNI */ + wolfSSL_UseSNI(qs->ssl, WOLFSSL_SNI_HOST_NAME, + hostname, (unsigned short)strlen(hostname)); + + return 0; +} +#endif /* defined(USE_WOLFSSL) */ static int cb_handshake_completed(ngtcp2_conn *tconn, void *user_data) { @@ -646,6 +760,7 @@ static ngtcp2_callbacks ng_callbacks = { NULL, /* version_negotiation */ cb_recv_rx_key, NULL, /* recv_tx_key */ + NULL, /* early_data_rejected */ }; /* @@ -691,6 +806,10 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, result = quic_set_client_cert(data, qs); if(result) return result; +#elif defined(USE_WOLFSSL) + qs->sslctx = quic_ssl_ctx(data); + if(!qs->sslctx) + return CURLE_QUIC_CONNECT_ERROR; #endif if(quic_init_ssl(qs)) @@ -818,6 +937,8 @@ static void qs_disconnect(struct quicsocket *qs) SSL_free(qs->ssl); #elif defined(USE_GNUTLS) gnutls_deinit(qs->ssl); +#elif defined(USE_WOLFSSL) + wolfSSL_free(qs->ssl); #endif qs->ssl = NULL; #ifdef USE_GNUTLS @@ -831,6 +952,8 @@ static void qs_disconnect(struct quicsocket *qs) ngtcp2_conn_del(qs->qconn); #ifdef USE_OPENSSL SSL_CTX_free(qs->sslctx); +#elif defined(USE_WOLFSSL) + wolfSSL_CTX_free(qs->sslctx); #endif } @@ -899,6 +1022,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, H3BUGF(infof(data, "cb_h3_stream_close CALLED")); stream->closed = TRUE; + stream->error3 = app_error_code; Curl_expire(data, 0, EXPIRE_QUIC); /* make sure that ngh3_stream_recv is called again to complete the transfer even if there are no more packets to be received from the server. */ @@ -1010,6 +1134,10 @@ static int cb_h3_end_headers(nghttp3_conn *conn, int64_t stream_id, return -1; } } + + if(stream->status_code / 100 != 1) { + stream->bodystarted = TRUE; + } return 0; } @@ -1032,9 +1160,10 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, if(token == NGHTTP3_QPACK_TOKEN__STATUS) { char line[14]; /* status line is always 13 characters long */ size_t ncopy; - int status = decode_status_code(h3val.base, h3val.len); - DEBUGASSERT(status != -1); - ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", status); + stream->status_code = decode_status_code(h3val.base, h3val.len); + DEBUGASSERT(stream->status_code != -1); + ncopy = msnprintf(line, sizeof(line), "HTTP/3 %03d \r\n", + stream->status_code); result = write_data(stream, line, ncopy); if(result) { return -1; @@ -1064,16 +1193,36 @@ static int cb_h3_recv_header(nghttp3_conn *conn, int64_t stream_id, return 0; } -static int cb_h3_send_stop_sending(nghttp3_conn *conn, int64_t stream_id, - uint64_t app_error_code, - void *user_data, - void *stream_user_data) +static int cb_h3_stop_sending(nghttp3_conn *conn, int64_t stream_id, + uint64_t app_error_code, void *user_data, + void *stream_user_data) { + struct quicsocket *qs = user_data; + int rv; + (void)conn; + (void)stream_user_data; + + rv = ngtcp2_conn_shutdown_stream_read(qs->qconn, stream_id, app_error_code); + if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) { + return NGTCP2_ERR_CALLBACK_FAILURE; + } + + return 0; +} + +static int cb_h3_reset_stream(nghttp3_conn *conn, int64_t stream_id, + uint64_t app_error_code, void *user_data, + void *stream_user_data) { + struct quicsocket *qs = user_data; + int rv; (void)conn; - (void)stream_id; - (void)app_error_code; - (void)user_data; (void)stream_user_data; + + rv = ngtcp2_conn_shutdown_stream_write(qs->qconn, stream_id, app_error_code); + if(rv && rv != NGTCP2_ERR_STREAM_NOT_FOUND) { + return NGTCP2_ERR_CALLBACK_FAILURE; + } + return 0; } @@ -1088,9 +1237,9 @@ static nghttp3_callbacks ngh3_callbacks = { NULL, /* begin_trailers */ cb_h3_recv_header, NULL, /* end_trailers */ - cb_h3_send_stop_sending, + cb_h3_stop_sending, NULL, /* end_stream */ - NULL, /* reset_stream */ + cb_h3_reset_stream, NULL /* shutdown */ }; @@ -1226,6 +1375,24 @@ static ssize_t ngh3_stream_recv(struct Curl_easy *data, } if(stream->closed) { + if(stream->error3 != NGHTTP3_H3_NO_ERROR) { + failf(data, + "HTTP/3 stream %" PRId64 " was not closed cleanly: (err %" PRIu64 + ")", + stream->stream3_id, stream->error3); + *curlcode = CURLE_HTTP3; + return -1; + } + + if(!stream->bodystarted) { + failf(data, + "HTTP/3 stream %" PRId64 " was closed cleanly, but before getting" + " all response header fields, treated as error", + stream->stream3_id); + *curlcode = CURLE_HTTP3; + return -1; + } + *curlcode = CURLE_OK; return 0; } @@ -1237,7 +1404,7 @@ static ssize_t ngh3_stream_recv(struct Curl_easy *data, /* this amount of data has now been acked on this stream */ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, - size_t datalen, void *user_data, + uint64_t datalen, void *user_data, void *stream_user_data) { struct Curl_easy *data = stream_user_data; @@ -1375,6 +1542,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, nva[i].namelen = hreq->header[i].namelen; nva[i].value = (unsigned char *)hreq->header[i].value; nva[i].valuelen = hreq->header[i].valuelen; + nva[i].flags = NGHTTP3_NV_FLAG_NONE; } } @@ -1443,6 +1611,11 @@ static ssize_t ngh3_stream_send(struct Curl_easy *data, curl_socket_t sockfd = conn->sock[sockindex]; struct HTTP *stream = data->req.p.http; + if(stream->closed) { + *curlcode = CURLE_HTTP3; + return -1; + } + if(!stream->h3req) { CURLcode result = http_request(data, mem, len); if(result) { @@ -1519,12 +1692,23 @@ static CURLcode ng_has_connected(struct Curl_easy *data, if(result) return result; infof(data, "Verified certificate just fine"); -#else +#elif defined(USE_GNUTLS) result = Curl_gtls_verifyserver(data, conn, conn->quic->ssl, FIRSTSOCKET); +#elif defined(USE_WOLFSSL) + char *snihost = Curl_ssl_snihost(data, SSL_HOST_NAME(), NULL); + if(!snihost || + (wolfSSL_check_domain_name(conn->quic->ssl, snihost) == SSL_FAILURE)) + return CURLE_PEER_FAILED_VERIFICATION; + infof(data, "Verified certificate just fine"); #endif } else infof(data, "Skipped certificate verification"); +#ifdef USE_OPENSSL + if(data->set.ssl.certinfo) + /* asked to gather certificate info */ + (void)Curl_ossl_certchain(data, conn->quic->ssl); +#endif return result; } @@ -1650,15 +1834,17 @@ static CURLcode do_sendmsg(size_t *psent, struct Curl_easy *data, int sockfd, size_t pktlen, size_t gsolen) { #ifdef HAVE_SENDMSG - struct iovec msg_iov = {(void *)pkt, pktlen}; + struct iovec msg_iov; struct msghdr msg = {0}; - uint8_t msg_ctrl[32]; ssize_t sent; #if defined(__linux__) && defined(UDP_SEGMENT) + uint8_t msg_ctrl[32]; struct cmsghdr *cm; #endif *psent = 0; + msg_iov.iov_base = (uint8_t *)pkt; + msg_iov.iov_len = pktlen; msg.msg_iov = &msg_iov; msg.msg_iovlen = 1; @@ -1803,9 +1989,9 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, ngtcp2_ssize outlen; uint8_t *outpos = qs->pktbuf; size_t max_udp_payload_size = - ngtcp2_conn_get_max_udp_payload_size(qs->qconn); + ngtcp2_conn_get_max_tx_udp_payload_size(qs->qconn); size_t path_max_udp_payload_size = - ngtcp2_conn_get_path_max_udp_payload_size(qs->qconn); + ngtcp2_conn_get_path_max_tx_udp_payload_size(qs->qconn); size_t max_pktcnt = CURLMIN(MAX_PKT_BURST, qs->pktbuflen / max_udp_payload_size); size_t pktcnt = 0; @@ -1889,22 +2075,11 @@ static CURLcode ng_flush_egress(struct Curl_easy *data, switch(outlen) { case NGTCP2_ERR_STREAM_DATA_BLOCKED: assert(ndatalen == -1); - rv = nghttp3_conn_block_stream(qs->h3conn, stream_id); - if(rv) { - failf(data, "nghttp3_conn_block_stream returned error: %s\n", - nghttp3_strerror(rv)); - return CURLE_SEND_ERROR; - } + nghttp3_conn_block_stream(qs->h3conn, stream_id); continue; case NGTCP2_ERR_STREAM_SHUT_WR: assert(ndatalen == -1); - rv = nghttp3_conn_shutdown_stream_write(qs->h3conn, stream_id); - if(rv) { - failf(data, - "nghttp3_conn_shutdown_stream_write returned error: %s\n", - nghttp3_strerror(rv)); - return CURLE_SEND_ERROR; - } + nghttp3_conn_shutdown_stream_write(qs->h3conn, stream_id); continue; case NGTCP2_ERR_WRITE_MORE: assert(ndatalen >= 0); diff --git a/libs/libcurl/src/vquic/ngtcp2.h b/libs/libcurl/src/vquic/ngtcp2.h index 23fbcb66df..6539f5fef3 100644 --- a/libs/libcurl/src/vquic/ngtcp2.h +++ b/libs/libcurl/src/vquic/ngtcp2.h @@ -38,6 +38,10 @@ #include <openssl/ssl.h> #elif defined(USE_GNUTLS) #include <gnutls/gnutls.h> +#elif defined(USE_WOLFSSL) +#include <wolfssl/options.h> +#include <wolfssl/ssl.h> +#include <wolfssl/quic.h> #endif struct blocked_pkt { @@ -62,6 +66,9 @@ struct quicsocket { #elif defined(USE_GNUTLS) gnutls_certificate_credentials_t cred; gnutls_session_t ssl; +#elif defined(USE_WOLFSSL) + WOLFSSL_CTX *sslctx; + WOLFSSL *ssl; #endif struct sockaddr_storage local_addr; socklen_t local_addrlen; diff --git a/libs/libcurl/src/vquic/quiche.c b/libs/libcurl/src/vquic/quiche.c index 9a2b74310a..a52a7e8e21 100644 --- a/libs/libcurl/src/vquic/quiche.c +++ b/libs/libcurl/src/vquic/quiche.c @@ -258,6 +258,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, struct quicsocket *qs = &conn->hequic[sockindex]; char ipbuf[40]; int port; + int rv; #ifdef DEBUG_QUICHE /* initialize debug log callback only once */ @@ -303,8 +304,16 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, if(result) return result; + qs->local_addrlen = sizeof(qs->local_addr); + rv = getsockname(sockfd, (struct sockaddr *)&qs->local_addr, + &qs->local_addrlen); + if(rv == -1) + return CURLE_QUIC_CONNECT_ERROR; + qs->conn = quiche_conn_new_with_tls((const uint8_t *) qs->scid, - sizeof(qs->scid), NULL, 0, addr, addrlen, + sizeof(qs->scid), NULL, 0, + (struct sockaddr *)&qs->local_addr, + qs->local_addrlen, addr, addrlen, qs->cfg, qs->ssl, false); if(!qs->conn) { failf(data, "can't create quiche connection"); @@ -407,6 +416,10 @@ static CURLcode quiche_has_connected(struct Curl_easy *data, qs->cfg = NULL; qs->conn = NULL; } + if(data->set.ssl.certinfo) + /* asked to gather certificate info */ + (void)Curl_ossl_certchain(data, qs->ssl); + return CURLE_OK; fail: quiche_h3_config_free(qs->h3config); @@ -478,6 +491,8 @@ static CURLcode process_ingress(struct Curl_easy *data, int sockfd, recv_info.from = (struct sockaddr *) &from; recv_info.from_len = from_len; + recv_info.to = (struct sockaddr *) &qs->local_addr; + recv_info.to_len = qs->local_addrlen; recvd = quiche_conn_recv(qs->conn, buf, recvd, &recv_info); if(recvd == QUICHE_ERR_DONE) diff --git a/libs/libcurl/src/vquic/quiche.h b/libs/libcurl/src/vquic/quiche.h index de68089451..2da65f5f48 100644 --- a/libs/libcurl/src/vquic/quiche.h +++ b/libs/libcurl/src/vquic/quiche.h @@ -49,6 +49,8 @@ struct quicsocket { SSL_CTX *sslctx; SSL *ssl; bool h3_recving; /* TRUE when in h3-body-reading state */ + struct sockaddr_storage local_addr; + socklen_t local_addrlen; }; #endif diff --git a/libs/libcurl/src/vssh/libssh.c b/libs/libcurl/src/vssh/libssh.c index 5aa99e618b..0105e4079c 100644 --- a/libs/libcurl/src/vssh/libssh.c +++ b/libs/libcurl/src/vssh/libssh.c @@ -96,6 +96,13 @@ #include "curl_memory.h" #include "memdebug.h" +/* in 0.10.0 or later, ignore deprecated warnings */ +#if defined(__GNUC__) && \ + (LIBSSH_VERSION_MINOR >= 10) || \ + (LIBSSH_VERSION_MAJOR > 0) +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + /* A recent macro provided by libssh. Or make our own. */ #ifndef SSH_STRING_FREE_CHAR #define SSH_STRING_FREE_CHAR(x) \ @@ -956,10 +963,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) rc = sftp_init(sshc->sftp_session); if(rc != SSH_OK) { - rc = sftp_get_error(sshc->sftp_session); failf(data, "Failure initializing sftp session: %s", ssh_get_error(sshc->ssh_session)); - MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(rc)); + MOVE_TO_ERROR_STATE(sftp_error_to_CURLE(SSH_FX_FAILURE)); break; } state(data, SSH_SFTP_REALPATH); @@ -1660,7 +1666,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(from_t == CURL_OFFT_FLOW) { return CURLE_RANGE_ERROR; } - while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + while(*ptr && (ISBLANK(*ptr) || (*ptr == '-'))) ptr++; to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); if(to_t == CURL_OFFT_FLOW) { @@ -2911,32 +2917,33 @@ static void sftp_quote_stat(struct Curl_easy *data) } sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_UIDGID; } - else if(strncasecompare(cmd, "atime", 5)) { + else if(strncasecompare(cmd, "atime", 5) || + strncasecompare(cmd, "mtime", 5)) { time_t date = Curl_getdate_capped(sshc->quote_path1); + bool fail = FALSE; if(date == -1) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: incorrect access date format"); - state(data, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - return; + failf(data, "incorrect date format for %.*s", 5, cmd); + fail = TRUE; } - sshc->quote_attrs->atime = (uint32_t)date; - sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME; - } - else if(strncasecompare(cmd, "mtime", 5)) { - time_t date = Curl_getdate_capped(sshc->quote_path1); - if(date == -1) { +#if SIZEOF_TIME_T > 4 + else if(date > 0xffffffff) { + failf(data, "date overflow"); + fail = TRUE; /* avoid setting a capped time */ + } +#endif + if(fail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: incorrect modification date format"); state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; return; } - sshc->quote_attrs->mtime = (uint32_t)date; + if(strncasecompare(cmd, "atime", 5)) + sshc->quote_attrs->atime = (uint32_t)date; + else /* mtime */ + sshc->quote_attrs->mtime = (uint32_t)date; + sshc->quote_attrs->flags |= SSH_FILEXFER_ATTR_ACMODTIME; } diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c index 2026a88e5d..5a2c0f8bbf 100644 --- a/libs/libcurl/src/vssh/libssh2.c +++ b/libs/libcurl/src/vssh/libssh2.c @@ -1755,32 +1755,35 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) break; } } - else if(strncasecompare(cmd, "atime", 5)) { + else if(strncasecompare(cmd, "atime", 5) || + strncasecompare(cmd, "mtime", 5)) { time_t date = Curl_getdate_capped(sshc->quote_path1); + bool fail = FALSE; + if(date == -1) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: incorrect access date format"); - state(data, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; + failf(data, "incorrect date format for %.*s", 5, cmd); + fail = TRUE; } - sshp->quote_attrs.atime = (unsigned long)date; - sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; - } - else if(strncasecompare(cmd, "mtime", 5)) { - time_t date = Curl_getdate_capped(sshc->quote_path1); - if(date == -1) { +#if SIZEOF_TIME_T > SIZEOF_LONG + if(date > 0xffffffff) { + /* if 'long' can't old >32bit, this date cannot be sent */ + failf(data, "date overflow"); + fail = TRUE; + } +#endif + if(fail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: incorrect modification date format"); state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - sshp->quote_attrs.mtime = (unsigned long)date; + if(strncasecompare(cmd, "atime", 5)) + sshp->quote_attrs.atime = (unsigned long)date; + else /* mtime */ + sshp->quote_attrs.mtime = (unsigned long)date; + sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; } @@ -2335,7 +2338,8 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) ((sshp->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK)) { Curl_dyn_init(&sshp->readdir_link, PATH_MAX); - result = Curl_dyn_add(&sshp->readdir_link, sshp->path); + result = Curl_dyn_addf(&sshp->readdir_link, "%s%s", sshp->path, + sshp->readdir_filename); state(data, SSH_SFTP_READDIR_LINK); if(!result) break; @@ -2502,7 +2506,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from); if(from_t == CURL_OFFT_FLOW) return CURLE_RANGE_ERROR; - while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) + while(*ptr && (ISBLANK(*ptr) || (*ptr == '-'))) ptr++; to_t = curlx_strtoofft(ptr, &ptr2, 0, &to); if(to_t == CURL_OFFT_FLOW) diff --git a/libs/libcurl/src/vssh/ssh.h b/libs/libcurl/src/vssh/ssh.h index 7e1d8159cb..13bb8aa2d6 100644 --- a/libs/libcurl/src/vssh/ssh.h +++ b/libs/libcurl/src/vssh/ssh.h @@ -26,10 +26,10 @@ #include "curl_setup.h" -#if defined(HAVE_LIBSSH2_H) +#if defined(USE_LIBSSH2) #include <libssh2.h> #include <libssh2_sftp.h> -#elif defined(HAVE_LIBSSH_LIBSSH_H) +#elif defined(USE_LIBSSH) #include <libssh/libssh.h> #include <libssh/sftp.h> #elif defined(USE_WOLFSSH) diff --git a/libs/libcurl/src/vtls/bearssl.c b/libs/libcurl/src/vtls/bearssl.c index f14eb66a20..1221ce8c84 100644 --- a/libs/libcurl/src/vtls/bearssl.c +++ b/libs/libcurl/src/vtls/bearssl.c @@ -76,9 +76,9 @@ struct cafile_parser { #define CAFILE_SOURCE_PATH 1 #define CAFILE_SOURCE_BLOB 2 struct cafile_source { - const int type; - const char * const data; - const size_t len; + int type; + const char *data; + size_t len; }; static void append_dn(void *ctx, const void *buf, size_t len) @@ -618,11 +618,11 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, } if(ca_info_blob) { - struct cafile_source source = { - CAFILE_SOURCE_BLOB, - ca_info_blob->data, - ca_info_blob->len, - }; + struct cafile_source source; + source.type = CAFILE_SOURCE_BLOB; + source.data = ca_info_blob->data; + source.len = ca_info_blob->len; + ret = load_cafile(&source, &backend->anchors, &backend->anchors_len); if(ret != CURLE_OK) { if(verifypeer) { @@ -635,11 +635,11 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, } if(ssl_cafile) { - struct cafile_source source = { - CAFILE_SOURCE_PATH, - ssl_cafile, - 0, - }; + struct cafile_source source; + source.type = CAFILE_SOURCE_PATH; + source.data = ssl_cafile; + source.len = 0; + ret = load_cafile(&source, &backend->anchors, &backend->anchors_len); if(ret != CURLE_OK) { if(verifypeer) { @@ -875,14 +875,14 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data, #ifdef USE_HTTP2 if(!strcmp(protocol, ALPN_H2)) - conn->negnpn = CURL_HTTP_VERSION_2; + conn->alpn = CURL_HTTP_VERSION_2; else #endif if(!strcmp(protocol, ALPN_HTTP_1_1)) - conn->negnpn = CURL_HTTP_VERSION_1_1; + conn->alpn = CURL_HTTP_VERSION_1_1; else infof(data, "ALPN, unrecognized protocol %s", protocol); - Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } else diff --git a/libs/libcurl/src/vtls/gtls.c b/libs/libcurl/src/vtls/gtls.c index e2d41f4102..cf3dbc5238 100644 --- a/libs/libcurl/src/vtls/gtls.c +++ b/libs/libcurl/src/vtls/gtls.c @@ -45,6 +45,7 @@ #include "inet_pton.h" #include "gtls.h" #include "vtls.h" +#include "vauth/vauth.h" #include "parsedate.h" #include "connect.h" /* for the connect timeout */ #include "select.h" @@ -448,7 +449,7 @@ gtls_connect_step1(struct Curl_easy *data, #ifdef USE_GNUTLS_SRP if((SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) && - Curl_allow_auth_to_host(data)) { + Curl_auth_allowed_to_host(data)) { infof(data, "Using TLS-SRP username: %s", SSL_SET_OPTION(primary.username)); @@ -1274,19 +1275,19 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(proto.size == ALPN_H2_LENGTH && !memcmp(ALPN_H2, proto.data, ALPN_H2_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_2; + conn->alpn = CURL_HTTP_VERSION_2; } else #endif if(proto.size == ALPN_HTTP_1_1_LENGTH && !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; + conn->alpn = CURL_HTTP_VERSION_1_1; } } else infof(data, VTLS_INFOF_NO_ALPN); - Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } diff --git a/libs/libcurl/src/vtls/keylog.c b/libs/libcurl/src/vtls/keylog.c index 7471217921..1952a690ca 100644 --- a/libs/libcurl/src/vtls/keylog.c +++ b/libs/libcurl/src/vtls/keylog.c @@ -24,6 +24,7 @@ #include "curl_setup.h" #include "keylog.h" +#include <curl/curl.h> /* The last #include files should be: */ #include "curl_memory.h" diff --git a/libs/libcurl/src/vtls/mbedtls.c b/libs/libcurl/src/vtls/mbedtls.c index ad9bd10f8a..fbde8976eb 100644 --- a/libs/libcurl/src/vtls/mbedtls.c +++ b/libs/libcurl/src/vtls/mbedtls.c @@ -821,19 +821,19 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, #ifdef USE_HTTP2 if(!strncmp(next_protocol, ALPN_H2, ALPN_H2_LENGTH) && !next_protocol[ALPN_H2_LENGTH]) { - conn->negnpn = CURL_HTTP_VERSION_2; + conn->alpn = CURL_HTTP_VERSION_2; } else #endif if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) && !next_protocol[ALPN_HTTP_1_1_LENGTH]) { - conn->negnpn = CURL_HTTP_VERSION_1_1; + conn->alpn = CURL_HTTP_VERSION_1_1; } } else { infof(data, VTLS_INFOF_NO_ALPN); } - Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } #endif diff --git a/libs/libcurl/src/vtls/nss.c b/libs/libcurl/src/vtls/nss.c index 9d3a8584c9..12cf618f56 100644 --- a/libs/libcurl/src/vtls/nss.c +++ b/libs/libcurl/src/vtls/nss.c @@ -336,7 +336,7 @@ static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc *model, char name[MAX_CIPHER_LENGTH + 1]; size_t len; bool found = FALSE; - while((*cipher) && (ISSPACE(*cipher))) + while((*cipher) && (ISBLANK(*cipher))) ++cipher; end = strpbrk(cipher, ":, "); @@ -850,7 +850,7 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg) unsigned int buflen; SSLNextProtoState state; - if(!conn->bits.tls_enable_npn && !conn->bits.tls_enable_alpn) { + if(!conn->bits.tls_enable_alpn) { return; } @@ -871,21 +871,21 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg) infof(data, VTLS_INFOF_ALPN_ACCEPTED_LEN_1STR, buflen, buf); break; #endif - case SSL_NEXT_PROTO_NEGOTIATED: - infof(data, "NPN, server accepted to use %.*s", buflen, buf); + default: + /* ignore SSL_NEXT_PROTO_NEGOTIATED */ break; } #ifdef USE_HTTP2 if(buflen == ALPN_H2_LENGTH && !memcmp(ALPN_H2, buf, ALPN_H2_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_2; + conn->alpn = CURL_HTTP_VERSION_2; } else #endif if(buflen == ALPN_HTTP_1_1_LENGTH && !memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; + conn->alpn = CURL_HTTP_VERSION_1_1; } /* This callback might get called when PR_Recv() is used within @@ -893,7 +893,7 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg) * be any "bundle" associated with the connection anymore. */ if(conn->bundle) - Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } } @@ -936,8 +936,8 @@ static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data, if(cipherInfo.symCipher != ssl_calg_aes_gcm) goto end; - /* Enforce ALPN or NPN to do False Start, as an indicator of server - * compatibility. */ + /* Enforce ALPN to do False Start, as an indicator of server + compatibility. */ rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn, &negotiatedExtension); if(rv != SECSuccess || !negotiatedExtension) { @@ -2136,12 +2136,6 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, } #endif -#ifdef SSL_ENABLE_NPN - if(SSL_OptionSet(backend->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn - ? PR_TRUE : PR_FALSE) != SECSuccess) - goto error; -#endif - #ifdef SSL_ENABLE_ALPN if(SSL_OptionSet(backend->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn ? PR_TRUE : PR_FALSE) != SECSuccess) @@ -2160,15 +2154,15 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, } #endif -#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN) - if(conn->bits.tls_enable_npn || conn->bits.tls_enable_alpn) { +#if defined(SSL_ENABLE_ALPN) + if(conn->bits.tls_enable_alpn) { int cur = 0; unsigned char protocols[128]; #ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2 #ifndef CURL_DISABLE_PROXY - && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) + && (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy) #endif ) { protocols[cur++] = ALPN_H2_LENGTH; diff --git a/libs/libcurl/src/vtls/openssl.c b/libs/libcurl/src/vtls/openssl.c index 78aacd0228..ad2efa5586 100644 --- a/libs/libcurl/src/vtls/openssl.c +++ b/libs/libcurl/src/vtls/openssl.c @@ -29,7 +29,7 @@ #include "curl_setup.h" -#ifdef USE_OPENSSL +#if defined(USE_QUICHE) || defined(USE_OPENSSL) #include <limits.h> @@ -55,6 +55,7 @@ #include "slist.h" #include "select.h" #include "vtls.h" +#include "vauth/vauth.h" #include "keylog.h" #include "strcase.h" #include "hostcheck.h" @@ -78,10 +79,6 @@ #include <openssl/buffer.h> #include <openssl/pkcs12.h> -#ifdef USE_AMISSL -#include "amigaos.h" -#endif - #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP) #include <openssl/ocsp.h> #endif @@ -275,6 +272,344 @@ struct ssl_backend_data { #endif }; +#define push_certinfo(_label, _num) \ +do { \ + long info_len = BIO_get_mem_data(mem, &ptr); \ + Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \ + if(1 != BIO_reset(mem)) \ + break; \ +} while(0) + +static void pubkey_show(struct Curl_easy *data, + BIO *mem, + int num, + const char *type, + const char *name, + const BIGNUM *bn) +{ + char *ptr; + char namebuf[32]; + + msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name); + + if(bn) + BN_print(mem, bn); + push_certinfo(namebuf, num); +} + +#ifdef HAVE_OPAQUE_RSA_DSA_DH +#define print_pubkey_BN(_type, _name, _num) \ + pubkey_show(data, mem, _num, #_type, #_name, _name) + +#else +#define print_pubkey_BN(_type, _name, _num) \ +do { \ + if(_type->_name) { \ + pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \ + } \ +} while(0) +#endif + +static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len) +{ + int i, ilen; + + ilen = (int)len; + if(ilen < 0) + return 1; /* buffer too big */ + + i = i2t_ASN1_OBJECT(buf, ilen, a); + + if(i >= ilen) + return 1; /* buffer too small */ + + return 0; +} + +static void X509V3_ext(struct Curl_easy *data, + int certnum, + CONST_EXTS STACK_OF(X509_EXTENSION) *exts) +{ + int i; + + if((int)sk_X509_EXTENSION_num(exts) <= 0) + /* no extensions, bail out */ + return; + + for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + BUF_MEM *biomem; + char namebuf[128]; + BIO *bio_out = BIO_new(BIO_s_mem()); + + if(!bio_out) + return; + + obj = X509_EXTENSION_get_object(ext); + + asn1_object_dump(obj, namebuf, sizeof(namebuf)); + + if(!X509V3_EXT_print(bio_out, ext, 0, 0)) + ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); + + BIO_get_mem_ptr(bio_out, &biomem); + Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data, + biomem->length); + BIO_free(bio_out); + } +} + +#ifdef OPENSSL_IS_BORINGSSL +typedef size_t numcert_t; +#else +typedef int numcert_t; +#endif + +CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl) +{ + CURLcode result; + STACK_OF(X509) *sk; + int i; + numcert_t numcerts; + BIO *mem; + + DEBUGASSERT(ssl); + + sk = SSL_get_peer_cert_chain(ssl); + if(!sk) { + return CURLE_OUT_OF_MEMORY; + } + + numcerts = sk_X509_num(sk); + + result = Curl_ssl_init_certinfo(data, (int)numcerts); + if(result) { + return result; + } + + mem = BIO_new(BIO_s_mem()); + if(!mem) { + return CURLE_OUT_OF_MEMORY; + } + + for(i = 0; i < (int)numcerts; i++) { + ASN1_INTEGER *num; + X509 *x = sk_X509_value(sk, i); + EVP_PKEY *pubkey = NULL; + int j; + char *ptr; + const ASN1_BIT_STRING *psig = NULL; + + X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); + push_certinfo("Subject", i); + + X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); + push_certinfo("Issuer", i); + + BIO_printf(mem, "%lx", X509_get_version(x)); + push_certinfo("Version", i); + + num = X509_get_serialNumber(x); + if(num->type == V_ASN1_NEG_INTEGER) + BIO_puts(mem, "-"); + for(j = 0; j < num->length; j++) + BIO_printf(mem, "%02x", num->data[j]); + push_certinfo("Serial Number", i); + +#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS) + { + const X509_ALGOR *sigalg = NULL; + X509_PUBKEY *xpubkey = NULL; + ASN1_OBJECT *pubkeyoid = NULL; + + X509_get0_signature(&psig, &sigalg, x); + if(sigalg) { + i2a_ASN1_OBJECT(mem, sigalg->algorithm); + push_certinfo("Signature Algorithm", i); + } + + xpubkey = X509_get_X509_PUBKEY(x); + if(xpubkey) { + X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey); + if(pubkeyoid) { + i2a_ASN1_OBJECT(mem, pubkeyoid); + push_certinfo("Public Key Algorithm", i); + } + } + + X509V3_ext(data, i, X509_get0_extensions(x)); + } +#else + { + /* before OpenSSL 1.0.2 */ + X509_CINF *cinf = x->cert_info; + + i2a_ASN1_OBJECT(mem, cinf->signature->algorithm); + push_certinfo("Signature Algorithm", i); + + i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm); + push_certinfo("Public Key Algorithm", i); + + X509V3_ext(data, i, cinf->extensions); + + psig = x->signature; + } +#endif + + ASN1_TIME_print(mem, X509_get0_notBefore(x)); + push_certinfo("Start date", i); + + ASN1_TIME_print(mem, X509_get0_notAfter(x)); + push_certinfo("Expire date", i); + + pubkey = X509_get_pubkey(x); + if(!pubkey) + infof(data, " Unable to load public key"); + else { + int pktype; +#ifdef HAVE_OPAQUE_EVP_PKEY + pktype = EVP_PKEY_id(pubkey); +#else + pktype = pubkey->type; +#endif + switch(pktype) { + case EVP_PKEY_RSA: + { +#ifndef HAVE_EVP_PKEY_GET_PARAMS + RSA *rsa; +#ifdef HAVE_OPAQUE_EVP_PKEY + rsa = EVP_PKEY_get0_RSA(pubkey); +#else + rsa = pubkey->pkey.rsa; +#endif /* HAVE_OPAQUE_EVP_PKEY */ +#endif /* !HAVE_EVP_PKEY_GET_PARAMS */ + + { +#ifdef HAVE_OPAQUE_RSA_DSA_DH + DECLARE_PKEY_PARAM_BIGNUM(n); + DECLARE_PKEY_PARAM_BIGNUM(e); +#ifdef HAVE_EVP_PKEY_GET_PARAMS + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n); + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e); +#else + RSA_get0_key(rsa, &n, &e, NULL); +#endif /* HAVE_EVP_PKEY_GET_PARAMS */ + BIO_printf(mem, "%d", BN_num_bits(n)); +#else + BIO_printf(mem, "%d", BN_num_bits(rsa->n)); +#endif /* HAVE_OPAQUE_RSA_DSA_DH */ + push_certinfo("RSA Public Key", i); + print_pubkey_BN(rsa, n, i); + print_pubkey_BN(rsa, e, i); + FREE_PKEY_PARAM_BIGNUM(n); + FREE_PKEY_PARAM_BIGNUM(e); + } + + break; + } + case EVP_PKEY_DSA: + { +#ifndef OPENSSL_NO_DSA +#ifndef HAVE_EVP_PKEY_GET_PARAMS + DSA *dsa; +#ifdef HAVE_OPAQUE_EVP_PKEY + dsa = EVP_PKEY_get0_DSA(pubkey); +#else + dsa = pubkey->pkey.dsa; +#endif /* HAVE_OPAQUE_EVP_PKEY */ +#endif /* !HAVE_EVP_PKEY_GET_PARAMS */ + { +#ifdef HAVE_OPAQUE_RSA_DSA_DH + DECLARE_PKEY_PARAM_BIGNUM(p); + DECLARE_PKEY_PARAM_BIGNUM(q); + DECLARE_PKEY_PARAM_BIGNUM(g); + DECLARE_PKEY_PARAM_BIGNUM(pub_key); +#ifdef HAVE_EVP_PKEY_GET_PARAMS + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p); + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q); + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g); + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key); +#else + DSA_get0_pqg(dsa, &p, &q, &g); + DSA_get0_key(dsa, &pub_key, NULL); +#endif /* HAVE_EVP_PKEY_GET_PARAMS */ +#endif /* HAVE_OPAQUE_RSA_DSA_DH */ + print_pubkey_BN(dsa, p, i); + print_pubkey_BN(dsa, q, i); + print_pubkey_BN(dsa, g, i); + print_pubkey_BN(dsa, pub_key, i); + FREE_PKEY_PARAM_BIGNUM(p); + FREE_PKEY_PARAM_BIGNUM(q); + FREE_PKEY_PARAM_BIGNUM(g); + FREE_PKEY_PARAM_BIGNUM(pub_key); + } +#endif /* !OPENSSL_NO_DSA */ + break; + } + case EVP_PKEY_DH: + { +#ifndef HAVE_EVP_PKEY_GET_PARAMS + DH *dh; +#ifdef HAVE_OPAQUE_EVP_PKEY + dh = EVP_PKEY_get0_DH(pubkey); +#else + dh = pubkey->pkey.dh; +#endif /* HAVE_OPAQUE_EVP_PKEY */ +#endif /* !HAVE_EVP_PKEY_GET_PARAMS */ + { +#ifdef HAVE_OPAQUE_RSA_DSA_DH + DECLARE_PKEY_PARAM_BIGNUM(p); + DECLARE_PKEY_PARAM_BIGNUM(q); + DECLARE_PKEY_PARAM_BIGNUM(g); + DECLARE_PKEY_PARAM_BIGNUM(pub_key); +#ifdef HAVE_EVP_PKEY_GET_PARAMS + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p); + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q); + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g); + EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key); +#else + DH_get0_pqg(dh, &p, &q, &g); + DH_get0_key(dh, &pub_key, NULL); +#endif /* HAVE_EVP_PKEY_GET_PARAMS */ + print_pubkey_BN(dh, p, i); + print_pubkey_BN(dh, q, i); + print_pubkey_BN(dh, g, i); +#else + print_pubkey_BN(dh, p, i); + print_pubkey_BN(dh, g, i); +#endif /* HAVE_OPAQUE_RSA_DSA_DH */ + print_pubkey_BN(dh, pub_key, i); + FREE_PKEY_PARAM_BIGNUM(p); + FREE_PKEY_PARAM_BIGNUM(q); + FREE_PKEY_PARAM_BIGNUM(g); + FREE_PKEY_PARAM_BIGNUM(pub_key); + } + break; + } + } + EVP_PKEY_free(pubkey); + } + + if(psig) { + for(j = 0; j < psig->length; j++) + BIO_printf(mem, "%02x:", psig->data[j]); + push_certinfo("Signature", i); + } + + PEM_write_bio_X509(mem, x); + push_certinfo("Cert", i); + } + + BIO_free(mem); + + return CURLE_OK; +} + +#endif /* quiche or OpenSSL */ + +#ifdef USE_OPENSSL + static bool ossl_associate_connection(struct Curl_easy *data, struct connectdata *conn, int sockindex); @@ -797,9 +1132,10 @@ int cert_stuff(struct Curl_easy *data, SSL_CTX_use_certificate_chain_file(ctx, cert_file); if(cert_use_result != 1) { failf(data, - "could not load PEM client certificate, " OSSL_PACKAGE + "could not load PEM client certificate from %s, " OSSL_PACKAGE " error %s, " "(no key found, wrong pass phrase, or wrong file format?)", + (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file), ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)) ); return 0; @@ -817,9 +1153,10 @@ int cert_stuff(struct Curl_easy *data, SSL_CTX_use_certificate_file(ctx, cert_file, file_type); if(cert_use_result != 1) { failf(data, - "could not load ASN1 client certificate, " OSSL_PACKAGE + "could not load ASN1 client certificate from %s, " OSSL_PACKAGE " error %s, " "(no key found, wrong pass phrase, or wrong file format?)", + (cert_blob ? "CURLOPT_SSLCERT_BLOB" : cert_file), ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)) ); return 0; @@ -872,8 +1209,9 @@ int cert_stuff(struct Curl_easy *data, } if(SSL_CTX_use_certificate(ctx, params.cert) != 1) { - failf(data, "unable to set client certificate"); - X509_free(params.cert); + failf(data, "unable to set client certificate [%s]", + ossl_strerror(ERR_get_error(), error_buffer, + sizeof(error_buffer))); return 0; } X509_free(params.cert); /* we don't need the handle any more... */ @@ -996,11 +1334,7 @@ int cert_stuff(struct Curl_easy *data, fail: EVP_PKEY_free(pri); X509_free(x509); -#ifdef USE_AMISSL - sk_X509_pop_free(ca, Curl_amiga_X509_free); -#else sk_X509_pop_free(ca, X509_free); -#endif if(!cert_done) return 0; /* failure! */ break; @@ -2259,72 +2593,6 @@ static void ossl_trace(int direction, int ssl_ver, int content_type, # define HAS_ALPN 1 #endif -/* Check for OpenSSL 1.0.1 which has NPN support. */ -#undef HAS_NPN -#if OPENSSL_VERSION_NUMBER >= 0x10001000L \ - && !defined(OPENSSL_NO_TLSEXT) \ - && !defined(OPENSSL_NO_NEXTPROTONEG) -# define HAS_NPN 1 -#endif - -#ifdef HAS_NPN - -/* - * in is a list of length prefixed strings. this function has to select - * the protocol we want to use from the list and write its string into out. - */ - -static int -select_next_protocol(unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, - const char *key, unsigned int keylen) -{ - unsigned int i; - for(i = 0; i + keylen <= inlen; i += in[i] + 1) { - if(memcmp(&in[i + 1], key, keylen) == 0) { - *out = (unsigned char *) &in[i + 1]; - *outlen = in[i]; - return 0; - } - } - return -1; -} - -static int -select_next_proto_cb(SSL *ssl, - unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, - void *arg) -{ - struct Curl_easy *data = (struct Curl_easy *)arg; - struct connectdata *conn = data->conn; - (void)ssl; - -#ifdef USE_HTTP2 - if(data->state.httpwant >= CURL_HTTP_VERSION_2 && - !select_next_protocol(out, outlen, in, inlen, ALPN_H2, ALPN_H2_LENGTH)) { - infof(data, "NPN, negotiated HTTP2 (%s)", ALPN_H2); - conn->negnpn = CURL_HTTP_VERSION_2; - return SSL_TLSEXT_ERR_OK; - } -#endif - - if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1, - ALPN_HTTP_1_1_LENGTH)) { - infof(data, "NPN, negotiated HTTP1.1"); - conn->negnpn = CURL_HTTP_VERSION_1_1; - return SSL_TLSEXT_ERR_OK; - } - - infof(data, "NPN, no overlap, use HTTP1.1"); - *out = (unsigned char *)ALPN_HTTP_1_1; - *outlen = ALPN_HTTP_1_1_LENGTH; - conn->negnpn = CURL_HTTP_VERSION_1_1; - - return SSL_TLSEXT_ERR_OK; -} -#endif /* HAS_NPN */ - #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */ static CURLcode set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn) @@ -2815,11 +3083,6 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, SSL_CTX_set_options(backend->ctx, ctx_options); -#ifdef HAS_NPN - if(conn->bits.tls_enable_npn) - SSL_CTX_set_next_proto_select_cb(backend->ctx, select_next_proto_cb, data); -#endif - #ifdef HAS_ALPN if(conn->bits.tls_enable_alpn) { int cur = 0; @@ -2909,7 +3172,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, #ifdef USE_OPENSSL_SRP if((ssl_authtype == CURL_TLSAUTH_SRP) && - Curl_allow_auth_to_host(data)) { + Curl_auth_allowed_to_host(data)) { char * const ssl_username = SSL_SET_OPTION(primary.username); char * const ssl_password = SSL_SET_OPTION(primary.password); infof(data, "Using TLS-SRP username: %s", ssl_username); @@ -3447,19 +3710,19 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, #ifdef USE_HTTP2 if(len == ALPN_H2_LENGTH && !memcmp(ALPN_H2, neg_protocol, len)) { - conn->negnpn = CURL_HTTP_VERSION_2; + conn->alpn = CURL_HTTP_VERSION_2; } else #endif if(len == ALPN_HTTP_1_1_LENGTH && !memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; + conn->alpn = CURL_HTTP_VERSION_1_1; } } else infof(data, VTLS_INFOF_NO_ALPN); - Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } #endif @@ -3468,342 +3731,6 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, } } -static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len) -{ - int i, ilen; - - ilen = (int)len; - if(ilen < 0) - return 1; /* buffer too big */ - - i = i2t_ASN1_OBJECT(buf, ilen, a); - - if(i >= ilen) - return 1; /* buffer too small */ - - return 0; -} - -#define push_certinfo(_label, _num) \ -do { \ - long info_len = BIO_get_mem_data(mem, &ptr); \ - Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \ - if(1 != BIO_reset(mem)) \ - break; \ -} while(0) - -static void pubkey_show(struct Curl_easy *data, - BIO *mem, - int num, - const char *type, - const char *name, - const BIGNUM *bn) -{ - char *ptr; - char namebuf[32]; - - msnprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name); - - if(bn) - BN_print(mem, bn); - push_certinfo(namebuf, num); -} - -#ifdef HAVE_OPAQUE_RSA_DSA_DH -#define print_pubkey_BN(_type, _name, _num) \ - pubkey_show(data, mem, _num, #_type, #_name, _name) - -#else -#define print_pubkey_BN(_type, _name, _num) \ -do { \ - if(_type->_name) { \ - pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \ - } \ -} while(0) -#endif - -static void X509V3_ext(struct Curl_easy *data, - int certnum, - CONST_EXTS STACK_OF(X509_EXTENSION) *exts) -{ - int i; - - if((int)sk_X509_EXTENSION_num(exts) <= 0) - /* no extensions, bail out */ - return; - - for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) { - ASN1_OBJECT *obj; - X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); - BUF_MEM *biomem; - char namebuf[128]; - BIO *bio_out = BIO_new(BIO_s_mem()); - - if(!bio_out) - return; - - obj = X509_EXTENSION_get_object(ext); - - asn1_object_dump(obj, namebuf, sizeof(namebuf)); - - if(!X509V3_EXT_print(bio_out, ext, 0, 0)) - ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); - - BIO_get_mem_ptr(bio_out, &biomem); - Curl_ssl_push_certinfo_len(data, certnum, namebuf, biomem->data, - biomem->length); - BIO_free(bio_out); - } -} - -#ifdef OPENSSL_IS_BORINGSSL -typedef size_t numcert_t; -#else -typedef int numcert_t; -#endif - -static CURLcode get_cert_chain(struct Curl_easy *data, - struct ssl_connect_data *connssl) -{ - CURLcode result; - STACK_OF(X509) *sk; - int i; - numcert_t numcerts; - BIO *mem; - struct ssl_backend_data *backend = connssl->backend; - - DEBUGASSERT(backend); - - sk = SSL_get_peer_cert_chain(backend->handle); - if(!sk) { - return CURLE_OUT_OF_MEMORY; - } - - numcerts = sk_X509_num(sk); - - result = Curl_ssl_init_certinfo(data, (int)numcerts); - if(result) { - return result; - } - - mem = BIO_new(BIO_s_mem()); - if(!mem) { - return CURLE_OUT_OF_MEMORY; - } - - for(i = 0; i < (int)numcerts; i++) { - ASN1_INTEGER *num; - X509 *x = sk_X509_value(sk, i); - EVP_PKEY *pubkey = NULL; - int j; - char *ptr; - const ASN1_BIT_STRING *psig = NULL; - - X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); - push_certinfo("Subject", i); - - X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); - push_certinfo("Issuer", i); - - BIO_printf(mem, "%lx", X509_get_version(x)); - push_certinfo("Version", i); - - num = X509_get_serialNumber(x); - if(num->type == V_ASN1_NEG_INTEGER) - BIO_puts(mem, "-"); - for(j = 0; j < num->length; j++) - BIO_printf(mem, "%02x", num->data[j]); - push_certinfo("Serial Number", i); - -#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS) - { - const X509_ALGOR *sigalg = NULL; - X509_PUBKEY *xpubkey = NULL; - ASN1_OBJECT *pubkeyoid = NULL; - - X509_get0_signature(&psig, &sigalg, x); - if(sigalg) { - i2a_ASN1_OBJECT(mem, sigalg->algorithm); - push_certinfo("Signature Algorithm", i); - } - - xpubkey = X509_get_X509_PUBKEY(x); - if(xpubkey) { - X509_PUBKEY_get0_param(&pubkeyoid, NULL, NULL, NULL, xpubkey); - if(pubkeyoid) { - i2a_ASN1_OBJECT(mem, pubkeyoid); - push_certinfo("Public Key Algorithm", i); - } - } - - X509V3_ext(data, i, X509_get0_extensions(x)); - } -#else - { - /* before OpenSSL 1.0.2 */ - X509_CINF *cinf = x->cert_info; - - i2a_ASN1_OBJECT(mem, cinf->signature->algorithm); - push_certinfo("Signature Algorithm", i); - - i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm); - push_certinfo("Public Key Algorithm", i); - - X509V3_ext(data, i, cinf->extensions); - - psig = x->signature; - } -#endif - - ASN1_TIME_print(mem, X509_get0_notBefore(x)); - push_certinfo("Start date", i); - - ASN1_TIME_print(mem, X509_get0_notAfter(x)); - push_certinfo("Expire date", i); - - pubkey = X509_get_pubkey(x); - if(!pubkey) - infof(data, " Unable to load public key"); - else { - int pktype; -#ifdef HAVE_OPAQUE_EVP_PKEY - pktype = EVP_PKEY_id(pubkey); -#else - pktype = pubkey->type; -#endif - switch(pktype) { - case EVP_PKEY_RSA: - { -#ifndef HAVE_EVP_PKEY_GET_PARAMS - RSA *rsa; -#ifdef HAVE_OPAQUE_EVP_PKEY - rsa = EVP_PKEY_get0_RSA(pubkey); -#else - rsa = pubkey->pkey.rsa; -#endif /* HAVE_OPAQUE_EVP_PKEY */ -#endif /* !HAVE_EVP_PKEY_GET_PARAMS */ - - { -#ifdef HAVE_OPAQUE_RSA_DSA_DH - DECLARE_PKEY_PARAM_BIGNUM(n); - DECLARE_PKEY_PARAM_BIGNUM(e); -#ifdef HAVE_EVP_PKEY_GET_PARAMS - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &n); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &e); -#else - RSA_get0_key(rsa, &n, &e, NULL); -#endif /* HAVE_EVP_PKEY_GET_PARAMS */ - BIO_printf(mem, "%d", BN_num_bits(n)); -#else - BIO_printf(mem, "%d", BN_num_bits(rsa->n)); -#endif /* HAVE_OPAQUE_RSA_DSA_DH */ - push_certinfo("RSA Public Key", i); - print_pubkey_BN(rsa, n, i); - print_pubkey_BN(rsa, e, i); - FREE_PKEY_PARAM_BIGNUM(n); - FREE_PKEY_PARAM_BIGNUM(e); - } - - break; - } - case EVP_PKEY_DSA: - { -#ifndef OPENSSL_NO_DSA -#ifndef HAVE_EVP_PKEY_GET_PARAMS - DSA *dsa; -#ifdef HAVE_OPAQUE_EVP_PKEY - dsa = EVP_PKEY_get0_DSA(pubkey); -#else - dsa = pubkey->pkey.dsa; -#endif /* HAVE_OPAQUE_EVP_PKEY */ -#endif /* !HAVE_EVP_PKEY_GET_PARAMS */ - { -#ifdef HAVE_OPAQUE_RSA_DSA_DH - DECLARE_PKEY_PARAM_BIGNUM(p); - DECLARE_PKEY_PARAM_BIGNUM(q); - DECLARE_PKEY_PARAM_BIGNUM(g); - DECLARE_PKEY_PARAM_BIGNUM(pub_key); -#ifdef HAVE_EVP_PKEY_GET_PARAMS - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key); -#else - DSA_get0_pqg(dsa, &p, &q, &g); - DSA_get0_key(dsa, &pub_key, NULL); -#endif /* HAVE_EVP_PKEY_GET_PARAMS */ -#endif /* HAVE_OPAQUE_RSA_DSA_DH */ - print_pubkey_BN(dsa, p, i); - print_pubkey_BN(dsa, q, i); - print_pubkey_BN(dsa, g, i); - print_pubkey_BN(dsa, pub_key, i); - FREE_PKEY_PARAM_BIGNUM(p); - FREE_PKEY_PARAM_BIGNUM(q); - FREE_PKEY_PARAM_BIGNUM(g); - FREE_PKEY_PARAM_BIGNUM(pub_key); - } -#endif /* !OPENSSL_NO_DSA */ - break; - } - case EVP_PKEY_DH: - { -#ifndef HAVE_EVP_PKEY_GET_PARAMS - DH *dh; -#ifdef HAVE_OPAQUE_EVP_PKEY - dh = EVP_PKEY_get0_DH(pubkey); -#else - dh = pubkey->pkey.dh; -#endif /* HAVE_OPAQUE_EVP_PKEY */ -#endif /* !HAVE_EVP_PKEY_GET_PARAMS */ - { -#ifdef HAVE_OPAQUE_RSA_DSA_DH - DECLARE_PKEY_PARAM_BIGNUM(p); - DECLARE_PKEY_PARAM_BIGNUM(q); - DECLARE_PKEY_PARAM_BIGNUM(g); - DECLARE_PKEY_PARAM_BIGNUM(pub_key); -#ifdef HAVE_EVP_PKEY_GET_PARAMS - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_P, &p); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_Q, &q); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_FFC_G, &g); - EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY, &pub_key); -#else - DH_get0_pqg(dh, &p, &q, &g); - DH_get0_key(dh, &pub_key, NULL); -#endif /* HAVE_EVP_PKEY_GET_PARAMS */ - print_pubkey_BN(dh, p, i); - print_pubkey_BN(dh, q, i); - print_pubkey_BN(dh, g, i); -#else - print_pubkey_BN(dh, p, i); - print_pubkey_BN(dh, g, i); -#endif /* HAVE_OPAQUE_RSA_DSA_DH */ - print_pubkey_BN(dh, pub_key, i); - FREE_PKEY_PARAM_BIGNUM(p); - FREE_PKEY_PARAM_BIGNUM(q); - FREE_PKEY_PARAM_BIGNUM(g); - FREE_PKEY_PARAM_BIGNUM(pub_key); - } - break; - } - } - EVP_PKEY_free(pubkey); - } - - if(psig) { - for(j = 0; j < psig->length; j++) - BIO_printf(mem, "%02x:", psig->data[j]); - push_certinfo("Signature", i); - } - - PEM_write_bio_X509(mem, x); - push_certinfo("Cert", i); - } - - BIO_free(mem); - - return CURLE_OK; -} - /* * Heavily modified from: * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL @@ -3898,8 +3825,8 @@ static CURLcode servercert(struct Curl_easy *data, } if(data->set.ssl.certinfo) - /* we've been asked to gather certificate info! */ - (void)get_cert_chain(data, connssl); + /* asked to gather certificate info */ + (void)Curl_ossl_certchain(data, connssl->backend->handle); backend->server_cert = SSL_get1_peer_certificate(backend->handle); if(!backend->server_cert) { @@ -4442,7 +4369,7 @@ static size_t ossl_version(char *buffer, size_t size) } count = msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, ver); for(p = buffer; *p; ++p) { - if(ISSPACE(*p)) + if(ISBLANK(*p)) *p = '_'; } return count; @@ -4454,7 +4381,13 @@ static size_t ossl_version(char *buffer, size_t size) (LIBRESSL_VERSION_NUMBER>>12)&0xff); #endif #elif defined(OPENSSL_IS_BORINGSSL) +#ifdef CURL_BORINGSSL_VERSION + return msnprintf(buffer, size, "%s/%s", + OSSL_PACKAGE, + CURL_BORINGSSL_VERSION); +#else return msnprintf(buffer, size, OSSL_PACKAGE); +#endif #elif defined(HAVE_OPENSSL_VERSION) && defined(OPENSSL_VERSION_STRING) return msnprintf(buffer, size, "%s/%s", OSSL_PACKAGE, OpenSSL_version(OPENSSL_VERSION_STRING)); diff --git a/libs/libcurl/src/vtls/openssl.h b/libs/libcurl/src/vtls/openssl.h index cb47f4ea81..9df4ecddba 100644 --- a/libs/libcurl/src/vtls/openssl.h +++ b/libs/libcurl/src/vtls/openssl.h @@ -31,6 +31,7 @@ * This header should only be needed to get included by vtls.c, openssl.c * and ngtcp2.c */ +#include <openssl/ssl.h> #include "urldata.h" @@ -53,5 +54,7 @@ CURLcode Curl_ossl_set_client_cert(struct Curl_easy *data, const struct curl_blob *key_blob, const char *key_type, char *key_passwd); +CURLcode Curl_ossl_certchain(struct Curl_easy *data, SSL *ssl); + #endif /* USE_OPENSSL */ #endif /* HEADER_CURL_SSLUSE_H */ diff --git a/libs/libcurl/src/vtls/rustls.c b/libs/libcurl/src/vtls/rustls.c index be4af98502..77a49f1ab4 100644 --- a/libs/libcurl/src/vtls/rustls.c +++ b/libs/libcurl/src/vtls/rustls.c @@ -415,20 +415,20 @@ cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn, #ifdef USE_HTTP2 if(len == ALPN_H2_LENGTH && 0 == memcmp(ALPN_H2, protocol, len)) { infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, ALPN_H2); - conn->negnpn = CURL_HTTP_VERSION_2; + conn->alpn = CURL_HTTP_VERSION_2; } else #endif if(len == ALPN_HTTP_1_1_LENGTH && 0 == memcmp(ALPN_HTTP_1_1, protocol, len)) { infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, ALPN_HTTP_1_1); - conn->negnpn = CURL_HTTP_VERSION_1_1; + conn->alpn = CURL_HTTP_VERSION_1_1; } else { infof(data, "ALPN, negotiated an unrecognized protocol"); } - Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } diff --git a/libs/libcurl/src/vtls/schannel.c b/libs/libcurl/src/vtls/schannel.c index 7e42285828..454eb79674 100644 --- a/libs/libcurl/src/vtls/schannel.c +++ b/libs/libcurl/src/vtls/schannel.c @@ -53,6 +53,7 @@ #include "curl_printf.h" #include "multiif.h" #include "version_win32.h" +#include "rand.h" /* The last #include file should be: */ #include "curl_memory.h" @@ -83,8 +84,35 @@ #endif #endif -#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) -#define HAS_CLIENT_CERT_PATH +#ifndef BCRYPT_CHACHA20_POLY1305_ALGORITHM +#define BCRYPT_CHACHA20_POLY1305_ALGORITHM L"CHACHA20_POLY1305" +#endif + +#ifndef BCRYPT_CHAIN_MODE_CCM +#define BCRYPT_CHAIN_MODE_CCM L"ChainingModeCCM" +#endif + +#ifndef BCRYPT_CHAIN_MODE_GCM +#define BCRYPT_CHAIN_MODE_GCM L"ChainingModeGCM" +#endif + +#ifndef BCRYPT_AES_ALGORITHM +#define BCRYPT_AES_ALGORITHM L"AES" +#endif + +#ifndef BCRYPT_SHA256_ALGORITHM +#define BCRYPT_SHA256_ALGORITHM L"SHA256" +#endif + +#ifndef BCRYPT_SHA384_ALGORITHM +#define BCRYPT_SHA384_ALGORITHM L"SHA384" +#endif + +/* Workaround broken compilers like MinGW. + Return the number of elements in a statically sized array. +*/ +#ifndef ARRAYSIZE +#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) #endif #ifdef HAS_CLIENT_CERT_PATH @@ -119,6 +147,10 @@ #define SP_PROT_TLS1_2_CLIENT 0x00000800 #endif +#ifndef SP_PROT_TLS1_3_CLIENT +#define SP_PROT_TLS1_3_CLIENT 0x00002000 +#endif + #ifndef SCH_USE_STRONG_CRYPTO #define SCH_USE_STRONG_CRYPTO 0x00400000 #endif @@ -149,6 +181,10 @@ #define ALG_CLASS_DHASH ALG_CLASS_HASH #endif +#ifndef PKCS12_NO_PERSIST_KEY +#define PKCS12_NO_PERSIST_KEY 0x00008000 +#endif + static Curl_recv schannel_recv; static Curl_send schannel_send; @@ -173,7 +209,7 @@ static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr, } static CURLcode -set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct Curl_easy *data, +set_ssl_version_min_max(DWORD *enabled_protocols, struct Curl_easy *data, struct connectdata *conn) { long ssl_version = SSL_CONN_CONFIG(version); @@ -183,23 +219,44 @@ set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct Curl_easy *data, switch(ssl_version_max) { case CURL_SSLVERSION_MAX_NONE: case CURL_SSLVERSION_MAX_DEFAULT: - ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + + /* Windows Server 2022 and newer (including Windows 11) support TLS 1.3 + built-in. Previous builds of Windows 10 had broken TLS 1.3 + implementations that could be enabled via registry. + */ + if(curlx_verify_windows_version(10, 0, 20348, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) { + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3; + } + else /* Windows 10 and older */ + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; + break; } + for(; i <= (ssl_version_max >> 16); ++i) { switch(i) { case CURL_SSLVERSION_TLSv1_0: - schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT; + (*enabled_protocols) |= SP_PROT_TLS1_0_CLIENT; break; case CURL_SSLVERSION_TLSv1_1: - schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT; + (*enabled_protocols) |= SP_PROT_TLS1_1_CLIENT; break; case CURL_SSLVERSION_TLSv1_2: - schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT; + (*enabled_protocols) |= SP_PROT_TLS1_2_CLIENT; break; case CURL_SSLVERSION_TLSv1_3: - failf(data, "schannel: TLS 1.3 is not yet supported"); - return CURLE_SSL_CONNECT_ERROR; + + /* Windows Server 2022 and newer */ + if(curlx_verify_windows_version(10, 0, 20348, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) { + (*enabled_protocols) |= SP_PROT_TLS1_3_CLIENT; + break; + } + else { /* Windows 10 and older */ + failf(data, "schannel: TLS 1.3 not supported on Windows prior to 11"); + return CURLE_SSL_CONNECT_ERROR; + } } } return CURLE_OK; @@ -216,8 +273,12 @@ get_alg_id_by_name(char *name) { char tmp[LONGEST_ALG_ID] = { 0 }; char *nameEnd = strchr(name, ':'); - size_t n = nameEnd ? min((size_t)(nameEnd - name), LONGEST_ALG_ID - 1) : \ - min(strlen(name), LONGEST_ALG_ID - 1); + size_t n = nameEnd ? (size_t)(nameEnd - name) : strlen(name); + + /* reject too-long alg names */ + if(n > (LONGEST_ALG_ID - 1)) + return 0; + strncpy(tmp, name, n); tmp[n] = 0; CIPHEROPTION(CALG_MD2); @@ -385,13 +446,13 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, else if(_tcsncmp(path, TEXT("Users"), store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_USERS; else if(_tcsncmp(path, TEXT("CurrentUserGroupPolicy"), - store_name_len) == 0) + store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY; else if(_tcsncmp(path, TEXT("LocalMachineGroupPolicy"), - store_name_len) == 0) + store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY; else if(_tcsncmp(path, TEXT("LocalMachineEnterprise"), - store_name_len) == 0) + store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE; else return CURLE_SSL_CERTPROBLEM; @@ -421,49 +482,52 @@ schannel_acquire_credential_handle(struct Curl_easy *data, int sockindex) { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - SCHANNEL_CRED schannel_cred; - ALG_ID algIds[NUM_CIPHERS]; + +#ifdef HAS_CLIENT_CERT_PATH PCCERT_CONTEXT client_certs[1] = { NULL }; + HCERTSTORE client_cert_store = NULL; +#endif SECURITY_STATUS sspi_status = SEC_E_OK; CURLcode result; + + /* setup Schannel API options */ + DWORD flags = 0; + DWORD enabled_protocols = 0; + struct ssl_backend_data *backend = connssl->backend; DEBUGASSERT(backend); - /* setup Schannel API options */ - memset(&schannel_cred, 0, sizeof(schannel_cred)); - schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; - if(conn->ssl_config.verifypeer) { #ifdef HAS_MANUAL_VERIFY_API if(backend->use_manual_cred_validation) - schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION; + flags = SCH_CRED_MANUAL_CRED_VALIDATION; else #endif - schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION; + flags = SCH_CRED_AUTO_CRED_VALIDATION; if(SSL_SET_OPTION(no_revoke)) { - schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | + flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE; DEBUGF(infof(data, "schannel: disabled server certificate revocation " "checks")); } else if(SSL_SET_OPTION(revoke_best_effort)) { - schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | + flags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN; DEBUGF(infof(data, "schannel: ignore revocation offline errors")); } else { - schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; + flags |= SCH_CRED_REVOCATION_CHECK_CHAIN; DEBUGF(infof(data, "schannel: checking server certificate revocation")); } } else { - schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | + flags = SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE; DEBUGF(infof(data, @@ -471,15 +535,15 @@ schannel_acquire_credential_handle(struct Curl_easy *data, } if(!conn->ssl_config.verifyhost) { - schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK; + flags |= SCH_CRED_NO_SERVERNAME_CHECK; DEBUGF(infof(data, "schannel: verifyhost setting prevents Schannel from " "comparing the supplied target name with the subject " "names in server certificates.")); } if(!SSL_SET_OPTION(auto_client_cert)) { - schannel_cred.dwFlags &= ~SCH_CRED_USE_DEFAULT_CREDS; - schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS; + flags &= ~SCH_CRED_USE_DEFAULT_CREDS; + flags |= SCH_CRED_NO_DEFAULT_CREDS; infof(data, "schannel: disabled automatic use of client certificate"); } else @@ -493,7 +557,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data, case CURL_SSLVERSION_TLSv1_2: case CURL_SSLVERSION_TLSv1_3: { - result = set_ssl_version_min_max(&schannel_cred, data, conn); + result = set_ssl_version_min_max(&enabled_protocols, data, conn); if(result != CURLE_OK) return result; break; @@ -507,16 +571,6 @@ schannel_acquire_credential_handle(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } - if(SSL_CONN_CONFIG(cipher_list)) { - result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list), - algIds); - if(CURLE_OK != result) { - failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG"); - return result; - } - } - - #ifdef HAS_CLIENT_CERT_PATH /* client certificate */ if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { @@ -542,7 +596,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; result = get_cert_location(cert_path, &cert_store_name, - &cert_store_path, &cert_thumbprint_str); + &cert_store_path, &cert_thumbprint_str); if(result && (data->set.ssl.primary.clientcert[0]!='\0')) fInCert = fopen(data->set.ssl.primary.clientcert, "rb"); @@ -557,18 +611,18 @@ schannel_acquire_credential_handle(struct Curl_easy *data, } if((fInCert || blob) && (data->set.ssl.cert_type) && - (!strcasecompare(data->set.ssl.cert_type, "P12"))) { + (!strcasecompare(data->set.ssl.cert_type, "P12"))) { failf(data, "schannel: certificate format compatibility error " - " for %s", - blob ? "(memory blob)" : data->set.ssl.primary.clientcert); + " for %s", + blob ? "(memory blob)" : data->set.ssl.primary.clientcert); curlx_unicodefree(cert_path); return CURLE_SSL_CERTPROBLEM; } if(fInCert || blob) { /* Reading a .P12 or .pfx file, like the example at bottom of - https://social.msdn.microsoft.com/Forums/windowsdesktop/ - en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5 + https://social.msdn.microsoft.com/Forums/windowsdesktop/ + en-US/3e7bc95f-b21a-4bcd-bd2c-7f996718cae5 */ CRYPT_DATA_BLOB datablob; WCHAR* pszPassword; @@ -596,7 +650,7 @@ schannel_acquire_credential_handle(struct Curl_easy *data, fclose(fInCert); if(!continue_reading) { failf(data, "schannel: Failed to read cert file %s", - data->set.ssl.primary.clientcert); + data->set.ssl.primary.clientcert); free(certdata); return CURLE_SSL_CERTPROBLEM; } @@ -612,16 +666,23 @@ schannel_acquire_credential_handle(struct Curl_easy *data, if(pszPassword) { if(pwd_len > 0) str_w_len = MultiByteToWideChar(CP_UTF8, - MB_ERR_INVALID_CHARS, - data->set.ssl.key_passwd, (int)pwd_len, - pszPassword, (int)(pwd_len + 1)); + MB_ERR_INVALID_CHARS, + data->set.ssl.key_passwd, + (int)pwd_len, + pszPassword, (int)(pwd_len + 1)); if((str_w_len >= 0) && (str_w_len <= (int)pwd_len)) pszPassword[str_w_len] = 0; else pszPassword[0] = 0; - cert_store = PFXImportCertStore(&datablob, pszPassword, 0); + if(curlx_verify_windows_version(6, 0, 0, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) + cert_store = PFXImportCertStore(&datablob, pszPassword, + PKCS12_NO_PERSIST_KEY); + else + cert_store = PFXImportCertStore(&datablob, pszPassword, 0); + free(pszPassword); } if(!blob) @@ -650,9 +711,6 @@ schannel_acquire_credential_handle(struct Curl_easy *data, CertCloseStore(cert_store, 0); return CURLE_SSL_CERTPROBLEM; } - - schannel_cred.cCreds = 1; - schannel_cred.paCred = client_certs; } else { cert_store = @@ -690,17 +748,13 @@ schannel_acquire_credential_handle(struct Curl_easy *data, curlx_unicodefree(cert_path); - if(client_certs[0]) { - schannel_cred.cCreds = 1; - schannel_cred.paCred = client_certs; - } - else { + if(!client_certs[0]) { /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ CertCloseStore(cert_store, 0); return CURLE_SSL_CERTPROBLEM; } } - CertCloseStore(cert_store, 0); + client_cert_store = cert_store; } #else if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { @@ -715,22 +769,279 @@ schannel_acquire_credential_handle(struct Curl_easy *data, if(!backend->cred) { failf(data, "schannel: unable to allocate memory"); +#ifdef HAS_CLIENT_CERT_PATH if(client_certs[0]) CertFreeCertificateContext(client_certs[0]); + if(client_cert_store) + CertCloseStore(client_cert_store, 0); +#endif return CURLE_OUT_OF_MEMORY; } backend->cred->refcount = 1; - sspi_status = - s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME, - SECPKG_CRED_OUTBOUND, NULL, - &schannel_cred, NULL, NULL, - &backend->cred->cred_handle, - &backend->cred->time_stamp); +#ifdef HAS_CLIENT_CERT_PATH + /* Since we did not persist the key, we need to extend the store's + * lifetime until the end of the connection + */ + backend->cred->client_cert_store = client_cert_store; +#endif + + /* Windows 10, 1809 (a.k.a. Windows 10 build 17763) */ + if(curlx_verify_windows_version(10, 0, 17763, PLATFORM_WINNT, + VERSION_GREATER_THAN_EQUAL)) { + + char *ciphers13 = 0; + + bool disable_aes_gcm_sha384 = FALSE; + bool disable_aes_gcm_sha256 = FALSE; + bool disable_chacha_poly = FALSE; + bool disable_aes_ccm_8_sha256 = FALSE; + bool disable_aes_ccm_sha256 = FALSE; + + SCH_CREDENTIALS credentials = { 0 }; + TLS_PARAMETERS tls_parameters = { 0 }; + CRYPTO_SETTINGS crypto_settings[4] = { 0 }; + UNICODE_STRING blocked_ccm_modes[1] = { 0 }; + UNICODE_STRING blocked_gcm_modes[1] = { 0 }; + + int crypto_settings_idx = 0; + + + /* If TLS 1.3 ciphers are explicitly listed, then + * disable all the ciphers and re-enable which + * ciphers the user has provided. + */ + ciphers13 = SSL_CONN_CONFIG(cipher_list13); + if(ciphers13) { + const int remaining_ciphers = 5; + + /* detect which remaining ciphers to enable + and then disable everything else. + */ + + char *startCur = ciphers13; + int algCount = 0; + char tmp[LONGEST_ALG_ID] = { 0 }; + char *nameEnd; + size_t n; + + disable_aes_gcm_sha384 = TRUE; + disable_aes_gcm_sha256 = TRUE; + disable_chacha_poly = TRUE; + disable_aes_ccm_8_sha256 = TRUE; + disable_aes_ccm_sha256 = TRUE; + + while(startCur && (0 != *startCur) && (algCount < remaining_ciphers)) { + nameEnd = strchr(startCur, ':'); + n = nameEnd ? (size_t)(nameEnd - startCur) : strlen(startCur); + + /* reject too-long cipher names */ + if(n > (LONGEST_ALG_ID - 1)) { + failf(data, "Cipher name too long, not checked."); + return CURLE_SSL_CIPHER; + } + + strncpy(tmp, startCur, n); + tmp[n] = 0; + + if(disable_aes_gcm_sha384 + && !strcmp("TLS_AES_256_GCM_SHA384", tmp)) { + disable_aes_gcm_sha384 = FALSE; + } + else if(disable_aes_gcm_sha256 + && !strcmp("TLS_AES_128_GCM_SHA256", tmp)) { + disable_aes_gcm_sha256 = FALSE; + } + else if(disable_chacha_poly + && !strcmp("TLS_CHACHA20_POLY1305_SHA256", tmp)) { + disable_chacha_poly = FALSE; + } + else if(disable_aes_ccm_8_sha256 + && !strcmp("TLS_AES_128_CCM_8_SHA256", tmp)) { + disable_aes_ccm_8_sha256 = FALSE; + } + else if(disable_aes_ccm_sha256 + && !strcmp("TLS_AES_128_CCM_SHA256", tmp)) { + disable_aes_ccm_sha256 = FALSE; + } + else { + failf(data, "Passed in an unknown TLS 1.3 cipher."); + return CURLE_SSL_CIPHER; + } + + startCur = nameEnd; + if(startCur) + startCur++; + + algCount++; + } + } + + if(disable_aes_gcm_sha384 && disable_aes_gcm_sha256 + && disable_chacha_poly && disable_aes_ccm_8_sha256 + && disable_aes_ccm_sha256) { + failf(data, "All available TLS 1.3 ciphers were disabled."); + return CURLE_SSL_CIPHER; + } + + /* Disable TLS_AES_128_CCM_8_SHA256 and/or TLS_AES_128_CCM_SHA256 */ + if(disable_aes_ccm_8_sha256 || disable_aes_ccm_sha256) { + /* + Disallow AES_CCM algorithm. + */ + blocked_ccm_modes[0].Length = sizeof(BCRYPT_CHAIN_MODE_CCM); + blocked_ccm_modes[0].MaximumLength = sizeof(BCRYPT_CHAIN_MODE_CCM); + blocked_ccm_modes[0].Buffer = (PWSTR)BCRYPT_CHAIN_MODE_CCM; + + crypto_settings[crypto_settings_idx].eAlgorithmUsage = + TlsParametersCngAlgUsageCipher; + crypto_settings[crypto_settings_idx].rgstrChainingModes = + blocked_ccm_modes; + crypto_settings[crypto_settings_idx].cChainingModes = + ARRAYSIZE(blocked_ccm_modes); + crypto_settings[crypto_settings_idx].strCngAlgId.Length = + sizeof(BCRYPT_AES_ALGORITHM); + crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength = + sizeof(BCRYPT_AES_ALGORITHM); + crypto_settings[crypto_settings_idx].strCngAlgId.Buffer = + (PWSTR)BCRYPT_AES_ALGORITHM; + + /* only disabling one of the CCM modes */ + if(disable_aes_ccm_8_sha256 != disable_aes_ccm_sha256) { + if(disable_aes_ccm_8_sha256) + crypto_settings[crypto_settings_idx].dwMinBitLength = 128; + else /* disable_aes_ccm_sha256 */ + crypto_settings[crypto_settings_idx].dwMaxBitLength = 64; + } + + crypto_settings_idx++; + } + /* Disable TLS_AES_256_GCM_SHA384 and/or TLS_AES_128_GCM_SHA256 */ + if(disable_aes_gcm_sha384 || disable_aes_gcm_sha256) { + + /* + Disallow AES_GCM algorithm + */ + blocked_gcm_modes[0].Length = sizeof(BCRYPT_CHAIN_MODE_GCM); + blocked_gcm_modes[0].MaximumLength = sizeof(BCRYPT_CHAIN_MODE_GCM); + blocked_gcm_modes[0].Buffer = (PWSTR)BCRYPT_CHAIN_MODE_GCM; + + /* if only one is disabled, then explicitly disable the + digest cipher suite (sha384 or sha256) */ + if(disable_aes_gcm_sha384 != disable_aes_gcm_sha256) { + crypto_settings[crypto_settings_idx].eAlgorithmUsage = + TlsParametersCngAlgUsageDigest; + crypto_settings[crypto_settings_idx].strCngAlgId.Length = + sizeof(disable_aes_gcm_sha384 ? + BCRYPT_SHA384_ALGORITHM : BCRYPT_SHA256_ALGORITHM); + crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength = + sizeof(disable_aes_gcm_sha384 ? + BCRYPT_SHA384_ALGORITHM : BCRYPT_SHA256_ALGORITHM); + crypto_settings[crypto_settings_idx].strCngAlgId.Buffer = + (PWSTR)(disable_aes_gcm_sha384 ? + BCRYPT_SHA384_ALGORITHM : BCRYPT_SHA256_ALGORITHM); + } + else { /* Disable both AES_GCM ciphers */ + crypto_settings[crypto_settings_idx].eAlgorithmUsage = + TlsParametersCngAlgUsageCipher; + crypto_settings[crypto_settings_idx].strCngAlgId.Length = + sizeof(BCRYPT_AES_ALGORITHM); + crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength = + sizeof(BCRYPT_AES_ALGORITHM); + crypto_settings[crypto_settings_idx].strCngAlgId.Buffer = + (PWSTR)BCRYPT_AES_ALGORITHM; + } + + crypto_settings[crypto_settings_idx].rgstrChainingModes = + blocked_gcm_modes; + crypto_settings[crypto_settings_idx].cChainingModes = 1; + + crypto_settings_idx++; + } + + /* + Disable ChaCha20-Poly1305. + */ + if(disable_chacha_poly) { + crypto_settings[crypto_settings_idx].eAlgorithmUsage = + TlsParametersCngAlgUsageCipher; + crypto_settings[crypto_settings_idx].strCngAlgId.Length = + sizeof(BCRYPT_CHACHA20_POLY1305_ALGORITHM); + crypto_settings[crypto_settings_idx].strCngAlgId.MaximumLength = + sizeof(BCRYPT_CHACHA20_POLY1305_ALGORITHM); + crypto_settings[crypto_settings_idx].strCngAlgId.Buffer = + (PWSTR)BCRYPT_CHACHA20_POLY1305_ALGORITHM; + crypto_settings_idx++; + } + + tls_parameters.pDisabledCrypto = crypto_settings; + + /* The number of blocked suites */ + tls_parameters.cDisabledCrypto = crypto_settings_idx; + credentials.pTlsParameters = &tls_parameters; + credentials.cTlsParameters = 1; + + credentials.dwVersion = SCH_CREDENTIALS_VERSION; + credentials.dwFlags = flags | SCH_USE_STRONG_CRYPTO; + + credentials.pTlsParameters->grbitDisabledProtocols = + (DWORD)~enabled_protocols; + +#ifdef HAS_CLIENT_CERT_PATH + if(client_certs[0]) { + credentials.cCreds = 1; + credentials.paCred = client_certs; + } +#endif + + sspi_status = + s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME, + SECPKG_CRED_OUTBOUND, NULL, + &credentials, NULL, NULL, + &backend->cred->cred_handle, + &backend->cred->time_stamp); + } + else { + /* Pre-Windows 10 1809 */ + ALG_ID algIds[NUM_CIPHERS]; + char *ciphers = SSL_CONN_CONFIG(cipher_list); + SCHANNEL_CRED schannel_cred = { 0 }; + schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; + schannel_cred.dwFlags = flags; + schannel_cred.grbitEnabledProtocols = enabled_protocols; + + if(ciphers) { + result = set_ssl_ciphers(&schannel_cred, ciphers, algIds); + if(CURLE_OK != result) { + failf(data, "Unable to set ciphers to passed via SSL_CONN_CONFIG"); + return result; + } + } + else { + schannel_cred.dwFlags = flags | SCH_USE_STRONG_CRYPTO; + } + +#ifdef HAS_CLIENT_CERT_PATH + if(client_certs[0]) { + schannel_cred.cCreds = 1; + schannel_cred.paCred = client_certs; + } +#endif + + sspi_status = + s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR*)UNISP_NAME, + SECPKG_CRED_OUTBOUND, NULL, + &schannel_cred, NULL, NULL, + &backend->cred->cred_handle, + &backend->cred->time_stamp); + } + +#ifdef HAS_CLIENT_CERT_PATH if(client_certs[0]) CertFreeCertificateContext(client_certs[0]); +#endif if(sspi_status != SEC_E_OK) { char buffer[STRERROR_LEN]; @@ -1018,6 +1329,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, backend->recv_unrecoverable_err = CURLE_OK; backend->recv_sspi_close_notify = false; backend->recv_connection_closed = false; + backend->recv_renegotiating = false; backend->encdata_is_incomplete = false; /* continue to second handshake step */ @@ -1417,6 +1729,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, if(alpn_result.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success) { + unsigned char alpn = 0; infof(data, VTLS_INFOF_ALPN_ACCEPTED_LEN_1STR, alpn_result.ProtocolIdSize, alpn_result.ProtocolId); @@ -1424,20 +1737,33 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, #ifdef USE_HTTP2 if(alpn_result.ProtocolIdSize == ALPN_H2_LENGTH && !memcmp(ALPN_H2, alpn_result.ProtocolId, ALPN_H2_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_2; + alpn = CURL_HTTP_VERSION_2; } else #endif if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH && !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; + alpn = CURL_HTTP_VERSION_1_1; } + if(backend->recv_renegotiating) { + if(alpn != conn->alpn) { + failf(data, "schannel: server selected an ALPN protocol too late"); + return CURLE_SSL_CONNECT_ERROR; + } + } + else + conn->alpn = alpn; + } + else { + if(!backend->recv_renegotiating) + infof(data, VTLS_INFOF_NO_ALPN); + } + + if(!backend->recv_renegotiating) { + Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? + BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } - else - infof(data, VTLS_INFOF_NO_ALPN); - Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? - BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } #endif @@ -1609,8 +1935,15 @@ schannel_connect_common(struct Curl_easy *data, struct connectdata *conn, if(ssl_connect_done == connssl->connecting_state) { connssl->state = ssl_connection_complete; - conn->recv[sockindex] = schannel_recv; - conn->send[sockindex] = schannel_send; + if(!connssl->backend->recv_renegotiating) { + /* On renegotiation, we don't want to reset the existing recv/send + * function pointers. They will have been set after the initial TLS + * handshake was completed. If they were subsequently modified, as + * is the case with HTTP/2, we don't want to override that change. + */ + conn->recv[sockindex] = schannel_recv; + conn->send[sockindex] = schannel_send; + } #ifdef SECPKG_ATTR_ENDPOINT_BINDINGS /* When SSPI is used in combination with Schannel @@ -1992,17 +2325,14 @@ schannel_recv(struct Curl_easy *data, int sockindex, infof(data, "schannel: can't renegotiate, an error is pending"); goto cleanup; } - if(backend->encdata_offset) { - *err = CURLE_RECV_ERROR; - infof(data, "schannel: can't renegotiate, " - "encrypted data available"); - goto cleanup; - } + /* begin renegotiation */ infof(data, "schannel: renegotiating SSL/TLS connection"); connssl->state = ssl_connection_negotiating; connssl->connecting_state = ssl_connect_2_writing; + backend->recv_renegotiating = true; *err = schannel_connect_common(data, conn, sockindex, FALSE, &done); + backend->recv_renegotiating = false; if(*err) { infof(data, "schannel: renegotiation failed"); goto cleanup; @@ -2156,6 +2486,12 @@ static void schannel_session_free(void *ptr) if(cred->refcount == 0) { s_pSecFn->FreeCredentialsHandle(&cred->cred_handle); curlx_unicodefree(cred->sni_hostname); +#ifdef HAS_CLIENT_CERT_PATH + if(cred->client_cert_store) { + CertCloseStore(cred->client_cert_store, 0); + cred->client_cert_store = NULL; + } +#endif Curl_safefree(cred); } } @@ -2298,21 +2634,9 @@ static size_t schannel_version(char *buffer, size_t size) static CURLcode schannel_random(struct Curl_easy *data UNUSED_PARAM, unsigned char *entropy, size_t length) { - HCRYPTPROV hCryptProv = 0; - (void)data; - if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - return CURLE_FAILED_INIT; - - if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) { - CryptReleaseContext(hCryptProv, 0UL); - return CURLE_FAILED_INIT; - } - - CryptReleaseContext(hCryptProv, 0UL); - return CURLE_OK; + return Curl_win32_random(entropy, length); } static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, @@ -2459,7 +2783,8 @@ const struct Curl_ssl Curl_ssl_schannel = { #ifdef HAS_MANUAL_VERIFY_API SSLSUPP_CAINFO_BLOB | #endif - SSLSUPP_PINNEDPUBKEY, + SSLSUPP_PINNEDPUBKEY | + SSLSUPP_TLS13_CIPHERSUITES, sizeof(struct ssl_backend_data), diff --git a/libs/libcurl/src/vtls/schannel.h b/libs/libcurl/src/vtls/schannel.h index 0b4c4d9344..24d7eff25b 100644 --- a/libs/libcurl/src/vtls/schannel.h +++ b/libs/libcurl/src/vtls/schannel.h @@ -28,6 +28,28 @@ #ifdef USE_SCHANNEL +#define SCHANNEL_USE_BLACKLISTS 1 + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4201) +#endif +#include <subauth.h> +#ifdef _MSC_VER +#pragma warning(pop) +#endif +/* Wincrypt must be included before anything that could include OpenSSL. */ +#if defined(USE_WIN32_CRYPTO) +#include <wincrypt.h> +/* Undefine wincrypt conflicting symbols for BoringSSL. */ +#undef X509_NAME +#undef X509_EXTENSIONS +#undef PKCS7_ISSUER_AND_SERIAL +#undef PKCS7_SIGNER_INFO +#undef OCSP_REQUEST +#undef OCSP_RESPONSE +#endif + #include <schnlsp.h> #include <schannel.h> #include "curl_sspi.h" @@ -61,21 +83,87 @@ CURLcode Curl_verify_certificate(struct Curl_easy *data, /* structs to expose only in schannel.c and schannel_verify.c */ #ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS +#include <wincrypt.h> + #ifdef __MINGW32__ #ifdef __MINGW64_VERSION_MAJOR #define HAS_MANUAL_VERIFY_API #endif #else -#include <wincrypt.h> #ifdef CERT_CHAIN_REVOCATION_CHECK_CHAIN #define HAS_MANUAL_VERIFY_API #endif #endif +#if defined(CryptStringToBinary) && defined(CRYPT_STRING_HEX) \ + && !defined(DISABLE_SCHANNEL_CLIENT_CERT) +#define HAS_CLIENT_CERT_PATH +#endif + +#ifndef SCH_CREDENTIALS_VERSION + +#define SCH_CREDENTIALS_VERSION 0x00000005 + +typedef enum _eTlsAlgorithmUsage +{ + TlsParametersCngAlgUsageKeyExchange, + TlsParametersCngAlgUsageSignature, + TlsParametersCngAlgUsageCipher, + TlsParametersCngAlgUsageDigest, + TlsParametersCngAlgUsageCertSig +} eTlsAlgorithmUsage; + +typedef struct _CRYPTO_SETTINGS +{ + eTlsAlgorithmUsage eAlgorithmUsage; + UNICODE_STRING strCngAlgId; + DWORD cChainingModes; + PUNICODE_STRING rgstrChainingModes; + DWORD dwMinBitLength; + DWORD dwMaxBitLength; +} CRYPTO_SETTINGS, * PCRYPTO_SETTINGS; + +typedef struct _TLS_PARAMETERS +{ + DWORD cAlpnIds; + PUNICODE_STRING rgstrAlpnIds; + DWORD grbitDisabledProtocols; + DWORD cDisabledCrypto; + PCRYPTO_SETTINGS pDisabledCrypto; + DWORD dwFlags; +} TLS_PARAMETERS, * PTLS_PARAMETERS; + +typedef struct _SCH_CREDENTIALS +{ + DWORD dwVersion; + DWORD dwCredFormat; + DWORD cCreds; + PCCERT_CONTEXT* paCred; + HCERTSTORE hRootStore; + + DWORD cMappers; + struct _HMAPPER **aphMappers; + + DWORD dwSessionLifespan; + DWORD dwFlags; + DWORD cTlsParameters; + PTLS_PARAMETERS pTlsParameters; +} SCH_CREDENTIALS, * PSCH_CREDENTIALS; + +#define SCH_CRED_MAX_SUPPORTED_PARAMETERS 16 +#define SCH_CRED_MAX_SUPPORTED_ALPN_IDS 16 +#define SCH_CRED_MAX_SUPPORTED_CRYPTO_SETTINGS 16 +#define SCH_CRED_MAX_SUPPORTED_CHAINING_MODES 16 + +#endif + struct Curl_schannel_cred { CredHandle cred_handle; TimeStamp time_stamp; TCHAR *sni_hostname; +#ifdef HAS_CLIENT_CERT_PATH + HCERTSTORE client_cert_store; +#endif int refcount; }; @@ -100,6 +188,7 @@ struct ssl_backend_data { CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */ bool recv_sspi_close_notify; /* true if connection closed by close_notify */ bool recv_connection_closed; /* true if connection closed, regardless how */ + bool recv_renegotiating; /* true if recv is doing renegotiation */ bool use_alpn; /* true if ALPN is used for this connection */ #ifdef HAS_MANUAL_VERIFY_API bool use_manual_cred_validation; /* true if manual cred validation is used */ diff --git a/libs/libcurl/src/vtls/sectransp.c b/libs/libcurl/src/vtls/sectransp.c index a18ca4ee9d..c764e3631b 100644 --- a/libs/libcurl/src/vtls/sectransp.c +++ b/libs/libcurl/src/vtls/sectransp.c @@ -2847,18 +2847,18 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, #ifdef USE_HTTP2 if(chosenProtocol && !CFStringCompare(chosenProtocol, CFSTR(ALPN_H2), 0)) { - conn->negnpn = CURL_HTTP_VERSION_2; + conn->alpn = CURL_HTTP_VERSION_2; } else #endif if(chosenProtocol && !CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; + conn->alpn = CURL_HTTP_VERSION_1_1; } else infof(data, VTLS_INFOF_NO_ALPN); - Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); /* chosenProtocol is a reference to the string within alpnArr diff --git a/libs/libcurl/src/vtls/vtls.c b/libs/libcurl/src/vtls/vtls.c index faa1b51417..9dee5aa3b3 100644 --- a/libs/libcurl/src/vtls/vtls.c +++ b/libs/libcurl/src/vtls/vtls.c @@ -146,8 +146,8 @@ Curl_ssl_config_matches(struct ssl_primary_config *data, Curl_safecmp(data->issuercert, needle->issuercert) && Curl_safecmp(data->clientcert, needle->clientcert) && #ifdef USE_TLS_SRP - Curl_safecmp(data->username, needle->username) && - Curl_safecmp(data->password, needle->password) && + !Curl_timestrcmp(data->username, needle->username) && + !Curl_timestrcmp(data->password, needle->password) && (data->authtype == needle->authtype) && #endif Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && @@ -219,13 +219,13 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) static int multissl_setup(const struct Curl_ssl *backend); #endif -int Curl_ssl_backend(void) +curl_sslbackend Curl_ssl_backend(void) { #ifdef USE_SSL multissl_setup(NULL); return Curl_ssl->info.id; #else - return (int)CURLSSLBACKEND_NONE; + return CURLSSLBACKEND_NONE; #endif } @@ -899,7 +899,7 @@ char *Curl_ssl_snihost(struct Curl_easy *data, const char *host, size_t *olen) size_t len = strlen(host); if(len && (host[len-1] == '.')) len--; - if((long)len >= data->set.buffer_size) + if(len >= data->set.buffer_size) return NULL; Curl_strntolower(data->state.buffer, host, len); diff --git a/libs/libcurl/src/vtls/vtls.h b/libs/libcurl/src/vtls/vtls.h index e1e58f4215..50c53b3fbd 100644 --- a/libs/libcurl/src/vtls/vtls.h +++ b/libs/libcurl/src/vtls/vtls.h @@ -200,7 +200,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc); ssl_connect_2_writing. */ int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks); -int Curl_ssl_backend(void); +curl_sslbackend Curl_ssl_backend(void); #ifdef USE_SSL int Curl_ssl_init(void); diff --git a/libs/libcurl/src/vtls/wolfssl.c b/libs/libcurl/src/vtls/wolfssl.c index 50cdb4abf0..594c39a324 100644 --- a/libs/libcurl/src/vtls/wolfssl.c +++ b/libs/libcurl/src/vtls/wolfssl.c @@ -763,17 +763,17 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, if(protocol_len == ALPN_HTTP_1_1_LENGTH && !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) - conn->negnpn = CURL_HTTP_VERSION_1_1; + conn->alpn = CURL_HTTP_VERSION_1_1; #ifdef USE_HTTP2 else if(data->state.httpwant >= CURL_HTTP_VERSION_2 && protocol_len == ALPN_H2_LENGTH && !memcmp(protocol, ALPN_H2, ALPN_H2_LENGTH)) - conn->negnpn = CURL_HTTP_VERSION_2; + conn->alpn = CURL_HTTP_VERSION_2; #endif else infof(data, "ALPN, unrecognized protocol %.*s", protocol_len, protocol); - Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? + Curl_multiuse_state(data, conn->alpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } else if(rc == SSL_ALPN_NOT_FOUND) @@ -811,8 +811,10 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn, if(SSL_SET_OPTION(primary.sessionid)) { bool incache; + bool added = FALSE; void *old_ssl_sessionid = NULL; - SSL_SESSION *our_ssl_sessionid = SSL_get_session(backend->handle); + /* SSL_get1_session allocates memory that has to be freed. */ + SSL_SESSION *our_ssl_sessionid = SSL_get1_session(backend->handle); bool isproxy = SSL_IS_PROXY() ? TRUE : FALSE; if(our_ssl_sessionid) { @@ -832,11 +834,20 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn, 0, sockindex, NULL); if(result) { Curl_ssl_sessionid_unlock(data); + SSL_SESSION_free(our_ssl_sessionid); failf(data, "failed to store ssl session"); return result; } + else { + added = TRUE; + } } Curl_ssl_sessionid_unlock(data); + + if(!added) { + /* If the session info wasn't added to the cache, free our copy. */ + SSL_SESSION_free(our_ssl_sessionid); + } } } @@ -956,8 +967,7 @@ static ssize_t wolfssl_recv(struct Curl_easy *data, static void wolfssl_session_free(void *ptr) { - (void)ptr; - /* wolfSSL reuses sessions on own, no free */ + SSL_SESSION_free(ptr); } diff --git a/libs/libcurl/src/vtls/x509asn1.c b/libs/libcurl/src/vtls/x509asn1.c index d5661b0976..0cfcbe87da 100644 --- a/libs/libcurl/src/vtls/x509asn1.c +++ b/libs/libcurl/src/vtls/x509asn1.c @@ -45,6 +45,7 @@ #include <curl/curl.h> #include "urldata.h" #include "strcase.h" +#include "curl_ctype.h" #include "hostcheck.h" #include "vtls/vtls.h" #include "sendf.h" @@ -716,7 +717,7 @@ static ssize_t encodeDN(char *buf, size_t buflen, struct Curl_asn1Element *dn) /* Encode delimiter. If attribute has a short uppercase name, delimiter is ", ". */ if(l) { - for(p3 = str; isupper(*p3); p3++) + for(p3 = str; ISUPPER(*p3); p3++) ; for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) { if(l < buflen) diff --git a/libs/libcurl/src/warnless.c b/libs/libcurl/src/warnless.c index 51187aa52e..b00d7a5a26 100644 --- a/libs/libcurl/src/warnless.c +++ b/libs/libcurl/src/warnless.c @@ -39,6 +39,8 @@ #include "warnless.h" +#include <limits.h> + #define CURL_MASK_UCHAR ((unsigned char)~0) #define CURL_MASK_SCHAR (CURL_MASK_UCHAR >> 1) diff --git a/libs/libcurl/src/wildcard.h b/libs/libcurl/src/wildcard.h index f9d2167bf2..21e933b9a4 100644 --- a/libs/libcurl/src/wildcard.h +++ b/libs/libcurl/src/wildcard.h @@ -27,6 +27,7 @@ #include "curl_setup.h" #ifndef CURL_DISABLE_FTP +#include <curl/curl.h> #include "llist.h" /* list of wildcard process states */ diff --git a/libs/libcurl/src/ws.c b/libs/libcurl/src/ws.c new file mode 100644 index 0000000000..a673446625 --- /dev/null +++ b/libs/libcurl/src/ws.c @@ -0,0 +1,757 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "curl_setup.h" +#include <curl/curl.h> + +#ifdef USE_WEBSOCKETS + +#include "urldata.h" +#include "dynbuf.h" +#include "rand.h" +#include "curl_base64.h" +#include "sendf.h" +#include "multiif.h" +#include "ws.h" +#include "easyif.h" +#include "transfer.h" +#include "nonblock.h" + +/* The last 3 #include files should be in this order */ +#include "curl_printf.h" +#include "curl_memory.h" +#include "memdebug.h" + +struct wsfield { + const char *name; + const char *val; +}; + +CURLcode Curl_ws_request(struct Curl_easy *data, REQTYPE *req) +{ + unsigned int i; + CURLcode result = CURLE_OK; + unsigned char rand[16]; + char *randstr; + size_t randlen; + char keyval[40]; + struct SingleRequest *k = &data->req; + struct wsfield heads[]= { + { + /* The request MUST contain an |Upgrade| header field whose value + MUST include the "websocket" keyword. */ + "Upgrade:", "websocket" + }, + { + /* The request MUST contain a |Connection| header field whose value + MUST include the "Upgrade" token. */ + "Connection:", "Upgrade", + }, + { + /* The request MUST include a header field with the name + |Sec-WebSocket-Version|. The value of this header field MUST be + 13. */ + "Sec-WebSocket-Version:", "13", + }, + { + /* The request MUST include a header field with the name + |Sec-WebSocket-Key|. The value of this header field MUST be a nonce + consisting of a randomly selected 16-byte value that has been + base64-encoded (see Section 4 of [RFC4648]). The nonce MUST be + selected randomly for each connection. */ + "Sec-WebSocket-Key:", NULL, + } + }; + heads[3].val = &keyval[0]; + + /* 16 bytes random */ + result = Curl_rand(data, (unsigned char *)rand, sizeof(rand)); + if(result) + return result; + result = Curl_base64_encode((char *)rand, sizeof(rand), &randstr, &randlen); + if(result) + return result; + DEBUGASSERT(randlen < sizeof(keyval)); + if(randlen >= sizeof(keyval)) + return CURLE_FAILED_INIT; + strcpy(keyval, randstr); + free(randstr); + for(i = 0; !result && (i < sizeof(heads)/sizeof(heads[0])); i++) { + if(!Curl_checkheaders(data, STRCONST(heads[i].name))) { +#ifdef USE_HYPER + char field[128]; + msnprintf(field, sizeof(field), "%s %s", heads[i].name, + heads[i].val); + result = Curl_hyper_header(data, req, field); +#else + (void)data; + result = Curl_dyn_addf(req, "%s %s\r\n", heads[i].name, + heads[i].val); +#endif + } + } + k->upgr101 = UPGR101_WS; + Curl_dyn_init(&data->req.p.http->ws.buf, MAX_WS_SIZE * 2); + return result; +} + +CURLcode Curl_ws_accept(struct Curl_easy *data) +{ + struct SingleRequest *k = &data->req; + struct HTTP *ws = data->req.p.http; + struct connectdata *conn = data->conn; + struct websocket *wsp = &data->req.p.http->ws; + CURLcode result; + + /* Verify the Sec-WebSocket-Accept response. + + The sent value is the base64 encoded version of a SHA-1 hash done on the + |Sec-WebSocket-Key| header field concatenated with + the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11". + */ + + /* If the response includes a |Sec-WebSocket-Extensions| header field and + this header field indicates the use of an extension that was not present + in the client's handshake (the server has indicated an extension not + requested by the client), the client MUST Fail the WebSocket Connection. + */ + + /* If the response includes a |Sec-WebSocket-Protocol| header field + and this header field indicates the use of a subprotocol that was + not present in the client's handshake (the server has indicated a + subprotocol not requested by the client), the client MUST Fail + the WebSocket Connection. */ + + /* 4 bytes random */ + result = Curl_rand(data, (unsigned char *)&ws->ws.mask, sizeof(ws->ws.mask)); + if(result) + return result; + + infof(data, "Received 101, switch to WebSocket; mask %02x%02x%02x%02x", + ws->ws.mask[0], ws->ws.mask[1], ws->ws.mask[2], ws->ws.mask[3]); + k->upgr101 = UPGR101_RECEIVED; + + if(data->set.connect_only) + /* switch off non-blocking sockets */ + (void)curlx_nonblock(conn->sock[FIRSTSOCKET], FALSE); + + wsp->oleft = 0; + return result; +} + +#define WSBIT_FIN 0x80 +#define WSBIT_OPCODE_CONT 0 +#define WSBIT_OPCODE_TEXT (1) +#define WSBIT_OPCODE_BIN (2) +#define WSBIT_OPCODE_CLOSE (8) +#define WSBIT_OPCODE_PING (9) +#define WSBIT_OPCODE_PONG (0xa) +#define WSBIT_OPCODE_MASK (0xf) + +#define WSBIT_MASK 0x80 + +/* remove the spent bytes from the beginning of the buffer as that part has + now been delivered to the application */ +static void ws_decode_clear(struct Curl_easy *data) +{ + struct websocket *wsp = &data->req.p.http->ws; + size_t spent = wsp->usedbuf; + size_t len = Curl_dyn_len(&wsp->buf); + size_t keep = len - spent; + DEBUGASSERT(len >= spent); + Curl_dyn_tail(&wsp->buf, keep); +} + +/* ws_decode() decodes a binary frame into structured WebSocket data, + + wpkt - the incoming raw data. If NULL, work on the already buffered data. + ilen - the size of the provided data, perhaps too little, perhaps too much + out - stored pointed to extracted data + olen - stored length of the extracted data + oleft - number of unread bytes pending to that belongs to this frame + more - if there is more data in there + flags - stored bitmask about the frame + + Returns CURLE_AGAIN if there is only a partial frame in the buffer. Then it + stores the first part in the ->extra buffer to be used in the next call + when more data is provided. +*/ + +static CURLcode ws_decode(struct Curl_easy *data, + unsigned char *wpkt, size_t ilen, + unsigned char **out, size_t *olen, + curl_off_t *oleft, + bool *more, + unsigned int *flags) +{ + bool fin; + unsigned char opcode; + curl_off_t total; + size_t dataindex = 2; + curl_off_t plen; /* size of data in the buffer */ + curl_off_t payloadsize; + struct websocket *wsp = &data->req.p.http->ws; + unsigned char *p; + CURLcode result; + + *olen = 0; + + /* add the incoming bytes, if any */ + if(wpkt) { + result = Curl_dyn_addn(&wsp->buf, wpkt, ilen); + if(result) + return result; + } + + plen = Curl_dyn_len(&wsp->buf); + if(plen < 2) { + /* the smallest possible frame is two bytes */ + infof(data, "WS: plen == %u, EAGAIN", (int)plen); + return CURLE_AGAIN; + } + + p = Curl_dyn_uptr(&wsp->buf); + + fin = p[0] & WSBIT_FIN; + opcode = p[0] & WSBIT_OPCODE_MASK; + infof(data, "WS:%d received FIN bit %u", __LINE__, (int)fin); + *flags = 0; + switch(opcode) { + case WSBIT_OPCODE_CONT: + if(!fin) + *flags |= CURLWS_CONT; + infof(data, "WS: received OPCODE CONT"); + break; + case WSBIT_OPCODE_TEXT: + infof(data, "WS: received OPCODE TEXT"); + *flags |= CURLWS_TEXT; + break; + case WSBIT_OPCODE_BIN: + infof(data, "WS: received OPCODE BINARY"); + *flags |= CURLWS_BINARY; + break; + case WSBIT_OPCODE_CLOSE: + infof(data, "WS: received OPCODE CLOSE"); + *flags |= CURLWS_CLOSE; + break; + case WSBIT_OPCODE_PING: + infof(data, "WS: received OPCODE PING"); + *flags |= CURLWS_PING; + break; + case WSBIT_OPCODE_PONG: + infof(data, "WS: received OPCODE PONG"); + *flags |= CURLWS_PONG; + break; + } + + if(p[1] & WSBIT_MASK) { + /* A client MUST close a connection if it detects a masked frame. */ + failf(data, "WS: masked input frame"); + return CURLE_RECV_ERROR; + } + payloadsize = p[1]; + if(payloadsize == 126) { + if(plen < 4) { + infof(data, "WS:%d plen == %u, EAGAIN", __LINE__, (int)plen); + return CURLE_AGAIN; /* not enough data available */ + } + payloadsize = (p[2] << 8) | p[3]; + dataindex += 2; + } + else if(payloadsize == 127) { + /* 64 bit payload size */ + if(plen < 10) + return CURLE_AGAIN; + if(p[2] & 80) { + failf(data, "WS: too large frame"); + return CURLE_RECV_ERROR; + } + dataindex += 8; + payloadsize = ((curl_off_t)p[2] << 56) | + (curl_off_t)p[3] << 48 | + (curl_off_t)p[4] << 40 | + (curl_off_t)p[5] << 32 | + (curl_off_t)p[6] << 24 | + (curl_off_t)p[7] << 16 | + (curl_off_t)p[8] << 8 | + p[9]; + } + + total = dataindex + payloadsize; + if(total > plen) { + /* deliver a partial frame */ + *oleft = total - dataindex; + payloadsize = total - dataindex; + } + else { + *oleft = 0; + if(plen > total) + /* there is another fragment after */ + *more = TRUE; + } + + /* point to the payload */ + *out = &p[dataindex]; + + /* return the payload length */ + *olen = payloadsize; + + /* number of bytes "used" from the buffer */ + wsp->usedbuf = dataindex + payloadsize; + infof(data, "WS: received %zu bytes payload (%zu left)", + payloadsize, *oleft); + return CURLE_OK; +} + +/* Curl_ws_writecb() is the write callback for websocket traffic. The + websocket data is provided to this raw, in chunks. This function should + handle/decode the data and call the "real" underlying callback accordingly. +*/ +size_t Curl_ws_writecb(char *buffer, size_t size /* 1 */, + size_t nitems, void *userp) +{ + struct HTTP *ws = (struct HTTP *)userp; + struct Curl_easy *data = ws->ws.data; + void *writebody_ptr = data->set.out; + if(data->set.ws_raw_mode) + return data->set.fwrite_func(buffer, size, nitems, writebody_ptr); + else if(nitems) { + unsigned char *frame = NULL; + size_t flen = 0; + size_t wrote = 0; + CURLcode result; + bool more; /* there's is more to parse in the buffer */ + curl_off_t oleft; + + decode: + more = FALSE; + oleft = ws->ws.frame.bytesleft; + if(!oleft) { + unsigned int recvflags; + result = ws_decode(data, (unsigned char *)buffer, nitems, + &frame, &flen, &oleft, &more, &recvflags); + if(result == CURLE_AGAIN) + /* insufficient amount of data, keep it for later */ + return nitems; + else if(result) { + infof(data, "WS: decode error %d", (int)result); + return nitems - 1; + } + /* Store details about the frame to be reachable with curl_ws_meta() + from within the write callback */ + ws->ws.frame.age = 0; + ws->ws.frame.offset = 0; + ws->ws.frame.flags = recvflags; + ws->ws.frame.bytesleft = oleft; + } + else { + if(nitems > (size_t)ws->ws.frame.bytesleft) { + nitems = ws->ws.frame.bytesleft; + more = TRUE; + } + else + more = FALSE; + ws->ws.frame.offset += nitems; + ws->ws.frame.bytesleft -= nitems; + frame = (unsigned char *)buffer; + flen = nitems; + } + if((ws->ws.frame.flags & CURLWS_PING) && !oleft) { + /* auto-respond to PINGs, only works for single-frame payloads atm */ + size_t bytes; + infof(data, "WS: auto-respond to PING with a PONG"); + DEBUGASSERT(frame); + /* send back the exact same content as a PONG */ + result = curl_ws_send(data, frame, flen, &bytes, 0, CURLWS_PONG); + if(result) + return result; + } + else { + /* deliver the decoded frame to the user callback */ + Curl_set_in_callback(data, true); + wrote = data->set.fwrite_func((char *)frame, 1, flen, writebody_ptr); + Curl_set_in_callback(data, false); + if(wrote != flen) + return 0; + } + if(oleft) + ws->ws.frame.offset += flen; + /* the websocket frame has been delivered */ + ws_decode_clear(data); + if(more) { + /* there's more websocket data to deal with in the buffer */ + buffer = NULL; /* the buffer as been drained already */ + goto decode; + } + } + return nitems; +} + + +CURL_EXTERN CURLcode curl_ws_recv(struct Curl_easy *data, void *buffer, + size_t buflen, size_t *nread, + struct curl_ws_frame **metap) +{ + size_t bytes; + CURLcode result; + struct websocket *wsp = &data->req.p.http->ws; + + *nread = 0; + *metap = NULL; + /* get a download buffer */ + result = Curl_preconnect(data); + if(result) + return result; + + do { + bool drain = FALSE; /* if there is pending buffered data to drain */ + char *inbuf = data->state.buffer; + bytes = wsp->stillbuffer; + if(!bytes) { + result = curl_easy_recv(data, data->state.buffer, + data->set.buffer_size, &bytes); + if(result) + return result; + } + else { + /* the pending bytes can be found here */ + inbuf = wsp->stillb; + drain = TRUE; + } + if(bytes) { + unsigned char *out; + size_t olen; + bool more; + unsigned int recvflags; + curl_off_t oleft = wsp->frame.bytesleft; + + infof(data, "WS: got %u websocket bytes to decode", (int)bytes); + if(!oleft && !drain) { + result = ws_decode(data, (unsigned char *)inbuf, bytes, + &out, &olen, &oleft, &more, &recvflags); + if(result == CURLE_AGAIN) + /* a packet fragment only */ + break; + else if(result) + return result; + wsp->frame.offset = 0; + wsp->frame.bytesleft = oleft; + wsp->frame.flags = recvflags; + } + else { + olen = oleft; + out = (unsigned char *)wsp->stillb; + recvflags = wsp->frame.flags; + if((curl_off_t)buflen < oleft) + /* there is still data left after this */ + wsp->frame.bytesleft -= buflen; + else + wsp->frame.bytesleft = 0; + } + + /* auto-respond to PINGs */ + if((recvflags & CURLWS_PING) && !oleft) { + infof(data, "WS: auto-respond to PING with a PONG"); + /* send back the exact same content as a PONG */ + result = curl_ws_send(data, out, olen, &bytes, 0, CURLWS_PONG); + if(result) + return result; + } + else { + if(olen < buflen) { + /* copy the payload to the user buffer */ + memcpy(buffer, out, olen); + *nread = olen; + if(!oleft) + /* websocket frame has been delivered */ + ws_decode_clear(data); + } + else { + /* copy a partial payload */ + memcpy(buffer, out, buflen); + *nread = buflen; + /* remember what is left and where */ + wsp->stillbuffer = olen - buflen; + wsp->stillb = (char *)buffer + buflen; + } + wsp->frame.offset += *nread; + } + } + else + *nread = bytes; + break; + } while(1); + *metap = &wsp->frame; + return CURLE_OK; +} + +static void ws_xor(struct Curl_easy *data, + const unsigned char *source, + unsigned char *dest, + size_t len) +{ + struct websocket *wsp = &data->req.p.http->ws; + size_t i; + /* append payload after the mask, XOR appropriately */ + for(i = 0; i < len; i++) { + dest[i] = source[i] ^ wsp->mask[wsp->xori]; + wsp->xori++; + wsp->xori &= 3; + } +} + +/*** + RFC 6455 Section 5.2 + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-------+-+-------------+-------------------------------+ + |F|R|R|R| opcode|M| Payload len | Extended payload length | + |I|S|S|S| (4) |A| (7) | (16/64) | + |N|V|V|V| |S| | (if payload len==126/127) | + | |1|2|3| |K| | | + +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + + | Extended payload length continued, if payload len == 127 | + + - - - - - - - - - - - - - - - +-------------------------------+ + | |Masking-key, if MASK set to 1 | + +-------------------------------+-------------------------------+ + | Masking-key (continued) | Payload Data | + +-------------------------------- - - - - - - - - - - - - - - - + + : Payload Data continued ... : + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + | Payload Data continued ... | + +---------------------------------------------------------------+ +*/ + +static size_t ws_packethead(struct Curl_easy *data, + size_t len, unsigned int flags) +{ + struct HTTP *ws = data->req.p.http; + unsigned char *out = (unsigned char *)data->state.ulbuf; + unsigned char firstbyte = 0; + int outi; + unsigned char opcode; + if(flags & CURLWS_TEXT) { + opcode = WSBIT_OPCODE_TEXT; + infof(data, "WS: send OPCODE TEXT"); + } + else if(flags & CURLWS_CLOSE) { + opcode = WSBIT_OPCODE_CLOSE; + infof(data, "WS: send OPCODE CLOSE"); + } + else if(flags & CURLWS_PING) { + opcode = WSBIT_OPCODE_PING; + infof(data, "WS: send OPCODE PING"); + } + else if(flags & CURLWS_PONG) { + opcode = WSBIT_OPCODE_PONG; + infof(data, "WS: send OPCODE PONG"); + } + else { + opcode = WSBIT_OPCODE_BIN; + infof(data, "WS: send OPCODE BINARY"); + } + + if(!(flags & CURLWS_CONT)) { + /* if not marked as continuing, assume this is the final fragment */ + firstbyte |= WSBIT_FIN | opcode; + ws->ws.contfragment = FALSE; + } + else if(ws->ws.contfragment) { + /* the previous fragment was not a final one and this isn't either, keep a + CONT opcode and no FIN bit */ + firstbyte |= WSBIT_OPCODE_CONT; + } + else { + ws->ws.contfragment = TRUE; + } + out[0] = firstbyte; + if(len > 65535) { + out[1] = 127 | WSBIT_MASK; + out[2] = (len >> 8) & 0xff; + out[3] = len & 0xff; + outi = 10; + } + else if(len > 126) { + out[1] = 126 | WSBIT_MASK; + out[2] = (len >> 8) & 0xff; + out[3] = len & 0xff; + outi = 4; + } + else { + out[1] = (unsigned char)len | WSBIT_MASK; + outi = 2; + } + + infof(data, "WS: send FIN bit %u (byte %02x)", + firstbyte & WSBIT_FIN ? 1 : 0, + firstbyte); + infof(data, "WS: send payload len %u", (int)len); + + /* 4 bytes mask */ + memcpy(&out[outi], &ws->ws.mask, 4); + + if(data->set.upload_buffer_size < (len + 10)) + return 0; + + /* pass over the mask */ + outi += 4; + + ws->ws.xori = 0; + /* return packet size */ + return outi; +} + +CURL_EXTERN CURLcode curl_ws_send(struct Curl_easy *data, const void *buffer, + size_t buflen, size_t *sent, + curl_off_t totalsize, + unsigned int sendflags) +{ + CURLcode result; + size_t headlen; + char *out; + ssize_t written; + struct websocket *wsp = &data->req.p.http->ws; + + if(!data->set.ws_raw_mode) { + result = Curl_get_upload_buffer(data); + if(result) + return result; + } + else { + if(totalsize || sendflags) + return CURLE_BAD_FUNCTION_ARGUMENT; + } + + if(data->set.ws_raw_mode) { + if(!buflen) + /* nothing to do */ + return CURLE_OK; + /* raw mode sends exactly what was requested, and this is from within + the write callback */ + if(Curl_is_in_callback(data)) + result = Curl_write(data, data->conn->writesockfd, buffer, buflen, + &written); + else + result = Curl_senddata(data, buffer, buflen, &written); + + infof(data, "WS: wanted to send %zu bytes, sent %zu bytes", + buflen, written); + *sent = written; + return result; + } + + if(buflen > (data->set.upload_buffer_size - 10)) + /* don't do more than this in one go */ + buflen = data->set.upload_buffer_size - 10; + + if(sendflags & CURLWS_OFFSET) { + if(totalsize) { + /* a frame series 'totalsize' bytes big, this is the first */ + headlen = ws_packethead(data, totalsize, sendflags); + wsp->sleft = totalsize - buflen; + } + else { + headlen = 0; + if((curl_off_t)buflen > wsp->sleft) { + infof(data, "WS: unaligned frame size (sending %zu instead of %zu)", + buflen, wsp->sleft); + wsp->sleft = 0; + } + else + wsp->sleft -= buflen; + } + } + else + headlen = ws_packethead(data, buflen, sendflags); + + /* headlen is the size of the frame header */ + out = data->state.ulbuf; + if(buflen) + /* for PING and PONG etc there might not be a payload */ + ws_xor(data, buffer, (unsigned char *)out + headlen, buflen); + + if(data->set.connect_only) + result = Curl_senddata(data, out, buflen + headlen, &written); + else + result = Curl_write(data, data->conn->writesockfd, out, + buflen + headlen, &written); + + infof(data, "WS: wanted to send %zu bytes, sent %zu bytes", + headlen + buflen, written); + *sent = written; + + return result; +} + +void Curl_ws_done(struct Curl_easy *data) +{ + struct websocket *wsp = &data->req.p.http->ws; + DEBUGASSERT(wsp); + Curl_dyn_free(&wsp->buf); +} + +CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data) +{ + /* we only return something for websocket, called from within the callback + when not using raw mode */ + if(GOOD_EASY_HANDLE(data) && Curl_is_in_callback(data) && data->req.p.http && + !data->set.ws_raw_mode) + return &data->req.p.http->ws.frame; + return NULL; +} + +#else + +CURL_EXTERN CURLcode curl_ws_recv(CURL *curl, void *buffer, size_t buflen, + size_t *nread, + struct curl_ws_frame **metap) +{ + (void)curl; + (void)buffer; + (void)buflen; + (void)nread; + (void)metap; + return CURLE_OK; +} + +CURL_EXTERN CURLcode curl_ws_send(CURL *curl, const void *buffer, + size_t buflen, size_t *sent, + curl_off_t framesize, + unsigned int sendflags) +{ + (void)curl; + (void)buffer; + (void)buflen; + (void)sent; + (void)framesize; + (void)sendflags; + return CURLE_OK; +} + +CURL_EXTERN struct curl_ws_frame *curl_ws_meta(struct Curl_easy *data) +{ + (void)data; + return NULL; +} +#endif /* USE_WEBSOCKETS */ diff --git a/libs/libcurl/src/ws.h b/libs/libcurl/src/ws.h new file mode 100644 index 0000000000..341242e50e --- /dev/null +++ b/libs/libcurl/src/ws.h @@ -0,0 +1,69 @@ +#ifndef HEADER_CURL_WS_H +#define HEADER_CURL_WS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "curl_setup.h" + +#ifdef USE_WEBSOCKETS + +#ifdef USE_HYPER +#define REQTYPE void +#else +#define REQTYPE struct dynbuf +#endif + +/* this is the largest single fragment size we support */ +#define MAX_WS_SIZE 65535 + +/* part of 'struct HTTP', when used in the 'struct SingleRequest' in the + Curl_easy struct */ +struct websocket { + bool contfragment; /* set TRUE if the previous fragment sent was not final */ + unsigned char mask[4]; /* 32 bit mask for this connection */ + struct Curl_easy *data; /* used for write callback handling */ + struct dynbuf buf; + size_t usedbuf; /* number of leading bytes in 'buf' the most recent complete + websocket frame uses */ + struct curl_ws_frame frame; /* the struct used for frame state */ + curl_off_t oleft; /* outstanding number of payload bytes left from the + server */ + curl_off_t stillbuffer; /* number of bytes left in the buffer to deliver in + the next curl_ws_recv() call */ + char *stillb; /* the stillbuffer pending bytes are here */ + curl_off_t sleft; /* outstanding number of payload bytes left to send */ + unsigned int xori; /* xor index */ +}; + +CURLcode Curl_ws_request(struct Curl_easy *data, REQTYPE *req); +CURLcode Curl_ws_accept(struct Curl_easy *data); + +size_t Curl_ws_writecb(char *buffer, size_t size, size_t nitems, void *userp); +void Curl_ws_done(struct Curl_easy *data); + +#else +#define Curl_ws_request(x,y) CURLE_OK +#define Curl_ws_done(x) Curl_nop_stmt +#endif + +#endif /* HEADER_CURL_WS_H */ |