diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-04-09 12:33:15 +0300 |
---|---|---|
committer | shadchin <shadchin@yandex-team.ru> | 2022-04-09 12:33:15 +0300 |
commit | 3416ae92be9b12575d51845887e8489e773047d3 (patch) | |
tree | ae20f37194e8c35ce06338fab3936124450dd1a7 /contrib/libs | |
parent | 41c0ca282300b7347a4551d1793b605ac1593733 (diff) | |
download | ydb-3416ae92be9b12575d51845887e8489e773047d3.tar.gz |
CONTRIB-2513 Update contrib/libs/curl to 7.78.0
ref:b290831c3e739ee8c89b5e4f10cc434f557bc92f
Diffstat (limited to 'contrib/libs')
107 files changed, 5040 insertions, 4200 deletions
diff --git a/contrib/libs/curl/.yandex_meta/devtools.copyrights.report b/contrib/libs/curl/.yandex_meta/devtools.copyrights.report index f3c3049905..004356ae43 100644 --- a/contrib/libs/curl/.yandex_meta/devtools.copyrights.report +++ b/contrib/libs/curl/.yandex_meta/devtools.copyrights.report @@ -135,6 +135,7 @@ BELONGS ya.make lib/dict.c [8:8] lib/easy.c [8:8] lib/file.c [8:8] + lib/formdata.c [8:8] lib/formdata.h [10:10] lib/ftp.c [8:8] lib/ftp.h [10:10] @@ -175,6 +176,7 @@ BELONGS ya.make lib/multi.c [8:8] lib/multihandle.h [10:10] lib/multiif.h [10:10] + lib/netrc.c [8:8] lib/non-ascii.c [8:8] lib/nonblock.c [8:8] lib/pingpong.c [8:8] @@ -183,6 +185,7 @@ BELONGS ya.make lib/progress.c [8:8] lib/progress.h [10:10] lib/quic.h [10:10] + lib/rand.c [8:8] lib/rtsp.c [8:8] lib/rtsp.h [10:10] lib/select.c [8:8] @@ -211,6 +214,8 @@ BELONGS ya.make lib/vauth/ntlm.c [8:8] lib/vauth/ntlm_sspi.c [8:8] lib/vauth/oauth2.c [8:8] + lib/vauth/spnego_gssapi.c [8:8] + lib/vauth/spnego_sspi.c [8:8] lib/version.c [8:8] lib/vquic/ngtcp2.c [8:8] lib/vquic/quiche.c [8:8] @@ -453,7 +458,6 @@ BELONGS ya.make Match type : COPYRIGHT Files with this license: include/curl/options.h [10:10] - include/curl/urlapi.h [10:10] lib/curl_sha256.h [10:11] KEEP COPYRIGHT_SERVICE_LABEL 520dfafb050652350468b32c3d62b5cd @@ -558,9 +562,7 @@ BELONGS ya.make Score : 100.00 Match type : COPYRIGHT Files with this license: - lib/altsvc.c [8:8] lib/altsvc.h [10:10] - lib/socketpair.c [8:8] KEEP COPYRIGHT_SERVICE_LABEL 84500f86b97af8062c8463ad37fdf711 BELONGS ya.make @@ -620,7 +622,6 @@ BELONGS ya.make lib/escape.c [8:8] lib/escape.h [10:10] lib/file.h [10:10] - lib/formdata.c [8:8] lib/ftplistparser.h [10:10] lib/getenv.c [8:8] lib/getinfo.h [10:10] @@ -636,7 +637,6 @@ BELONGS ya.make lib/inet_pton.h [10:10] lib/llist.h [10:10] lib/memdebug.h [11:11] - lib/netrc.c [8:8] lib/netrc.h [10:10] lib/non-ascii.h [10:10] lib/nonblock.h [10:10] @@ -644,7 +644,6 @@ BELONGS ya.make lib/parsedate.h [10:10] lib/psl.c [8:8] lib/psl.h [10:10] - lib/rand.c [8:8] lib/rand.h [10:10] lib/setopt.h [10:10] lib/setup-win32.h [10:10] @@ -668,8 +667,6 @@ BELONGS ya.make lib/urlapi-int.h [10:10] lib/vauth/digest.h [10:10] lib/vauth/ntlm.h [10:10] - lib/vauth/spnego_gssapi.c [8:8] - lib/vauth/spnego_sspi.c [8:8] lib/vquic/vquic.c [8:8] lib/vtls/gskit.h [10:10] lib/vtls/gtls.h [10:10] @@ -702,6 +699,8 @@ BELONGS ya.make Score : 100.00 Match type : COPYRIGHT Files with this license: + lib/altsvc.c [8:8] + lib/socketpair.c [8:8] lib/socketpair.h [10:10] lib/vssh/wolfssh.c [8:8] @@ -1020,6 +1019,7 @@ BELONGS ya.make Score : 100.00 Match type : COPYRIGHT Files with this license: + include/curl/urlapi.h [10:10] lib/doh.c [8:8] lib/doh.h [10:10] lib/sha256.c [8:9] diff --git a/contrib/libs/curl/CHANGES b/contrib/libs/curl/CHANGES index e7a462b50e..3842d916a4 100644 --- a/contrib/libs/curl/CHANGES +++ b/contrib/libs/curl/CHANGES @@ -6,6 +6,2103 @@ Changelog +Version 7.78.0 (21 Jul 2021) + +Daniel Stenberg (21 Jul 2021) +- RELEASE-NOTES: synced + + curl 7.78.0 release + +- winbuild/MakefileBuild.vc: bump copyright year + +Jay Satiro (21 Jul 2021) +- docs: mention max-filesize options also apply to MQTT transfers + + Also make it clearer that the caveat 'if the file size is unknown it + the option will have no effect' may apply to protocols other than FTP + and HTTP. + + Reported-by: Josh Soref + + Fixes https://github.com/curl/curl/issues/7453 + +- [Josh Soref brought this change] + + docs/cmdline: fix grammar and typos + +- [Josh Soref brought this change] + + dump-header.d: Drop suggestion to use for cookie storage + + Since --cookie-jar is the preferred way to store cookies, no longer + suggest using --dump-header to do so. + + Co-authored-by: Daniel Stenberg + + Closes https://github.com/curl/curl/issues/7414 + +- [Josh Soref brought this change] + + doc/cmdline: fix grammar and typos + + Closes https://github.com/curl/curl/pull/7454 + Closes https://github.com/curl/curl/pull/7455 + Closes https://github.com/curl/curl/pull/7456 + Closes https://github.com/curl/curl/pull/7459 + Closes https://github.com/curl/curl/pull/7460 + Closes https://github.com/curl/curl/pull/7461 + Closes https://github.com/curl/curl/pull/7462 + Closes https://github.com/curl/curl/pull/7463 + +Daniel Stenberg (20 Jul 2021) +- vtls: fix connection reuse checks for issuer cert and case sensitivity + + CVE-2021-22924 + + Reported-by: Harry Sintonen + Bug: https://curl.se/docs/CVE-2021-22924.html + +- sectransp: check for client certs by name first, then file + + CVE-2021-22926 + + Bug: https://curl.se/docs/CVE-2021-22926.html + + Assisted-by: Daniel Gustafsson + Reported-by: Harry Sintonen + +- telnet: fix option parser to not send uninitialized contents + + CVS-2021-22925 + + Reported-by: Red Hat Product Security + Bug: https://curl.se/docs/CVE-2021-22925.html + +Jay Satiro (20 Jul 2021) +- connect: fix wrong format specifier in connect error string + + 0842175 (not in any release) used the wrong format specifier (long int) + for timediff_t. On an OS such as Windows libcurl's timediff_t (usually + 64-bit) is bigger than long int (32-bit). In 32-bit Windows builds the + upper 32-bits of the timediff_t were erroneously then used by the next + format specifier. Usually since the timeout isn't larger than 32-bits + this would result in null as a pointer to the string with the reason for + the connection failing. On other OSes or maybe other compilers it could + probably result in garbage values (ie crash on deref). + + Before: + Failed to connect to localhost port 12345 after 1201 ms: (nil) + + After: + Failed to connect to localhost port 12345 after 1203 ms: Connection refused + + Closes https://github.com/curl/curl/pull/7449 + +- winbuild: support alternate nghttp2 static lib name + + - Support both nghttp2.lib and nghttp2_static.lib for static nghttp2. + + nghttp2 briefly changed its static lib name to nghttp2_static, but then + made the _static suffix optional. + + Ref: https://github.com/nghttp2/nghttp2/pull/1394 + Ref: https://github.com/nghttp2/nghttp2/pull/1418 + Ref: https://github.com/nghttp2/nghttp2/issues/1466 + + Reported-by: Pierre Yager + + Fixes https://github.com/curl/curl/issues/7446 + Closes https://github.com/curl/curl/pull/7447 + +- [Josh Soref brought this change] + + docs/cmdline: fix grammar and typos + + Closes https://github.com/curl/curl/pull/7432 + Closes https://github.com/curl/curl/pull/7436 + Closes https://github.com/curl/curl/pull/7438 + Closes https://github.com/curl/curl/pull/7440 + Closes https://github.com/curl/curl/pull/7445 + +- [Josh Soref brought this change] + + delegation.d: mention what happens when used multiple times + + Closes https://github.com/curl/curl/pull/7408 + +- [Josh Soref brought this change] + + create-file-mode.d: mention what happens when used multiple times + + Closes https://github.com/curl/curl/pull/7407 + +- [Josh Soref brought this change] + + config.d: split comments and option-per line + + Closes https://github.com/curl/curl/pull/7405 + +Daniel Stenberg (19 Jul 2021) +- misc: copyright year range updates + +- mailmap: add Tobias and Timur + +Daniel Gustafsson (18 Jul 2021) +- [Josh Soref brought this change] + + docs: spell out directories instead of dirs in create-dirs + + Write out directories rather than using the dirs abbrevation. Also + use plural form consistently, even if the code in the end might just + create a single directory. + + Closes #7406 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + Reviewed-by: Daniel Gustafsson <daniel@yesql.se> + +- [Tobias Nyholm brought this change] + + docs: correct spelling errors and a broken link + + Update grammar and spelling in docs and source code comments. + + Closes: #7427 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +Marc Hoersken (18 Jul 2021) +- CI/cirrus: install impacket from PyPI instead of FreeBSD packages + + Availability of impacket as FreeBSD package is too flaky. + + Stick to legacy version of cryptography which still + supports OpenSSL version 1.0.2 due to FreeBSD 11. + + Reviewed-by: Daniel Stenberg + + Closes #7418 + +Daniel Stenberg (18 Jul 2021) +- [Josh Soref brought this change] + + docs/cmdline: mention what happens when used multiple times + + For --dns-ipv4-addr, --dns-ipv6-addr and --dns-servers + + Closes #7410 + Closes #7411 + Closes #7412 + +- [MAntoniak brought this change] + + lib: fix compiler warnings with CURL_DISABLE_NETRC + + warning C4189: 'netrc_user_changed': local variable is initialized but + not referenced + + warning C4189: 'netrc_passwd_changed': local variable is initialized but + not referenced + + Closes #7423 + +- disable-epsv.d: remove duplicate "(FTP)" + + ... since the tooling adds that to the output based on the "Protocols:" + tag. + +- [Max Zettlmeißl brought this change] + + docs: make the documentation for --etag-save match the program behaviour + + When using curl with the option `--etag-save` I expected it to save the + ETag without its surrounding quotes, as stated by the documentation in + the repository and by the generated man pages. + + My first endeavour was to fix the program, but while investigating the + history of the relevant parts, I discovered that curl once saved the + ETag without the quotes. This was undone by Daniel Stenberg in commit + `98c94596f5928840177b6bd3c7b0f0dd03a431af`, therefore I decided that in + this case the documentation should be adjusted to match the behaviour of + curl. + + The changed save behaviour also made parts of the `--etag-compare` + documentation wrong or superfluous, so I adjusted those accordingly. + + Closes #7429 + +- [Josh Soref brought this change] + + write-out.d: add missing periods + + Closes #7404 + +- [Josie Huddleston brought this change] + + easy: during upkeep, attach Curl_easy to connections in the cache + + During the protocol-specific parts of connection upkeep, some code + assumes that the data->conn pointer already is set correctly. However, + there's currently no guarantee of that in the code. + + This fix temporarily attaches each connection to the Curl_easy object + before performing the protocol-specific connection check on it, in a + similar manner to the connection checking in extract_if_dead(). + + Fixes #7386 + Closes #7387 + Reported-by: Josie Huddleston + +- [Josh Soref brought this change] + + cleanup: spell DoH with a lowercase o + + Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> + + Closes #7413 + +- [Josh Soref brought this change] + + TheArtOfHttpScripting: polish + + - add missing backticks and comma + + - fix proxy description: + + * example proxy isn't local + * locally doesn't really make sense + + Closes #7416 + +- [Josh Soref brought this change] + + form.d: add examples of `,`/`;` for file[name] + + Fixes #7415 + Closes #7417 + +- [MAntoniak brought this change] + + mbedtls: Remove unnecessary include + + - curl_setup.h: all references to mbedtls_md4* functions and structures + are in the md4.c. This file already includes the <mbedtls/md4.h> file + along with the file existence control (defined (MBEDTLS_MD4_C)) + + - curl_ntlm_core.c: unnecessary include - repeated below + + Closes #7419 + +- RELEASE-NOTES: synced + +Jay Satiro (16 Jul 2021) +- [User Sg brought this change] + + multi: fix crash in curl_multi_wait / curl_multi_poll + + Appears to have been caused by 51c0ebc (precedes 7.77.0) which added a + VALID_SOCK check to one of the loops through the sockets but not the + other. + + Reported-by: sylgal@users.noreply.github.com + Authored-by: sylgal@users.noreply.github.com + + Fixes https://github.com/curl/curl/issues/7379 + Closes https://github.com/curl/curl/pull/7389 + +- [Daniel Gustafsson brought this change] + + tool_help: remove unused define + + The PRINT_LINES_PAUSE macro is no longer used, and has been mostly + cleaned out but one occurrence remained. + + Closes https://github.com/curl/curl/pull/7380 + +- [Sergey Markelov brought this change] + + build: fix compiler warnings when CURL_DISABLE_VERBOSE_STRINGS + + fix compiler warnings about unused variables and parameters when + built with --disable-verbose. + + Closes https://github.com/curl/curl/pull/7377 + +- [Andrea Pappacoda brought this change] + + build: fix IoctlSocket FIONBIO check + + Prior to this change HAVE_IOCTLSOCKET_CAMEL_FIONBIO mistakenly checked + for (lowercase) ioctlsocket when it should have checked for IoctlSocket. + + Closes https://github.com/curl/curl/pull/7375 + +- [Timur Artikov brought this change] + + configure: fix nghttp2 library name for static builds + + Don't hardcode the nghttp2 library name, + because it can vary, be "nghttp2_static" for example. + + Fixes https://github.com/curl/curl/issues/7367 + Closes https://github.com/curl/curl/pull/7368 + +Gisle Vanem (16 Jul 2021) +- [PellesC] fix _lseeki64() macro + +- [SChannel] Use '_tcsncmp()' instead + + Revert previous change for PellesC. + + Instead replace all use of `_tcsnccmp()` with `_tcsncmp()`. + +- [PellesC] missing '_tcsnccmp' + + PellesC compiler does not have this macro in it's `<tchar.h>` + +Daniel Gustafsson (14 Jul 2021) +- TODO: add mention of mbedTLS 3 incompatibilities + + Wyatt OʼDay reported in #7385 that mbedTLS isn't backwards compatible + and curl no longer builds with it. Document the need to fix our support + until so has been done. + + Closes #7390 + Fixes #7385 + Reported-by: Wyatt OʼDay + Reviewed-by: Jay Satiro <raysatiro@yahoo.com> + +- docs: fix inconsistencies in EGDSOCKET documentation + + Only the OpenSSL backend actually use the EGDSOCKET, and also use + TLS consistently rather than mixing SSL and TLS. While there, also + fix a minor spelling nit. + + Closes: #7391 + Reviewed-by: Jay Satiro <raysatiro@yahoo.com> + +- [Борис Верховский brought this change] + + docs: document missing arguments to commands + + This is a followup to commit f410b9e538129e77607fef1 fixing a few + more commands which takes arguments. + + Closes #7382 + Reviewed-by: Daniel Gustafsson <daniel@yesql.se> + +- [Randolf J brought this change] + + docs: fix incorrect argument name reference + + The documentation for the read callback was erroneously referencing + the nitems argument by nmemb. The error was introduced in commit + ce0881edee3c7. + + Closes #7383 + Reviewed-by: Daniel Gustafsson <daniel@yesql.se> + +- [Борис Верховский brought this change] + + tool_help: Document that --tlspassword takes a password + + Closes #7378 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +- scripts: Fix typo in release-notes instructions + + The command to run had a typo in the pathname which prevented copy + pasting it to work, which has annoyed me enough to fix this now. + +- RELEASE-NOTES: synced + +Jay Satiro (10 Jul 2021) +- write-out.d: Clarify urlnum is not unique for de-globbed URLs + + Reported-by: Коваленко Анатолий Викторович + + Fixes https://github.com/curl/curl/issues/7342 + Closes https://github.com/curl/curl/pull/7369 + +Daniel Gustafsson (3 Jul 2021) +- [William Desportes brought this change] + + docs: Fix typos + + Closes: #7370 + Reviewed-by: Daniel Gustafsson <daniel@yesql.se> + +Daniel Stenberg (8 Jul 2021) +- [Jonathan Wernberg brought this change] + + Revert "ftp: Expression 'ftpc->wait_data_conn' is always false" + + The reverted commit introduced a logic error in code that was + correct. + + The client using libcurl would notice the error since FTP file + uploads in active transfer mode would somtimes complete with + success despite no transfer having been performed and the + "uploaded" file thus not being on the remote server afterwards. + + The FTP server would notice the error because it receives a + RST on the data connection it has established with the client + before any data was transferred at all. + + The logic error happens if the STOR response from the server have + arrived by the time ftp_multi_statemach() in the affected code path + is called, but the incoming data connection have not arrived yet. + In that case, the processing of the STOR response will cause + 'ftpc->wait_data_conn' to be set to TRUE, contradicting the comment + in the code. Since 'complete' will also be set, later logic would + believe the transfer was done. + + In most cases, the STOR response will not have arrived yet when + the affected code path is executed, or the incoming connection will + also have arrived, and thus the error would not express itself. + But if the speed difference of the device using libcurl and the + FTP server is exactly right, the error may happen as often as in + one out of hundred file transfers. + + This reverts commit 49f3117a238b6eac0e22a32f50699a9eddcb66ab. + + Bug: https://curl.se/mail/lib-2021-07/0025.html + Closes #7362 + +- msnprintf: return number of printed characters excluding null byte + + ... even when the output is "capped" by the maximum length argument. + + Clarified in the docs. + + Closes #7361 + +- infof: remove newline from format strings, always append it + + - the data needs to be "line-based" anyway since it's also passed to the + debug callback/application + + - it makes infof() work like failf() and consistency is good + + - there's an assert that triggers on newlines in the format string + + - Also removes a few instances of "..." + + - Removes the code that would append "..." to the end of the data *iff* + it was truncated in infof() + + Closes #7357 + +- examples/multi-single: fix scan-build warning + + warning: Value stored to 'mc' during its initialization is never read + + Follow-up to ae8e11ed5fd2ce + + Closes #7360 + +- wolfssl: failing to set a session id is not reason to error out + + ... as it is *probably* just timed out. + + Reported-by: Francisco Munoz + + Closes #7358 + +- docs/examples: use curl_multi_poll() in multi examples + + The API is soon two years old and deserves being shown as the primary + way to drive multi code as it makes it much easier to write code. + + multi-poll: removed + + multi-legacy: add to show how we did multi API use before + curl_multi_wait/poll. + + Closes #7352 + +- KNOWN_BUGS: flaky Windows CI builds + + Closes #6972 + +- RELEASE-NOTES: synced + +- test1147: hyper doesn't allow "crazy" request headers like built-in + + ... so strip that from the test. + + Closes #7349 + +- c-hyper: bail on too long response headers + + To match with built-in behaviors. Makes test 1154 work. + + Closes #7350 + +- test1151: added missing CRLF to work with hyper + + Closes #7350 + +- c-hyper: add support for transfer-encoding in the request + + Closes #7348 + +- [Andrea Pappacoda brought this change] + + cmake: remove libssh2 feature checks + + libssh2 features are detected based on version since commit + 9dbbba997608f7c3c5de1c627c77c8cd2aa85b73 + + Closes #7343 + +- test1116: hyper doesn't pass through "surprise-trailers" + + Closes #7344 + +- socks4: scan for the IPv4 address in resolve results + + Follow-up to 84d2839740 which changed the resolving to always resolve + both address families, but since SOCKS4 only supports IPv4 it should + scan for and use the first available IPv4 address. + + Reported-by: shithappens2016 on github + Fixes #7345 + Closes #7346 + +Jay Satiro (5 Jul 2021) +- proto.d: fix formatting for paragraphs after margin changes + + Closes https://github.com/curl/curl/pull/7341 + +- pinnedpubkey.d: fix formatting for version support lists + + Closes https://github.com/curl/curl/pull/7340 + +Daniel Stenberg (2 Jul 2021) +- TODO: "Support in-memory certs/ca certs/keys" done + + Has been suppored for a while now with the *BLOB options. + +- examples: safer and more proper read callback logic + + The same callback code is used in: + + imap-append.c + smtp-authzid.c + smtp-mail.c + smtp-multi.c + smtp-ssl.c + smtp-tls.c + + It should not assume that it can copy full lines into the buffer as it + will encourage sloppy coding practices. Instead use byte-wise logic and + check/acknowledge the buffer size appropriately. + + Reported-by: Harry Sintonen + Fixes #7330 + Closes #7331 + +- test1519: adjusted to work with hyper + + Closes #7333 + +- test1518: adjusted to work with hyper + + ... by making sure the stdout output doesn't look like HTTP headers. + + Closes #7333 + +- test1514: add a CRLF to the response to make it correct + + Makes hyper accept it fine instead returning HYPERE_UNEXPECTED_EOF on + us. + + Closes #7334 + +- formdata: avoid "Argument cannot be negative" warning + + ... when converting a curl_off_t to size_t, by using + CURL_ZERO_TERMINATED before passing the argument to the function. + + Detected by Coverity CID 1486590. + + Closes #7328 + Assisted-by: Daniel Gustafsson + +- lib: more %u for port and int for %*s fixes + + Detected by Coverity + + Closes #7329 + +- doh: (void)-prefix call to curl_easy_setopt + +- lib: fix type of len passed to *printf's %*s + + ... it needs to be 'int'. Detected by Coverity CID 1486611 (etc) + + Closes #7326 + +- lib: use %u instead of %ld for port number printf + + Follow-up to 764c6bd3bf which changed the type of some port number + fields. Detected by Coverity (CID 1486624) etc. + + Closes #7325 + +- version: turn version number functions into returning void + + ... as we never use the return codes from them. + + Reviewed-by: Daniel Gustafsson + Closes #7319 + +- mqtt: extend the error message for no topic + + ... and mention that it needs URL encoding. + + Reported-by: Peter Körner + Fixes #7316 + Closes #7317 + +- formdata: correct typecast in curl_mime_data call + + Coverity pointed out it the mismatch. CID 1486590 + + Closes #7327 + +- url: (void)-prefix a curl_url_get() call + + Coverity (CID 1486645) pointed out a use of curl_url_get() in the + parse_proxy function where the return code wasn't checked. A + (void)-prefix makes the intention obvious. + + Closes #7320 + +- glob: pass an 'int' as len when using printf's %*s + + Detected by Coverity CID 1486629. + + Closes #7324 + +- vtls: use free() not curl_free() + + curl_free() is provided for users of the API to free returned data, + there's no need to use it internally. + + Closes #7318 + +- zuul: use the new rustls directory name + + Follow-up to 6d972c8b1cbb3 which missed updating this directory name. + + Also no longer call it crustls in the docs and bump to rusttls-ffi 0.7.1 + + Closes #7311 + +Jay Satiro (29 Jun 2021) +- http: fix crash in rate-limited upload + + - Don't set the size of the piece of data to send to the rate limit if + that limit is larger than the buffer size that will hold the piece. + + Prior to this change if CURLOPT_MAX_SEND_SPEED_LARGE + (curl tool: --limit-rate) was set then it was possible that a temporary + buffer used for uploading could be written to out of bounds. A likely + scenario for this would be a non-trivial amount of post data combined + with a rate limit larger than CURLOPT_UPLOAD_BUFFERSIZE (default 64k). + + The bug was introduced in 24e469f which is in releases since 7.76.0. + + perl -e "print '0' x 200000" > tmp + curl --limit-rate 128k -d @tmp httpbin.org/post + + Reported-by: Richard Marion + + Fixes https://github.com/curl/curl/issues/7308 + Closes https://github.com/curl/curl/pull/7315 + +Daniel Stenberg (29 Jun 2021) +- copyright: add boiler-plate headers to CI config files + + And whitelist .zuul.ignore + + Closes #7314 + +- CI: remove travis details + + Rename still used leftovers to "zuul" as that's now the CI using them. + + Closes #7313 + +- RELEASE-NOTES: synced + +- openssl: avoid static variable for seed flag + + Avoid the race condition risk by instead storing the "seeded" flag in + the multi handle. Modern OpenSSL versions handle the seeding itself so + doing the seeding once per multi-handle instead of once per process is + less of an issue. + + Reported-by: Gerrit Renker + Fixes #7296 + Closes #7306 + +- configure: inhibit the implicit-fallthrough warning on gcc-12 + + ... since it no longer acknowledges the comment markup we use for that + purpose. + + Reported-by: Younes El-karama + Fixes #7295 + Closes #7307 + +Daniel Gustafsson (28 Jun 2021) +- [Andrei Rybak brought this change] + + misc: fix typos in comments which repeat a word + + Fix typos in code comments which repeat various words. In trivial + cases, just delete the repeated word. Reword the affected sentence in + "lib/url.c" for it to make sense. + + Closes #7303 + Reviewed-by: Daniel Gustafsson <daniel@yesql.se> + +Daniel Stenberg (27 Jun 2021) +- lib677: make it survive torture testing + + Follow-up to a5ab72d5edd7 + + Closes #7300 + +- [Tommy Chiang brought this change] + + docs/BINDINGS: fix outdated links + + * luacurl page is now not accessible, fix it with wayback machine page + * Scheme one seems not providing https now, change it back to http one + + Closes #7301 + +- [Jacob Hoffman-Andrews brought this change] + + curstls: bump crustls version and use new URL + + crustls moved to https://github.com/rustls/rustls-ffi. This also bumps + the expected version to 0.7.0. + + Closes #7297 + +- RELEASE-NOTES: synced + +- examples: length-limit two sscanf() uses of %s + + Reported-by: Jishan Shaikh + Fixes #7293 + Closes #7294 + +- [Richard Whitehouse brought this change] + + multi: alter transfer timeout ordering + + - Check whether a connection has succeded before checking whether it's + timed out. + + This means if we've connected quickly, but subsequently been + descheduled, we allow the connection to succeed. Note, if we timeout, + but between checking the timeout, and connecting to the server the + connection succeeds, we will allow it to go ahead. This is viewed as + an acceptable trade off. + + - Add additional failf logging around failed connection attempts to + propogate the cause up to the caller. + + Co-Authored-by: Martin Howarth + Closes #7178 + +- test677: IMAP CONNECT_ONLY, custom command and then exit + + Adjusted ftpserver.pl to add support for the IMAP IDLE command + + Adjusted test 660 to sync with the fix + +- multi: do not switch off connect_only flag when closing + + ... as it made protocol specific disconnect commands wrongly get used. + + Bug: https://curl.se/mail/lib-2021-06/0024.html + Reported-by: Aleksander Mazur + Closes #7288 + +- http: make the haproxy support work with unix domain sockets + + ... it should then pass on "PROXY UNKNOWN" since it doesn't know the + involved IP addresses. + + Reported-by: Valentín Gutiérrez + Fixes #7290 + Closes #7291 + +- [Xiang Xiao brought this change] + + curl.h: include sys/select.h for NuttX RTOS + + Closes #7287 + +- [Bin Meng brought this change] + + curl.h: remove the execution bit + + The execution bit of curl.h file was wrongly added: + + commit 2621025d6f96 ("curl.h: <sys/select.h> is supported by VxWorks7") + + and should be removed. + + Follow-up to 2621025d6f96 ("curl.h: <sys/select.h> is supported by VxWorks7") + Signed-off-by: Bin Meng <bmeng.cn@gmail.com> + Closes #7286 + +- [Bin Lan brought this change] + + curl.h: <sys/select.h> is supported by VxWorks7 + + Closes #7285 + +- [Bachue Zhou brought this change] + + quiche: use send() instead of sendto() to avoid macOS issue + + sendto() always returns "Socket is already connected" error on macos + + Closes #7260 + +- [Li Xinwei brought this change] + + cmake: fix support for UnixSockets feature on Win32 + + Move the definition of sockaddr_un struct from config-win32.h to + curl_setup.h, so that it could be shared by all build systems. + + Add ADDRESS_FAMILY typedef for old mingw, now old mingw can also use + unix sockets. + + Also fix the build of tests/server/sws.c on Win32 when USE_UNIX_SOCKETS + is defined. + + Closes #7034 + +- [Gregory Muchka brought this change] + + hostip: (macOS) free returned memory of SCDynamicStoreCopyProxies + + From Apples documentation on SCDynamicStoreCopyProxies, "Return Value: A + dictionary of key-value pairs that represent the current internet proxy + settings, or NULL if no proxy settings have been defined or if an error + occurred. You must release the returned value." + + Failure to release the returned value of SCDynamicStoreCopyProxies can + result in a memory leak. + + Source: https://developer.apple.com/documentation/systemconfiguration/1517088-scdynamicstorecopyproxies + + Closes #7265 + +- RELEASE-NOTES: synced + +Jay Satiro (21 Jun 2021) +- vtls: fix warning due to function prototype mismatch + + b09c8ee changed the function prototype. Caught by Visual Studio. + +- curl_multibyte: Remove local encoding fallbacks + + - If the UTF-8 to UTF-16 conversion fails in Windows Unicode builds then + no longer fall back to assuming the string is in a local encoding. + + Background: + + Some functions in Windows Unicode builds must convert UTF-8 to UTF-16 to + pass to the Windows CRT API wide-character functions since in Windows + UTF-8 is not a valid locale (or at least 99% of the time right now). + + Prior to this change if the Unicode encoding conversion failed then + libcurl would assume, for backwards compatibility with applications that + may have written their code for non-Unicode builds, attempt to convert + the string from local encoding to UTF-16. + + That type of "best effort" could theoretically cause some type of + security or other problem if a string that was locally encoded was also + valid UTF-8, and therefore an unexpected UTF-8 to UTF-16 conversion + could occur. + + Ref: https://github.com/curl/curl/pull/7246 + + Closes https://github.com/curl/curl/pull/7257 + +Daniel Stenberg (20 Jun 2021) +- curl_endian: remove the unused Curl_write64_le function + + The last usage was removed in cca455a36 + + Closes #7280 + +- vtls: only store TIMER_APPCONNECT for non-proxy connect + + Introducing a 'isproxy' argument to the connect function so that it + knows wether to store the time stamp or not. + + Reported-by: Yongkang Huang + Fixes #7274 + Closes #7274 + +- gnutls: set the preferred TLS versions in correct order + + Regression since 781864bedbc57 (curl 7.77.0) + + Reported-by: civodul on github + Assisted-by: Nikos Mavrogiannopoulos + Fixes #7277 + Closes #7278 + +- [Gergely Nagy brought this change] + + configure/cmake: remove checks for unused gethostbyaddr and gethostbyaddr_r + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove checks for unused inet_ntoa and inet_ntoa_r + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove unused define HAVE_PERROR + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure: remove unused check for gai_strerror + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove unused define HAVE_FREEIFADDRS + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove unused define HAVE_FORK + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove unused define HAVE_FDOPEN + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove checks for unused sgtty.h + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove remaining checks for rsa.h + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove remaining checks for err.h + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove remaining checks for crypto.h + + Closes #7276 + +- [Gergely Nagy brought this change] + + configure/cmake: remove checks for unused getservbyport_r + + Closes #7276 + +- --socks4[a]: clarify where the host name is resolved + + Closes #7273 + +- libcurl-security.3: mention file descriptors and forks + + ... and move the security report section last. + + Reported-by: Harry Sintonen + Closes #7270 + +- [Alex Xu (Hello71) brought this change] + + configure.ac: make non-executable + + it needs to be processed by autoconf or autoreconf, and doesn't have a + suitable shebang to be directly executed. other projects normally set + configure.ac -x. + + Closes #7272 + +- configure: do not strip out debug flags + + To allow users to set them when invoking configure without using + --with-debug. + + Reported-by: Alex Xu + Fixes #7216 + Closes #7267 + +- libssh2: limit time a disconnect can take to 1 second + + Closes #7271 + +- TLS: prevent shutdown loops to get stuck + + ... by making sure the loops are only allowed to read the shutdown + traffic a limited number of times. + + Reported-by: Harry Sintonen + Closes #7271 + +- hyper: propagate errors back up from read callbacks + + Makes test 513 work with hyper + + Closes #7266 + +- KNOWN_BUGS: Negotiate on Windows fails + + Closes #5881 + +- KNOWN_BUGS: renames instead of locking for atomic operations + + Closes #6882 + Closes #6884 + +- zuul: add two missing CI jobs + + ... that were configured, just not run + + Closes #7261 + +Viktor Szakats (15 Jun 2021) +- idn: fix libidn2 with windows unicode builds + + Unicode Windows builds use UTF-8 strings internally in libcurl, + so make sure to call the UTF-8 flavour of the libidn2 API. Also + document that Windows builds with libidn2 and UNICODE do expect + CURLOPT_URL as an UTF-8 string. + + Reported-by: dEajL3kA on github + Assisted-by: Jay Satiro + Reviewed-by: Marcel Raad + Closes #7246 + Fixes #7228 + +Daniel Stenberg (15 Jun 2021) +- curl_url_set: reject spaces in URLs w/o CURLU_ALLOW_SPACE + + They were never officially allowed and slipped in only due to sloppy + parsing. Spaces (ascii 32) should be correctly encoded (to %20) before + being part of a URL. + + The new flag bit CURLU_ALLOW_SPACE when a full URL is set, makes libcurl + allow spaces. + + Updated test 1560 to verify. + + Closes #7073 + +- RELEASE-NOTES: synced + + ... and bump to version 7.78.0 for the next planned release. + +Jay Satiro (15 Jun 2021) +- docs: Remove outdated curl tool limitation + + - Document that HTTP/2 multiplexing is supported by the curl tool when + parallel transfers are used. + + Supported since 7.66.0 via --parallel, but the doc wasn't updated. + + Closes https://github.com/curl/curl/pull/7259 + +- http2: Clarify 'Using HTTP2' verbose message + + - Change phrasing from multi-use to multiplexing since the former may + not be as well understood. + + Before: * Using HTTP2, server supports multi-use + + After: * Using HTTP2, server supports multiplexing + + Bug: https://github.com/curl/curl/discussions/7255 + Reported-by: David Hu + + Closes https://github.com/curl/curl/pull/7258 + +Daniel Stenberg (14 Jun 2021) +- winbuild/README: VC should be set to 6 'or larger' + + Previously it listed all versions up to 15 (missing 16) but this new + phrasing is more open ended. + + Reported-by: Hugh Macdonald + Fixes #7253 + Closes #7254 + +- [Jacob Hoffman-Andrews brought this change] + + rustls: remove native_roots fallback + + For the commandline tool, we expect to be passed + SSL_CONN_CONFIG(CAfile); for library use, the use should pass a set of + trusted roots (like in other TLS backends). + + This also removes a dependency on Security.framework when building on + macOS. + + Closes #7250 + +- [Albin Vass brought this change] + + travis: remove jobs that have migrated to zuul + + Closes #7245 + +- [Mohammed Naser brought this change] + + CI: add jobs using Zuul + + It also includes a few changes to get the builds going: + - Added autoconf to common dependencies + - Added automake to common dependencies + - Added libtool to common dependencies + - Added libssl-dev to common dependencies + + Co-authored-by: Albin Vass + + Closes #7245 + +- netrc: skip 'macdef' definitions + + Add test 494 to verify + + Reported-by: Harry Sintonen + Fixes #7238 + Closes #7244 + +- multi: add scan-build-6 work-around in curl_multi_fdset + + scan-build-6 otherwise warns, saying: warning: The left operand of '>=' + is a garbage value otherwise, which is false. + + Later scan-builds don't claim this on the same code. + + Closes #7248 + +- asyn-ares: remove check for 'data' in Curl_resolver_cancel + + It implied it would survive a NULL in there which it won't. Instead do + an assert. + + Pointed out by scan-build. + + Closes #7248 + +- url.c: remove two variable assigns that are never read + + Pointed out by scan-build + + Closes #7248 + +- [Gealber Morales brought this change] + + mqtt: add support for username and password + + Minor-edits-by: Daniel Stenberg + Added test 2200 to 2205 + + Closes #7243 + +- travis: remove the arm job + + We do it on circle CI instead + +- CI: add .circleci/config.yml + + Assisted-by: Gabriel Simmer + + Closes #7239 + +- RELEASE-NOTES: synced + +- runtests: init $VERSION to avoid warnings when using -l + +- openssl: don't remove session id entry in disassociate + + When a connection is disassociated from a transfer, the Session ID entry + should remain. + + Regression since 7f4a9a9 (shipped in libcurl 7.77.0) + Reported-by: Gergely Nagy + Reported-by: Paul Groke + + Fixes #7222 + Closes #7230 + +- single_transfer: ignore blank --output-dir + + ... as otherwise it creates a rather unexpected target directory with a + leading slash. + + Reported-by: Harry Sintonen + Fixes #7218 + Closes #7233 + +- tests: update README about servers and port numbers + + Closes #7242 + +- conn_shutdown: if closed during CONNECT cleanup properly + + Reported-by: Alex Xu + Reported-by: Phil E. Taylor + + Fixes #7236 + Closes #7237 + +- [Christian Weisgerber brought this change] + + sws: malloc request struct instead of using stack + + ... 2MB requests is otherwise just too big for some systems. + + (The allocations are not freed properly.) + + Bug: https://curl.se/mail/lib-2021-06/0018.html + + Closes #7235 + +- [Mark Swaanenburg brought this change] + + lib: don't compare fd to FD_SETSIZE when using poll + + FD_SETSIZE is irrelevant when using poll. So ensuring that the file + descriptor is smaller than FD_SETSIZE in VALID_SOCK, can cause + multi_wait to ignore perfectly valid file descriptors and simply wait + for 1s to avoid hammering the CPU in a busy loop. + + Fixes #7240 + Closes #7241 + +- [zhangxiuhua brought this change] + + doh: fix wrong DEBUGASSERT for doh private_data + + Closes #7227 + +- [yb999 brought this change] + + tests: update README.md with a missing single quote + + Closes #7231 + +- GHA: run all tests for hyper too + + As it lists disabled ones in DISABLED now + + Closes #7209 + +- tests/data/DISABLED: add tests not working with hyper + + The goal is to remove them all from here over time. + + Closes #7209 + +- runtests: also find the last test in Makefile.inc + + Closes #7209 + +- test3010: work with hyper mode + + Closes #7209 + +- configure: disable RTSP when hyper is selected + + Makes test 1013 work + + Closes #7209 + +- test1594/1595/1596: fix to work in hyper mode + + Closes #7209 + +- test1438/1457: add HTTP keyword to make hyper mode work + + Closes #7209 + +- test1340/1341: adjusted for hyper mode + + Closes #7209 + +- test1218: adjusted for hyper mode + + Closes #7209 + +- test1216: adjusted for hyper mode + + Closes #7209 + +- test1230: adjust to work in hyper mode + + Closes #7209 + +- c-hyper: abort CONNECT response reading early on non 2xx responses + + Fixes test 493 + + Closes #7209 + +- test434: add HTTP keyword + + Closes #7209 + +- test599: adjusted to work in hyper mode + + Closes #7209 + +- c-hyper: fix the uploaded field in progress callbacks + + Makes test 578 work + + Closes #7209 + +- test566: adjust to work with hyper mode + + Closes #7209 + +- [Fawad Mirza brought this change] + + CURLOPT_WRITEFUNCTION.3: minor update of the example + + Safely avoid chunk.size garbage value if declared non globally. + + Closes #7219 + +- [Bastian Krause brought this change] + + configure: rename get-easy-option configure option to get-easy-options + + "get-easy-options" is the configure option advertised by the help text + anyway, so use that. + + Fixes #7211 + Closes #7213 + + Follow-up to ad691b191 ("configure: added --disable-get-easy-options") + Suggested-by: Daniel Stenberg <daniel@haxx.se> + Signed-off-by: Bastian Krause <bst@pengutronix.de> + +- runtests: skip disabled tests unless -f is used + + To make it easier to write ranges like '115 to 229' without that + explicitly enabling tests that are listed in DISABLED, this makes + runtests always skip disabled tests unless the -f command line option is + used. + + Previously the code attempted to not run such tests, but didn't do it + correctly. + + Closes #7212 + +- [Jun-ya Kato brought this change] + + ngtcp2: disable TLSv1.3 compatible mode when using GnuTLS + + The latest GnuTLS-3.7.2 implements disable switch for TLSv1.3 compatible + mode for middle box but it is enabled by default, which is unnecessary + for QUIC. + + Fixes #6896 + Closes #7202 + +- test644: remove as duplicate of test 587 + + Closes #7208 + +Daniel Gustafsson (8 Jun 2021) +- RELEASE-NOTES: synced + +- cookies: track expiration in jar to optimize removals + + Removing expired cookies needs to be a fast operation since we want to + be able to perform it often and speculatively. By tracking the timestamp + of the next known expiration we can exit early in case the timestamp is + in the future. + + Closes: #7172 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +Daniel Stenberg (7 Jun 2021) +- GHA: add several libcurl tests to the hyper job + + 500 to 512 + +- test500: adjust to work with hyper mode + +- c-hyper: support CURLINFO_STARTTRANSFER_TIME + + Closes #7204 + +- c-hyper: support CURLOPT_HEADER + + When enabled, the headers are passed to the body write callback as well. + + Like in test 500 + + Closes #7204 + +- GHA: run the newly fixed tests with hyper + + Closes #7205 + +- test433: adjust for hyper mode + + Closes #7205 + +- test395: hyper cannot work around > 64 bit content-lengths like built-in + + Closes #7205 + +- test394: hyper returns a different error + + Closes #7205 + +- test393: make Content-Length fit within 64 bit for hyper + + Closes #7205 + +- test347: CRLFify to work in hyper mode + + Closes #7205 + +- test339: CRLFify better to work in hyper mode + + Closes #7205 + +- travis: remove the hyper build + +- GHA: add a linux-hyper job + + Closes #7206 + +- test328: avoid a header-looking body to make hyper mode work + + The test still works the same, just modified two bytes in the content. + + Closes #7203 + +- release-notes.pl: also spot common 'closes' typo + +- metalink: remove + + Warning: this will make existing curl command lines that use metalink to + stop working. + + Reasons for removal: + + 1. We've found several security problems and issues involving the + metalink support in curl. The issues are not detailed here. When + working on those, it become apparent to the team that several of the + problems are due to the system design, metalink library API and what + the metalink RFC says. They are very hard to fix on the curl side + only. + + 2. The metalink usage with curl was only very briefly documented and was + not following the "normal" curl usage pattern in several ways, making + it surprising and non-intuitive which could lead to further security + issues. + + 3. The metalink library was last updated 6 years ago and wasn't so + active the years before that either. An unmaintained library means + there's a security problem waiting to happen. This is probably reason + enough. + + 4. Metalink requires an XML parsing library, which is complex code (even + the smaller alternatives) and to this day often gets security + updates. + + 5. Metalink is not a widely used curl feature. In the 2020 curl user + survey, only 1.4% of the responders said that they'd are using it. In + 2021 that number was 1.2%. Searching the web also show very few + traces of it being used, even with other tools. + + 6. The torrent format and associated technology clearly won for + downloading large files from multiple sources in parallel. + + Cloes #7176 + +- docs/INSTALL: remove mentions of configure --with-darwin-ssl + + ... as it isn't supported since a while back. + + Make configure fail with a warning if used. + + Reported-by: Vadim Grinshpun + Bug: https://curl.se/mail/lib-2021-06/0008.html + Closes #7200 + +- RELEASE-NOTES: synced + +- [Gregor Jasny brought this change] + + cmake: Avoid leaking absolute paths into exported config + + The `find_libarary` command resolves the library or framework + into an absolute path. In case of system frameworks which are + located within an Xcode-provided SDK this results in the Xcode + path and SDK version being part of the library path. + + Because those library paths end up in the exported CMake config + importing curl will fail once the Xcode location or SDK version + changes: + + ```cmake + set_target_properties(CURL::libcurl PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include" + INTERFACE_LINK_LIBRARIES "lber;ldap;/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk/System/Library/Frameworks/SystemConfiguration.framework;OpenSSL::SSL;OpenSSL::Crypto;ZLIB::ZLIB" + ) + ``` + + A work-around is to link against system-level frameworks with + `-framework XYZ`. In case of `SystemConfiguration` we might be able + to omit the lookup-check because we could assume the framework is + always present. + + Closes #7152 + +- [Shikha Sharma brought this change] + + http2_connisdead: handle trailing GOAWAY better + + When checking the connection the input processing returns error + immediately, we now consider that a dead connnection. + + Bug: https://curl.se/mail/lib-2021-06/0001.html + Closes #7192 + +- [Dmitry Karpov brought this change] + + ares: always store IPv6 addresses first + + Trying dual-stack on some embedded platform, I noticed that quite + frequently (20%) libCurl starts from IPv4 regardless the Happy Eyeballs + timeout value. After debugging this issue, I noticed that this happens + if c-ares resolver response for IPv6 family comes before IPv4 (which was + randomly happening in my tests). + + In such cases, because libCurl puts the last resolver response on top of + the address list, when IPv4 resolver response comes after IPv6 one - the + IPv4 family starts the connection phase instead of IPv6 family. + + The solution for this issue is to always put IPv6 addresses on top of + the address list, regardless the order of resolver responses. + + Bug: https://curl.se/mail/lib-2021-06/0003.html + + Closes #7188 + +- Revert "Revert "socketpair: fix potential hangs"" + + This reverts commit 3e70c3430a370a31eff2c1d8fea29edaca8f1127. + + Thus brings back the change from #7144 as was originally landed in + c769d1eab4de8b + + Closes #7144 (again) + +- [Ebe Janchivdorj brought this change] + + schannel: move code out of SChannel_connect_step1 + + Reviewed-by: Marc Hoersken + Closes #7168 + +- tests/data/Makefile.inc: error: trailing backslash on last line + + Follow-up to d8dcb399b8009d + +- TODO: Support rate-limiting for MQTT + +- [Dmitry Kostjuchenko brought this change] + + warnless: simplify type size handling + + By using sizeof(T), existing defines and relying on the compiler to + define the required signed/unsigned mask. + + Closes #7181 + +Gisle Vanem (4 Jun 2021) +- [Win32] Fix for USE_WATT32 + + My Watt-32 tcp/ip stack works on Windows but it does not have `WSAIoctl()` + +Daniel Stenberg (4 Jun 2021) +- [Alexis Vachette brought this change] + + url: bad CURLOPT_CONNECT_TO syntax now returns error + + Added test 3020 to verify + + Closes #7183 + +- github: remove the cmake macOS gcc-8 jobs + + They're too similar to the gcc-9 ones to be useful (and seems to not + work anymore). + + Closes #7187 + +- test269: disable for hyper + + --ignore-content-length / CURLOPT_IGNORE_CONTENT_LENGTH doesn't work + with hyper. + + Closes #7184 + +- runtests: enable 'hyper mode' only for HTTP tests + + The 'hyper mode' makes line-ending checks work in the test suite for + when hyper is used. Now it also requires that HTTP or HTTPS are + mentioned as keywords to be enabled so that it doesn't wrongly adjusts + tests for other protocols. + + This makes test 271 (TFTP) work again in hyper enabled builds. + + Closes #7185 + +- [Alexis Vachette brought this change] + + hostip: bad CURLOPT_RESOLVE syntax now returns error + + Added test 3019 + Fixes #7170 + Closes #7174 + +Daniel Gustafsson (3 Jun 2021) +- cookies: fix typo and expand comment + + Fix a typo in the sorting comment, and while in there elaborate slightly + on why creationtime can be used as a tiebreaker. + +- cookies: remove unused header + + Commit 1c1d9f1affbd3367bcb24062e261d0ea5d185e3a removed the last use + for the inet_pton.h headerfile, this removes the inclusion of the + header. + + Closes: #7182 + Reviewed-by: Daniel Stenberg <daniel@haxx.se> + +Daniel Stenberg (3 Jun 2021) +- Revert "socketpair: fix potential hangs" + + This reverts commit c769d1eab4de8b9f1bd84d992c63692fdc43c5be. + + See #7144 for details + +- [Paul Groke brought this change] + + socketpair: fix potential hangs + + Fixes potential hang in accept by using select + non-blocking accept. + + Fixes potential hang in peer check by replacing the send/recv check with + a getsockname/getpeername check. + + Adds length check for returned sockaddr data. + + Closes #7144 + +- runtests: parse data/Makefile.inc instead of using make + + The warning about missing entries in that file then doesn't require that + the Makefile has been regenerated which was confusing. + + The scan for the test num is a little more error prone than before + (since now it doesn't actually verify that it is legitimate Makefile + syntax), but I think it is good enough. + + Closes #7177 + +- [Harry Sintonen brought this change] + + filecheck: quietly remove test-place/*~ + + Closes #7179 + +- CURLE_SETOPT_OPTION_SYNTAX: new error name for wrong setopt syntax + + For options that pass in lists or strings that are subsequently parsed + and must be correct. This broadens the scope for the option previously + known as CURLE_TELNET_OPTION_SYNTAX but the old name is of course still + provided as a #define for existing applications. + + Closes #7175 + +- tests: fix Accept-Encoding strips to work with Hyper builds + + The previous strip also removed the CR which turned problematic. + + valgrind.supp: add zstd suppression using hyper + + Reported-and-analyzed-by: Kevin Burke + Fixes #7169 + Closes #7171 + +- github: timeout jobs on macOS after 90 minutes + + Assisted-by: Marc Hoersken + Closes #7173 + +- [Harry Sintonen brought this change] + + mqtt: detect illegal and too large file size + + Add test 3017 and 3018 to verify. + Closes #7166 + +- [theawless brought this change] + + cmake: add CURL_DISABLE_NTLM option + + Closes #7028 + +- [theawless brought this change] + + configure: add --disable-ntlm option + + Closes #7028 + +- [theawless brought this change] + + define: re-add CURL_DISABLE_NTLM and corresponding ifdefs + + This flag will be further exposed by adding build options. + + Reverts #6809 + Closes #7028 + +- RELEASE-NOTES: synced + +Viktor Szakats (1 Jun 2021) +- travis: delete --enable-hsts option (it is the default now) [ci skip] + + Reviewed-by: Daniel Stenberg + Closes #7167 + +Daniel Stenberg (1 Jun 2021) +- hostip: fix 3 coverity complaints + + Follow-up to 1a0ebf6632f889eed + + - Check the return code to Curl_inet_pton() in two instances, even + though we know the input is valid so the functions won't fail. + + - Clear the 'struct sockaddr_in' struct before use so that the + 'sin_zero' field isn't left uninitialized. + + Detected by Coverity. + Assisted-by: Harry Sintonen + Closes #7163 + +- c-hyper: fix NTLM on closed connection tested with test159 + + Closes #7154 + +- conncache: lowercase the hash key for better match + + As host names are case insensitive, the use of case sensitive hashing + caused unnecesary cache misses and therefore lost performance. This + lowercases the hash key. + + Reported-by: Harry Sintonen + Fixes #7159 + Closes #7161 + +- mbedtls: make mbedtls_strerror always work + + If the function doesn't exist, provide a macro that just clears the + error message. Removes #ifdef uses from the code. + + Closes #7162 + +- vtls: exit addsessionid if no cache is inited + + Follow-up to b249592d29ae0 + + Avoids NULL pointer derefs. + + Closes #7165 + +- [Harry Sintonen brought this change] + + Curl_ntlm_core_mk_nt_hash: fix OOM in error path + + Closes #7164 + +Michael Kaufmann (1 Jun 2021) +- ssl: read pending close notify alert before closing the connection + + This avoids a TCP reset (RST) if the server initiates a connection + shutdown by sending an SSL close notify alert and then closes the TCP + connection. + + For SSL connections, usually the server announces that it will close the + connection with an SSL close notify alert. curl should read this alert. + If curl does not read this alert and just closes the connection, some + operating systems close the TCP connection with an RST flag. + + See RFC 1122, section 4.2.2.13 + + If curl reads the close notify alert, the TCP connection is closed + normally with a FIN flag. + + The new code is similar to existing code in the "SSL shutdown" function: + try to read an alert (non-blocking), and ignore any read errors. + + Closes #7095 + +Daniel Stenberg (1 Jun 2021) +- [Laurent Dufresne brought this change] + + setopt: fix incorrect comments + + Closes #7157 + +- [Laurent Dufresne brought this change] + + mbedtls: add support for cert and key blob options + + CURLOPT_SSLCERT_BLOB and CURLOPT_SSLKEY_BLOB weren't usable with + mbedtls backend, so the support was added. + + Closes #7157 + +- [Gregor Jasny brought this change] + + cmake: try well-known send/recv signature for Apple + + The CMake `try_compile` command is especially slow for + the Xcode generator. With this patch applied it first tests + for the currently used (and Open Group specified) send/recv + signature. In case this fails testing falls-back to the + permutations. + + speed-up: + + ``` + time cmake .. -GNinja -DCMAKE_USE_SECTRANSP=ON -DHTTP_ONLY=ON -DCMAKE_USE_LIBSSH2=OFF + before: 11.64s user 11.09s system 55% cpu 40.754 total + after: 7.84s user 6.57s system 51% cpu 28.074 total + ``` + + ``` + time cmake .. -GXcode -DCMAKE_USE_SECTRANSP=ON -DHTTP_ONLY=ON -DCMAKE_USE_LIBSSH2=OFF + before: 217.07s user 104.15s system 60% cpu 8:51.79 total + after: 108.76s user 51.80s system 58% cpu 4:32.58 total + ``` + + Closes #7158 + +- http2: init recvbuf struct for pushed streams + + Debug builds would warn that these structs were not initialized properly + for pushed streams. + + Ref: #7148 + Closes #7153 + +- Curl_ssl_getsessionid: fail if no session cache exists + + This function might get called for an easy handle for which the session + cache hasn't been setup. It now just returns a "miss" in that case. + + Reported-by: Christoph M. Becker + Fixes #7148 + Closes #7153 + +- GOVERNANCE: add 'user', 'committer' and 'contributor' + + As those are commonly used terms in the project. + + Closes #7151 + +- URL-SYNTAX.md: document the new 'localhost' treatment + +- hostip: make 'localhost' return fixed values + + Resolving the case insensitive host name 'localhost' now returns the + addresses 127.0.0.1 and (if IPv6 is enabled) ::1 without using any + resolver. + + This removes the risk that users accidentally resolves 'localhost' to + something else. By making sure 'localhost' is always local, we can + assume a "secure context" for such transfers (for cookies etc). + + Closes #7039 + +Daniel Gustafsson (31 May 2021) +- docs: fix typos + +Daniel Stenberg (30 May 2021) +- hsts: ignore numberical IP address hosts + + Also, use a single function library-wide for detecting if a given hostname is + a numerical IP address. + + Reported-by: Harry Sintonen + Fixes #7146 + Closes #7149 + +- test178: adjust for hyper + + Hyper returns the same error for wrong HTTP version as for negative + content-length. Test 178 verifies that negative content-length is + rejected but the hyper backend will return a different error for it (and + without any helpful message telling why the message was bad). It will + also not return any headers at all for the response, not even the ones + that arrived before the error. + + Closes #7147 + +- HYPER: remove mentions of deprecated development branch + +- c-hyper: handle NULL from hyper_buf_copy() + + Closes #7143 + +- HSTS: not experimental anymore + +- [Douglas R. Reno brought this change] + + INSTALL: use correct extension for CURL-DISABLE.md + + In INSTALL.MD, it's currently set to CURL-DISABLE-md instead of + CURL-DISABLE.md. This generates a 404 on the cURL website as well as + when viewing the docs through Github. + + Closes #7142 + +- travis: run tests 1 - 153 with hyper + +- c-hyper: convert HYPERE_INVALID_PEER_MESSAGE to CURLE_UNSUPPORTED_PROTOCOL + + Makes test 129 work (HTTP/1.2 response). + + Closes #7141 + +- http_proxy: deal with non-200 CONNECT response with Hyper + + Makes test 94 and 95 work + + Closes #7141 + +- c-hyper: clear NTLM auth buffer when request is issued + + To prevent previous ones to get reused on subsequent requests. Matches + how the built-in HTTP code works. Makes test 90 to 93 work. + + Add test 90 to 93 in travis. + + Closes #7139 + +- [Joel Depooter brought this change] + + schannel: set ALPN length correctly for HTTP/2 + + In a3268eca792f1 this code was changed to use the ALPN_H2 constant + instead of the NGHTTP2_PROTO_ALPN constant. However, these constants are + not the same. The nghttp2 constant included the length of the string, + like this: "\x2h2". The ALPN_H2 constant is just "h2". Therefore we need + to re-add the length of the string to the ALPN buffer. + + Closes #7138 + +- travis: run tests 1-89 in the hyper build + + Closes #7137 + +- Revert "c-hyper: handle body on HYPER_TASK_EMPTY" + + This reverts commit c3eefa95c31f55657f0af422e8268d738f689066. + + Reported-by: Kevin Burke + Fixes #7122 + Closes #7136 + +- [Jon Rumsey brought this change] + + ccsidcurl: fix the compile errors + + Looks like the declaration of cpp shoule be const char ** and return + null if convert_version_info_string fails. + + Fixes #7134 + Closes #7135 + +- [Viktor Szakats brought this change] + + docs: use --max-redirs instead of --max-redir + + For consistency. + + Closes #7130 + +- RELEASE-NOTES: synced + + ... and bump to 7.77.1 + +- [Michael Forney brought this change] + + travis: add bearssl build + + Closes #7133 + +- [Michael Forney brought this change] + + bearssl: explicitly initialize all fields of Curl_ssl + + Also, add comments like the other vtls backends. + + Closes #7133 + +- [Michael Forney brought this change] + + bearssl: remove incorrect const on variable that is modified + + hostname may be set to NULL later on in this function if it is an + IP address. + + Closes #7133 + Version 7.77.0 (26 May 2021) Daniel Stenberg (26 May 2021) @@ -5992,1839 +8089,3 @@ Daniel Stenberg (1 Dec 2020) The HAVE_LINUX_TCP_H define was not set by cmake. Closes #6252 - -- NEW-PROTOCOL: document what needs to be done to add one - - Closes #6263 - -- splay: rename Curl_splayremovebyaddr to Curl_splayremove - - ... and remove the old unused proto for the old Curl_splayremove - version. - - Closes #6269 - -- openssl: free mem_buf in error path - - To fix a memory-leak. - - Closes #6267 - -- openssl: remove #if 0 leftover - - Follow-up to 4c9768565ec3a9 (from Sep 2008) - - Closes #6268 - -- ntlm: avoid malloc(0) on zero length user and domain - - ... and simplify the too-long checks somewhat. - - Detected by OSS-Fuzz - - Closes #6264 - -- RELEASE-NOTES: synced - -Marc Hoersken (28 Nov 2020) -- tests/server/tftpd.c: close upload file in case of abort - - Commit c353207 removed the closing right after do_tftp - which covered the case of abort. This handles that case. - - Reviewed-by: Jay Satiro - Reviewed-by: Daniel Stenberg - - Follow up to #6209 - Closes #6234 - -Daniel Stenberg (26 Nov 2020) -- [Daiki Ueno brought this change] - - ngtcp2: use the minimal version of QUIC supported by ngtcp2 - - Closes #6250 - -- [Daiki Ueno brought this change] - - ngtcp2: advertise h3 ALPN unconditionally - - Closes #6250 - -- [Daiki Ueno brought this change] - - vquic/ngtcp2.h: define local_addr as sockaddr_storage - - This field needs to be wide enough to hold sockaddr_in6 when - connecting via IPv6. Otherwise, ngtcp2_conn_read_pkt will drop the - packets because of the address mismatch: - I00000022 [...] con ignore packet from unknown path - - We can safely assume that struct sockaddr_storage is available, as it - is used in the public interface of ngtcp2. - - Closes #6250 - -- socks: check for DNS entries with the right port number - - The resolve call is done with the right port number, but the subsequent - check used the wrong one, which then could find a previous resolve which - would return and leave the fresh resolve "incomplete" and leaking - memory. - - Fixes #6247 - Closes #6253 - -- curl_setup: USE_RESOLVE_ON_IPS is for Apple native resolver use - - ... so don't define it when instructed to use c-ares! - -- test506: make it not run in c-ares builds - - As the asynch nature of it may trigger events in another order. A c-ares - upgrade made it break. - - Reported-by: Marc Hörsken - Fixes #6247 - -- runtests: make 'c-ares' a "feature" to depend on - - ... also added to the docs. - -- tool_writeout: use off_t getinfo-types instead of doubles - - Commit 3b80d3ca46b12e52342 (June 2017) introduced getinfo replacement - variables that use curl_off_t instead of doubles. Switch the --write-out - function over to use them. - - Closes #6248 - -- [Emil Engler brought this change] - - file: avoid duplicated code sequence - - file_disconnect() is identical with file_do() except the function header - but as the arguments are unused anyway so why not just return file_do() - directly! - - Reviewed-by: Daniel Stenberg - Closes #6249 - -- [Rikard Falkeborn brought this change] - - infof/failf calls: fix format specifiers - - Update a few format specifiers to match what is being printed. - - Closes #6241 - -- docs/INTERNALS: remove reference to Curl_sendf() - - The function has been removed from common usage. Also removed comment in - gopher.c that still referenced it. - - Reported-by: Rikard Falkeborn - Fixes #6242 - Closes #6243 - -- [Rikard Falkeborn brought this change] - - examples: update .gitignore - - Add files that are generated by 'make examples' and remove some that - have been renamed. - - The commits that renamed the programs are e9625c5bc6c046a (imap.c and - simplesmtp.c were renamed to imap-fetch.c and smtp-send.c) and - ad39e7ec01e7 (pop3slist.c and pop3s.c were renamed to pop3-list.c and - pop3-ssl.c). - - Closes #6240 - -- asyn: use 'struct thread_data *' instead of 'void *' - - To reduce use of types that can't be checked at compile time. Also - removes several typecasts. - - ... and rename the struct field from 'os_specific' to 'tdata'. - - Closes #6239 - Reviewed-by: Jay Satiro - -Viktor Szakats (23 Nov 2020) -- Makefile.m32: add support for UNICODE builds - - It requires the linker to support the `-municode` option. - This is available in more recent mingw-w64 releases. - - Ref: https://gcc.gnu.org/onlinedocs/gcc/x86-Windows-Options.html - Ref: https://stackoverflow.com/questions/3571250/wwinmain-unicode-and-mingw/11706847#11706847 - - Reviewed-by: Jay Satiro - Reviewed-by: Marcel Raad - - Closes #6228 - -Daniel Stenberg (23 Nov 2020) -- urldata: remove 'void *protop' and create the union 'p' - - ... to avoid the use of 'void *' for the protocol specific structs done - per transfer. - - Closes #6238 - -- winbuild: remove docs from Makefiles and refer to README.md - - Reduce risk for conflicting docs and makes it to a single place to fix - and polish. - - add these missing options to the readme: - - ENABLE_OPENSSL_AUTO_LOAD_CONFIG and ENABLE_UNICODE - - clarify ENABLE_SCHANNEL default varies - - Fixes #6216 - Closes #6227 - Co-Authored-by: Jay Satiro - -- [Daiki Ueno brought this change] - - http3: use the master branch of GnuTLS for testing - - Closes #6235 - -- KNOWN_BUGS: curl with wolfSSL lacks support for renegotiation - - Closes #5839 - -- KNOWN_BUGS: wakeup socket disconnect causes havoc - - Closes #6132 - Closes #6133 - -- RELEASE-NOTES: synced - -- [Oliver Urbann brought this change] - - curl: add compatibility for Amiga and GCC 6.5 - - Changes are mainly reordering and adding of includes required - to compile with a more recent version of GCC. - - Closes #6220 - -Marc Hoersken (20 Nov 2020) -- tests/server/tftpd.c: close upload file right after transfer - - Make sure uploaded file is no longer locked after the - transfer while waiting for the final ACK to be handled. - - Assisted-by: Daniel Stenberg - - Bug: #6058 - Closes #6209 - -- CI/cirrus: simplify logic for disabled tests - - The OpenSSH server instance for the testsuite cannot - be started on FreeBSD, therefore the SFTP and SCP - tests are disabled right away from the beginning. - - The previous OS version specific logic for SKIP_TESTS - is no longer needed/used and can therefore be removed. - - Reviewed-by: Daniel Stenberg - - Follow up to #6211 - Closes #6229 - -Daniel Gustafsson (20 Nov 2020) -- mailmap: Daniel Hwang - - Add Daniel Hwang to the mailmap to cover the alternative spelling - Daniel Lee Hwang which was used in one commit. - - Closes #6230 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - -- openssl: guard against OOM on context creation - - EVP_MD_CTX_create will allocate memory for the context and returns - NULL in case the allocation fails. Make sure to catch any allocation - failures and exit early if so. - - In passing, also move to EVP_DigestInit rather than EVP_DigestInit_ex - as the latter is intended for ENGINE selection which we don't do. - - Closes #6224 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - Reviewed-by: Emil Engler <me@emilengler.com> - -Daniel Stenberg (19 Nov 2020) -- [Vincent Torri brought this change] - - cmake: use libcurl.rc in all Windows builds - - Reviewed-by: Marcel Raad - Closes #6215 - -- [Cristian Morales Vega brought this change] - - cmake: make CURL_ZLIB a tri-state variable - - By differentiating between ON and AUTO it can make a missing zlib - library a hard error when CURL_ZLIB=ON is used. - - Reviewed-by: Jakub Zakrzewski - Closes #6221 - Fixes #6173 - -- quiche: remove 'static' from local buffer - - For thread-safety - - Closes #6223 - -- KNOWN_BUGS: cmake: libspsl is not supported - - Closes #6214 - -- KNOWN_BUGS: cmake autodetects cert paths when cross-compiling - - Closes #6178 - -- KNOWN_BUGS: cmake build doesn't fail if zlib not found - - Closes #6173 - -- KNOWN_BUGS: cmake libcurl.pc uses absolute library paths - - Closes #6169 - -- KNOWN_BUGS: cmake: generated .pc file contains strange entries - - Closes #6167 - -- KNOWN_BUGS: cmake uses -lpthread instead of Threads::Threads - - Closes #6166 - -- KNOWN_BUGS: cmake build in Linux links libcurl to libdl - - Closes #6165 - -- KNOWN_BUGS: make a new section for cmake topics - - Closes #6219 - -- [Emil Engler brought this change] - - cirrus: build with FreeBSD 12.2 in CirrusCI - - Closes #6211 - -Marc Hoersken (14 Nov 2020) -- tests/*server.py: close log file after each log line - - Make sure the log file is not locked once a test has - finished and align with the behavior of our logmsg. - - Rename curl_test_data.py to be a general util.py. - Format and sort Python imports with isort/VSCode. - - Bug: #6058 - Closes #6206 - -Daniel Stenberg (13 Nov 2020) -- CURLOPT_HSTS.3: document the file format - - Closes #6205 - -- RELEASE-NOTES: synced - -- release-notes.pl: detect #[number] better for Ref: etc - -- curl: only warn not fail, if not finding the home dir - - ... as there's no good reason to error out completely. - - Reported-by: Andreas Fischer - Fixes #6200 - Closes #6201 - -- httpput-postfields.c: new example doing PUT with POSTFIELDS - - Proposed-by: Jeroen Ooms - Ref: #6186 - Closes #6188 - -- [Tobias Hieta brought this change] - - cmake: correctly handle linker flags for static libs - - curl CMake was setting the the EXE flags for static libraries which made - the /manifest:no flag ended up when linking the static library, which is - not a valid flag for lib.exe or llvm-lib.exe and caused llvm-lib to exit - with an error. - - The better way to handle this is to make sure that we pass the correct - linker flags to CMAKE_STATIC_LINKER_FLAGS instead. - - Reviewed-by: Jakub Zakrzewski - Closes #6195 - -- [Tobias Hieta brought this change] - - cmake: don't pass -fvisibility=hidden to clang-cl on Windows - - When using clang-cl on windows -fvisibility=hidden is not an known - argument. Instead it behaves exactly like MSVC in this case. So let's - make sure we take that path. - - In CMake clang-cl sets both CMAKE_C_COMPILER_ID=clang and MSVC get's - defined since clang-cl is basically a MSVC emulator. So guarding like we - do in this patch seems logical. - - Reviewed-by: Jakub Zakrzewski - Closes #6194 - -- http_proxy: use enum with state names for 'keepon' - - To make the code clearer, change the 'keepon' from an int to an enum - with better state names. - - Reported-by: Niranjan Hasabnis - Bug: https://curl.se/mail/lib-2020-11/0026.html - Closes #6193 - -- curl_easy_escape: limit output string length to 3 * max input - - ... instead of the limiting it to just the max input size. As every - input byte can be expanded to 3 output bytes, this could limit the input - string to 2.66 MB instead of the intended 8 MB. - - Reported-by: Marc Schlatter - Closes #6192 - -- docs: document the 8MB input string limit - - for curl_easy_escape and curl_easy_setopt() - - The limit is there to catch mistakes and abuse. It is meant to be large - enough to allow virtually all "fine" use cases. - - Reported-by: Marc Schlatter - Fixes #6190 - Closes #6191 - -- mqttd: fclose test file when done - - Reported-by: Marc Hörsken - Reviewed-by: Jay Satiro - Bug: #6058 - Closes #6189 - -- RELEASE-NOTES: synced - -- THANKS-filter: ignore autobuild links - -- Revert "libcurl.pc: make it relocatable" - - This reverts commit 3862c37b6373a55ca704171d45ba5ee91dec2c9f. - - That fix should either be done differently or with an option. - - Reported-by: asavah on github - Fixes #6157 - Closes #6183 - -- examples/httpput: remove use of CURLOPT_PUT - - It is deprecated and unnecessary since it already sets CURLOPT_UPLOAD. - - Reported-by: Jeroen Ooms - Fixes #6186 - Closes #6187 - -- Curl_pgrsStartNow: init speed limit time stamps at start - - By setting the speed limit time stamps unconditionally at transfer - start, we can start off a transfer without speed limits and yet allow - them to get set during transfer and have an effect. - - Reported-by: Kael1117 on github - Fixes #6162 - Closes #6184 - -- ngtcp2: adapt to recent nghttp3 updates - - 'reset_stream' was added to the nghttp3_conn_callbacks struct - - Closes #6185 - -- configure: pass -pthread to Libs.private for pkg-config - - Reported-by: Cristian Morales Vega - Fixes #6168 - Closes #6181 - -- altsvc: minimize variable scope and avoid "DEAD_STORE" - - Closes #6182 - -- FAQ: remove "Why is there a HTTP/1.1 in my HTTP/2 request?" - - This hasn't been the case for a while now, remove. - -- FAQ: refresh "Why do I get "certificate verify failed" - - Add more details, remove references to ancient curl version. - -- test493: verify --hsts upgrade and that %{url_effective} reflects that - - Closes #6175 - -- url: make sure an HSTS upgrade updates URL and scheme correctly - - Closes #6175 - -- tool_operate: set HSTS with CURLOPT_HSTS to pass on filename - - Closes #6175 - -- hsts: remove debug code leftovers - - Closes #6175 - -- FAQ: refreshed - - - remove a few ancient questions - - add configure with static libs question - - updated wording in several places - - lowercased curl - - Closes #6177 - -Daniel Gustafsson (5 Nov 2020) -- examples: fix comment syntax - - Commit ac0a88fd2 accidentally added a stray character outside of the - comment which broke compilation. Fix by removing. - - Reported-by: autobuild https://curl.se/dev/log.cgi?id=20201105084306-12742 - -- hsts: Remove pointless call to free in errorpath - - The line variable will always be NULL in the error path, so remove - the free call since it's pointless. - - Closes #6170 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - -- docs: Fix various typos in documentation - - Closes #6171 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - -Daniel Stenberg (5 Nov 2020) -- copyright: fix year ranges - - Follow-up from 4d2f8006777 - -- HISTORY: the new domain - -- curl.se: new home - - Closes #6172 - -- KNOWN_BUGS: FTPS with Schannel times out file list operation - - Reported-by: bobmitchell1956 on github - Closes #5284 - -- KNOWN_BUGS: SMB tests fail with Python 2 - - Reported-by: Jay Satiro - Closes #5983 - -- KNOWN_BUGS: LDAPS with NSS is slow - - Reported-by: nosajsnikta on github - Closes #5874 - -Sergei Nikulov (4 Nov 2020) -- travis: use ninja-build for CMake builds - - Added package ninja-build to environment - Use ninja to speed up CMake builds - - Closes #6077 - -Daniel Stenberg (4 Nov 2020) -- [Harry Sintonen brought this change] - - rtsp: error out on empty Session ID, unified the code - -- [Harry Sintonen brought this change] - - rtsp: fixed the RTST Session ID mismatch in test 570 - - Closes #6161 - -- [Harry Sintonen brought this change] - - rtsp: fixed Session ID comparison to refuse prefix - - Closes #6161 - -- RELEASE-NOTES: synced - - (forgot to update the list of contributors) - -- RELEASE-NOTES: synced - -- curlver: bumped to 7.74.0 - -- hsts: add read/write callbacks - - - read/write callback options - - man pages for the 4 new setopts - - test 1915 verifies the callbacks - - Closes #5896 - -- hsts: add support for Strict-Transport-Security - - - enable in the build (configure) - - header parsing - - host name lookup - - unit tests for the above - - CI build - - CURL_VERSION_HSTS bit - - curl_version_info support - - curl -V output - - curl-config --features - - CURLOPT_HSTS_CTRL - - man page for CURLOPT_HSTS_CTRL - - curl --hsts (sets CURLOPT_HSTS_CTRL and works with --libcurl) - - man page for --hsts - - save cache to disk - - load cache from disk - - CURLOPT_HSTS - - man page for CURLOPT_HSTS - - added docs/HSTS.md - - fixed --version docs - - adjusted curl_easy_duphandle - - Closes #5896 - -- [Sergei Nikulov brought this change] - - CI/tests: enable test target on TravisCI for CMake builds - - Added test-nonflaky target to CMake builds - - Disabled test 1139 because the cmake build doesn't create docs/curl.1 - - Closes #6074 - -- tool_debug_cb: do not assume zero-terminated data - - Follow-up to d70a5b5a0f5e3 - -- sendf: move the verbose-check into Curl_debug - - Saves us from having the same check done everywhere. - - Closes #6159 - -- travis: use valgrind when running tests for debug builds - - Except the non-x86 and sanitizer builds - - Closes #6154 - -- header.d: fix syntax mistake - - follow-up from 1144886f38fd0 - -- [Harry Sintonen brought this change] - - gnutls: fix memory leaks (certfields memory wasn't released) - - Closes #6153 - -- tests: add missing global_init/cleanup calls - - Without the cleanup call in these test files, the mbedTLS backend leaks - memory. - - Closes #6156 - -- tool_operate: --retry for HTTP 408 responses too - - This was inadvertently dropped from the code when the parallel support - was added. - - Regression since b88940850 (7.66.0) - - Reviewed-by: Jay Satiro - Closes #6155 - -- http: pass correct header size to debug callback for chunked post - - ... when the chunked framing was added, the size of the "body part" of - the data was calculated wrongly so the debug callback would get told a - header chunk a few bytes too big that would also contain the first few - bytes of the request body. - - Reported-by: Dirk Wetter - Ref: #6144 - Closes #6147 - -- header.d: mention the "Transfer-Encoding: chunked" handling - - Ref: #6144 - Closes #6148 - -- acinclude: detect manually set minimum macos/ipod version - - ... even if set in the CC or IPHONEOS/MACOSX_DEPLOYMENT_TARGET - variables. - - Reported-by: hamstergene on github - Fixes #6138 - Closes #6140 - -Jay Satiro (29 Oct 2020) -- tests: fix some http/2 tests for older versions of nghttpx - - - Add regex that strips http/2 server header name to those http/2 tests - that don't already have it. - - - Improve that regex in all http/2 tests. - - Tests 358 and 359 were failing for me before this change on a system - that uses an older version of nghttpx which includes its version number - in the server header. - - Closes https://github.com/curl/curl/pull/6139 - -Daniel Stenberg (30 Oct 2020) -- RELEASE-NOTES: synced - -- [Cristian Morales Vega brought this change] - - configure: use pkgconfig to find openSSL when cross-compiling - - This reverts 736a40fec (November 2004), which doesn't explain why it was - done. - - Closes #6145 - -- tool_operate: bail out proper on errors for parallel setup - - ... otherwise for example trying to upload a missing file just causes a - loop. - - Reported-by: BrumBrum on hackerone - Closes #6141 - -- [Sergei Nikulov brought this change] - - CMake: make BUILD_TESTING dependent option - - CMake will now handle BUILD_TESTING depending on PERL_FOUND and - CURL_DISABLE_TESTING - - Ref: #6036 - Closes #6072 - -- libssh2: fix transport over HTTPS proxy - - The fix in #6021 was not enough. This fix makes sure SCP/SFTP content - can also be transfered over a HTTPS proxy. - - Fixes #6113 - Closes #6128 - -- curl.1: add an "OUTPUT" section at the top of the manpage - - Explain the basic concepts behind curl output. - - Inspired by #6124 - - Closes #6134 - -- mailmap: set Viktor Szakats's email - -- runtests: show keywords when no tests ran - - To help out future debugging, runtests now outputs the list of keywords - when it fails because no tests ran. - - Ref: #6120 - Closes #6126 - -Jay Satiro (26 Oct 2020) -- CURLOPT_DNS_USE_GLOBAL_CACHE.3: fix typo - - Reported-by: Rui LIU - - Closes https://github.com/curl/curl/issues/6131 - -- range.d: fix typo - - Follow-up to 15ae039 from earlier today. - -Daniel Stenberg (26 Oct 2020) -- CI/github: work-around for brew breakage on macOS - - ... and make it use OpenSSL 1.1 properly - - Fixes #6130 - Closes #6129 - -- [José Joaquín Atria brought this change] - - range.d: clarify that curl will not parse multipart responses - - Closes #6127 - Fixes #6124 - -- RELEASE-NOTES: synced - -- [Baruch Siach brought this change] - - libssh2: fix build with disabled proxy support - - Build breaks because the http_proxy field is missing: - - vssh/libssh2.c:3119:10: error: 'struct connectdata' has no member named 'http_proxy' - - Regression from #6021, shipped in curl 7.73.0 - - Closes #6125 - -- alt-svc: enable by default - - Remove CURLALTSVC_IMMEDIATELY, which was never implemented/supported. - - alt-svc support in curl is no longer considered experimental - - Closes #5868 - -- CI/appveyor: remove (unused) runtests.pl -b option - -- [Emil Engler brought this change] - - tool_help: make "output" description less confusing - - Currently the description of "output" is misleading when comparing it - "verbose". - - Closes #6118 - -- CI/appveyor: disable test 571 in two cmake builds - - ... they're simply too flaky there. - - Closes #6119 - -- cmake: set the unicode feature in curl-config on Windows - - ... if built that way. To make it match curl -V output. - - Reviewed-by: Marcel Raad - Closes #6117 - -- libssh2: require version 1.0 or later - - ... and simplify the code accordingly. libssh2 version 1.0 was released - in April 2009. - - Closes #6116 - -- KNOWN_BUGS: mention the individual cmake issues - - ... to make them easier to refer to and address separately and - one-by-one. - -- CMake: store IDN2 information in curl_config.h - - This allows the build to enable IDN properly and it makes test 1014 - happier. - - Ref: #6074 - Closes #6108 - -- CMake: call the feature unixsockets without dash - - ... so that curl-config gets correct and makes test 1014 happy! - - Ref: #6074 - Closes #6108 - -- CI/travis: add brotli and zstd to the libssh2 build - - ... to make sure such tests are run with valgrind. Suppress the zstd - valgrind warnings we get with version 1.3.3 on Ubuntu 18.04 (for debug - and non-debug builds). - - Closes #6105 - -- runtests: revert the mistaken edit of $CURL - - Regression from c4693adc62 - -- RELEASE-NOTES: synced - -- curl_url_set.3: fix typo in the RETURN VALUE section - - Reported-by: Basuke Suzuki - Fixes #6102 - -Jay Satiro (17 Oct 2020) -- [Daniel Stenberg brought this change] - - packages/OS400: make the source code-style compliant - - ... and make sure 'make checksrc' in the root dir also verifies the - packages/OS400 sources. - - Closes https://github.com/curl/curl/pull/6085 - -- os400: Sync libcurl API options - - This fixes the OS400 build and also an incorrect entry for - CURLINFO_APPCONNECT_TIME_T where it was treated as - CURLINFO_STARTTRANSFER_TIME_T. - - Reported-by: Jon Rumsey - - Fixes https://github.com/curl/curl/issues/6083 - Closes https://github.com/curl/curl/pull/6084 - -Daniel Stenberg (16 Oct 2020) -- CURLOPT_NOBODY.3: fix typo - - Reported-by: Basuke Suzuki - Fixes #6097 - -Marc Hoersken (16 Oct 2020) -- CI/azure: improve on flakiness by avoiding libtool wrappers - - Install curl binaries into MinGW bin folder and use that - for the tests in order to avoid libtool wrapper binaries. - - The libtool wrapper binaries (not scripts) on Windows seem - to be one of the possible causes for the following issues: - - 1. Process output can be lost in the wrapper process chain. - 2. Killing the wrapper process does not kill the actual one. - - Derived from #5904 - Closes #6049 - -Daniel Stenberg (16 Oct 2020) -- CURLOPT_URL.3: clarify SCP/SFTP URLs are for uploads as well - -- [Zenju brought this change] - - CURLOPT_TCP_NODELAY.3: fix comment in example code - - Closes #6096 - -- openssl: acknowledge SRP disabling in configure properly - - Follow-up to 68a513247409 - - Use a new separate define that is the combination of both - HAVE_OPENSSL_SRP and USE_TLS_SRP: USE_OPENSSL_SRP - - Bug: https://curl.haxx.se/mail/lib-2020-10/0037.html - - Closes #6094 - -Viktor Szakats (16 Oct 2020) -- http3: fix two build errors, silence warnings - - * fix two build errors due to mismatch between function - declarations and their definitions - * silence two mismatched signs warnings via casts - - Approved-by: Daniel Stenberg - Closes #6093 - -- Makefile.m32: add support for HTTP/3 via ngtcp2+nghttp3 - - Approved-by: Daniel Stenberg - Closes #6092 - -Daniel Stenberg (16 Oct 2020) -- tool_operate: fix compiler warning when --libcurl is disabled - - Closes #6095 - -- checksrc: warn on empty line before open brace - - ... and fix a few occurances - - Closes #6088 - -- urlapi: URL encode a '+' in the query part - - ... when asked to with CURLU_URLENCODE. - - Extended test 1560 to verify. - Reported-by: Dietmar Hauser - Fixes #6086 - Closes #6087 - -- [Cristian Morales Vega brought this change] - - libcurl.pc: make it relocatable - - It supposes when people specify the libdir/includedir they do it to - change where under prefix/exec_prefix it should be, not to make it - independent of prefix/exec_prefix. - - Closes #6061 - -- runtests: return error if no tests ran - - ... and make TESTFAIL stand out a little better by adding newlines - before and after. - - Reported-by: Marc Hörsken - Issue: #6052 - Closes #6053 - -- docs/FEATURE: convert to markdown - - ... and clean it up a bit. - - Closes #6067 - -- [Philipp Klaus Krause brought this change] - - strerror: use 'const' as the string should never be modified - - Closes #6068 - -- [Jay Satiro brought this change] - - connect: repair build without ipv6 availability - - Assisted-by: Daniel Stenberg - Reported-by: Tom G. Christensen - - Fixes https://github.com/curl/curl/issues/6069 - Closes https://github.com/curl/curl/pull/6071 - -- RELEASE-NOTES: synced - - Started over for the journey to next release. - -- src/tool_filetime: disable -Wformat on mingw for this file - - With gcc 10 on mingw we otherwise get this warning: - - error: ISO C does not support the 'I' printf flag [-Werror=format=] - - Fixes #6079 - Closes #6082 - -- test122[12]: remove these two tests - - ... and remove the objnames scripts they tested. They're not used for - anything anymore so testing them serves no purpose! - - Reported-by: Marc Hörsken - Fixes #6080 - Closes #6081 - -Version 7.73.0 (14 Oct 2020) - -Daniel Stenberg (14 Oct 2020) -- RELEASE-NOTES: synced - - for 7.73.0 - -- THANKS: from 7.73.0 and .mailmap fixes - -- mailmap: fixups of some contributors - -- projects/build-wolfssl.bat: fix the copyright year range - -Marc Hoersken (14 Oct 2020) -- [Sergei Nikulov brought this change] - - CI/tests: fix invocation of tests for CMake builds - - Update appveyor.yml to set env variable TFLAGS and run tests - Remove curly braces due to CMake error (${TFLAGS} -> $TFLAGS) - Move testdeps build to build step (per review comments) - - Reviewed-by: Marc Hörsken - - Closes #6066 - Fixes #6052 - -- tests/server/util.c: fix support for Windows Unicode builds - - Detected via #6066 - Closes #6070 - -Daniel Stenberg (13 Oct 2020) -- [Jay Satiro brought this change] - - strerror: Revert to local codepage for Windows error string - - - Change get_winapi_error() to return the error string in the local - codepage instead of UTF-8 encoding. - - Two weeks ago bed5f84 fixed get_winapi_error() to work on xbox, but it - also changed the error string's encoding from local codepage to UTF-8. - - We return the local codepage version of the error string because if it - is output to the user's terminal it will likely be with functions which - expect the local codepage (eg fprintf, failf, infof). - - This is essentially a partial revert of bed5f84. The support for xbox - remains but the error string is reverted back to local codepage. - - Ref: https://github.com/curl/curl/pull/6005 - - Reviewed-by: Marcel Raad - Closes #6065 - -Marc Hoersken (13 Oct 2020) -- CI/tests: use verification curl for test reporting APIs - - Avoid using our own, potentially installed, curl for - the test reporting APIs in case it is broken. - - Reviewed-by: Daniel Stenberg - - Preparation for #6049 - Closes #6063 - -Viktor Szakats (12 Oct 2020) -- windows: fix comparison of mismatched types warning - - clang 10, mingw-w64: - ``` - vtls/openssl.c:2917:33: warning: comparison of integers of different signs: 'DWORD' (aka 'unsigned long') and 'HRESULT' (aka 'long') - [-Wsign-compare] - if(GetLastError() != CRYPT_E_NOT_FOUND) - ~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~ - ``` - - Approved-by: Daniel Stenberg - Closes #6062 - -Daniel Stenberg (11 Oct 2020) -- [Viktor Szakats brought this change] - - src/Makefile.m32: fix undefined curlx_dyn_* errors - - by linking `lib/dynbuf.c` when building a static curl binary. - Previously this source file was only included when building - a dynamic curl binary. This was likely possibly because no - functions from the `src/Makefile.inc` / `CURLX_CFILES` sources - were actually required for a curl tool build. This has - recently changed with the introduction of `curlx_dyn_*()` - memory functions and their use by the tool sources. - - Closes #6060 - -- HISTORY: curl verifies SSL certs by default since version 7.10 - -Marc Hoersken (8 Oct 2020) -- runtests.pl: use $LIBDIR variable instead of hardcoded path - - Reviewed-by: Daniel Stenberg - Closes #6051 - -Daniel Stenberg (7 Oct 2020) -- checksrc: detect // comments on column 0 - - Spotted while working on #6045 - - Closes #6048 - -- [Frederik Wedel-Heinen brought this change] - - mbedtls: add missing header when defining MBEDTLS_DEBUG - - Closes #6045 - -- curl: make sure setopt CURLOPT_IPRESOLVE passes on a long - - Previously, it would pass on a define (int) which could make libcurl - read junk as a value - which prevented the CURLOPT_IPRESOLVE option to - "take". This could then make test 2100 do two DoH requests instead of - one! - - Fixes #6042 - Closes #6043 - -- RELEASE-NOTES: synced - -- scripts/release-notes.pl: don't "embed" $ in format string for printf() - - ... since they might contain %-codes that mess up the output! - -Jay Satiro (5 Oct 2020) -- [M.R.T brought this change] - - build-wolfssl: fix build with Visual Studio 2019 - - Closes https://github.com/curl/curl/pull/6033 - -Daniel Stenberg (4 Oct 2020) -- runtests: add %repeat[]% for test files - - ... and use this new keywords in all the test files larger than 50K to reduce - their sizes and make them a lot easier to read and understand. - - Closes #6040 - -- [Emil Engler brought this change] - - --help: move two options from the misc category - - The cmdline opts delegation and suppress-connect-headers - fit better into auth and proxy rather than misc. - - Follow-up to aa8777f63febc - Closes #6038 - -- [Samanta Navarro brought this change] - - docs/opts: fix typos in two manual pages - - Closes #6039 - -- ldap: reduce the amount of #ifdefs needed - - Closes #6035 - -- runtests: provide curl's version string as %VERSION for tests - - ... so that we can check HTTP requests for User-Agent: curl/%VERSION - - Update 600+ test cases accordingly. - - Closes #6037 - -- checksrc: warn on space after exclamation mark - - Closes #6034 - -- test1465: verify --libcurl with binary POST data - -- runtests: allow generating a binary sequence from hex - -- tool_setopt: escape binary data to hex, not octal - -- curl: make --libcurl show binary posts correctly - - Reported-by: Stephan Mühlstrasser - Fixes #6031 - Closes #6032 - -Jay Satiro (1 Oct 2020) -- strerror: fix null deref on winapi out-of-memory - - Follow-up to bed5f84 from several days ago. - - Ref: https://github.com/curl/curl/pull/6005 - -Daniel Stenberg (1 Oct 2020) -- [Kamil Dudka brought this change] - - vtls: deduplicate some DISABLE_PROXY ifdefs - - ... in the code of gtls, nss, and openssl - - Closes #5735 - -- RELEASE-NOTES: synced - -- [Emil Engler brought this change] - - TODO: Add OpenBSD libtool notice - - See #5862 - Closes #6030 - -- tests/unit/README: convert to markdown - - ... and add to dist! - - Closes #6028 - -- tests/README: convert to markdown - - Closes #6028 - -- include/README: convert to markdown - - Closes #6028 - -- examples/README: convert to markdown - - Closes #6028 - -- configure: don't say HTTPS-proxy is enabled when disabled! - - Reported-by: Kamil Dudka - Reviewed-by: Kamil Dudka - Bug: https://github.com/curl/curl/pull/5735#issuecomment-701376388 - Closes #6029 - -Daniel Gustafsson (30 Sep 2020) -- src: Consistently spell whitespace without whitespace - - Whitespace is spelled without a space between white and space, so - make sure to consistently spell it that way across the codebase. - - Closes #6023 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - Reviewed-by: Emil Engler <me@emilengler.com> - -- MANUAL: update examples to resolve without redirects - - www.netscape.com is redirecting to a cookie consent form on Aol, and - cool.haxx.se isn't responding to FTP anymore. Replace with examples - that resolves in case users try out the commands when reading the - manual. - - Closes #6024 - Reviewed-by: Daniel Stenberg <daniel@haxx.se> - Reviewed-by: Emil Engler <me@emilengler.com> - -Daniel Stenberg (30 Sep 2020) -- HISTORY: add some 2020 events - -- sectransp: make it build with --disable-proxy - - Follow-up from #5466 and f3d501dc678d80 - Reported-by: Javier Navarro - Fixes #6025 - Closes #6026 - -- ECH: renamed from ESNI in docs and configure - - Encrypted Client Hello (ECH) is the current name. - - Closes #6022 - -- configure: use "no" instead of "disabled" for the end summary - - ... for consistency but also to make them more distinctly stand out next - to the "enabled" lines. - -- TODO: SSH over HTTPS proxy with more backends - - ... as right now only the libssh2 backend supports it. - -- libssh2: handle the SSH protocols done over HTTPS proxy - - Reported-by: Robin Douine - Fixes #4295 - Closes #6021 - -- [Emil Engler brought this change] - - memdebug: remove 9 year old unused debug function - - There used to be a way to have memdebug fill allocated memory. 9 years - later this has no value there (valgrind and ASAN etc are way better). If - people need to know about it they can have a look at VCS logs. - - Closes #5973 - -- sendf: move Curl_sendf to dict.c and make it static - - ... as the only remaining user of that function. Also fix gopher.c to - instead use Curl_write() - - Closes #6020 - -- ROADMAP: updates and cleanups - - Fix the HSTS PR - - Remove DoT, thread-safe init and hard-coded localhost. I feel very - little interest for these with users so I downgrade them to plain "TODO" - entries again. - -- schannel: return CURLE_PEER_FAILED_VERIFICATION for untrusted root - - This matches what is returned in other TLS backends in the same - situation. - - Reviewed-by: Jay Satiro - Reviewed-by: Emil Engler - Follow-up to 5a3efb1 - Reported-by: iammrtau on github - Fixes #6003 - Closes #6018 - -- RELEASE-NOTES: synced - -- ftp: make a 552 response return CURLE_REMOTE_DISK_FULL - - Added test 348 to verify. Added a 'STOR' command to the test FTP - server to enable test 348. Documented the command in FILEFORMAT.md - - Reported-by: Duncan Wilcox - Fixes #6016 - Closes #6017 - -- pause: only trigger a reread if the unpause sticks - - As an unpause might itself get paused again and then triggering another - reread doesn't help. - - Follow-up from e040146f22608fd9 (shipped since 7.69.1) - - Bug: https://curl.haxx.se/mail/lib-2020-09/0081.html - Patch-by: Kunal Chandarana - Fixes #5988 - Closes #6013 - -- test163[12]: require http to be built-in to run - - ... as speaking over an HTTPS proxy implies http! - - Closes #6014 - -- ngtcp2: adapt to new NGTCP2_PROTO_VER_MAX define - - Closes #6012 - -- [Javier Blazquez brought this change] - - strerror: honor Unicode API choice on Windows - - Closes #6005 - -- imap: make imap_send use dynbuf for the send buffer management - - Reuses the buffer and thereby reduces number of mallocs over a transfer. - - Closes #6010 - -- Curl_send: return error when pre_receive_plain can't malloc - - ... will probably trigger some false DEAD CODE positives on non-windows - code analyzers for the conditional code. - - Closes #6011 - -- ftp: separate FTPS from FTP over "HTTPS proxy" - - When using HTTPS proxy, SSL is used but not in the view of the FTP - protocol handler itself so separate the connection's use of SSL from the - FTP control connection's sue. - - Reported-by: Mingtao Yang - Fixes #5523 - Closes #6006 - -Dan Fandrich (23 Sep 2020) -- tests/data: Fix some mismatched XML tags in test cases - - This allows these test files to pass xmllint. - -Daniel Stenberg (23 Sep 2020) -- pingpong: use a dynbuf for the *_pp_sendf() function - - ... reuses the same dynamic buffer instead of doing repeated malloc/free - cycles. - - Test case 100 (FTP dir list PASV) does 7 fewer memory allocation calls - after this change in my test setup (132 => 125), curl 7.72.0 needed 140 - calls for this. - - Test case 103 makes 9 less allocations now (130). Down from 149 in - 7.72.0. - - Closes #6004 - -- dynbuf: add Curl_dyn_vaddf - - Closes #6004 - -- dynbuf: make *addf() not require extra mallocs - - ... by introducing a printf() function that appends directly into a - dynbuf: Curl_dyn_vprintf(). This avoids the mandatory extra malloc so if - the buffer is already big enough it can just printf directly into it. - - Since this less-malloc version requires tthe use of a library internal - printf function, we only provide this version when building libcurl and - not for the dynbuf code that is used when building the curl tool. - - Closes #5998 - -- KNOWN_BUGS: Unable to use PKCS12 certificate with Secure Transport - - Closes #5403 - -- pingpong: remove a malloc per Curl_pp_vsendf call - - This typically makes 7-9 fewer mallocs per FTP transfer. - - Closes #5997 - -- symbian: drop support - - The OS is deprecated. I see no traces of anyone having actually built - curl for Symbian after 2012. - - The public headers are unmodified. - - Closes #5989 - -- RELEASE-NOTES: synced - -- curl_krb5.h: rename from krb5.h - - Follow-up from f4873ebd0be32cf - - Turns out some older openssl installations go bananas otherwise. - Reported-by: Tom van der Woerdt - Fixes #5995 - Closes #5996 - -- test1297: verify GOT_NOTHING with http proxy tunnel - -- http_proxy: do not count proxy headers in the header bytecount - - ... as that counter is subsequently used to detect if nothing was - returned from the peer. This made curl return CURLE_OK when it should - have returned CURLE_GOT_NOTHING. - - Fixes #5992 - Reported-by: Tom van der Woerdt - Closes #5994 - -- setopt: return CURLE_BAD_FUNCTION_ARGUMENT on bad argument - - Fixed two return code mixups. CURLE_UNKNOWN_OPTION is saved for when the - option is, yeah, not known. Clarified this in the setopt man page too. - - Closes #5993 - -- krb5: merged security.c and krb specific FTP functions in here - - These two files were always tightly connected and it was hard to - understand what went into which. This also allows us to make the - ftpsend() function static (moved from ftp.c). - - Removed security.c - Renamed curl_sec.h to krb5.h - - Closes #5987 - -- Curl_handler: add 'family' to each protocol - - Makes get_protocol_family() faster and it moves the knowledge about the - "families" to each protocol handler, where it belongs. - - Closes #5986 - -- parsedate: tune the date to epoch conversion - - By avoiding an unnecessary error check and the temp use of the tm - struct, the time2epoch conversion function gets a little bit faster. - When repeating test 517, the updated version is perhaps 1% faster (on - one particular build on one particular architecture). - - Closes #5985 - -- cmake: remove scary warning - - Remove the text saying - - "the curl cmake build system is poorly maintained. Be aware" - - ... not because anything changed just now, but to encourage users to use - it and subsequently improve it. - - Closes #5984 - -- docs/MQTT: remove outdated paaragraphs - -- docs/MQTT: not experimental anymore - - Follow-up to e37e4468688d8f - -- docs/RESOURCES: remove - - This document is not maintained and rather than trying to refresh it, - let's kill it. A more up-to-date document with relevant RFCs is this - page on the curl website: https://curl.haxx.se/rfc/ - - Closes #5980 - -- docs/TheArtOfHttpScripting: convert to markdown - - Makes it easier to browse on github etc. Offers (better) links. - - It should be noted that this document is already mostly outdated and - "Everything curl" at https://ec.haxx.se/ is a better resource and - tutorial. - - Closes #5981 - -- BUGS: convert document to markdown - - Closes #5979 - -- --help: strdup the category - - ... since it is converted and the original pointer is freed on Windows - unicode handling. - - Follow-up to aa8777f63febc - Fixes #5977 - Closes #5978 - Reported-by: xwxbug on github - -- CHECKSRC: document two missing warnings - -- RELEASE-NOTES: synced - -- ftp: avoid risk of reading uninitialized integers - - If the received PASV response doesn't match the expected pattern, we - could end up reading uninitialized integers for IP address and port - number. - - Issue pointed out by muse.dev - Closes #5972 - -- [Quentin Balland brought this change] - - easy_reset: clear retry counter - - Closes #5975 - Fixes #5974 - -- ftp: get rid of the PPSENDF macro - - The use of such a macro hides some of what's actually going on to the - reader and is generally disapproved of in the project. - - Closes #5971 - -- man pages: switch to https://example.com URLs - - Since HTTPS is "the new normal", this update changes a lot of man page - examples to use https://example.com instead of the previous "http://..." - - Closes #5969 - -- github: remove the duplicate "Security vulnerability" entry - - ... since github adds an entry automatically by itself. - - Closes #5970 - -- [Emil Engler brought this change] - - github: use new issue template feature - - This helps us to avoid getting feature requests as well as security - bugs reported into the issue tracker. - - Closes #5936 - -- [Emil Engler brought this change] - - urlapi: use more Curl_safefree - - Closes #5968 - -Marc Hoersken (17 Sep 2020) -- multi: align WinSock mask variables in Curl_multi_wait - - Also skip pre-checking sockets to set timeout_ms to 0 - after the first socket has been detected to be ready. - - Reviewed-by: rcombs on github - Reviewed-by: Daniel Stenberg - - Follow up to #5886 - -- multi: reuse WinSock events variable in Curl_multi_wait - - Since the struct is quite large (1 long and 10 ints) we - declare it once at the beginning of the function instead - of multiple times inside loops to avoid stack movements. - - Reviewed-by: Viktor Szakats - Reviewed-by: Daniel Stenberg - - Closes #5886 - -Daniel Stenberg (16 Sep 2020) -- TODO: dynamically decide to use socketpair - - Suggested-by: Anders Bakken - - Closes #4829 - -- TODO: add PR reference for native IDN support on macOS - - As there was work started on this that never got completed. - - Closes #5371 - -- tool_help.h: update copyright year range - - Follow-up from aa8777f63febca - -- CI/azure: disable test 571 in the msys2 builds - - It's just too flaky there - - Reviewed-by: Marc Hoersken - Closes #5954 - -- tool_writeout: protect fputs() from NULL - - When the code was changed to do fputs() instead of fprintf() it got - sensitive for NULL pointers; add checks for that. - - Follow-up from 0c1e767e83ec66 - - Closes #5963 - -- test3015: verify stdout "as text" - - Follow-up from 0c1e767e83e to please win32 tests - - Closes #5962 - -- travis: use libressl v3.1.4 instead of master - - ... as their git master seems too fragile to use (and 3.2.1 which is the - latest has a build failure). - - Closes #5964 - -- tests/FILEFORMAT: document type=shell for <command> - -- tests/FILEFORMAT: document nonewline support for <file> - - The one in <client>, that creates files. - - Follow-up from b83947c8df7 - -- [anio brought this change] - - tool_writeout: add new writeout variable, %{num_headers} - - This variable gives the number of headers. - - Closes #5947 - -- tool_urlglob: fix compiler warning "unreachable code" - - (On Windows builds.) - - Follow-up to 70a3b003d9 - -- [Gergely Nagy brought this change] - - vtls: deduplicate client certificates in ssl_config_data - - Closes #5629 - -- ftp: a 550 response to SIZE returns CURLE_REMOTE_FILE_NOT_FOUND - - This is primarily interesting for cases where CURLOPT_NOBODY is set as - previously curl would not return an error for this case. - - MDTM getting 550 now also returns this error (it returned - CURLE_FTP_COULDNT_RETR_FILE before) in order to unify return codes for - missing files across protocols and specific FTP commands. - - libcurl already returns error on a 550 as a MDTM response (when - CURLOPT_FILETIME is set). If CURLOPT_NOBODY is not set, an error would - happen subsequently anyway since the RETR command would fail. - - Add test 1913 and 1914 to verify. Updated several tests accordingly due - to the updated SIZE behavior. - - Reported-by: Tomas Berger - Fixes #5953 - Closes #5957 - -- curl: make checkpasswd use dynbuf - - Closes #5952 - -- curl: make glob_match_url use dynbuf - - Closes #5952 - -- curl: make file2memory use dynbuf - - Closes #5952 - -- curl: make file2string use dynbuf - - Closes #5952 - -- [Antarpreet Singh brought this change] - - imap: set cselect_bits to CURL_CSELECT_IN initially - - ... when continuing a transfer from a FETCH response. - - When the size of the file was small enough that the entirety of the - transfer happens in a single go and schannel buffers holds the entire - data. However, it wasn't completely read in Curl_pp_readresp since a - line break was found before that could happen. So, by the time we are in - imap_state_fetch_resp - there's data in buffers that needs to be read - via Curl_read but nothing to read from the socket. After we setup a - transfer (Curl_setup_transfer), curl just waits on the socket state to - change - which doesn't happen since no new data ever comes. - - Closes #5961 - -- RELEASE-NOTES: synced - -- test434: test -K use in a single line without newline - - Closes #5946 - -- runtests: allow creating files without newlines - - Closes #5946 - -- curl: use curlx_dynbuf for realloc when loading config files - - ... fixes an integer overflow at the same time. - - Reported-by: ihsinme on github - Assisted-by: Jay Satiro - - Closes #5946 - -- dynbuf: provide curlx_ names for reuse by the curl tool - - Closes #5946 - -- dynbuf: make sure Curl_dyn_tail() zero terminates - - Closes #5959 diff --git a/contrib/libs/curl/RELEASE-NOTES b/contrib/libs/curl/RELEASE-NOTES index 3786d16593..1dc81810fc 100644 --- a/contrib/libs/curl/RELEASE-NOTES +++ b/contrib/libs/curl/RELEASE-NOTES @@ -1,154 +1,198 @@ -curl and libcurl 7.77.0 +curl and libcurl 7.78.0 - Public curl releases: 200 + Public curl releases: 201 Command line options: 242 curl_easy_setopt() options: 290 Public functions in libcurl: 85 - Contributors: 2408 + Contributors: 2459 This release includes the following changes: - o configure: make the TLS library choice(s) explicit [3] - o curl: ignore options asking for SSLv2 or SSLv3 [10] - o hsts: enable by default [8] - o SSL: support in-memory CA certs for some backends [85] - o vtls: refuse setting any SSL version [9] + o curl_url_set: reject spaces in URLs w/o CURLU_ALLOW_SPACE [118] + o CURLE_SETOPT_OPTION_SYNTAX: new error name for wrong setopt syntax [40] + o hostip: make 'localhost' return fixed values [16] + o mbedtls: add support for cert and key blob options [11] + o metalink: remove all support for it [54] + o mqtt: add support for username and password [91] This release includes the following bugfixes: - o CVE-2021-22297: schannel cipher selection surprise [132] - o CVE-2021-22298: TELNET stack contents disclosure [131] - o CVE-2021-22901: TLS session caching disaster [130] - o AmigaOS: add functions definitions for SHA256 [126] - o build: fix compilation for Windows UWP platform [82] - o c-hyper: don't write to set.writeheader if null [67] - o c-hyper: fix handling of zero-byte chunk from hyper [39] - o c-hyper: handle body on HYPER_TASK_EMPTY [104] - o checksrc: complain on == NULL or != 0 checks in conditions [20] - o CI/cirrus: add shared and static Windows release builds [102] - o cmake: add CURL_ENABLE_EXPORT_TARGET option [133] - o cmake: check for getppid and utimes [87] - o cmake: detect CURL_SA_FAMILY_T [124] - o cmake: fix two invokes result in different curl_config.h [123] - o cmake: make libcurl output filename configurable [41] - o cmake: Use multithreaded compilation on VS 2008+ [122] - o config: remove now-unused macros [107] - o configure: if asked for, fail if ldap is not found [109] - o configure: provide --with-openssl, deprecate --with-ssl [15] - o conn: add 'attach' to protocol handler, make libssh2 use it [119] - o connect: use CURL_SA_FAMILY_T for portability [34] - o ConnectionExists: respect requests for h1 connections better - o cookie: CURLOPT_COOKIEFILE set to NULL switches off cookies [1] - o curl-wolfssl.m4: without custom include path, assume /usr/include [116] - o curl: include libmetalink version in --version output [111] - o Curl_http_header: check for colon when matching Persistent-Auth [51] - o Curl_http_input_auth: require valid separator after negotiation type [52] - o Curl_input_digest: require space after Digest [50] - o curl_mprintf.3: add description [73] - o curl_setup: provide the shutdown flags wider [33] - o curl_url_set.3: add memory management information [38] - o CURLcode: add CURLE_SSL_CLIENTCERT [47] - o CURLOPT_CAPATH.3: defaults to a path, not NULL [103] - o CURLOPT_IPRESOLVE: preventing wrong IP version from being used [125] - o CURLOPT_POSTFIELDS.3: clarify how it gets the size of the data [40] - o data_pending: check only SECONDARY socket for FTP(S) transfers [117] - o docs/TheArtOfHttpScripting: fix markdown links [129] - o docs: camelcase it like GitHub everywhere [62] - o docs: cookies from HTTP headers need domain set [121] - o docs: fix typo in fail-with-body doc [63] - o docs: improve INTERNALS.md regarding getsock cb [105] - o docs: replace dots with dashes in markdown enums [101] - o easy: ignore sigpipe in curl_easy_send [69] - o FILEFORMAT: mention sectransp as a feature [89] - o GIT-INFO: suggest using autoreconf instead of buildconf [96] - o github: add a workflow with libssh2 on macOS using cmake [81] - o github: inhibit deprecated declarations for clang on macOS [118] - o GnuTLS: don't allow TLS 1.3 for versions that don't support it [77] - o gnutls: make setting only the MAX TLS allowed version work [83] - o gskit: fix CURL_DISABLE_PROXY build [57] - o gskit: fix undefined reference to 'conn' [58] - o hostip.h: remove declaration of unimplemented function [108] - o hostip: remove the debug code for LocalHost [113] - o http2: call the handle-closed function correctly on closed stream [37] - o http2: fix a resource leak in push_promise() [54] - o http2: fix resource leaks in set_transfer_url() [55] - o http2: make sure pause is done on HTTP [120] - o http2: move the stream error field to the per-transfer storage [36] - o http2: skip immediate parsing of payload following protocol switch [90] - o http2: use nghttp2_session_upgrade2 instead of nghttp2_session_upgrade [91] - o HTTP3.md: fix nghttp2's HTTP/3 server port [21] - o HTTP3.md: make the ngtcp2 build use the quictls fork [98] - o http: deal with partial CONNECT sends [97] - o http: fix the check for 'Authorization' with Bearer [53] - o http: limit the initial send amount to used upload buffer size [99] - o http: reset the header buffer when sending the request [61] - o http: use offsets inst of integer literals for header parsing [95] - o INSTALL: add IBM i specific quirks [75] - o krb5/name_to_level: replace checkprefix with curl_strequal [49] - o krb5: don't use 'static' to store PBSZ size response [23] - o krb5: remove the unused 'overhead' function [35] - o lib/hostip6.c: make NAT64 address synthesis on macOS work [135] - o lib1564.c: enable last wakeup test part on Windows [26] - o lib: fix 0-length Curl_client_write calls [60] - o lib: fix some misuse of curlx_convert_UTF8_to_tchar [64] - o libcurl-security.3: be careful of setuid [66] - o libcurl-security.3: don't try to filter IPv4 hosts based on the URL [71] - o libcurl.3: mention the URL API [76] - o libssh2: fix Value stored to 'sshp' is never read [13] - o libssh2: ignore timeout during disconnect [45] - o libssh: fix "empty expression statement has no effect" warnings [7] - o libtest: remove lib530.c [88] - o m4: add security frameworks on Mac when compiling rustls [31] - o multi: don't close connection HTTP_1_1_REQUIRED - o multi: fix slow write/upload performance on Windows [27] - o multi: reduce Win32 API calls to improve performance [28] - o ngtcp2: fix the cb_acked_stream_data_offset proto [46] - o NSS: add ciphers to map [30] - o NSS: make colons, commas and spaces valid separators in cipher list [106] - o nss_set_blocking: avoid static for sock_opt [72] - o ntlm: precaution against super huge type2 offsets [65] - o openldap: protect SSL-specific code with proper #ifdef [12] - o openldap: replace ldap_ prefix on private functions [84] - o openssl: fix build error with OpenSSL < 1.0.2 [4] - o openssl: remove unneeded cast for CertOpenSystemStore() [93] - o os400: additional support for options metadata [24] - o progress: fix scan-build-11 warnings [92] - o progress: reset limit_size variables at transfer start [114] - o progress: when possible, calculate transfer speeds with microseconds [48] - o README.md: delete Codacy UTM parameters [5] - o Revert "Revert 'multi: implement wait using winsock events'" [26] - o rustls: only return CURLE_AGAIN when TLS session is fully drained [2] - o rustls: use ALPN [56] - o sasl: use 'unsigned short' to store mechanism [112] - o schannel: Disable auto credentials; add an option to enable it [18] - o schannel: Support strong crypto option [44] - o sectransp: allow cipher name to be specified [29] - o sectransp: fix EXC_BAD_ACCESS caused by uninitialized buffer [136] - o sigpipe: ignore SIGPIPE when using wolfSSL as well [70] - o sockfilt: avoid getting stuck waiting for writable socket [80] - o sockfilt: fix invalid increment of handles index variable nfd [79] - o sws: #ifdef S_IFSOCK use [32] - o sws: allow HTTP requests up to 2MB in size [100] - o test server: take care of siginterrupt() deprecation [25] - o test2100: make it run with and require IPv6 [127] - o tests/disable-scan.pl: also scan all m4 files [17] - o tests/getpart: generate output URL encoded for better diffs [128] - o tests: ignore case of chunked hex numbers in tests [86] - o tls: add USE_HTTP2 define [59] - o tool_getparam: handle failure of curlx_convert_tchar_to_UTF8() [78] - o tool_getparam: replace (in-place) '%20' by '+' according to RFC1866 [14] - o tool_operate: don't discard failed parallel transfer result [16] - o tool_writeout: fix the HTTP_CODE json output [11] - o travis: disable the failing libssh build [94] - o URL-SYNTAX: update IDNA section for WHATWG spec changes [74] - o urlapi: "normalize" numerical IPv4 host names [6] - o vauth: factor base64 conversions out of authentication procedures [22] - o version: add gsasl_version to curl_version_info_data [43] - o version: add OpenLDAP version in the output [110] - o vtls: deduplicate some DISABLE_PROXY ifdefs [19] - o vtls: reset ssl use flag upon negotiation failure [42] - o wolfssl: handle SSL_write() returns 0 for error [68] - o wolfssl: remove SSLv3 support leftovers [115] + o --socks4[a]: clarify where the host name is resolved [107] + o ares: always store IPv6 addresses first [20] + o asyn-ares: remove check for 'data' in Curl_resolver_cancel [89] + o bearssl: explicitly initialize all fields of Curl_ssl [1] + o bearssl: remove incorrect const on variable that is modified [1] + o build: fix compiler warnings when CURL_DISABLE_VERBOSE_STRINGS [155] + o c-hyper: abort CONNECT response reading early on non 2xx responses [75] + o c-hyper: add support for transfer-encoding in the request [121] + o c-hyper: bail on too long response headers [115] + o c-hyper: clear NTLM auth buffer when request is issued [23] + o c-hyper: convert HYPERE_INVALID_PEER_MESSAGE to CURLE_UNSUPPORTED_PROTOCOL [21] + o c-hyper: fix NTLM on closed connection tested with test159 [4] + o c-hyper: fix the uploaded field in progress callbacks [78] + o c-hyper: handle NULL from hyper_buf_copy() [19] + o c-hyper: support CURLINFO_STARTTRANSFER_TIME [29] + o c-hyper: support CURLOPT_HEADER [32] + o ccsidcurl: fix the compile errors [27] + o CI/cirrus: install impacket from PyPI instead of FreeBSD packages [166] + o CI: add bearssl build [1] + o CI: add Circle CI [92] + o CI: add jobs using Zuul [86] + o CI: delete --enable-hsts option (it is the default now) [2] + o CI: remove travis details [144] + o cleanup: spell DoH with a lowercase o [172] + o cmake: add CURL_DISABLE_NTLM option [44] + o cmake: avoid leaking absolute paths into exported config [3] + o cmake: fix IoctlSocket FIONBIO check [156] + o cmake: fix support for UnixSockets feature on Win32 [104] + o cmake: remove libssh2 feature checks [122] + o cmake: try well-known send/recv signature for Apple [12] + o configure.ac: make non-executable [109] + o configure/cmake: remove checks for many unused functions [95] + o configure: add --disable-ntlm option [45] + o configure: disable RTSP when hyper is selected [68] + o configure: do not strip out debug flags [110] + o configure: fix nghttp2 library name for static builds [157] + o configure: inhibit the implicit-fallthrough warning on gcc-12 [106] + o configure: rename get-easy-option configure option to get-easy-options [81] + o conn_shutdown: if closed during CONNECT cleanup properly [59] + o conncache: lowercase the hash key for better match [5] + o cookies: track expiration in jar to optimize removals [25] + o copyright: add boiler-plate headers to CI config files [143] + o crustls: bump crustls version and use new URL [119] + o curl.h: <sys/select.h> is supported by VxWorks7 [102] + o curl.h: include sys/select.h for NuttX RTOS [100] + o curl: ignore blank --output-dir [57] + o curl_endian: remove the unused Curl_write64_le function [85] + o curl_multibyte: Remove local encoding fallbacks [58] + o Curl_ntlm_core_mk_nt_hash: fix OOM in error path [8] + o Curl_ssl_getsessionid: fail if no session cache exists [14] + o CURLOPT_WRITEFUNCTION.3: minor update of the example [80] + o docs/BINDINGS: fix outdated links [116] + o docs/examples: use curl_multi_poll() in multi examples [152] + o docs/INSTALL: remove mentions of configure --with-darwin-ssl [55] + o docs: document missing arguments to commands [160] + o docs: fix inconsistencies in EGDSOCKET documentation [159] + o docs: fix incorrect argument name reference [161] + o docs: Fix typos [146] + o docs: make docs for --etag-save match the program behaviour [169] + o docs: use --max-redirs instead of --max-redir [28] + o doh: (void)-prefix call to curl_easy_setopt + o doh: fix wrong DEBUGASSERT for doh private_data [62] + o easy: during upkeep, attach Curl_easy to connections in the cache [171] + o examples/multi-single: fix scan-build warning [150] + o examples: length-limit two sscanf() uses of %s [96] + o examples: safer and more proper read callback logic [127] + o filecheck: quietly remove test-place/*~ [39] + o formdata: avoid "Argument cannot be negative" warning [131] + o formdata: correct typecast in curl_mime_data call [137] + o GHA: add a linux-hyper job [52] + o GHA: add several libcurl tests to the hyper job + o GHA: run the newly fixed tests with hyper [36] + o github: timeout jobs on macOS after 90 minutes [42] + o glob: pass an 'int' as len when using printf's %*s [139] + o gnutls: set the preferred TLS versions in correct order [94] + o GOVERNANCE: add 'user', 'committer' and 'contributor' [15] + o hostip: (macOS) free returned memory of SCDynamicStoreCopyProxies [105] + o hostip: bad CURLOPT_RESOLVE syntax now returns error [35] + o hsts: ignore numberical IP address hosts [17] + o HSTS: not experimental anymore + o http2: clarify 'Using HTTP2' verbose message [63] + o http2: init recvbuf struct for pushed streams [13] + o http2_connisdead: handle trailing GOAWAY better [18] + o http: fix crash in rate-limited upload [142] + o http: make the haproxy support work with unix domain sockets [99] + o http_proxy: deal with non-200 CONNECT response with Hyper [22] + o hyper: propagate errors back up from read callbacks [113] + o HYPER: remove mentions of deprecated development branch + o idn: fix libidn2 with windows unicode builds [117] + o infof: remove newline from format strings, always append it [149] + o lib: don't compare fd to FD_SETSIZE when using poll [61] + o lib: fix compiler warnings with CURL_DISABLE_NETRC [168] + o lib: fix type of len passed to *printf's %*s [133] + o lib: more %u for port and int for %*s fixes [132] + o lib: use %u instead of %ld for port number printf [134] + o libcurl-security.3: mention file descriptors and forks [108] + o libssh2: limit time a disconnect can take to 1 second [111] + o mbedtls: make mbedtls_strerror always work [6] + o mbedtls: Remove unnecessary include [175] + o mqtt: detect illegal and too large file size [43] + o mqtt: extend the error message for no topic [136] + o msnprintf: return number of printed characters excluding null byte [148] + o multi: add scan-build-6 work-around in curl_multi_fdset [88] + o multi: alter transfer timeout ordering [97] + o multi: do not switch off connect_only flag when closing [98] + o multi: fix crash in curl_multi_wait / curl_multi_poll [153] + o netrc: skip 'macdef' definitions [87] + o ngtcp2: disable TLSv1.3 compatible mode when using GnuTLS [83] + o openssl: avoid static variable for seed flag [101] + o openssl: don't remove session id entry in disassociate [56] + o pinnedpubkey.d: fix formatting for version support lists [126] + o proto.d: fix formatting for paragraphs after margin changes [125] + o quiche: use send() instead of sendto() to avoid macOS issue [103] + o Revert "c-hyper: handle body on HYPER_TASK_EMPTY" [26] + o Revert "ftp: Expression 'ftpc->wait_data_conn' is always false" [147] + o runtests: also find the last test in Makefile.inc [66] + o runtests: enable 'hyper mode' only for HTTP tests [34] + o runtests: init $VERSION to avoid warnings when using -l + o runtests: parse data/Makefile.inc instead of using make [38] + o runtests: skip disabled tests unless -f is used [82] + o rustls: remove native_roots fallback [65] + o schannel: set ALPN length correctly for HTTP/2 [24] + o SChannel: Use '_tcsncmp()' instead [164] + o sectransp: check for client certs by name first, then file [167] + o setopt: fix incorrect comments [10] + o socketpair: fix potential hangs [37] + o socks4: scan for the IPv4 address in resolve results [124] + o ssl: read pending close notify alert before closing the connection [9] + o sws: malloc request struct instead of using stack [60] + o telnet: fix option parser to not send uninitialized contents [170] + o test1116: hyper doesn't pass through "surprise-trailers" [123] + o test1147: hyper doesn't allow "crazy" request headers like built-in [114] + o test1151: added missing CRLF to work with hyper [120] + o test1216: adjusted for hyper mode [73] + o test1218: adjusted for hyper mode [72] + o test1230: adjust to work in hyper mode [74] + o test1340/1341: adjusted for hyper mode [71] + o test1438/1457: add HTTP keyword to make hyper mode work [70] + o test1514: add a CRLF to the response to make it correct [130] + o test1518: adjusted to work with hyper [129] + o test1519: adjusted to work with hyper [128] + o test1594/1595/1596: fix to work in hyper mode [69] + o test269: disable for hyper [33] + o test3010: work with hyper mode [67] + o test328: avoid a header-looking body to make hyper mode work [53] + o test339: CRLFify better to work in hyper mode [51] + o test347: CRLFify to work in hyper mode [50] + o test393: make Content-Length fit within 64 bit for hyper [49] + o test394: hyper returns a different error [48] + o test395: hyper cannot work around > 64 bit content-lengths like built-in [47] + o test433: adjust for hyper mode [46] + o test434: add HTTP keyword [76] + o test500: adjust to work with hyper mode + o test566: adjust to work with hyper mode [79] + o test599: adjusted to work in hyper mode [77] + o test644: remove as duplicate of test 587 [84] + o tests: fix Accept-Encoding strips to work with Hyper builds [41] + o TLS: prevent shutdown loops to get stuck [112] + o tool: make _lseeki64() macro work with the PellesC compiler [163] + o tool_help: document that --tlspassword takes a password [162] + o tool_help: remove unused define [154] + o url.c: remove two variable assigns that are never read [90] + o url: (void)-prefix a curl_url_get() call [138] + o url: bad CURLOPT_CONNECT_TO syntax now returns error [31] + o version: turn version number functions into returning void [135] + o vtls: exit addsessionid if no cache is inited [7] + o vtls: fix connection reuse checks for issuer cert and case sensitivity [165] + o vtls: only store TIMER_APPCONNECT for non-proxy connect [93] + o vtls: use free() not curl_free() [140] + o warnless: simplify type size handling [30] + o Win32: fix build with Watt-32 + o winbuild/README: VC should be set to 6 'or larger' [64] + o winbuild: support alternate nghttp2 static lib name [174] + o wolfssl: failing to set a session id is not reason to error out [151] + o write-out.d: clarify urlnum is not unique for de-globbed URLs [145] + o zuul: use the new rustls directory name [141] This release includes the following known bugs: @@ -157,161 +201,199 @@ This release includes the following known bugs: This release would not have looked like this without help, code, reports and advice from friends like these: - 3eka on github, Alessandro Ghedini, Andrew Barnert, Ayushman Singh Chauhan, - Benjamin Riefenstahl, Blake Burkhart, Brad Spencer, Calvin Buckley, - Cameron Cawley, Dan Fandrich, Daniel Carpenter, Daniel Gustafsson, - Daniel Stenberg, David Cook, Denis Goleshchikhin, Dmitry Karpov, - Dmitry Kostjuchenko, ebejan on github, Emil Engler, Georeth Zhou, - Gergely Nagy, Gilles Vollant, Harry Sintonen, Howard Chu, Ikko Ashimine, - Illarion Taev, Jacob Hoffman-Andrews, Jakub Zakrzewski, Javier Blazquez, - J. Bromley, Jeroen Ooms, Joel Depooter, Joel Jakobsson, Johann150 on github, - Jon Rumsey, Kamil Dudka, Kevin Burke, Kevin R. Bulgrien, Koichi Shiraishi, - Lucas Clemente Vella, Lucas Servén Marín, MAntoniak on github, Marc Aldorasi, - Marcel Raad, Marc Hörsken, Martin Dorey, Martin Halle, Matias N. Goldberg, - Max Dymond, Michael Kolechkin, Michael O'Farrell, Michał Antoniak, - Michal Rus, Morten Minde Neergaard, Oliver Urbann, Orgad Shaneh, - Patrick Monnerat, Paweł Wegner, Peng-Yu Chen, Pontus Lundkvist, Radek Zajic, - Ralph Langendam, Ray Satiro, rcombs on github, Rich FitzJohn, - Ryan Beck-Buysse, Sergey Markelov, sergio-nsk on github, Stefan Karpinski, - Timo Lange, Timothy Gu, tmkk on github, Tobias Gabriel, Tommy Odom, - Travis Burtrum, Tuomas Siipola, ustcqidi on github, Victor Vieux, - Viktor Szakats, Wes Hinsley, Ymir1711 on github, Yusuke Nakamura, - (82 contributors) + Albin Vass, Aleksander Mazur, Alexis Vachette, Alex Xu, Andrea Pappacoda, + Andrei Rybak, Bachue Zhou, Bastian Krause, Bin Lan, Bin Meng, + Christian Weisgerber, Christoph M. Becker, civodul on github, Dan Fandrich, + Daniel Gustafsson, Daniel Stenberg, David Hu, dEajL3kA on github, + Dmitry Karpov, Dmitry Kostjuchenko, Douglas R. Reno, Ebe Janchivdorj, + Fawad Mirza, Francisco Munoz, Gabriel Simmer, Gealber Morales, Gergely Nagy, + Gerrit Renker, Gisle Vanem, Gregor Jasny, Gregory Muchka, Harry Sintonen, + Hugh Macdonald, Jacob Hoffman-Andrews, Jishan Shaikh, Joel Depooter, + Jonathan Wernberg, Jon Rumsey, Josh Soref, Josie Huddleston, Jun-ya Kato, + Kevin Burke, Laurent Dufresne, Li Xinwei, MAntoniak on github, Marcel Raad, + Marc Hörsken, Mark Swaanenburg, Martin Howarth, Max Zettlmeißl, + Michael Forney, Michael Kaufmann, Mohammed Naser, nian6324 on github, + Nikos Mavrogiannopoulos, Paul Groke, Peter Körner, Phil E. Taylor, + Pierre Yager, Randolf J, Ray Satiro, Red Hat Product Security, + Richard Marion, Richard Whitehouse, Sergey Markelov, Shikha Sharma, + shithappens2016 on github, sylgal on github, Timur Artikov, Tobias Nyholm, + Tommy Chiang, User Sg, Vadim Grinshpun, Valentín Gutiérrez, Viktor Szakats, + William Desportes, Wyatt OʼDay, Xiang Xiao, Yongkang Huang, Younes El-karama, + Zhang Xiuhua, Борис Верховский, Коваленко Анатолий Викторович, + (83 contributors) References to bug reports and discussions on issues: - [1] = https://curl.se/bug/?i=6889 - [2] = https://curl.se/bug/?i=6894 - [3] = https://curl.se/bug/?i=6897 - [4] = https://curl.se/bug/?i=6920 - [5] = https://curl.se/bug/?i=6919 - [6] = https://curl.se/bug/?i=6863 - [7] = https://curl.se/bug/?i=6847 - [8] = https://curl.se/bug/?i=6700 - [9] = https://curl.se/bug/?i=6773 - [10] = https://curl.se/bug/?i=6772 - [11] = https://curl.se/bug/?i=6905 - [12] = https://curl.se/bug/?i=6901 - [13] = https://curl.se/bug/?i=6900 - [14] = https://curl.se/bug/?i=6895 - [15] = https://curl.se/bug/?i=6887 - [16] = https://curl.se/bug/?i=6921 - [17] = https://curl.se/bug/?i=1165 - [18] = https://curl.se/bug/?i=2262 - [19] = https://curl.se/bug/?i=6660 - [20] = https://curl.se/bug/?i=6912 - [21] = https://curl.se/bug/?i=6964 - [22] = https://curl.se/bug/?i=6654 - [23] = https://curl.se/bug/?i=6963 - [24] = https://curl.se/bug/?i=6574 - [25] = https://curl.se/bug/?i=6529 - [26] = https://curl.se/bug/?i=6245 - [27] = https://curl.se/bug/?i=6146 - [28] = https://curl.se/bug/?i=6146 - [29] = https://curl.se/bug/?i=6464 - [30] = https://curl.se/bug/?i=6670 - [31] = https://curl.se/bug/?i=6955 - [32] = https://curl.se/mail/lib-2021-04/0074.html - [33] = https://curl.se/mail/lib-2021-04/0073.html - [34] = https://curl.se/mail/lib-2021-04/0071.html - [35] = https://curl.se/bug/?i=6947 - [36] = https://curl.se/bug/?i=6910 - [37] = https://curl.se/bug/?i=6862 - [38] = https://curl.se/bug/?i=6953 - [39] = https://curl.se/bug/?i=6951 - [40] = https://curl.se/bug/?i=6943 - [41] = https://curl.se/bug/?i=6933 - [42] = https://curl.se/bug/?i=6934 - [43] = https://curl.se/bug/?i=6843 - [44] = https://curl.se/bug/?i=6734 - [45] = https://curl.se/bug/?i=6990 - [46] = https://curl.se/mail/lib-2021-05/0019.html - [47] = https://curl.se/bug/?i=6721 - [48] = https://curl.se/bug/?i=7017 - [49] = https://curl.se/bug/?i=6993 - [50] = https://curl.se/bug/?i=6993 - [51] = https://curl.se/bug/?i=6993 - [52] = https://curl.se/bug/?i=6993 - [53] = https://curl.se/bug/?i=6988 - [54] = https://curl.se/bug/?i=6986 - [55] = https://curl.se/bug/?i=6986 - [56] = https://curl.se/bug/?i=6960 - [57] = https://curl.se/bug/?i=6981 - [58] = https://curl.se/bug/?i=6980 - [59] = https://curl.se/bug/?i=6959 - [60] = https://curl.se/bug/?i=6954 - [61] = https://curl.se/bug/?i=7018 - [62] = https://curl.se/bug/?i=6979 - [63] = https://curl.se/bug/?i=6977 - [64] = https://github.com/curl/curl/pull/6602#issuecomment-825236763 - [65] = https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33720 - [66] = https://curl.se/bug/?i=6970 - [67] = https://curl.se/bug/?i=6619 - [68] = https://curl.se/bug/?i=6967 - [69] = https://curl.se/bug/?i=6965 - [70] = https://curl.se/bug/?i=6966 - [71] = https://curl.se/bug/?i=6942 - [72] = https://curl.se/bug/?i=6945 - [73] = https://curl.se/bug/?i=7010 - [74] = https://curl.se/bug/?i=7026 - [75] = https://curl.se/bug/?i=6830 - [76] = https://curl.se/bug/?i=7009 - [77] = https://curl.se/bug/?i=7014 - [78] = https://curl.se/bug/?i=7023 - [79] = https://curl.se/bug/?i=6992 - [80] = https://curl.se/bug/?i=6992 - [81] = https://curl.se/bug/?i=7047 - [82] = https://curl.se/bug/?i=7006 - [83] = https://curl.se/bug/?i=6998 - [84] = https://curl.se/bug/?i=7004 - [85] = https://curl.se/bug/?i=6662 - [86] = https://curl.se/bug/?i=6987 - [87] = https://curl.se/bug/?i=6997 - [88] = https://curl.se/bug/?i=6999 - [89] = https://curl.se/bug/?i=7001 - [90] = https://curl.se/bug/?i=7036 - [91] = https://curl.se/bug/?i=7041 - [92] = https://curl.se/mail/lib-2021-05/0022.html - [93] = https://curl.se/bug/?i=7025 - [94] = https://curl.se/bug/?i=7011 - [95] = https://curl.se/bug/?i=7032 - [96] = https://curl.se/bug/?i=7033 - [97] = https://curl.se/bug/?i=6950 - [98] = https://curl.se/bug/?i=7031 - [99] = https://curl.se/bug/?i=7022 - [100] = https://curl.se/bug/?i=7075 - [101] = https://curl.se/bug/?i=7093 - [102] = https://curl.se/bug/?i=6991 - [103] = https://curl.se/bug/?i=7062 - [104] = https://curl.se/bug/?i=7064 - [105] = https://curl.se/bug/?i=7092 - [106] = https://curl.se/bug/?i=7110 - [107] = https://curl.se/bug/?i=7094 - [108] = https://curl.se/bug/?i=7094 - [109] = https://curl.se/bug/?i=7053 - [110] = https://curl.se/bug/?i=7054 - [111] = https://curl.se/bug/?i=7112 - [112] = https://curl.se/bug/?i=7045 - [113] = https://curl.se/bug/?i=7044 - [114] = https://curl.se/bug/?i=7042 - [115] = https://curl.se/bug/?i=7088 - [116] = https://curl.se/bug/?i=7085 - [117] = https://curl.se/bug/?i=7068 - [118] = https://curl.se/bug/?i=7081 - [119] = https://curl.se/bug/?i=6898 - [120] = https://curl.se/bug/?i=7079 - [121] = https://curl.se/bug/?i=6723 - [122] = https://curl.se/bug/?i=7109 - [123] = https://curl.se/bug/?i=7100 - [124] = https://curl.se/bug/?i=7049 - [125] = https://curl.se/bug/?i=6853 - [126] = https://github.com/jens-maus/amissl/issues/15 - [127] = https://curl.se/bug/?i=7083 - [128] = https://curl.se/bug/?i=7083 - [129] = https://curl.se/bug/?i=7097 - [130] = https://curl.se/docs/CVE-2021-22901.html - [131] = https://curl.se/docs/CVE-2021-22898.html - [132] = https://curl.se/docs/CVE-2021-22897.html - [133] = https://curl.se/bug/?i=7060 - [135] = https://curl.se/bug/?i=7121 - [136] = https://curl.se/bug/?i=7126 + [1] = https://curl.se/bug/?i=7133 + [2] = https://curl.se/bug/?i=7167 + [3] = https://curl.se/bug/?i=7152 + [4] = https://curl.se/bug/?i=7154 + [5] = https://curl.se/bug/?i=7159 + [6] = https://curl.se/bug/?i=7162 + [7] = https://curl.se/bug/?i=7165 + [8] = https://curl.se/bug/?i=7164 + [9] = https://curl.se/bug/?i=7095 + [10] = https://curl.se/bug/?i=7157 + [11] = https://curl.se/bug/?i=7157 + [12] = https://curl.se/bug/?i=7158 + [13] = https://curl.se/bug/?i=7153 + [14] = https://curl.se/bug/?i=7148 + [15] = https://curl.se/bug/?i=7151 + [16] = https://curl.se/bug/?i=7039 + [17] = https://curl.se/bug/?i=7146 + [18] = https://curl.se/mail/lib-2021-06/0001.html + [19] = https://curl.se/bug/?i=7143 + [20] = https://curl.se/mail/lib-2021-06/0003.html + [21] = https://curl.se/bug/?i=7141 + [22] = https://curl.se/bug/?i=7141 + [23] = https://curl.se/bug/?i=7139 + [24] = https://curl.se/bug/?i=7138 + [25] = https://curl.se/bug/?i=7172 + [26] = https://curl.se/bug/?i=7122 + [27] = https://curl.se/bug/?i=7134 + [28] = https://curl.se/bug/?i=7130 + [29] = https://curl.se/bug/?i=7204 + [30] = https://curl.se/bug/?i=7181 + [31] = https://curl.se/bug/?i=7183 + [32] = https://curl.se/bug/?i=7204 + [33] = https://curl.se/bug/?i=7184 + [34] = https://curl.se/bug/?i=7185 + [35] = https://curl.se/bug/?i=7170 + [36] = https://curl.se/bug/?i=7205 + [37] = https://curl.se/bug/?i=7144 + [38] = https://curl.se/bug/?i=7177 + [39] = https://curl.se/bug/?i=7179 + [40] = https://curl.se/bug/?i=7175 + [41] = https://curl.se/bug/?i=7169 + [42] = https://curl.se/bug/?i=7173 + [43] = https://curl.se/bug/?i=7166 + [44] = https://curl.se/bug/?i=7028 + [45] = https://curl.se/bug/?i=7028 + [46] = https://curl.se/bug/?i=7205 + [47] = https://curl.se/bug/?i=7205 + [48] = https://curl.se/bug/?i=7205 + [49] = https://curl.se/bug/?i=7205 + [50] = https://curl.se/bug/?i=7205 + [51] = https://curl.se/bug/?i=7205 + [52] = https://curl.se/bug/?i=7206 + [53] = https://curl.se/bug/?i=7203 + [54] = https://curl.se/bug/?i=7176 + [55] = https://curl.se/mail/lib-2021-06/0008.html + [56] = https://curl.se/bug/?i=7222 + [57] = https://curl.se/bug/?i=7218 + [58] = https://curl.se/bug/?i=7257 + [59] = https://curl.se/bug/?i=7236 + [60] = https://curl.se/mail/lib-2021-06/0018.html + [61] = https://curl.se/bug/?i=7240 + [62] = https://curl.se/bug/?i=7227 + [63] = https://github.com/curl/curl/discussions/7255 + [64] = https://curl.se/bug/?i=7253 + [65] = https://curl.se/bug/?i=7250 + [66] = https://curl.se/bug/?i=7209 + [67] = https://curl.se/bug/?i=7209 + [68] = https://curl.se/bug/?i=7209 + [69] = https://curl.se/bug/?i=7209 + [70] = https://curl.se/bug/?i=7209 + [71] = https://curl.se/bug/?i=7209 + [72] = https://curl.se/bug/?i=7209 + [73] = https://curl.se/bug/?i=7209 + [74] = https://curl.se/bug/?i=7209 + [75] = https://curl.se/bug/?i=493 + [76] = https://curl.se/bug/?i=7209 + [77] = https://curl.se/bug/?i=7209 + [78] = https://curl.se/bug/?i=7209 + [79] = https://curl.se/bug/?i=7209 + [80] = https://curl.se/bug/?i=7219 + [81] = https://curl.se/bug/?i=7211 + [82] = https://curl.se/bug/?i=7212 + [83] = https://curl.se/bug/?i=6896 + [84] = https://curl.se/bug/?i=7208 + [85] = https://curl.se/bug/?i=7280 + [86] = https://curl.se/bug/?i=7245 + [87] = https://curl.se/bug/?i=7238 + [88] = https://curl.se/bug/?i=7248 + [89] = https://curl.se/bug/?i=7248 + [90] = https://curl.se/bug/?i=7248 + [91] = https://curl.se/bug/?i=7243 + [92] = https://curl.se/bug/?i=7239 + [93] = https://curl.se/bug/?i=7274 + [94] = https://curl.se/bug/?i=7277 + [95] = https://curl.se/bug/?i=7276 + [96] = https://curl.se/bug/?i=7293 + [97] = https://curl.se/bug/?i=7178 + [98] = https://curl.se/mail/lib-2021-06/0024.html + [99] = https://curl.se/bug/?i=7290 + [100] = https://curl.se/bug/?i=7287 + [101] = https://curl.se/bug/?i=7296 + [102] = https://curl.se/bug/?i=7285 + [103] = https://curl.se/bug/?i=7260 + [104] = https://curl.se/bug/?i=7034 + [105] = https://curl.se/bug/?i=7265 + [106] = https://curl.se/bug/?i=7295 + [107] = https://curl.se/bug/?i=7273 + [108] = https://curl.se/bug/?i=7270 + [109] = https://curl.se/bug/?i=7272 + [110] = https://curl.se/bug/?i=7216 + [111] = https://curl.se/bug/?i=7271 + [112] = https://curl.se/bug/?i=7271 + [113] = https://curl.se/bug/?i=7266 + [114] = https://curl.se/bug/?i=7349 + [115] = https://curl.se/bug/?i=7350 + [116] = https://curl.se/bug/?i=7301 + [117] = https://curl.se/bug/?i=7228 + [118] = https://curl.se/bug/?i=7073 + [119] = https://curl.se/bug/?i=7297 + [120] = https://curl.se/bug/?i=7350 + [121] = https://curl.se/bug/?i=7348 + [122] = https://curl.se/bug/?i=7343 + [123] = https://curl.se/bug/?i=7344 + [124] = https://curl.se/bug/?i=7345 + [125] = https://curl.se/bug/?i=7341 + [126] = https://curl.se/bug/?i=7340 + [127] = https://curl.se/bug/?i=7330 + [128] = https://curl.se/bug/?i=7333 + [129] = https://curl.se/bug/?i=7333 + [130] = https://curl.se/bug/?i=7334 + [131] = https://curl.se/bug/?i=7328 + [132] = https://curl.se/bug/?i=7329 + [133] = https://curl.se/bug/?i=7326 + [134] = https://curl.se/bug/?i=7325 + [135] = https://curl.se/bug/?i=7319 + [136] = https://curl.se/bug/?i=7316 + [137] = https://curl.se/bug/?i=7327 + [138] = https://curl.se/bug/?i=7320 + [139] = https://curl.se/bug/?i=7324 + [140] = https://curl.se/bug/?i=7318 + [141] = https://curl.se/bug/?i=7311 + [142] = https://curl.se/bug/?i=7308 + [143] = https://curl.se/bug/?i=7314 + [144] = https://curl.se/bug/?i=7313 + [145] = https://curl.se/bug/?i=7342 + [146] = https://curl.se/bug/?i=7370 + [147] = https://curl.se/mail/lib-2021-07/0025.html + [148] = https://curl.se/bug/?i=7361 + [149] = https://curl.se/bug/?i=7357 + [150] = https://curl.se/bug/?i=7360 + [151] = https://curl.se/bug/?i=7358 + [152] = https://curl.se/bug/?i=7352 + [153] = https://curl.se/bug/?i=7379 + [154] = https://curl.se/bug/?i=7380 + [155] = https://curl.se/bug/?i=7377 + [156] = https://curl.se/bug/?i=7375 + [157] = https://curl.se/bug/?i=7367 + [159] = https://curl.se/bug/?i=7391 + [160] = https://curl.se/bug/?i=7382 + [161] = https://curl.se/bug/?i=7383 + [162] = https://curl.se/bug/?i=7378 + [163] = https://curl.se/bug/?i=7397 + [164] = https://curl.se/bug/?i=7398 + [165] = https://curl.se/docs/CVE-2021-22924.html + [166] = https://curl.se/bug/?i=7418 + [167] = https://curl.se/docs/CVE-2021-22926.html + [168] = https://curl.se/bug/?i=7423 + [169] = https://curl.se/bug/?i=7429 + [170] = https://curl.se/docs/CVE-2021-22925.html + [171] = https://curl.se/bug/?i=7386 + [172] = https://curl.se/bug/?i=7413 + [174] = https://curl.se/bug/?i=7446 + [175] = https://curl.se/bug/?i=7419 diff --git a/contrib/libs/curl/include/curl/curl.h b/contrib/libs/curl/include/curl/curl.h index 4e00f3fb70..8bd8982c43 100644 --- a/contrib/libs/curl/include/curl/curl.h +++ b/contrib/libs/curl/include/curl/curl.h @@ -74,8 +74,9 @@ #if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ - defined(__CYGWIN__) || defined(AMIGA) || \ - (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) + defined(__CYGWIN__) || defined(AMIGA) || defined(__NuttX__) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) || \ + defined(__VXWORKS__) #include <sys/select.h> #endif @@ -541,7 +542,7 @@ typedef enum { CURLE_OBSOLETE46, /* 46 - NOT USED */ CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ - CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ + CURLE_SETOPT_OPTION_SYNTAX, /* 49 - Malformed setopt option */ CURLE_OBSOLETE50, /* 50 - NOT USED */ CURLE_OBSOLETE51, /* 51 - NOT USED */ CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ @@ -636,6 +637,9 @@ typedef enum { /* The following were added in 7.21.5, April 2011 */ #define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION +/* Added for 7.78.0 */ +#define CURLE_TELNET_OPTION_SYNTAX CURLE_SETOPT_OPTION_SYNTAX + /* The following were added in 7.17.1 */ /* These are scheduled to disappear by 2009 */ #define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION @@ -2084,13 +2088,13 @@ typedef enum { /* Parameters for V4 signature */ CURLOPT(CURLOPT_AWS_SIGV4, CURLOPTTYPE_STRINGPOINT, 305), - /* Same as CURLOPT_SSL_VERIFYPEER but for DOH (DNS-over-HTTPS) servers. */ + /* Same as CURLOPT_SSL_VERIFYPEER but for DoH (DNS-over-HTTPS) servers. */ CURLOPT(CURLOPT_DOH_SSL_VERIFYPEER, CURLOPTTYPE_LONG, 306), - /* Same as CURLOPT_SSL_VERIFYHOST but for DOH (DNS-over-HTTPS) servers. */ + /* Same as CURLOPT_SSL_VERIFYHOST but for DoH (DNS-over-HTTPS) servers. */ CURLOPT(CURLOPT_DOH_SSL_VERIFYHOST, CURLOPTTYPE_LONG, 307), - /* Same as CURLOPT_SSL_VERIFYSTATUS but for DOH (DNS-over-HTTPS) servers. */ + /* Same as CURLOPT_SSL_VERIFYSTATUS but for DoH (DNS-over-HTTPS) servers. */ CURLOPT(CURLOPT_DOH_SSL_VERIFYSTATUS, CURLOPTTYPE_LONG, 308), /* The CA certificates as "blob" used to validate the peer certificate diff --git a/contrib/libs/curl/include/curl/curlver.h b/contrib/libs/curl/include/curl/curlver.h index 98f7d0cdf4..d2ccdbaf83 100644 --- a/contrib/libs/curl/include/curl/curlver.h +++ b/contrib/libs/curl/include/curl/curlver.h @@ -30,12 +30,12 @@ /* This is the version number of the libcurl package from which this header file origins: */ -#define LIBCURL_VERSION "7.77.0" +#define LIBCURL_VERSION "7.78.0" /* The numeric version number is also available "in parts" by using these defines: */ #define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 77 +#define LIBCURL_VERSION_MINOR 78 #define LIBCURL_VERSION_PATCH 0 /* This is the numeric version of the libcurl version number, meant for easier @@ -57,7 +57,7 @@ CURL_VERSION_BITS() macro since curl's own configure script greps for it and needs it to contain the full number. */ -#define LIBCURL_VERSION_NUM 0x074d00 +#define LIBCURL_VERSION_NUM 0x074e00 /* * This is the date and time when the full source package was created. The @@ -68,7 +68,7 @@ * * "2007-11-23" */ -#define LIBCURL_TIMESTAMP "2021-05-26" +#define LIBCURL_TIMESTAMP "2021-07-21" #define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|(z)) #define CURL_AT_LEAST_VERSION(x,y,z) \ diff --git a/contrib/libs/curl/include/curl/urlapi.h b/contrib/libs/curl/include/curl/urlapi.h index 7343cb659e..1d70880117 100644 --- a/contrib/libs/curl/include/curl/urlapi.h +++ b/contrib/libs/curl/include/curl/urlapi.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2018 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2018 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -79,6 +79,7 @@ typedef enum { #define CURLU_GUESS_SCHEME (1<<9) /* legacy curl-style guessing */ #define CURLU_NO_AUTHORITY (1<<10) /* Allow empty authority when the scheme is unknown. */ +#define CURLU_ALLOW_SPACE (1<<11) /* Allow spaces in the URL */ typedef struct Curl_URL CURLU; diff --git a/contrib/libs/curl/lib/altsvc.c b/contrib/libs/curl/lib/altsvc.c index 4ab77fdfc8..36acc3a5ef 100644 --- a/contrib/libs/curl/lib/altsvc.c +++ b/contrib/libs/curl/lib/altsvc.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2019 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -460,7 +460,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, (void)data; #endif if(result) { - infof(data, "Excessive alt-svc header, ignoring...\n"); + infof(data, "Excessive alt-svc header, ignoring."); return CURLE_OK; } @@ -496,7 +496,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, p++; len = p - hostp; if(!len || (len >= MAX_ALTSVC_HOSTLEN)) { - infof(data, "Excessive alt-svc host name, ignoring...\n"); + infof(data, "Excessive alt-svc host name, ignoring."); dstalpnid = ALPN_none; } else { @@ -513,7 +513,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, /* a port number */ 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...\n"); + infof(data, "Unknown alt-svc port number, ignoring."); dstalpnid = ALPN_none; } p = end_ptr; @@ -579,12 +579,12 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data, as->expires = maxage + time(NULL); as->persist = persist; Curl_llist_insert_next(&asi->list, asi->list.tail, as, &as->node); - infof(data, "Added alt-svc: %s:%d over %s\n", dsthost, dstport, + infof(data, "Added alt-svc: %s:%d over %s", dsthost, dstport, Curl_alpnid2str(dstalpnid)); } } else { - infof(data, "Unknown alt-svc protocol \"%s\", skipping...\n", + infof(data, "Unknown alt-svc protocol \"%s\", skipping.", alpnbuf); } } diff --git a/contrib/libs/curl/lib/asyn-ares.c b/contrib/libs/curl/lib/asyn-ares.c index 7827847350..839fabb86a 100644 --- a/contrib/libs/curl/lib/asyn-ares.c +++ b/contrib/libs/curl/lib/asyn-ares.c @@ -206,7 +206,8 @@ static void destroy_async_data(struct Curl_async *async); */ void Curl_resolver_cancel(struct Curl_easy *data) { - if(data && data->state.async.resolver) + DEBUGASSERT(data); + if(data->state.async.resolver) ares_cancel((ares_channel)data->state.async.resolver); destroy_async_data(&data->state.async); } @@ -493,17 +494,31 @@ CURLcode Curl_resolver_wait_resolv(struct Curl_easy *data, static void compound_results(struct thread_data *res, struct Curl_addrinfo *ai) { - struct Curl_addrinfo *ai_tail; if(!ai) return; - ai_tail = ai; - while(ai_tail->ai_next) - ai_tail = ai_tail->ai_next; +#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ + if(res->temp_ai && res->temp_ai->ai_family == PF_INET6) { + /* We have results already, put the new IPv6 entries at the head of the + list. */ + struct Curl_addrinfo *temp_ai_tail = res->temp_ai; - /* Add the new results to the list of old results. */ - ai_tail->ai_next = res->temp_ai; - res->temp_ai = ai; + while(temp_ai_tail->ai_next) + temp_ai_tail = temp_ai_tail->ai_next; + + temp_ai_tail->ai_next = ai; + } + else +#endif /* CURLRES_IPV6 */ + { + /* Add the new results to the list of old results. */ + struct Curl_addrinfo *ai_tail = ai; + while(ai_tail->ai_next) + ai_tail = ai_tail->ai_next; + + ai_tail->ai_next = res->temp_ai; + res->temp_ai = ai; + } } /* diff --git a/contrib/libs/curl/lib/c-hyper.c b/contrib/libs/curl/lib/c-hyper.c index fac5e3e214..361035d85a 100644 --- a/contrib/libs/curl/lib/c-hyper.c +++ b/contrib/libs/curl/lib/c-hyper.c @@ -124,6 +124,17 @@ static int hyper_each_header(void *userdata, size_t len; char *headp; CURLcode result; + int writetype; + + if(name_len + value_len + 2 > CURL_MAX_HTTP_HEADER) { + failf(data, "Too long response header"); + data->state.hresult = CURLE_OUT_OF_MEMORY; + return HYPER_ITER_BREAK; + } + + if(!data->req.bytecount) + Curl_pgrsTime(data, TIMER_STARTTRANSFER); + Curl_dyn_reset(&data->state.headerb); if(name_len) { if(Curl_dyn_addf(&data->state.headerb, "%.*s: %.*s\r\n", @@ -145,7 +156,10 @@ static int hyper_each_header(void *userdata, Curl_debug(data, CURLINFO_HEADER_IN, headp, len); - result = Curl_client_write(data, CLIENTWRITE_HEADER, headp, len); + writetype = CLIENTWRITE_HEADER; + if(data->set.include_header) + writetype |= CLIENTWRITE_BODY; + result = Curl_client_write(data, writetype, headp, len); if(result) { data->state.hresult = CURLE_ABORTED_BY_CALLBACK; return HYPER_ITER_BREAK; @@ -166,9 +180,27 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk) if(0 == k->bodywrites++) { bool done = FALSE; - result = Curl_http_firstwrite(data, data->conn, &done); +#if defined(USE_NTLM) + struct connectdata *conn = data->conn; + if(conn->bits.close && + (((data->req.httpcode == 401) && + (conn->http_ntlm_state == NTLMSTATE_TYPE2)) || + ((data->req.httpcode == 407) && + (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) { + infof(data, "Connection closed while negotiating NTLM"); + data->state.authproblem = TRUE; + Curl_safefree(data->req.newurl); + } +#endif + if(data->state.hconnect && + (data->req.httpcode/100 != 2)) { + done = TRUE; + result = CURLE_OK; + } + else + result = Curl_http_firstwrite(data, data->conn, &done); if(result || done) { - infof(data, "Return early from hyper_body_chunk\n"); + infof(data, "Return early from hyper_body_chunk"); data->state.hresult = result; return HYPER_ITER_BREAK; } @@ -207,6 +239,7 @@ static CURLcode status_line(struct Curl_easy *data, CURLcode result; size_t len; const char *vstr; + int writetype; vstr = http_version == HYPER_HTTP_VERSION_1_1 ? "1.1" : (http_version == HYPER_HTTP_VERSION_2 ? "2" : "1.0"); conn->httpversion = @@ -229,7 +262,10 @@ static CURLcode status_line(struct Curl_easy *data, len = Curl_dyn_len(&data->state.headerb); Curl_debug(data, CURLINFO_HEADER_IN, Curl_dyn_ptr(&data->state.headerb), len); - result = Curl_client_write(data, CLIENTWRITE_HEADER, + writetype = CLIENTWRITE_HEADER; + if(data->set.include_header) + writetype |= CLIENTWRITE_BODY; + result = Curl_client_write(data, writetype, Curl_dyn_ptr(&data->state.headerb), len); if(result) { data->state.hresult = CURLE_ABORTED_BY_CALLBACK; @@ -309,7 +345,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, if(errnum == HYPERE_ABORTED_BY_CALLBACK) { /* override Hyper's view, might not even be an error */ result = data->state.hresult; - infof(data, "hyperstream is done (by early callback)\n"); + infof(data, "hyperstream is done (by early callback)"); } else { uint8_t errbuf[256]; @@ -318,6 +354,8 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, failf(data, "Hyper: [%d] %.*s", (int)code, (int)errlen, errbuf); if((code == HYPERE_UNEXPECTED_EOF) && !data->req.bytecount) result = CURLE_GOT_NOTHING; + else if(code == HYPERE_INVALID_PEER_MESSAGE) + result = CURLE_UNSUPPORTED_PROTOCOL; /* maybe */ else result = CURLE_RECV_ERROR; } @@ -328,10 +366,10 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data, else if(h->endtask == task) { /* end of transfer */ *done = TRUE; - infof(data, "hyperstream is done!\n"); + infof(data, "hyperstream is done!"); break; } - else if(t != HYPER_TASK_RESPONSE && t != HYPER_TASK_EMPTY) { + else if(t != HYPER_TASK_RESPONSE) { *didwhat = KEEP_RECV; break; } @@ -472,7 +510,7 @@ CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers, if(HYPERE_OK != hyper_headers_add(headers, (uint8_t *)n, nlen, (uint8_t *)v, vlen)) { - failf(data, "hyper_headers_add host"); + failf(data, "hyper refused to add header '%s'", line); return CURLE_OUT_OF_MEMORY; } if(data->set.verbose) { @@ -530,8 +568,18 @@ static int uploadpostfields(void *userdata, hyper_context *ctx, *chunk = NULL; /* nothing more to deliver */ else { /* send everything off in a single go */ - *chunk = hyper_buf_copy(data->set.postfields, - (size_t)data->req.p.http->postsize); + hyper_buf *copy = hyper_buf_copy(data->set.postfields, + (size_t)data->req.p.http->postsize); + if(copy) + *chunk = copy; + else { + data->state.hresult = CURLE_OUT_OF_MEMORY; + return HYPER_POLL_ERROR; + } + /* increasing the writebytecount here is a little premature but we + don't know exactly when the body is sent*/ + data->req.writebytecount += (size_t)data->req.p.http->postsize; + Curl_pgrsSetUploadCounter(data, data->req.writebytecount); data->req.upload_done = TRUE; } return HYPER_POLL_READY; @@ -545,13 +593,26 @@ static int uploadstreamed(void *userdata, hyper_context *ctx, CURLcode result = Curl_fillreadbuffer(data, data->set.upload_buffer_size, &fillcount); (void)ctx; - if(result) + if(result) { + data->state.hresult = result; return HYPER_POLL_ERROR; + } if(!fillcount) /* done! */ *chunk = NULL; - else - *chunk = hyper_buf_copy((uint8_t *)data->state.ulbuf, fillcount); + else { + hyper_buf *copy = hyper_buf_copy((uint8_t *)data->state.ulbuf, fillcount); + if(copy) + *chunk = copy; + else { + data->state.hresult = CURLE_OUT_OF_MEMORY; + return HYPER_POLL_ERROR; + } + /* increasing the writebytecount here is a little premature but we + don't know exactly when the body is sent*/ + data->req.writebytecount += fillcount; + Curl_pgrsSetUploadCounter(data, fillcount); + } return HYPER_POLL_READY; } @@ -646,7 +707,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) the rest of the request in the PERFORM phase. */ *done = TRUE; - infof(data, "Time for the Hyper dance\n"); + infof(data, "Time for the Hyper dance"); memset(h, 0, sizeof(struct hyptransfer)); result = Curl_http_host(data, conn); @@ -830,6 +891,15 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) else Curl_safefree(data->state.aptr.accept_encoding); +#ifdef HAVE_LIBZ + /* we only consider transfer-encoding magic if libz support is built-in */ + result = Curl_transferencode(data); + if(result) + return result; + if(Curl_hyper_header(data, headers, data->state.aptr.te)) + goto error; +#endif + result = cookies(data, conn, headers); if(result) return result; @@ -881,6 +951,10 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) } conn->datastream = Curl_hyper_stream; + /* clear userpwd and proxyuserpwd to avoid re-using old credentials + * from re-used connections */ + Curl_safefree(data->state.aptr.userpwd); + Curl_safefree(data->state.aptr.proxyuserpwd); return CURLE_OK; error: @@ -899,6 +973,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) hyper_code code = hyper_error_code(hypererr); failf(data, "Hyper: [%d] %.*s", (int)code, (int)errlen, errbuf); hyper_error_free(hypererr); + if(data->state.hresult) + return data->state.hresult; } return CURLE_OUT_OF_MEMORY; } diff --git a/contrib/libs/curl/lib/conncache.c b/contrib/libs/curl/lib/conncache.c index 5453c00f33..f5ba8ff70a 100644 --- a/contrib/libs/curl/lib/conncache.c +++ b/contrib/libs/curl/lib/conncache.c @@ -34,6 +34,7 @@ #include "share.h" #include "sigpipe.h" #include "connect.h" +#include "strcase.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -161,6 +162,7 @@ static void hashkey(struct connectdata *conn, char *buf, /* put the number first so that the hostname gets cut off if too long */ msnprintf(buf, len, "%ld%s", port, hostname); + Curl_strntolower(buf, buf, len); } /* Returns number of connections currently held in the connection cache. @@ -264,7 +266,7 @@ CURLcode Curl_conncache_add_conn(struct Curl_easy *data) connc->num_conn++; DEBUGF(infof(data, "Added connection %ld. " - "The cache now contains %zu members\n", + "The cache now contains %zu members", conn->connection_id, connc->num_conn)); unlock: @@ -298,7 +300,7 @@ void Curl_conncache_remove_conn(struct Curl_easy *data, conn->bundle = NULL; /* removed from it */ if(connc) { connc->num_conn--; - DEBUGF(infof(data, "The cache now contains %zu members\n", + DEBUGF(infof(data, "The cache now contains %zu members", connc->num_conn)); } if(lock) { @@ -408,7 +410,7 @@ bool Curl_conncache_return_conn(struct Curl_easy *data, conn->lastused = Curl_now(); /* it was used up until now */ if(maxconnects > 0 && Curl_conncache_size(data) > maxconnects) { - infof(data, "Connection cache is full, closing the oldest one.\n"); + infof(data, "Connection cache is full, closing the oldest one"); conn_candidate = Curl_conncache_extract_oldest(data); if(conn_candidate) { @@ -464,7 +466,7 @@ Curl_conncache_extract_bundle(struct Curl_easy *data, /* remove it to prevent another thread from nicking it */ bundle_remove_conn(bundle, conn_candidate); data->state.conn_cache->num_conn--; - DEBUGF(infof(data, "The cache now contains %zu members\n", + DEBUGF(infof(data, "The cache now contains %zu members", data->state.conn_cache->num_conn)); } @@ -526,7 +528,7 @@ Curl_conncache_extract_oldest(struct Curl_easy *data) /* remove it to prevent another thread from nicking it */ bundle_remove_conn(bundle_candidate, conn_candidate); connc->num_conn--; - DEBUGF(infof(data, "The cache now contains %zu members\n", + DEBUGF(infof(data, "The cache now contains %zu members", connc->num_conn)); } CONNCACHE_UNLOCK(data); diff --git a/contrib/libs/curl/lib/connect.c b/contrib/libs/curl/lib/connect.c index d9317f3783..11e6b888b7 100644 --- a/contrib/libs/curl/lib/connect.c +++ b/contrib/libs/curl/lib/connect.c @@ -111,7 +111,7 @@ tcpkeepalive(struct Curl_easy *data, /* only set IDLE and INTVL if setting KEEPALIVE is successful */ if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, sizeof(optval)) < 0) { - infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd); + infof(data, "Failed to set SO_KEEPALIVE on fd %d", sockfd); } else { #if defined(SIO_KEEPALIVE_VALS) @@ -126,7 +126,7 @@ tcpkeepalive(struct Curl_easy *data, vals.keepaliveinterval = optval; if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals), NULL, 0, &dummy, NULL, NULL) != 0) { - infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n", + infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d", (int)sockfd, WSAGetLastError()); } #else @@ -135,7 +135,7 @@ tcpkeepalive(struct Curl_easy *data, KEEPALIVE_FACTOR(optval); if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&optval, sizeof(optval)) < 0) { - infof(data, "Failed to set TCP_KEEPIDLE on fd %d\n", sockfd); + infof(data, "Failed to set TCP_KEEPIDLE on fd %d", sockfd); } #endif #ifdef TCP_KEEPINTVL @@ -143,7 +143,7 @@ tcpkeepalive(struct Curl_easy *data, KEEPALIVE_FACTOR(optval); if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&optval, sizeof(optval)) < 0) { - infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd); + infof(data, "Failed to set TCP_KEEPINTVL on fd %d", sockfd); } #endif #ifdef TCP_KEEPALIVE @@ -152,7 +152,7 @@ tcpkeepalive(struct Curl_easy *data, KEEPALIVE_FACTOR(optval); if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE, (void *)&optval, sizeof(optval)) < 0) { - infof(data, "Failed to set TCP_KEEPALIVE on fd %d\n", sockfd); + infof(data, "Failed to set TCP_KEEPALIVE on fd %d", sockfd); } #endif #endif @@ -331,7 +331,7 @@ static CURLcode bindlocal(struct Curl_easy *data, /* * We now have the numerical IP address in the 'myhost' buffer */ - infof(data, "Local Interface %s is ip %s using address family %i\n", + infof(data, "Local Interface %s is ip %s using address family %i", dev, myhost, af); done = 1; break; @@ -364,7 +364,7 @@ static CURLcode bindlocal(struct Curl_easy *data, if(h) { /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */ Curl_printable_address(h->addr, myhost, sizeof(myhost)); - infof(data, "Name '%s' family %i resolved to '%s' family %i\n", + infof(data, "Name '%s' family %i resolved to '%s' family %i", dev, af, myhost, h->addr->ai_family); Curl_resolv_unlock(data, h); if(af != h->addr->ai_family) { @@ -458,13 +458,13 @@ static CURLcode bindlocal(struct Curl_easy *data, error, Curl_strerror(error, buffer, sizeof(buffer))); return CURLE_INTERFACE_FAILED; } - infof(data, "Local port: %hu\n", port); + infof(data, "Local port: %hu", port); conn->bits.bound = TRUE; return CURLE_OK; } if(--portnum > 0) { - infof(data, "Bind to local port %hu failed, trying next\n", port); + infof(data, "Bind to local port %hu failed, trying next", port); port++; /* try next port */ /* We re-use/clobber the port variable here below */ if(sock->sa_family == AF_INET) @@ -872,15 +872,6 @@ CURLcode Curl_is_connected(struct Curl_easy *data, now = Curl_now(); - /* figure out how long time we have left to connect */ - allow = Curl_timeleft(data, &now, TRUE); - - if(allow < 0) { - /* time-out, bail out, go home */ - failf(data, "Connection time-out"); - return CURLE_OPERATION_TIMEDOUT; - } - if(SOCKS_STATE(conn->cnnct.state)) { /* still doing SOCKS */ result = connect_SOCKS(data, sockindex, connected); @@ -930,7 +921,7 @@ CURLcode Curl_is_connected(struct Curl_easy *data, if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr[i]) { infof(data, "After %" CURL_FORMAT_TIMEDIFF_T - "ms connect time, move on!\n", conn->timeoutms_per_addr[i]); + "ms connect time, move on!", conn->timeoutms_per_addr[i]); error = ETIMEDOUT; } @@ -989,11 +980,12 @@ CURLcode Curl_is_connected(struct Curl_easy *data, char buffer[STRERROR_LEN]; Curl_printable_address(conn->tempaddr[i], ipaddress, sizeof(ipaddress)); - infof(data, "connect to %s port %ld failed: %s\n", + infof(data, "connect to %s port %u failed: %s", ipaddress, conn->port, Curl_strerror(error, buffer, sizeof(buffer))); #endif + allow = Curl_timeleft(data, &now, TRUE); conn->timeoutms_per_addr[i] = conn->tempaddr[i]->ai_next == NULL ? allow : allow / 2; ainext(conn, i, TRUE); @@ -1006,6 +998,21 @@ CURLcode Curl_is_connected(struct Curl_easy *data, } } + /* + * Now that we've checked whether we are connected, check whether we've + * already timed out. + * + * First figure out how long time we have left to connect */ + + allow = Curl_timeleft(data, &now, TRUE); + + if(allow < 0) { + /* time-out, bail out, go home */ + failf(data, "Connection timeout after %ld ms", + Curl_timediff(now, data->progress.t_startsingle)); + return CURLE_OPERATION_TIMEDOUT; + } + if(result && (conn->tempsock[0] == CURL_SOCKET_BAD) && (conn->tempsock[1] == CURL_SOCKET_BAD)) { @@ -1031,9 +1038,11 @@ CURLcode Curl_is_connected(struct Curl_easy *data, else hostname = conn->host.name; - failf(data, "Failed to connect to %s port %ld: %s", - hostname, conn->port, - Curl_strerror(error, buffer, sizeof(buffer))); + failf(data, "Failed to connect to %s port %u after " + "%" CURL_FORMAT_TIMEDIFF_T " ms: %s", + hostname, conn->port, + Curl_timediff(now, data->progress.t_startsingle), + Curl_strerror(error, buffer, sizeof(buffer))); Curl_quic_disconnect(data, conn, 0); Curl_quic_disconnect(data, conn, 1); @@ -1065,7 +1074,7 @@ static void tcpnodelay(struct Curl_easy *data, curl_socket_t sockfd) if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff, sizeof(onoff)) < 0) - infof(data, "Could not set TCP_NODELAY: %s\n", + infof(data, "Could not set TCP_NODELAY: %s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); #else (void)data; @@ -1084,9 +1093,11 @@ static void nosigpipe(struct Curl_easy *data, int onoff = 1; if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff, sizeof(onoff)) < 0) { +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) char buffer[STRERROR_LEN]; - infof(data, "Could not set SO_NOSIGPIPE: %s\n", + infof(data, "Could not set SO_NOSIGPIPE: %s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer))); +#endif } } #else @@ -1180,7 +1191,7 @@ static CURLcode singleipconnect(struct Curl_easy *data, Curl_closesocket(data, conn, sockfd); return CURLE_OK; } - infof(data, " Trying %s:%d...\n", ipaddress, port); + infof(data, " Trying %s:%d...", ipaddress, port); #ifdef ENABLE_IPV6 is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) && @@ -1271,7 +1282,7 @@ static CURLcode singleipconnect(struct Curl_easy *data, #elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */ if(setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, (void *)&optval, sizeof(optval)) < 0) - infof(data, "Failed to enable TCP Fast Open on fd %d\n", sockfd); + infof(data, "Failed to enable TCP Fast Open on fd %d", sockfd); rc = connect(sockfd, &addr.sa_addr, addr.addrlen); #elif defined(MSG_FASTOPEN) /* old Linux */ @@ -1321,7 +1332,7 @@ static CURLcode singleipconnect(struct Curl_easy *data, default: /* unknown error, fallthrough and try another address! */ - infof(data, "Immediate connect fail for %s: %s\n", + infof(data, "Immediate connect fail for %s: %s", ipaddress, Curl_strerror(error, buffer, sizeof(buffer))); data->state.os_errno = error; @@ -1394,7 +1405,7 @@ CURLcode Curl_connecthost(struct Curl_easy *data, ainext(conn, 1, FALSE); /* assigns conn->tempaddr[1] accordingly */ - DEBUGF(infof(data, "family0 == %s, family1 == %s\n", + DEBUGF(infof(data, "family0 == %s, family1 == %s", conn->tempfamily[0] == AF_INET ? "v4" : "v6", conn->tempfamily[1] == AF_INET ? "v4" : "v6")); diff --git a/contrib/libs/curl/lib/cookie.c b/contrib/libs/curl/lib/cookie.c index 941623f9d2..b7531f7424 100644 --- a/contrib/libs/curl/lib/cookie.c +++ b/contrib/libs/curl/lib/cookie.c @@ -95,7 +95,6 @@ Example set of cookies: #include "strcase.h" #include "curl_get_line.h" #include "curl_memrchr.h" -#include "inet_pton.h" #include "parsedate.h" #include "rand.h" #include "rename.h" @@ -147,31 +146,6 @@ static bool tailmatch(const char *cooke_domain, const char *hostname) } /* - * isip - * - * Returns true if the given string is an IPv4 or IPv6 address (if IPv6 has - * been enabled while building libcurl, and false otherwise. - */ -static bool isip(const char *domain) -{ - struct in_addr addr; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif - - if(Curl_inet_pton(AF_INET, domain, &addr) -#ifdef ENABLE_IPV6 - || Curl_inet_pton(AF_INET6, domain, &addr6) -#endif - ) { - /* domain name given as IP address */ - return TRUE; - } - - return FALSE; -} - -/* * matching cookie path and url path * RFC6265 5.1.4 Paths and Path-Match */ @@ -303,7 +277,7 @@ static size_t cookiehash(const char * const domain) const char *top; size_t len; - if(!domain || isip(domain)) + if(!domain || Curl_host_is_ipnum(domain)) return 0; top = get_top_domain(domain, &len); @@ -366,7 +340,7 @@ void Curl_cookie_loadfiles(struct Curl_easy *data) * Failure may be due to OOM or a bad cookie; both are ignored * but only the first should be */ - infof(data, "ignoring failed cookie_init for %s\n", list->data); + infof(data, "ignoring failed cookie_init for %s", list->data); else data->cookies = newcookies; list = list->next; @@ -397,7 +371,9 @@ static void strstore(char **str, const char *newstr) * * Remove expired cookies from the hash by inspecting the expires timestamp on * each cookie in the hash, freeing and deleting any where the timestamp is in - * the past. + * the past. If the cookiejar has recorded the next timestamp at which one or + * more cookies expire, then processing will exit early in case this timestamp + * is in the future. */ static void remove_expired(struct CookieInfo *cookies) { @@ -405,6 +381,20 @@ static void remove_expired(struct CookieInfo *cookies) curl_off_t now = (curl_off_t)time(NULL); unsigned int i; + /* + * If the earliest expiration timestamp in the jar is in the future we can + * skip scanning the whole jar and instead exit early as there won't be any + * cookies to evict. If we need to evict however, reset the next_expiration + * counter in order to track the next one. In case the recorded first + * expiration is the max offset, then perform the safe fallback of checking + * all cookies. + */ + if(now < cookies->next_expiration && + cookies->next_expiration != CURL_OFF_T_MAX) + return; + else + cookies->next_expiration = CURL_OFF_T_MAX; + for(i = 0; i < COOKIE_HASH_SIZE; i++) { struct Cookie *pv = NULL; co = cookies->cookies[i]; @@ -421,6 +411,12 @@ static void remove_expired(struct CookieInfo *cookies) freecookie(co); } else { + /* + * If this cookie has an expiration timestamp earlier than what we've + * seen so far then record it for the next round of expirations. + */ + if(co->expires && co->expires < cookies->next_expiration) + cookies->next_expiration = co->expires; pv = co; } co = nx; @@ -524,7 +520,7 @@ Curl_cookie_add(struct Curl_easy *data, if(nlen >= (MAX_NAME-1) || len >= (MAX_NAME-1) || ((nlen + len) > MAX_NAME)) { freecookie(co); - infof(data, "oversized cookie dropped, name/val %zu + %zu bytes\n", + infof(data, "oversized cookie dropped, name/val %zu + %zu bytes", nlen, len); return NULL; } @@ -645,7 +641,7 @@ Curl_cookie_add(struct Curl_easy *data, domain = ":"; #endif - is_ip = isip(domain ? domain : whatptr); + is_ip = Curl_host_is_ipnum(domain ? domain : whatptr); if(!domain || (is_ip && !strcmp(whatptr, domain)) @@ -665,7 +661,7 @@ Curl_cookie_add(struct Curl_easy *data, * not a domain to which the current host belongs. Mark as bad. */ badcookie = TRUE; - infof(data, "skipped cookie with bad tailmatch domain: %s\n", + infof(data, "skipped cookie with bad tailmatch domain: %s", whatptr); } } @@ -996,7 +992,7 @@ Curl_cookie_add(struct Curl_easy *data, * must also check that the data handle isn't NULL since the psl code will * dereference it. */ - if(data && (domain && co->domain && !isip(co->domain))) { + if(data && (domain && co->domain && !Curl_host_is_ipnum(co->domain))) { const psl_ctx_t *psl = Curl_psl_use(data); int acceptable; @@ -1009,7 +1005,7 @@ Curl_cookie_add(struct Curl_easy *data, if(!acceptable) { infof(data, "cookie '%s' dropped, domain '%s' must not " - "set cookies for '%s'\n", co->name, domain, co->domain); + "set cookies for '%s'", co->name, domain, co->domain); freecookie(co); return NULL; } @@ -1121,7 +1117,7 @@ Curl_cookie_add(struct Curl_easy *data, if(c->running) /* Only show this when NOT reading the cookies from a file */ infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, " - "expire %" CURL_FORMAT_CURL_OFF_T "\n", + "expire %" CURL_FORMAT_CURL_OFF_T, replace_old?"Replaced":"Added", co->name, co->value, co->domain, co->path, co->expires); @@ -1134,6 +1130,13 @@ Curl_cookie_add(struct Curl_easy *data, c->numcookies++; /* one more cookie in the jar */ } + /* + * Now that we've added a new cookie to the jar, update the expiration + * tracker in case it is the next one to expire. + */ + if(co->expires && (co->expires < c->next_expiration)) + c->next_expiration = co->expires; + return co; } @@ -1169,6 +1172,11 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, c->filename = strdup(file?file:"none"); /* copy the name just in case */ if(!c->filename) goto fail; /* failed to get memory */ + /* + * Initialize the next_expiration time to signal that we don't have enough + * information yet. + */ + c->next_expiration = CURL_OFF_T_MAX; } else { /* we got an already existing one, use that */ @@ -1215,7 +1223,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data, /* * Remove expired cookies from the hash. We must make sure to run this - * after reading the file, and not not on every cookie. + * after reading the file, and not on every cookie. */ remove_expired(c); @@ -1247,7 +1255,8 @@ fail: * * Helper function to sort cookies such that the longest path gets before the * shorter path. Path, domain and name lengths are considered in that order, - * with tge creationtime as the tiebreaker. + * with the creationtime as the tiebreaker. The creationtime is guaranteed to + * be unique per cookie, so we know we will get an ordering at that point. */ static int cookie_sort(const void *p1, const void *p2) { @@ -1355,7 +1364,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, remove_expired(c); /* check if host is an IP(v4|v6) address */ - is_ip = isip(host); + is_ip = Curl_host_is_ipnum(host); co = c->cookies[myhash]; @@ -1734,7 +1743,7 @@ void Curl_flush_cookies(struct Curl_easy *data, bool cleanup) /* if we have a destination file for all the cookies to get dumped to */ res = cookie_output(data, data->cookies, data->set.str[STRING_COOKIEJAR]); if(res) - infof(data, "WARNING: failed to save cookies in %s: %s\n", + infof(data, "WARNING: failed to save cookies in %s: %s", data->set.str[STRING_COOKIEJAR], curl_easy_strerror(res)); } else { diff --git a/contrib/libs/curl/lib/cookie.h b/contrib/libs/curl/lib/cookie.h index 460bbb1040..0ffe08e63a 100644 --- a/contrib/libs/curl/lib/cookie.h +++ b/contrib/libs/curl/lib/cookie.h @@ -65,6 +65,7 @@ struct CookieInfo { bool running; /* state info, for cookie adding information */ bool newsession; /* new session, discard session cookies on load */ int lastct; /* last creation-time used in the jar */ + curl_off_t next_expiration; /* the next time at which expiration happens */ }; /* This is the maximum line length we accept for a cookie line. RFC 2109 diff --git a/contrib/libs/curl/lib/curl_addrinfo.c b/contrib/libs/curl/lib/curl_addrinfo.c index 0dd41ef530..52299cd1b2 100644 --- a/contrib/libs/curl/lib/curl_addrinfo.c +++ b/contrib/libs/curl/lib/curl_addrinfo.c @@ -50,12 +50,6 @@ # define in_addr_t unsigned long #endif -#if defined(USE_UNIX_SOCKETS) && defined(WINAPI_FAMILY) && \ - (WINAPI_FAMILY == WINAPI_FAMILY_APP) - /* Required for sockaddr_un type */ -# error #include <afunix.h> -#endif - #include <stddef.h> #include "curl_addrinfo.h" diff --git a/contrib/libs/curl/lib/curl_config-linux.h b/contrib/libs/curl/lib/curl_config-linux.h index c0e2135957..9af3db897d 100644 --- a/contrib/libs/curl/lib/curl_config-linux.h +++ b/contrib/libs/curl/lib/curl_config-linux.h @@ -73,6 +73,9 @@ /* disable netrc parsing */ /* #undef CURL_DISABLE_NETRC */ +/* to disable NTLM support */ +/* #undef CURL_DISABLE_NTLM */ + /* if the OpenSSL configuration won't be loaded automatically */ /* #undef CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG */ @@ -133,12 +136,6 @@ /* Define to the type of arg 2 for gethostname. */ #define GETHOSTNAME_TYPE_ARG2 size_t -/* Specifies the number of arguments to getservbyport_r */ -#define GETSERVBYPORT_R_ARGS 6 - -/* Specifies the size of the buffer to pass to getservbyport_r */ -#define GETSERVBYPORT_R_BUFSIZE 4096 - /* Define to 1 if you have the alarm function. */ #define HAVE_ALARM 1 @@ -218,9 +215,6 @@ /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 -/* Define to 1 if you have the freeifaddrs function. */ -#define HAVE_FREEIFADDRS 1 - /* Define to 1 if you have the fsetxattr function. */ #define HAVE_FSETXATTR 1 @@ -233,9 +227,6 @@ /* Define to 1 if you have the ftruncate function. */ #define HAVE_FTRUNCATE 1 -/* Define to 1 if you have the gai_strerror function. */ -#define HAVE_GAI_STRERROR 1 - /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 @@ -245,21 +236,6 @@ /* Define to 1 if you have the `geteuid' function. */ #define HAVE_GETEUID 1 -/* Define to 1 if you have the gethostbyaddr function. */ -#define HAVE_GETHOSTBYADDR 1 - -/* Define to 1 if you have the gethostbyaddr_r function. */ -#define HAVE_GETHOSTBYADDR_R 1 - -/* gethostbyaddr_r() takes 5 args */ -/* #undef HAVE_GETHOSTBYADDR_R_5 */ - -/* gethostbyaddr_r() takes 7 args */ -/* #undef HAVE_GETHOSTBYADDR_R_7 */ - -/* gethostbyaddr_r() takes 8 args */ -#define HAVE_GETHOSTBYADDR_R_8 1 - /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 @@ -299,9 +275,6 @@ /* Define to 1 if you have the `getrlimit' function. */ #define HAVE_GETRLIMIT 1 -/* Define to 1 if you have the getservbyport_r function. */ -#define HAVE_GETSERVBYPORT_R 1 - /* Define to 1 if you have the getsockname function. */ #define HAVE_GETSOCKNAME 1 @@ -350,15 +323,6 @@ /* Define to 1 if you have the `if_nametoindex' function. */ #define HAVE_IF_NAMETOINDEX 1 -/* Define to 1 if you have the inet_ntoa_r function. */ -/* #undef HAVE_INET_NTOA_R */ - -/* inet_ntoa_r() takes 2 args */ -/* #undef HAVE_INET_NTOA_R_2 */ - -/* inet_ntoa_r() takes 3 args */ -/* #undef HAVE_INET_NTOA_R_3 */ - /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 @@ -610,9 +574,6 @@ /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ -/* Define to 1 if you have the <sgtty.h> header file. */ -#define HAVE_SGTTY_H 1 - /* Define to 1 if you have the sigaction function. */ #define HAVE_SIGACTION 1 @@ -1018,9 +979,6 @@ /* if MesaLink is enabled */ /* #undef USE_MESALINK */ -/* Define to enable metalink support */ -/* #undef USE_METALINK */ - /* if nghttp2 is in use */ #define USE_NGHTTP2 1 diff --git a/contrib/libs/curl/lib/curl_endian.c b/contrib/libs/curl/lib/curl_endian.c index b6f107e10a..ecde74bfb1 100644 --- a/contrib/libs/curl/lib/curl_endian.c +++ b/contrib/libs/curl/lib/curl_endian.c @@ -80,45 +80,3 @@ unsigned short Curl_read16_be(const unsigned char *buf) return (unsigned short)(((unsigned short)buf[0] << 8) | ((unsigned short)buf[1])); } - -#if (SIZEOF_CURL_OFF_T > 4) -/* - * write32_le() - * - * This function converts a 32-bit integer from the native endian format, - * to little endian format ready for sending down the wire. - * - * Parameters: - * - * value [in] - The 32-bit integer value. - * buffer [in] - A pointer to the output buffer. - */ -static void write32_le(const int value, unsigned char *buffer) -{ - buffer[0] = (char)(value & 0x000000FF); - buffer[1] = (char)((value & 0x0000FF00) >> 8); - buffer[2] = (char)((value & 0x00FF0000) >> 16); - buffer[3] = (char)((value & 0xFF000000) >> 24); -} - -/* - * Curl_write64_le() - * - * This function converts a 64-bit integer from the native endian format, - * to little endian format ready for sending down the wire. - * - * Parameters: - * - * value [in] - The 64-bit integer value. - * buffer [in] - A pointer to the output buffer. - */ -#if defined(HAVE_LONGLONG) -void Curl_write64_le(const long long value, unsigned char *buffer) -#else -void Curl_write64_le(const __int64 value, unsigned char *buffer) -#endif -{ - write32_le((int)value, buffer); - write32_le((int)(value >> 32), buffer + 4); -} -#endif /* SIZEOF_CURL_OFF_T > 4 */ diff --git a/contrib/libs/curl/lib/curl_gssapi.c b/contrib/libs/curl/lib/curl_gssapi.c index d020072bc7..e80a07609f 100644 --- a/contrib/libs/curl/lib/curl_gssapi.c +++ b/contrib/libs/curl/lib/curl_gssapi.c @@ -59,7 +59,7 @@ OM_uint32 Curl_gss_init_sec_context( req_flags |= GSS_C_DELEG_POLICY_FLAG; #else infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not " - "compiled in\n"); + "compiled in"); #endif } @@ -130,7 +130,7 @@ void Curl_gss_log_error(struct Curl_easy *data, const char *prefix, display_gss_error(minor, GSS_C_MECH_CODE, buf, len); - infof(data, "%s%s\n", prefix, buf); + infof(data, "%s%s", prefix, buf); #ifdef CURL_DISABLE_VERBOSE_STRINGS (void)data; (void)prefix; diff --git a/contrib/libs/curl/lib/curl_multibyte.c b/contrib/libs/curl/lib/curl_multibyte.c index 16418bee4c..e9d2a8cb88 100644 --- a/contrib/libs/curl/lib/curl_multibyte.c +++ b/contrib/libs/curl/lib/curl_multibyte.c @@ -102,14 +102,16 @@ int curlx_win32_open(const char *filename, int oflag, ...) va_end(param); #ifdef _UNICODE - if(filename_w) + if(filename_w) { result = _wopen(filename_w, oflag, pmode); - free(filename_w); - if(result != -1) - return result; -#endif - + free(filename_w); + } + else + errno = EINVAL; + return result; +#else return (_open)(filename, oflag, pmode); +#endif } FILE *curlx_win32_fopen(const char *filename, const char *mode) @@ -120,19 +122,20 @@ FILE *curlx_win32_fopen(const char *filename, const char *mode) wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode); if(filename_w && mode_w) result = _wfopen(filename_w, mode_w); + else + errno = EINVAL; free(filename_w); free(mode_w); - if(result) - return result; -#endif - + return result; +#else return (fopen)(filename, mode); +#endif } int curlx_win32_stat(const char *path, struct_stat *buffer) { - int result = -1; #ifdef _UNICODE + int result = -1; wchar_t *path_w = curlx_convert_UTF8_to_wchar(path); if(path_w) { #if defined(USE_WIN32_SMALL_FILES) @@ -141,31 +144,34 @@ int curlx_win32_stat(const char *path, struct_stat *buffer) result = _wstati64(path_w, buffer); #endif free(path_w); - if(result != -1) - return result; } -#endif /* _UNICODE */ - + else + errno = EINVAL; + return result; +#else #if defined(USE_WIN32_SMALL_FILES) - result = _stat(path, buffer); + return _stat(path, buffer); #else - result = _stati64(path, buffer); + return _stati64(path, buffer); +#endif #endif - return result; } int curlx_win32_access(const char *path, int mode) { #if defined(_UNICODE) + int result = -1; wchar_t *path_w = curlx_convert_UTF8_to_wchar(path); if(path_w) { - int result = _waccess(path_w, mode); + result = _waccess(path_w, mode); free(path_w); - if(result != -1) - return result; } -#endif /* _UNICODE */ + else + errno = EINVAL; + return result; +#else return _access(path, mode); +#endif } #endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */ diff --git a/contrib/libs/curl/lib/curl_ntlm_core.c b/contrib/libs/curl/lib/curl_ntlm_core.c index f1c07b2dd5..1c3013c83f 100644 --- a/contrib/libs/curl/lib/curl_ntlm_core.c +++ b/contrib/libs/curl/lib/curl_ntlm_core.c @@ -86,7 +86,6 @@ #elif defined(USE_MBEDTLS) # error #include <mbedtls/des.h> -# include "curl_md4.h" #elif defined(USE_SECTRANSP) @@ -498,17 +497,14 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data, * network encoding not the host encoding. */ result = Curl_convert_to_network(data, (char *)pw, len * 2); - if(result) - return result; - - /* Create NT hashed password. */ - Curl_md4it(ntbuffer, pw, 2 * len); - - memset(ntbuffer + 16, 0, 21 - 16); - + if(!result) { + /* Create NT hashed password. */ + Curl_md4it(ntbuffer, pw, 2 * len); + memset(ntbuffer + 16, 0, 21 - 16); + } free(pw); - return CURLE_OK; + return result; } #if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI) diff --git a/contrib/libs/curl/lib/curl_ntlm_wb.c b/contrib/libs/curl/lib/curl_ntlm_wb.c index 9af79fd66a..ca9e2874a7 100644 --- a/contrib/libs/curl/lib/curl_ntlm_wb.c +++ b/contrib/libs/curl/lib/curl_ntlm_wb.c @@ -355,17 +355,17 @@ CURLcode Curl_input_ntlm_wb(struct Curl_easy *data, } else { if(*state == NTLMSTATE_LAST) { - infof(data, "NTLM auth restarted\n"); + infof(data, "NTLM auth restarted"); Curl_http_auth_cleanup_ntlm_wb(conn); } else if(*state == NTLMSTATE_TYPE3) { - infof(data, "NTLM handshake rejected\n"); + infof(data, "NTLM handshake rejected"); Curl_http_auth_cleanup_ntlm_wb(conn); *state = NTLMSTATE_NONE; return CURLE_REMOTE_ACCESS_DENIED; } else if(*state >= NTLMSTATE_TYPE1) { - infof(data, "NTLM handshake failure (internal error)\n"); + infof(data, "NTLM handshake failure (internal error)"); return CURLE_REMOTE_ACCESS_DENIED; } diff --git a/contrib/libs/curl/lib/curl_range.c b/contrib/libs/curl/lib/curl_range.c index f7fb7c0824..24bdb3052e 100644 --- a/contrib/libs/curl/lib/curl_range.c +++ b/contrib/libs/curl/lib/curl_range.c @@ -53,14 +53,14 @@ CURLcode Curl_range(struct Curl_easy *data) if((to_t == CURL_OFFT_INVAL) && !from_t) { /* X - */ data->state.resume_from = from; - DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n", + DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file", from)); } else if((from_t == CURL_OFFT_INVAL) && !to_t) { /* -Y */ data->req.maxdownload = to; data->state.resume_from = -to; - DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n", + DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes", to)); } else { @@ -78,12 +78,12 @@ CURLcode Curl_range(struct Curl_easy *data) data->req.maxdownload = totalsize + 1; /* include last byte */ data->state.resume_from = from; DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T - " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n", + " getting %" CURL_FORMAT_CURL_OFF_T " bytes", from, data->req.maxdownload)); } DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T " to %" CURL_FORMAT_CURL_OFF_T ", totally %" - CURL_FORMAT_CURL_OFF_T " bytes\n", + CURL_FORMAT_CURL_OFF_T " bytes", from, to, data->req.maxdownload)); } else diff --git a/contrib/libs/curl/lib/curl_sasl.c b/contrib/libs/curl/lib/curl_sasl.c index a4d1059cb9..f5ac99a68d 100644 --- a/contrib/libs/curl/lib/curl_sasl.c +++ b/contrib/libs/curl/lib/curl_sasl.c @@ -234,7 +234,7 @@ static void state(struct SASL *sasl, struct Curl_easy *data, }; if(sasl->state != newstate) - infof(data, "SASL %p state change from %s to %s\n", + infof(data, "SASL %p state change from %s to %s", (void *)sasl, names[sasl->state], names[newstate]); #else (void) data; diff --git a/contrib/libs/curl/lib/curl_setup.h b/contrib/libs/curl/lib/curl_setup.h index 304b9fdd25..42aaaf8c59 100644 --- a/contrib/libs/curl/lib/curl_setup.h +++ b/contrib/libs/curl/lib/curl_setup.h @@ -456,6 +456,15 @@ #endif #endif +#ifndef SSIZE_T_MAX +/* some limits.h headers have this defined, some don't */ +#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4) +#define SSIZE_T_MAX 9223372036854775807 +#else +#define SSIZE_T_MAX 2147483647 +#endif +#endif + /* * Arg 2 type for gethostname in case it hasn't been defined in config file. */ @@ -644,24 +653,16 @@ int netware_init(void); #endif /* Single point where USE_NTLM definition might be defined */ -#ifndef CURL_DISABLE_CRYPTO_AUTH -#if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \ - defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \ - defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \ - (defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT)) - -#define USE_CURL_NTLM_CORE - -# if defined(USE_MBEDTLS) -/* Get definition of MBEDTLS_MD4_C */ -# error #include <mbedtls/md4.h> +#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(CURL_DISABLE_NTLM) +# if defined(USE_OPENSSL) || defined(USE_MBEDTLS) || \ + defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_SECTRANSP) || \ + defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \ + (defined(USE_WOLFSSL) && defined(HAVE_WOLFSSL_DES_ECB_ENCRYPT)) +# define USE_CURL_NTLM_CORE +# endif +# if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI) +# define USE_NTLM # endif - -#endif - -#if defined(USE_CURL_NTLM_CORE) || defined(USE_WINDOWS_SSPI) -#define USE_NTLM -#endif #endif #ifdef CURL_WANTS_CA_BUNDLE_ENV @@ -819,4 +820,20 @@ int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, #define ENABLE_QUIC #endif +#if defined(USE_UNIX_SOCKETS) && defined(WIN32) +# if defined(__MINGW32__) && !defined(LUP_SECURE) + typedef u_short ADDRESS_FAMILY; /* Classic mingw, 11y+ old mingw-w64 */ +# endif +# if !defined(UNIX_PATH_MAX) + /* Replicating logic present in afunix.h + (distributed with newer Windows 10 SDK versions only) */ +# define UNIX_PATH_MAX 108 + /* !checksrc! disable TYPEDEFSTRUCT 1 */ + typedef struct sockaddr_un { + ADDRESS_FAMILY sun_family; + char sun_path[UNIX_PATH_MAX]; + } SOCKADDR_UN, *PSOCKADDR_UN; +# endif +#endif + #endif /* HEADER_CURL_SETUP_H */ diff --git a/contrib/libs/curl/lib/dict.c b/contrib/libs/curl/lib/dict.c index 625b057774..5d53b8f1ff 100644 --- a/contrib/libs/curl/lib/dict.c +++ b/contrib/libs/curl/lib/dict.c @@ -216,7 +216,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) } if(!word || (*word == (char)0)) { - infof(data, "lookup word is missing\n"); + infof(data, "lookup word is missing"); word = (char *)"default"; } if(!database || (*database == (char)0)) { @@ -267,7 +267,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) } if(!word || (*word == (char)0)) { - infof(data, "lookup word is missing\n"); + infof(data, "lookup word is missing"); word = (char *)"default"; } if(!database || (*database == (char)0)) { diff --git a/contrib/libs/curl/lib/doh.c b/contrib/libs/curl/lib/doh.c index 36f8cd58dc..de0c902b86 100644 --- a/contrib/libs/curl/lib/doh.c +++ b/contrib/libs/curl/lib/doh.c @@ -186,19 +186,19 @@ doh_write_cb(const void *contents, size_t size, size_t nmemb, void *userp) return realsize; } -/* called from multi.c when this DOH transfer is complete */ +/* called from multi.c when this DoH transfer is complete */ static int doh_done(struct Curl_easy *doh, CURLcode result) { struct Curl_easy *data = doh->set.dohfor; struct dohdata *dohp = data->req.doh; - /* so one of the DOH request done for the 'data' transfer is now complete! */ + /* so one of the DoH request done for the 'data' transfer is now complete! */ dohp->pending--; - infof(data, "a DOH request is completed, %u to go\n", dohp->pending); + infof(data, "a DoH request is completed, %u to go", dohp->pending); if(result) - infof(data, "DOH request %s\n", curl_easy_strerror(result)); + infof(data, "DoH request %s", curl_easy_strerror(result)); if(!dohp->pending) { - /* DOH completed */ + /* DoH completed */ curl_slist_free_all(dohp->headers); dohp->headers = NULL; Curl_expire(data, 0, EXPIRE_RUN_NOW); @@ -228,7 +228,7 @@ static CURLcode dohprobe(struct Curl_easy *data, DOHcode d = doh_encode(host, dnstype, p->dohbuffer, sizeof(p->dohbuffer), &p->dohlen); if(d) { - failf(data, "Failed to encode DOH packet [%d]", d); + failf(data, "Failed to encode DoH packet [%d]", d); return CURLE_OUT_OF_MEMORY; } @@ -302,7 +302,7 @@ static CURLcode dohprobe(struct Curl_easy *data, /* Inherit *some* SSL options from the user's transfer. This is a best-guess as to which options are needed for compatibility. #3661 - Note DOH does not inherit the user's proxy server so proxy SSL settings + Note DoH does not inherit the user's proxy server so proxy SSL settings have no effect and are not inherited. If that changes then two new options should be added to check doh proxy insecure separately, CURLOPT_DOH_PROXY_SSL_VERIFYHOST and CURLOPT_DOH_PROXY_SSL_VERIFYPEER. @@ -359,17 +359,17 @@ static CURLcode dohprobe(struct Curl_easy *data, (data->set.ssl.auto_client_cert ? CURLSSLOPT_AUTO_CLIENT_CERT : 0); - curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask); + (void)curl_easy_setopt(doh, CURLOPT_SSL_OPTIONS, mask); } doh->set.fmultidone = doh_done; doh->set.dohfor = data; /* identify for which transfer this is done */ p->easy = doh; - /* DOH private_data must be null because the user must have a way to - distinguish their transfer's handle from DOH handles in user + /* DoH private_data must be null because the user must have a way to + distinguish their transfer's handle from DoH handles in user callbacks (ie SSL CTX callback). */ - DEBUGASSERT(!data->set.private_data); + DEBUGASSERT(!doh->set.private_data); if(curl_multi_add_handle(multi, doh)) goto error; @@ -386,7 +386,7 @@ static CURLcode dohprobe(struct Curl_easy *data, } /* - * Curl_doh() resolves a name using DOH. It resolves a name and returns a + * Curl_doh() resolves a name using DoH. It resolves a name and returns a * 'Curl_addrinfo *' with the address information. */ @@ -420,7 +420,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, if(!dohp->headers) goto error; - /* create IPv4 DOH request */ + /* create IPv4 DoH request */ result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V4], DNS_TYPE_A, hostname, data->set.str[STRING_DOH], data->multi, dohp->headers); @@ -429,7 +429,7 @@ struct Curl_addrinfo *Curl_doh(struct Curl_easy *data, dohp->pending++; if(Curl_ipv6works(data)) { - /* create IPv6 DOH request */ + /* create IPv6 DoH request */ result = dohprobe(data, &dohp->probe[DOH_PROBE_SLOT_IPADDR_V6], DNS_TYPE_AAAA, hostname, data->set.str[STRING_DOH], data->multi, dohp->headers); @@ -764,11 +764,11 @@ static void showdoh(struct Curl_easy *data, const struct dohentry *d) { int i; - infof(data, "TTL: %u seconds\n", d->ttl); + infof(data, "TTL: %u seconds", d->ttl); for(i = 0; i < d->numaddr; i++) { const struct dohaddr *a = &d->addr[i]; if(a->type == DNS_TYPE_A) { - infof(data, "DOH A: %u.%u.%u.%u\n", + infof(data, "DoH A: %u.%u.%u.%u", a->ip.v4[0], a->ip.v4[1], a->ip.v4[2], a->ip.v4[3]); } @@ -777,7 +777,7 @@ static void showdoh(struct Curl_easy *data, char buffer[128]; char *ptr; size_t len; - msnprintf(buffer, 128, "DOH AAAA: "); + msnprintf(buffer, 128, "DoH AAAA: "); ptr = &buffer[10]; len = 118; for(j = 0; j < 16; j += 2) { @@ -788,11 +788,11 @@ static void showdoh(struct Curl_easy *data, len -= l; ptr += l; } - infof(data, "%s\n", buffer); + infof(data, "%s", buffer); } } for(i = 0; i < d->numcname; i++) { - infof(data, "CNAME: %s\n", Curl_dyn_ptr(&d->cname[i])); + infof(data, "CNAME: %s", Curl_dyn_ptr(&d->cname[i])); } } #else @@ -803,7 +803,7 @@ static void showdoh(struct Curl_easy *data, * doh2ai() * * This function returns a pointer to the first element of a newly allocated - * Curl_addrinfo struct linked list filled with the data from a set of DOH + * Curl_addrinfo struct linked list filled with the data from a set of DoH * lookups. Curl_addrinfo is meant to work like the addrinfo struct does for * a IPv6 stack, but usable also for IPv4, all hosts and environments. * @@ -931,7 +931,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, if(!dohp->probe[DOH_PROBE_SLOT_IPADDR_V4].easy && !dohp->probe[DOH_PROBE_SLOT_IPADDR_V6].easy) { - failf(data, "Could not DOH-resolve: %s", data->state.async.hostname); + failf(data, "Could not DoH-resolve: %s", data->state.async.hostname); return data->conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY: CURLE_COULDNT_RESOLVE_HOST; } @@ -941,7 +941,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, }; struct dohentry de; int slot; - /* remove DOH handles from multi handle and close them */ + /* remove DoH handles from multi handle and close them */ for(slot = 0; slot < DOH_PROBE_SLOTS; slot++) { curl_multi_remove_handle(data->multi, dohp->probe[slot].easy); Curl_close(&dohp->probe[slot].easy); @@ -958,7 +958,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, &de); Curl_dyn_free(&p->serverdoh); if(rc[slot]) { - infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc[slot]), + infof(data, "DoH: %s type %s for %s", doh_strerror(rc[slot]), type2name(p->dnstype), dohp->host); } } /* next slot */ @@ -969,7 +969,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, struct Curl_dns_entry *dns; struct Curl_addrinfo *ai; - infof(data, "DOH Host name: %s\n", dohp->host); + infof(data, "DoH Host name: %s", dohp->host); showdoh(data, &de); ai = doh2ai(&de, dohp->host, dohp->port); @@ -1007,7 +1007,7 @@ CURLcode Curl_doh_is_resolved(struct Curl_easy *data, } /* !dohp->pending */ - /* else wait for pending DOH transactions to complete */ + /* else wait for pending DoH transactions to complete */ return CURLE_OK; } diff --git a/contrib/libs/curl/lib/doh.h b/contrib/libs/curl/lib/doh.h index b3584d1b27..70e96e012f 100644 --- a/contrib/libs/curl/lib/doh.h +++ b/contrib/libs/curl/lib/doh.h @@ -101,7 +101,7 @@ void de_init(struct dohentry *d); void de_cleanup(struct dohentry *d); #endif -#else /* if DOH is disabled */ +#else /* if DoH is disabled */ #define Curl_doh(a,b,c,d) NULL #define Curl_doh_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST #endif diff --git a/contrib/libs/curl/lib/easy.c b/contrib/libs/curl/lib/easy.c index 530b7c73f2..588b1fb47e 100644 --- a/contrib/libs/curl/lib/easy.c +++ b/contrib/libs/curl/lib/easy.c @@ -417,13 +417,13 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */ ev->list = nxt; free(m); m = nxt; - infof(easy, "socket cb: socket %d REMOVED\n", s); + infof(easy, "socket cb: socket %d REMOVED", s); } else { /* The socket 's' is already being monitored, update the activity mask. Convert from libcurl bitmask to the poll one. */ m->socket.events = socketcb2poll(what); - infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s, + infof(easy, "socket cb: socket %d UPDATED as %s%s", s, (what&CURL_POLL_IN)?"IN":"", (what&CURL_POLL_OUT)?"OUT":""); } @@ -447,7 +447,7 @@ static int events_socket(struct Curl_easy *easy, /* easy handle */ m->socket.events = socketcb2poll(what); m->socket.revents = 0; ev->list = m; - infof(easy, "socket cb: socket %d ADDED as %s%s\n", s, + infof(easy, "socket cb: socket %d ADDED as %s%s", s, (what&CURL_POLL_IN)?"IN":"", (what&CURL_POLL_OUT)?"OUT":""); } @@ -532,7 +532,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) if(fds[i].revents) { /* socket activity, tell libcurl */ int act = poll2cselect(fds[i].revents); /* convert */ - infof(multi->easyp, "call curl_multi_socket_action(socket %d)\n", + infof(multi->easyp, "call curl_multi_socket_action(socket %d)", fds[i].fd); mcode = curl_multi_socket_action(multi, fds[i].fd, act, &ev->running_handles); @@ -1027,7 +1027,7 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action) if((newstate & (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE)) == oldstate) { /* Not changing any pause state, return */ - DEBUGF(infof(data, "pause: no change, early return\n")); + DEBUGF(infof(data, "pause: no change, early return")); return CURLE_OK; } @@ -1213,9 +1213,16 @@ static int conn_upkeep(struct Curl_easy *data, /* Param is unused. */ (void)param; - if(conn->handler->connection_check) + if(conn->handler->connection_check) { + /* briefly attach the connection to this transfer for the purpose of + checking it */ + Curl_attach_connnection(data, conn); + /* Do a protocol-specific keepalive check on the connection. */ conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE); + /* detach the connection again */ + Curl_detach_connnection(data); + } return 0; /* continue iteration */ } diff --git a/contrib/libs/curl/lib/formdata.c b/contrib/libs/curl/lib/formdata.c index 769f06a705..ac7a0009cd 100644 --- a/contrib/libs/curl/lib/formdata.c +++ b/contrib/libs/curl/lib/formdata.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -865,8 +865,6 @@ CURLcode Curl_getformdata(struct Curl_easy *data, if(post->flags & CURL_HTTPPOST_LARGE) clen = post->contentlen; - if(!clen) - clen = -1; if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) { if(!strcmp(file->contents, "-")) { @@ -888,13 +886,21 @@ CURLcode Curl_getformdata(struct Curl_easy *data, else if(post->flags & HTTPPOST_BUFFER) result = curl_mime_data(part, post->buffer, post->bufferlength? post->bufferlength: -1); - else if(post->flags & HTTPPOST_CALLBACK) + else if(post->flags & HTTPPOST_CALLBACK) { /* the contents should be read with the callback and the size is set with the contentslength */ + if(!clen) + clen = -1; result = curl_mime_data_cb(part, clen, fread_func, NULL, NULL, post->userp); + } else { - result = curl_mime_data(part, post->contents, (ssize_t) clen); + size_t uclen; + if(!clen) + uclen = CURL_ZERO_TERMINATED; + else + uclen = (size_t)clen; + result = curl_mime_data(part, post->contents, uclen); #ifdef CURL_DOES_CONVERSIONS /* Convert textual contents now. */ if(!result && data && part->datasize) diff --git a/contrib/libs/curl/lib/ftp.c b/contrib/libs/curl/lib/ftp.c index 444cf35f55..1a699de594 100644 --- a/contrib/libs/curl/lib/ftp.c +++ b/contrib/libs/curl/lib/ftp.c @@ -289,7 +289,7 @@ static CURLcode AcceptServerConnect(struct Curl_easy *data) failf(data, "Error accept()ing server connect"); return CURLE_FTP_PORT_FAILED; } - infof(data, "Connection accepted from server\n"); + infof(data, "Connection accepted from server"); /* when this happens within the DO state it is important that we mark us as not needing DO_MORE anymore */ conn->bits.do_more = FALSE; @@ -380,7 +380,7 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received) *received = FALSE; timeout_ms = ftp_timeleft_accept(data); - infof(data, "Checking for server connect\n"); + infof(data, "Checking for server connect"); if(timeout_ms < 0) { /* if a timeout was already reached, bail out */ failf(data, "Accept timeout occurred while waiting server connect"); @@ -390,7 +390,7 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received) /* First check whether there is a cached response from server */ if(pp->cache_size && pp->cache && pp->cache[0] > '3') { /* Data connection could not be established, let's return */ - infof(data, "There is negative response in cache while serv connect\n"); + infof(data, "There is negative response in cache while serv connect"); (void)Curl_GetFTPResponse(data, &nread, &ftpcode); return CURLE_FTP_ACCEPT_FAILED; } @@ -408,11 +408,11 @@ static CURLcode ReceivedServerConnect(struct Curl_easy *data, bool *received) default: if(result & CURL_CSELECT_IN2) { - infof(data, "Ready to accept data connection from server\n"); + infof(data, "Ready to accept data connection from server"); *received = TRUE; } else if(result & CURL_CSELECT_IN) { - infof(data, "Ctrl conn has data while waiting for data conn\n"); + infof(data, "Ctrl conn has data while waiting for data conn"); (void)Curl_GetFTPResponse(data, &nread, &ftpcode); if(ftpcode/100 > 3) @@ -444,7 +444,7 @@ static CURLcode InitiateTransfer(struct Curl_easy *data) if(conn->bits.ftp_use_data_ssl) { /* since we only have a plaintext TCP connection here, we must now * do the TLS stuff */ - infof(data, "Doing the SSL/TLS handshake on the data stream\n"); + infof(data, "Doing the SSL/TLS handshake on the data stream"); result = Curl_ssl_connect(data, conn, SECONDARYSOCKET); if(result) return result; @@ -487,7 +487,7 @@ static CURLcode AllowServerConnect(struct Curl_easy *data, bool *connected) CURLcode result = CURLE_OK; *connected = FALSE; - infof(data, "Preparing for accepting server on data port\n"); + infof(data, "Preparing for accepting server on data port"); /* Save the time we start accepting server connect */ Curl_pgrsTime(data, TIMER_STARTACCEPT); @@ -592,7 +592,7 @@ static CURLcode ftp_readresp(struct Curl_easy *data, * This response code can come at any point so having it treated * generically is a good idea. */ - infof(data, "We got a 421 - timeout!\n"); + infof(data, "We got a 421 - timeout!"); state(data, FTP_STOP); return CURLE_OPERATION_TIMEDOUT; } @@ -768,7 +768,7 @@ static void _state(struct Curl_easy *data, (void) lineno; #else if(ftpc->state != newstate) - infof(data, "FTP %p (line %d) state change from %s to %s\n", + infof(data, "FTP %p (line %d) state change from %s to %s", (void *)ftpc, lineno, ftp_state_names[ftpc->state], ftp_state_names[newstate]); #endif @@ -1139,7 +1139,7 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data, /* The requested bind address is not local. Use the address used for * the control connection instead and restart the port loop */ - infof(data, "bind(port=%hu) on non-local address failed: %s\n", port, + infof(data, "bind(port=%hu) on non-local address failed: %s", port, Curl_strerror(error, buffer, sizeof(buffer))); sslen = sizeof(ss); @@ -1341,7 +1341,7 @@ static CURLcode ftp_state_use_pasv(struct Curl_easy *data, if(!result) { ftpc->count1 = modeoff; state(data, FTP_PASV); - infof(data, "Connect data stream passively\n"); + infof(data, "Connect data stream passively"); } return result; } @@ -1648,7 +1648,7 @@ static CURLcode ftp_state_ul_setup(struct Curl_easy *data, data->state.infilesize -= data->state.resume_from; if(data->state.infilesize <= 0) { - infof(data, "File already completely uploaded\n"); + infof(data, "File already completely uploaded"); /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); @@ -1802,7 +1802,7 @@ static CURLcode ftp_epsv_disable(struct Curl_easy *data, return CURLE_WEIRD_SERVER_REPLY; } - infof(data, "Failed EPSV attempt. Disabling EPSV\n"); + infof(data, "Failed EPSV attempt. Disabling EPSV"); /* disable it for next transfer */ conn->bits.ftp_use_epsv = FALSE; data->state.errorbuf = FALSE; /* allow error message to get @@ -1921,7 +1921,7 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data, if(data->set.ftp_skip_ip) { /* told to ignore the remotely given IP but instead use the host we used for the control connection */ - infof(data, "Skip %u.%u.%u.%u for data connection, re-use %s instead\n", + infof(data, "Skip %u.%u.%u.%u for data connection, re-use %s instead", ip[0], ip[1], ip[2], ip[3], conn->host.name); ftpc->newhost = strdup(control_address(conn)); @@ -2044,7 +2044,7 @@ static CURLcode ftp_state_port_resp(struct Curl_easy *data, /* the command failed */ if(EPRT == fcmd) { - infof(data, "disabling EPRT usage\n"); + infof(data, "disabling EPRT usage"); conn->bits.ftp_use_eprt = FALSE; } fcmd++; @@ -2058,7 +2058,7 @@ static CURLcode ftp_state_port_resp(struct Curl_easy *data, result = ftp_state_use_port(data, fcmd); } else { - infof(data, "Connect data stream actively\n"); + infof(data, "Connect data stream actively"); state(data, FTP_STOP); /* end of DO phase */ result = ftp_dophase_done(data, FALSE); } @@ -2128,7 +2128,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, } break; default: - infof(data, "unsupported MDTM reply format\n"); + infof(data, "unsupported MDTM reply format"); break; case 550: /* "No such file or directory" */ failf(data, "Given file does not exist"); @@ -2142,7 +2142,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, case CURL_TIMECOND_IFMODSINCE: default: if(data->info.filetime <= data->set.timevalue) { - infof(data, "The requested document is not new enough\n"); + infof(data, "The requested document is not new enough"); ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */ data->info.timecond = TRUE; state(data, FTP_STOP); @@ -2151,7 +2151,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, break; case CURL_TIMECOND_IFUNMODSINCE: if(data->info.filetime > data->set.timevalue) { - infof(data, "The requested document is not old enough\n"); + infof(data, "The requested document is not old enough"); ftp->transfer = PPTRANSFER_NONE; /* mark to not transfer data */ data->info.timecond = TRUE; state(data, FTP_STOP); @@ -2161,7 +2161,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, } /* switch */ } else { - infof(data, "Skipping time comparison\n"); + infof(data, "Skipping time comparison"); } } @@ -2186,7 +2186,7 @@ static CURLcode ftp_state_type_resp(struct Curl_easy *data, return CURLE_FTP_COULDNT_SET_TYPE; } if(ftpcode != 200) - infof(data, "Got a %03d response code instead of the assumed 200\n", + infof(data, "Got a %03d response code instead of the assumed 200", ftpcode); if(instate == FTP_TYPE) @@ -2219,7 +2219,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data, /* We always (attempt to) get the size of downloads, so it is done before this even when not doing resumes. */ if(filesize == -1) { - infof(data, "ftp server doesn't support SIZE\n"); + infof(data, "ftp server doesn't support SIZE"); /* We couldn't get the size and therefore we can't know if there really is a part of the file left to get, although the server will just close the connection when we start the connection so it won't cause @@ -2256,7 +2256,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data, if(ftp->downloadsize == 0) { /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); - infof(data, "File already completely downloaded\n"); + infof(data, "File already completely downloaded"); /* Set ->transfer so that we won't get any error in ftp_done() * because we didn't transfer the any file */ @@ -2267,7 +2267,7 @@ static CURLcode ftp_state_retr(struct Curl_easy *data, /* Set resume file transfer offset */ infof(data, "Instructs server to resume from offset %" - CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); + CURL_FORMAT_CURL_OFF_T, data->state.resume_from); result = Curl_pp_sendf(data, &ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T, data->state.resume_from); @@ -2413,7 +2413,7 @@ static CURLcode ftp_state_stor_resp(struct Curl_easy *data, if(!connected) { struct ftp_conn *ftpc = &conn->proto.ftpc; - infof(data, "Data conn was not available immediately\n"); + infof(data, "Data conn was not available immediately"); ftpc->wait_data_conn = TRUE; } @@ -2506,11 +2506,11 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data, else if((instate != FTP_LIST) && (data->state.prefer_ascii)) size = -1; /* kludge for servers that understate ASCII mode file size */ - infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n", + infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T, data->req.maxdownload); if(instate != FTP_LIST) - infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T "\n", + infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T, size); /* FTP download: */ @@ -2526,7 +2526,7 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data, if(!connected) { struct ftp_conn *ftpc = &conn->proto.ftpc; - infof(data, "Data conn was not available immediately\n"); + infof(data, "Data conn was not available immediately"); state(data, FTP_STOP); ftpc->wait_data_conn = TRUE; } @@ -2702,9 +2702,9 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]); if(Curl_sec_login(data, conn)) - infof(data, "Logging in with password in cleartext!\n"); + infof(data, "Logging in with password in cleartext!"); else - infof(data, "Authentication successful\n"); + infof(data, "Authentication successful"); } #endif @@ -2895,7 +2895,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, } Curl_safefree(ftpc->entrypath); ftpc->entrypath = dir; /* remember this */ - infof(data, "Entry path is '%s'\n", ftpc->entrypath); + infof(data, "Entry path is '%s'", ftpc->entrypath); /* also save it where getinfo can access it: */ data->state.most_recent_ftp_entrypath = ftpc->entrypath; state(data, FTP_SYST); @@ -2904,18 +2904,18 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, Curl_safefree(ftpc->entrypath); ftpc->entrypath = dir; /* remember this */ - infof(data, "Entry path is '%s'\n", ftpc->entrypath); + infof(data, "Entry path is '%s'", ftpc->entrypath); /* also save it where getinfo can access it: */ data->state.most_recent_ftp_entrypath = ftpc->entrypath; } else { /* couldn't get the path */ free(dir); - infof(data, "Failed to figure out path\n"); + infof(data, "Failed to figure out path"); } } state(data, FTP_STOP); /* we are done with the CONNECT phase! */ - DEBUGF(infof(data, "protocol connect phase DONE\n")); + DEBUGF(infof(data, "protocol connect phase DONE")); break; case FTP_SYST: @@ -2962,7 +2962,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, } state(data, FTP_STOP); /* we are done with the CONNECT phase! */ - DEBUGF(infof(data, "protocol connect phase DONE\n")); + DEBUGF(infof(data, "protocol connect phase DONE")); break; case FTP_NAMEFMT: @@ -2973,7 +2973,7 @@ static CURLcode ftp_statemachine(struct Curl_easy *data, } state(data, FTP_STOP); /* we are done with the CONNECT phase! */ - DEBUGF(infof(data, "protocol connect phase DONE\n")); + DEBUGF(infof(data, "protocol connect phase DONE")); break; case FTP_QUOTE: @@ -3272,7 +3272,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, } if(ftpc->prevpath) - infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath); + infof(data, "Remembering we are in dir \"%s\"", ftpc->prevpath); } /* free the dir tree and file parts */ @@ -3338,7 +3338,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, if(ftpc->dont_check && data->req.maxdownload > 0) { /* we have just sent ABOR and there is no reliable way to check if it was * successful or not; we have to close the connection now */ - infof(data, "partial download completed, closing connection\n"); + infof(data, "partial download completed, closing connection"); connclose(conn, "Partial download with no ability to check"); return result; } @@ -3529,7 +3529,7 @@ ftp_pasv_verbose(struct Curl_easy *data, { char buf[256]; Curl_printable_address(ai, buf, sizeof(buf)); - infof(data, "Connecting to %s (%s) port %d\n", newhost, buf, port); + infof(data, "Connecting to %s (%s) port %d", newhost, buf, port); } #endif @@ -3569,7 +3569,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) /* Ready to do more? */ if(connected) { - DEBUGF(infof(data, "DO-MORE connected phase starts\n")); + DEBUGF(infof(data, "DO-MORE connected phase starts")); } else { if(result && (ftpc->count1 == 0)) { @@ -3644,8 +3644,13 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) return result; result = ftp_multi_statemach(data, &complete); - /* ftpc->wait_data_conn is always false here */ - *completep = (int)complete; + if(ftpc->wait_data_conn) + /* if we reach the end of the FTP state machine here, *complete will be + TRUE but so is ftpc->wait_data_conn, which says we need to wait for + the data connection and therefore we're not actually complete */ + *completep = 0; + else + *completep = (int)complete; } else { /* download */ @@ -3692,7 +3697,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) if(!ftpc->wait_data_conn) { /* no waiting for the data connection so this is now complete */ *completep = 1; - DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result)); + DEBUGF(infof(data, "DO-MORE phase ends with %d", (int)result)); } return result; @@ -3717,7 +3722,7 @@ CURLcode ftp_perform(struct Curl_easy *data, CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); if(data->set.opt_no_body) { /* requested no body means no transfer... */ @@ -3737,10 +3742,10 @@ CURLcode ftp_perform(struct Curl_easy *data, *connected = conn->bits.tcpconnect[SECONDARYSOCKET]; - infof(data, "ftp_perform ends with SECONDARY: %d\n", *connected); + infof(data, "ftp_perform ends with SECONDARY: %d", *connected); if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete1\n")); + DEBUGF(infof(data, "DO phase is complete1")); return result; } @@ -3834,7 +3839,7 @@ static CURLcode init_wc_data(struct Curl_easy *data) /* let the writefunc callback know the transfer */ data->set.out = data; - infof(data, "Wildcard - Parsing started\n"); + infof(data, "Wildcard - Parsing started"); return CURLE_OK; fail: @@ -3901,7 +3906,7 @@ static CURLcode wc_statemach(struct Curl_easy *data) free(ftp->pathalloc); ftp->pathalloc = ftp->path = tmp_path; - infof(data, "Wildcard - START of \"%s\"\n", finfo->filename); + infof(data, "Wildcard - START of \"%s\"", finfo->filename); if(data->set.chunk_bgn) { long userresponse; Curl_set_in_callback(data, true); @@ -3910,7 +3915,7 @@ static CURLcode wc_statemach(struct Curl_easy *data) Curl_set_in_callback(data, false); switch(userresponse) { case CURL_CHUNK_BGN_FUNC_SKIP: - infof(data, "Wildcard - \"%s\" skipped by user\n", + infof(data, "Wildcard - \"%s\" skipped by user", finfo->filename); wildcard->state = CURLWC_SKIP; continue; @@ -4233,7 +4238,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data) n -= ftpc->file?strlen(ftpc->file):0; if((strlen(oldPath) == n) && !strncmp(rawPath, oldPath, n)) { - infof(data, "Request has same path as previous transfer\n"); + infof(data, "Request has same path as previous transfer"); ftpc->cwddone = TRUE; } } @@ -4279,11 +4284,11 @@ static CURLcode ftp_doing(struct Curl_easy *data, CURLcode result = ftp_multi_statemach(data, dophase_done); if(result) - DEBUGF(infof(data, "DO phase failed\n")); + DEBUGF(infof(data, "DO phase failed")); else if(*dophase_done) { result = ftp_dophase_done(data, FALSE /* not connected */); - DEBUGF(infof(data, "DO phase is complete2\n")); + DEBUGF(infof(data, "DO phase is complete2")); } return result; } diff --git a/contrib/libs/curl/lib/hostcheck.c b/contrib/libs/curl/lib/hostcheck.c index fa0223d754..7f2d5ce0ce 100644 --- a/contrib/libs/curl/lib/hostcheck.c +++ b/contrib/libs/curl/lib/hostcheck.c @@ -36,7 +36,7 @@ #include "hostcheck.h" #include "strcase.h" -#include "inet_pton.h" +#include "hostip.h" #include "curl_memory.h" /* The last #include file should be: */ @@ -67,10 +67,6 @@ static int hostmatch(char *hostname, char *pattern) const char *pattern_label_end, *pattern_wildcard, *hostname_label_end; int wildcard_enabled; size_t prefixlen, suffixlen; - struct in_addr ignored; -#ifdef ENABLE_IPV6 - struct sockaddr_in6 si6; -#endif /* normalize pattern and hostname by stripping off trailing dots */ size_t len = strlen(hostname); @@ -86,12 +82,8 @@ static int hostmatch(char *hostname, char *pattern) CURL_HOST_MATCH : CURL_HOST_NOMATCH; /* detect IP address as hostname and fail the match if so */ - if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0) - return CURL_HOST_NOMATCH; -#ifdef ENABLE_IPV6 - if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0) + if(Curl_host_is_ipnum(hostname)) return CURL_HOST_NOMATCH; -#endif /* We require at least 2 dots in pattern to avoid too wide wildcard match. */ diff --git a/contrib/libs/curl/lib/hostip.c b/contrib/libs/curl/lib/hostip.c index 07c534ff3a..5ec84a3f87 100644 --- a/contrib/libs/curl/lib/hostip.c +++ b/contrib/libs/curl/lib/hostip.c @@ -63,6 +63,7 @@ #include "multiif.h" #include "doh.h" #include "warnless.h" +#include "strcase.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -289,7 +290,7 @@ static struct Curl_dns_entry *fetch_addr(struct Curl_easy *data, user.cache_timeout = data->set.dns_cache_timeout; if(hostcache_timestamp_remove(&user, dns)) { - infof(data, "Hostname in DNS cache was stale, zapped\n"); + infof(data, "Hostname in DNS cache was stale, zapped"); dns = NULL; /* the memory deallocation is being handled by the hash */ Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1); } @@ -460,6 +461,97 @@ Curl_cache_addr(struct Curl_easy *data, return dns; } +#ifdef ENABLE_IPV6 +/* return a static IPv6 resolve for 'localhost' */ +static struct Curl_addrinfo *get_localhost6(int port) +{ + struct Curl_addrinfo *ca; + const size_t ss_size = sizeof(struct sockaddr_in6); + const size_t hostlen = strlen("localhost"); + struct sockaddr_in6 sa6; + unsigned char ipv6[16]; + unsigned short port16 = (unsigned short)(port & 0xffff); + ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1); + if(!ca) + return NULL; + + sa6.sin6_family = AF_INET6; + sa6.sin6_port = htons(port16); + sa6.sin6_flowinfo = 0; + sa6.sin6_scope_id = 0; + if(Curl_inet_pton(AF_INET6, "::1", ipv6) < 1) + return NULL; + memcpy(&sa6.sin6_addr, ipv6, sizeof(ipv6)); + + ca->ai_flags = 0; + ca->ai_family = AF_INET6; + ca->ai_socktype = SOCK_STREAM; + ca->ai_protocol = IPPROTO_TCP; + ca->ai_addrlen = (curl_socklen_t)ss_size; + ca->ai_next = NULL; + 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"); + return ca; +} +#else +#define get_localhost6(x) NULL +#endif + +/* return a static IPv4 resolve for 'localhost' */ +static struct Curl_addrinfo *get_localhost(int port) +{ + struct Curl_addrinfo *ca; + const size_t ss_size = sizeof(struct sockaddr_in); + const size_t hostlen = strlen("localhost"); + struct sockaddr_in sa; + unsigned int ipv4; + unsigned short port16 = (unsigned short)(port & 0xffff); + ca = calloc(sizeof(struct Curl_addrinfo) + ss_size + hostlen + 1, 1); + if(!ca) + return NULL; + + /* memset to clear the sa.sin_zero field */ + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons(port16); + if(Curl_inet_pton(AF_INET, "127.0.0.1", (char *)&ipv4) < 1) + return NULL; + memcpy(&sa.sin_addr, &ipv4, sizeof(ipv4)); + + ca->ai_flags = 0; + ca->ai_family = AF_INET; + ca->ai_socktype = SOCK_STREAM; + ca->ai_protocol = IPPROTO_TCP; + ca->ai_addrlen = (curl_socklen_t)ss_size; + 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); + return ca; +} + +/* + * Curl_host_is_ipnum() returns TRUE if the given string is a numerical IPv4 + * (or IPv6 if supported) address. + */ +bool Curl_host_is_ipnum(const char *hostname) +{ + struct in_addr in; +#ifdef ENABLE_IPV6 + struct in6_addr in6; +#endif + if(Curl_inet_pton(AF_INET, hostname, &in) > 0 +#ifdef ENABLE_IPV6 + || Curl_inet_pton(AF_INET6, hostname, &in6) > 0 +#endif + ) + return TRUE; + return FALSE; +} + /* * 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 @@ -487,7 +579,6 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, CURLcode result; enum resolve_t rc = CURLRESOLV_ERROR; /* default to failure */ struct connectdata *conn = data->conn; - *entry = NULL; conn->bits.doh = FALSE; /* default is not */ @@ -497,7 +588,7 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, dns = fetch_addr(data, hostname, port); if(dns) { - infof(data, "Hostname %s was found in DNS cache\n", hostname); + infof(data, "Hostname %s was found in DNS cache", hostname); dns->inuse++; /* we use it! */ rc = CURLRESOLV_RESOLVED; } @@ -534,16 +625,20 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, } #if defined(ENABLE_IPV6) && defined(CURL_OSX_CALL_COPYPROXIES) - /* - * The automagic conversion from IPv4 literals to IPv6 literals only works - * if the SCDynamicStoreCopyProxies system function gets called first. As - * Curl currently doesn't support system-wide HTTP proxies, we therefore - * don't use any value this function might return. - * - * This function is only available on a macOS and is not needed for - * IPv4-only builds, hence the conditions above. - */ - SCDynamicStoreCopyProxies(NULL); + { + /* + * The automagic conversion from IPv4 literals to IPv6 literals only + * works if the SCDynamicStoreCopyProxies system function gets called + * first. As Curl currently doesn't support system-wide HTTP proxies, we + * therefore don't use any value this function might return. + * + * This function is only available on a macOS and is not needed for + * IPv4-only builds, hence the conditions above. + */ + CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL); + if(dict) + CFRelease(dict); + } #endif #ifndef USE_RESOLVE_ON_IPS @@ -584,9 +679,10 @@ enum resolve_t Curl_resolv(struct Curl_easy *data, if(!Curl_ipvalid(data, conn)) return CURLRESOLV_ERROR; - if(allowDOH && data->set.doh && !ipnum) { + if(strcasecompare(hostname, "localhost")) + addr = get_localhost(port); + else if(allowDOH && data->set.doh && !ipnum) addr = Curl_doh(data, hostname, port, &respwait); - } else { /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a non-zero value indicating that we need to wait for the response to @@ -757,7 +853,7 @@ enum resolve_t Curl_resolv_timeout(struct Curl_easy *data, #else #ifndef CURLRES_ASYNCH if(timeoutms) - infof(data, "timeout on name lookup is not supported\n"); + infof(data, "timeout on name lookup is not supported"); #else (void)timeoutms; /* timeoutms not used with an async resolver */ #endif @@ -895,7 +991,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) size_t entry_len; if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) { - infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n", + infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'", hostp->data); continue; } @@ -984,7 +1080,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) #ifndef ENABLE_IPV6 if(strchr(address, ':')) { - infof(data, "Ignoring resolve address '%s', missing IPv6 support.\n", + infof(data, "Ignoring resolve address '%s', missing IPv6 support.", address); continue; } @@ -992,7 +1088,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) ai = Curl_str2addr(address, port); if(!ai) { - infof(data, "Resolve address '%s' found illegal!\n", address); + infof(data, "Resolve address '%s' found illegal!", address); goto err; } @@ -1011,10 +1107,10 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) error = false; err: if(error) { - infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n", + failf(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!", hostp->data); Curl_freeaddrinfo(head); - continue; + return CURLE_SETOPT_OPTION_SYNTAX; } /* Create an entry id, based upon the hostname and port */ @@ -1028,7 +1124,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1); if(dns) { - infof(data, "RESOLVE %s:%d is - old addresses discarded!\n", + infof(data, "RESOLVE %s:%d is - old addresses discarded!", hostname, port); /* delete old entry, there are two reasons for this 1. old entry may have different addresses. @@ -1061,12 +1157,12 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data) Curl_freeaddrinfo(head); return CURLE_OUT_OF_MEMORY; } - infof(data, "Added %s:%d:%s to DNS cache%s\n", + infof(data, "Added %s:%d:%s to DNS cache%s", hostname, port, addresses, permanent ? "" : " (non-permanent)"); /* Wildcard hostname */ if(hostname[0] == '*' && hostname[1] == '\0') { - infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks\n", + infof(data, "RESOLVE %s:%d is wildcard, enabling wildcard checks", hostname, port); data->state.wildcard_resolve = true; } @@ -1094,7 +1190,7 @@ int Curl_resolv_getsock(struct Curl_easy *data, { #ifdef CURLRES_ASYNCH if(data->conn->bits.doh) - /* nothing to wait for during DOH resolve, those handles have their own + /* nothing to wait for during DoH resolve, those handles have their own sockets */ return GETSOCK_BLANK; return Curl_resolver_getsock(data, socks); diff --git a/contrib/libs/curl/lib/hostip.h b/contrib/libs/curl/lib/hostip.h index d178976aa1..28f3b84018 100644 --- a/contrib/libs/curl/lib/hostip.h +++ b/contrib/libs/curl/lib/hostip.h @@ -71,6 +71,8 @@ struct Curl_dns_entry { long inuse; }; +bool Curl_host_is_ipnum(const char *hostname); + /* * Curl_resolv() returns an entry with the info for the specified host * and port. diff --git a/contrib/libs/curl/lib/hostip4.c b/contrib/libs/curl/lib/hostip4.c index d0754af223..ac92126d8c 100644 --- a/contrib/libs/curl/lib/hostip4.c +++ b/contrib/libs/curl/lib/hostip4.c @@ -104,7 +104,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, ai = Curl_ipv4_resolve_r(hostname, port); if(!ai) - infof(data, "Curl_ipv4_resolve_r failed for %s\n", hostname); + infof(data, "Curl_ipv4_resolve_r failed for %s", hostname); return ai; } diff --git a/contrib/libs/curl/lib/hostip6.c b/contrib/libs/curl/lib/hostip6.c index 9791d86468..943cdd261c 100644 --- a/contrib/libs/curl/lib/hostip6.c +++ b/contrib/libs/curl/lib/hostip6.c @@ -172,7 +172,7 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res); if(error) { - infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port); + infof(data, "getaddrinfo(3) failed for %s:%d", hostname, port); return NULL; } diff --git a/contrib/libs/curl/lib/hsts.c b/contrib/libs/curl/lib/hsts.c index ef166f196c..0d5a584012 100644 --- a/contrib/libs/curl/lib/hsts.c +++ b/contrib/libs/curl/lib/hsts.c @@ -138,6 +138,11 @@ CURLcode Curl_hsts_parse(struct hsts *h, const char *hostname, struct stsentry *sts; time_t now = time(NULL); + if(Curl_host_is_ipnum(hostname)) + /* "explicit IP address identification of all forms is excluded." + / RFC 6797 */ + return CURLE_OK; + do { while(*p && ISSPACE(*p)) p++; diff --git a/contrib/libs/curl/lib/http.c b/contrib/libs/curl/lib/http.c index f4100a79f5..d49a8c0aa1 100644 --- a/contrib/libs/curl/lib/http.c +++ b/contrib/libs/curl/lib/http.c @@ -504,7 +504,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data, /* rewind data when completely done sending! */ if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) { conn->bits.rewindaftersend = TRUE; - infof(data, "Rewind stream after send\n"); + infof(data, "Rewind stream after send"); } return CURLE_OK; @@ -515,7 +515,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data, return CURLE_OK; infof(data, "NTLM send, close instead of sending %" - CURL_FORMAT_CURL_OFF_T " bytes\n", + CURL_FORMAT_CURL_OFF_T " bytes", (curl_off_t)(expectsend - bytessent)); } #endif @@ -532,7 +532,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data, /* rewind data when completely done sending! */ if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) { conn->bits.rewindaftersend = TRUE; - infof(data, "Rewind stream after send\n"); + infof(data, "Rewind stream after send"); } return CURLE_OK; @@ -543,7 +543,7 @@ static CURLcode http_perhapsrewind(struct Curl_easy *data, return CURLE_OK; infof(data, "NEGOTIATE send, close instead of sending %" - CURL_FORMAT_CURL_OFF_T " bytes\n", + CURL_FORMAT_CURL_OFF_T " bytes", (curl_off_t)(expectsend - bytessent)); } #endif @@ -756,14 +756,14 @@ output_auth_headers(struct Curl_easy *data, if(auth) { #ifndef CURL_DISABLE_PROXY - infof(data, "%s auth using %s with user '%s'\n", + infof(data, "%s auth using %s with user '%s'", proxy ? "Proxy" : "Server", auth, proxy ? (data->state.aptr.proxyuser ? data->state.aptr.proxyuser : "") : (data->state.aptr.user ? data->state.aptr.user : "")); #else - infof(data, "Server auth using %s with user '%s'\n", + infof(data, "Server auth using %s with user '%s'", auth, data->state.aptr.user ? data->state.aptr.user : ""); #endif @@ -850,7 +850,9 @@ 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, we do some weirdo checks here */ if(!data->state.this_is_a_follow || +#ifndef CURL_DISABLE_NETRC conn->bits.netrc || +#endif !data->state.first_host || data->set.allow_auth_to_other_hosts || strcasecompare(data->state.first_host, conn->host.name)) { @@ -995,14 +997,14 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, result = Curl_input_ntlm_wb(data, conn, proxy, auth); if(result) { - infof(data, "Authentication problem. Ignoring this.\n"); + infof(data, "Authentication problem. Ignoring this."); data->state.authproblem = TRUE; } } #endif } else { - infof(data, "Authentication problem. Ignoring this.\n"); + infof(data, "Authentication problem. Ignoring this."); data->state.authproblem = TRUE; } } @@ -1013,7 +1015,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, #ifndef CURL_DISABLE_CRYPTO_AUTH if(checkprefix("Digest", auth) && is_valid_auth_separator(auth[6])) { if((authp->avail & CURLAUTH_DIGEST) != 0) - infof(data, "Ignoring duplicate digest auth header.\n"); + infof(data, "Ignoring duplicate digest auth header."); else if(Curl_auth_is_digest_supported()) { CURLcode result; @@ -1026,7 +1028,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, * Digest */ result = Curl_input_digest(data, proxy, auth); if(result) { - infof(data, "Authentication problem. Ignoring this.\n"); + infof(data, "Authentication problem. Ignoring this."); data->state.authproblem = TRUE; } } @@ -1042,7 +1044,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, anyway, which basically means our name+password isn't valid. */ authp->avail = CURLAUTH_NONE; - infof(data, "Authentication problem. Ignoring this.\n"); + infof(data, "Authentication problem. Ignoring this."); data->state.authproblem = TRUE; } } @@ -1055,7 +1057,7 @@ CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy, /* We asked for Bearer authentication but got a 40X back anyway, which basically means our token isn't valid. */ authp->avail = CURLAUTH_NONE; - infof(data, "Authentication problem. Ignoring this.\n"); + infof(data, "Authentication problem. Ignoring this."); data->state.authproblem = TRUE; } } @@ -1177,6 +1179,7 @@ static size_t readmoredata(char *buffer, data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE; if(data->set.max_send_speed && + (data->set.max_send_speed < (curl_off_t)fullsize) && (data->set.max_send_speed < http->postsize)) /* speed limit */ fullsize = (size_t)data->set.max_send_speed; @@ -1537,38 +1540,35 @@ static int http_getsock_do(struct Curl_easy *data, #ifndef CURL_DISABLE_PROXY static CURLcode add_haproxy_protocol_header(struct Curl_easy *data) { - char proxy_header[128]; struct dynbuf req; CURLcode result; - char tcp_version[5]; + const char *tcp_version; DEBUGASSERT(data->conn); + Curl_dyn_init(&req, DYN_HAXPROXY); - /* Emit the correct prefix for IPv6 */ - if(data->conn->bits.ipv6) { - strcpy(tcp_version, "TCP6"); - } +#ifdef USE_UNIX_SOCKETS + if(data->conn->unix_domain_socket) + /* the buffer is large enough to hold this! */ + result = Curl_dyn_add(&req, "PROXY UNKNOWN\r\n"); else { - strcpy(tcp_version, "TCP4"); - } +#endif + /* Emit the correct prefix for IPv6 */ + tcp_version = data->conn->bits.ipv6 ? "TCP6" : "TCP4"; - msnprintf(proxy_header, - sizeof(proxy_header), - "PROXY %s %s %s %i %i\r\n", - tcp_version, - data->info.conn_local_ip, - data->info.conn_primary_ip, - data->info.conn_local_port, - data->info.conn_primary_port); + result = Curl_dyn_addf(&req, "PROXY %s %s %s %i %i\r\n", + tcp_version, + data->info.conn_local_ip, + data->info.conn_primary_ip, + data->info.conn_local_port, + data->info.conn_primary_port); - Curl_dyn_init(&req, DYN_HAXPROXY); - - result = Curl_dyn_add(&req, proxy_header); - if(result) - return result; - - result = Curl_buffer_send(&req, data, &data->info.request_size, - 0, FIRSTSOCKET); +#ifdef USE_UNIX_SOCKETS + } +#endif + if(!result) + result = Curl_buffer_send(&req, data, &data->info.request_size, + 0, FIRSTSOCKET); return result; } #endif @@ -1588,7 +1588,7 @@ static CURLcode https_connecting(struct Curl_easy *data, bool *done) #endif /* perform SSL initialization for this socket */ - result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET, done); + result = Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, done); if(result) connclose(conn, "Failed HTTPS connection"); @@ -2912,7 +2912,7 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data, /* We have a new url to load, but since we want to be able to re-use this connection properly, we read the full response in "ignore more" */ k->ignorebody = TRUE; - infof(data, "Ignoring the response-body\n"); + infof(data, "Ignoring the response-body"); } if(data->state.resume_from && !k->content_range && (data->state.httpreq == HTTPREQ_GET) && @@ -2947,7 +2947,7 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data, /* We're simulating a http 304 from server so we return what should have been returned from the server */ data->info.httpcode = 304; - infof(data, "Simulate a HTTP 304 response!\n"); + infof(data, "Simulate a HTTP 304 response!"); /* we abort the transfer before it is completed == we ruin the re-use ability. Close the connection */ connclose(conn, "Simulated 304 handling"); @@ -2958,6 +2958,39 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data, return CURLE_OK; } +#ifdef HAVE_LIBZ +CURLcode Curl_transferencode(struct Curl_easy *data) +{ + if(!Curl_checkheaders(data, "TE") && + data->set.http_transfer_encoding) { + /* When we are to insert a TE: header in the request, we must also insert + TE in a Connection: header, so we need to merge the custom provided + Connection: header and prevent the original to get sent. Note that if + the user has inserted his/her own TE: header we don't do this magic + but then assume that the user will handle it all! */ + char *cptr = Curl_checkheaders(data, "Connection"); +#define TE_HEADER "TE: gzip\r\n" + + Curl_safefree(data->state.aptr.te); + + if(cptr) { + cptr = Curl_copy_header_value(cptr); + if(!cptr) + return CURLE_OUT_OF_MEMORY; + } + + /* Create the (updated) Connection: header */ + data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER, + cptr ? cptr : "", (cptr && *cptr) ? ", ":""); + + free(cptr); + if(!data->state.aptr.te) + return CURLE_OUT_OF_MEMORY; + } + return CURLE_OK; +} +#endif + #ifndef USE_HYPER /* * Curl_http() gets called from the generic multi_do() function when a HTTP @@ -3004,11 +3037,11 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { /* We don't support HTTP/2 proxies yet. Also it's debatable whether or not this setting should apply to HTTP/2 proxies. */ - infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n"); + infof(data, "Ignoring HTTP/2 prior knowledge due to proxy"); break; } #endif - DEBUGF(infof(data, "HTTP/2 over clean TCP\n")); + DEBUGF(infof(data, "HTTP/2 over clean TCP")); conn->httpversion = 20; result = Curl_http2_switched(data, NULL, 0); @@ -3074,33 +3107,9 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) #ifdef HAVE_LIBZ /* we only consider transfer-encoding magic if libz support is built-in */ - - if(!Curl_checkheaders(data, "TE") && - data->set.http_transfer_encoding) { - /* When we are to insert a TE: header in the request, we must also insert - TE in a Connection: header, so we need to merge the custom provided - Connection: header and prevent the original to get sent. Note that if - the user has inserted his/her own TE: header we don't do this magic - but then assume that the user will handle it all! */ - char *cptr = Curl_checkheaders(data, "Connection"); -#define TE_HEADER "TE: gzip\r\n" - - Curl_safefree(data->state.aptr.te); - - if(cptr) { - cptr = Curl_copy_header_value(cptr); - if(!cptr) - return CURLE_OUT_OF_MEMORY; - } - - /* Create the (updated) Connection: header */ - data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER, - cptr ? cptr : "", (cptr && *cptr) ? ", ":""); - - free(cptr); - if(!data->state.aptr.te) - return CURLE_OUT_OF_MEMORY; - } + result = Curl_transferencode(data); + if(result) + return result; #endif result = Curl_http_body(data, conn, httpreq, &te); @@ -3253,7 +3262,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) /* already sent the entire request body, mark the "upload" as complete */ infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T - " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n", + " out of %" CURL_FORMAT_CURL_OFF_T " bytes", data->req.writebytecount, http->postsize); data->req.upload_done = TRUE; data->req.keepon &= ~KEEP_SEND; /* we're done writing */ @@ -3411,7 +3420,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, return CURLE_FILESIZE_EXCEEDED; } streamclose(conn, "overflow content-length"); - infof(data, "Overflow Content-Length: value!\n"); + infof(data, "Overflow Content-Length: value!"); } else { /* negative or just rubbish - bad HTTP */ @@ -3443,7 +3452,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, * Default action for 1.0 is to close. */ connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */ - infof(data, "HTTP/1.0 proxy connection set to keep alive!\n"); + infof(data, "HTTP/1.0 proxy connection set to keep alive!"); } else if((conn->httpversion == 11) && conn->bits.httpproxy && @@ -3453,7 +3462,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, * close down after this transfer. */ connclose(conn, "Proxy-Connection: asked to close after done"); - infof(data, "HTTP/1.1 proxy connection set close!\n"); + infof(data, "HTTP/1.1 proxy connection set close!"); } #endif else if((conn->httpversion == 10) && @@ -3465,7 +3474,7 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, * * [RFC2068, section 19.7.1] */ connkeep(conn, "Connection keep-alive"); - infof(data, "HTTP/1.0 connection set to keep alive!\n"); + infof(data, "HTTP/1.0 connection set to keep alive!"); } else if(Curl_compareheader(headp, "Connection:", "close")) { /* @@ -3646,10 +3655,10 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, Curl_hsts_parse(data->hsts, data->state.up.hostname, headp + strlen("Strict-Transport-Security:")); if(check) - infof(data, "Illegal STS header skipped\n"); + infof(data, "Illegal STS header skipped"); #ifdef DEBUGBUILD else - infof(data, "Parsed STS header fine (%zu entries)\n", + infof(data, "Parsed STS header fine (%zu entries)", data->hsts->list.size); #endif } @@ -3719,12 +3728,12 @@ CURLcode Curl_http_statusline(struct Curl_easy *data, /* Default action for HTTP/1.0 must be to close, unless we get one of those fancy headers that tell us the server keeps it open for us! */ - infof(data, "HTTP 1.0, assume close after body\n"); + infof(data, "HTTP 1.0, assume close after body"); connclose(conn, "HTTP/1.0 close after body"); } else if(conn->httpversion == 20 || (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) { - DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n")); + DEBUGF(infof(data, "HTTP/2 found, allow multiplexing")); /* HTTP/2 cannot avoid multiplexing since it is a core functionality of the protocol */ conn->bundle->multiuse = BUNDLE_MULTIPLEX; @@ -3733,7 +3742,7 @@ CURLcode Curl_http_statusline(struct Curl_easy *data, !conn->bits.close) { /* If HTTP version is >= 1.1 and connection is persistent */ DEBUGF(infof(data, - "HTTP 1.1 or later with persistent connection\n")); + "HTTP 1.1 or later with persistent connection")); } k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200; @@ -3911,7 +3920,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, /* Switching Protocols */ if(k->upgr101 == UPGR101_REQUESTED) { /* Switching to HTTP/2 */ - infof(data, "Received 101\n"); + infof(data, "Received 101"); k->upgr101 = UPGR101_RECEIVED; /* we'll get more headers (HTTP/2 response) */ @@ -3951,7 +3960,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, assume that the server will close the connection to signal the end of the document. */ infof(data, "no chunk, no close, no size. Assume close to " - "signal end\n"); + "signal end"); streamclose(conn, "HTTP: No end-of-message indicator"); } } @@ -3964,7 +3973,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, (conn->http_ntlm_state == NTLMSTATE_TYPE2)) || ((data->req.httpcode == 407) && (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) { - infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); + infof(data, "Connection closure while negotiating auth (HTTP 1.0?)"); data->state.authproblem = TRUE; } #endif @@ -3974,7 +3983,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, (conn->http_negotiate_state == GSS_AUTHRECV)) || ((data->req.httpcode == 407) && (conn->proxy_negotiate_state == GSS_AUTHRECV)))) { - infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); + infof(data, "Connection closure while negotiating auth (HTTP 1.0?)"); data->state.authproblem = TRUE; } if((conn->http_negotiate_state == GSS_AUTHDONE) && @@ -4054,21 +4063,21 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if((k->httpcode == 417) && data->state.expect100header) { /* 417 Expectation Failed - try again without the Expect header */ - infof(data, "Got 417 while waiting for a 100\n"); + infof(data, "Got 417 while waiting for a 100"); data->state.disableexpect = TRUE; DEBUGASSERT(!data->req.newurl); data->req.newurl = strdup(data->state.url); Curl_done_sending(data, k); } else if(data->set.http_keep_sending_on_error) { - infof(data, "HTTP error before end of send, keep sending\n"); + infof(data, "HTTP error before end of send, keep sending"); if(k->exp100 > EXP100_SEND_DATA) { k->exp100 = EXP100_SEND_DATA; k->keepon |= KEEP_SEND; } } else { - infof(data, "HTTP error before end of send, stop sending\n"); + infof(data, "HTTP error before end of send, stop sending"); streamclose(conn, "Stop sending data before everything sent"); result = Curl_done_sending(data, k); if(result) @@ -4088,7 +4097,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(conn->bits.rewindaftersend) { /* We rewind after a complete send, so thus we continue sending now */ - infof(data, "Keep sending data to get tossed away!\n"); + infof(data, "Keep sending data to get tossed away!"); k->keepon |= KEEP_SEND; } } @@ -4243,11 +4252,11 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, if(k->upgr101 == UPGR101_RECEIVED) { /* supposedly upgraded to http2 now */ if(conn->httpversion != 20) - infof(data, "Lying server, not serving HTTP/2\n"); + infof(data, "Lying server, not serving HTTP/2"); } if(conn->httpversion < 20) { conn->bundle->multiuse = BUNDLE_NO_MULTIUSE; - infof(data, "Mark bundle as not supporting multiuse\n"); + infof(data, "Mark bundle as not supporting multiuse"); } } else if(!nc) { diff --git a/contrib/libs/curl/lib/http.h b/contrib/libs/curl/lib/http.h index 2a3834ae11..bce171550d 100644 --- a/contrib/libs/curl/lib/http.h +++ b/contrib/libs/curl/lib/http.h @@ -93,6 +93,7 @@ CURLcode Curl_http_statusline(struct Curl_easy *data, struct connectdata *conn); CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, char *headp); +CURLcode Curl_transferencode(struct Curl_easy *data); CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn, Curl_HttpReq httpreq, const char **teep); diff --git a/contrib/libs/curl/lib/http2.c b/contrib/libs/curl/lib/http2.c index f194c18b23..60e0143c15 100644 --- a/contrib/libs/curl/lib/http2.c +++ b/contrib/libs/curl/lib/http2.c @@ -146,12 +146,12 @@ static CURLcode http2_disconnect(struct Curl_easy *data, (void)data; #endif - H2BUGF(infof(data, "HTTP/2 DISCONNECT starts now\n")); + H2BUGF(infof(data, "HTTP/2 DISCONNECT starts now")); nghttp2_session_del(c->h2); Curl_safefree(c->inbuf); - H2BUGF(infof(data, "HTTP/2 DISCONNECT done\n")); + H2BUGF(infof(data, "HTTP/2 DISCONNECT done")); return CURLE_OK; } @@ -196,11 +196,13 @@ static bool http2_connisdead(struct Curl_easy *data, struct connectdata *conn) data, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result); if(nread != -1) { infof(data, - "%d bytes stray data read before trying h2 connection\n", + "%d bytes stray data read before trying h2 connection", (int)nread); httpc->nread_inbuf = 0; httpc->inbuflen = nread; - (void)h2_process_pending_input(data, httpc, &result); + if(h2_process_pending_input(data, httpc, &result) < 0) + /* immediate error, considered dead */ + dead = TRUE; } else /* the read failed so let's say this is dead anyway */ @@ -350,13 +352,12 @@ static const struct Curl_handler Curl_handler_http2_ssl = { }; /* - * Store nghttp2 version info in this buffer, Prefix with a space. Return - * total length written. + * Store nghttp2 version info in this buffer. */ -int Curl_http2_ver(char *p, size_t len) +void Curl_http2_ver(char *p, size_t len) { nghttp2_info *h2 = nghttp2_version(0); - return msnprintf(p, len, "nghttp2/%s", h2->version_str); + (void)msnprintf(p, len, "nghttp2/%s", h2->version_str); } /* @@ -551,7 +552,7 @@ static int push_promise(struct Curl_easy *data, const nghttp2_push_promise *frame) { int rv; /* one of the CURL_PUSH_* defines */ - H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!\n", + H2BUGF(infof(data, "PUSH_PROMISE received, stream %u!", frame->promised_stream_id)); if(data->multi->push_cb) { struct HTTP *stream; @@ -563,7 +564,7 @@ static int push_promise(struct Curl_easy *data, /* clone the parent */ struct Curl_easy *newhandle = duphandle(data); if(!newhandle) { - infof(data, "failed to duplicate handle\n"); + infof(data, "failed to duplicate handle"); rv = CURL_PUSH_DENY; /* FAIL HARD */ goto fail; } @@ -571,7 +572,7 @@ static int push_promise(struct Curl_easy *data, heads.data = data; heads.frame = frame; /* ask the application */ - H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!\n")); + H2BUGF(infof(data, "Got PUSH_PROMISE, ask application!")); stream = data->req.p.http; if(!stream) { @@ -619,7 +620,7 @@ static int push_promise(struct Curl_easy *data, state with the given connection !*/ rc = Curl_multi_add_perform(data->multi, newhandle, conn); if(rc) { - infof(data, "failed to add handle to multi\n"); + infof(data, "failed to add handle to multi"); http2_stream_free(newhandle->req.p.http); newhandle->req.p.http = NULL; Curl_close(&newhandle); @@ -632,15 +633,17 @@ static int push_promise(struct Curl_easy *data, frame->promised_stream_id, newhandle); if(rv) { - infof(data, "failed to set user_data for stream %d\n", + infof(data, "failed to set user_data for stream %d", frame->promised_stream_id); DEBUGASSERT(0); rv = CURL_PUSH_DENY; goto fail; } + Curl_dyn_init(&newstream->header_recvbuf, DYN_H2_HEADERS); + Curl_dyn_init(&newstream->trailer_recvbuf, DYN_H2_TRAILERS); } else { - H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n")); + H2BUGF(infof(data, "Got PUSH_PROMISE, ignore it!")); rv = CURL_PUSH_DENY; } fail: @@ -676,21 +679,21 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, /* stream ID zero is for connection-oriented stuff */ if(frame->hd.type == NGHTTP2_SETTINGS) { uint32_t max_conn = httpc->settings.max_concurrent_streams; - H2BUGF(infof(data, "Got SETTINGS\n")); + H2BUGF(infof(data, "Got SETTINGS")); httpc->settings.max_concurrent_streams = nghttp2_session_get_remote_settings( session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); httpc->settings.enable_push = nghttp2_session_get_remote_settings( session, NGHTTP2_SETTINGS_ENABLE_PUSH); - H2BUGF(infof(data, "MAX_CONCURRENT_STREAMS == %d\n", + H2BUGF(infof(data, "MAX_CONCURRENT_STREAMS == %d", httpc->settings.max_concurrent_streams)); - H2BUGF(infof(data, "ENABLE_PUSH == %s\n", + H2BUGF(infof(data, "ENABLE_PUSH == %s", httpc->settings.enable_push?"TRUE":"false")); if(max_conn != httpc->settings.max_concurrent_streams) { /* only signal change if the value actually changed */ infof(data, - "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!\n", + "Connection state changed (MAX_CONCURRENT_STREAMS == %u)!", httpc->settings.max_concurrent_streams); multi_connchanged(data->multi); } @@ -700,19 +703,19 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, data_s = nghttp2_session_get_stream_user_data(session, stream_id); if(!data_s) { H2BUGF(infof(data, - "No Curl_easy associated with stream: %x\n", + "No Curl_easy associated with stream: %x", stream_id)); return 0; } stream = data_s->req.p.http; if(!stream) { - H2BUGF(infof(data_s, "No proto pointer for stream: %x\n", + H2BUGF(infof(data_s, "No proto pointer for stream: %x", stream_id)); return NGHTTP2_ERR_CALLBACK_FAILURE; } - H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x\n", + H2BUGF(infof(data_s, "on_frame_recv() header %x stream %x", frame->hd.type, stream_id)); switch(frame->hd.type) { @@ -760,7 +763,7 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, ncopy); stream->nread_header_recvbuf += ncopy; - H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n", + H2BUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p", ncopy, stream_id, stream->mem)); stream->len -= ncopy; @@ -782,13 +785,13 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, if(nghttp2_is_fatal(h2)) return NGHTTP2_ERR_CALLBACK_FAILURE; else if(rv == CURL_PUSH_ERROROUT) { - DEBUGF(infof(data_s, "Fail the parent stream (too)\n")); + DEBUGF(infof(data_s, "Fail the parent stream (too)")); return NGHTTP2_ERR_CALLBACK_FAILURE; } } break; default: - H2BUGF(infof(data_s, "Got frame type %x for stream %u!\n", + H2BUGF(infof(data_s, "Got frame type %x for stream %u!", frame->hd.type, stream_id)); break; } @@ -833,7 +836,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, Curl_expire(data_s, 0, EXPIRE_RUN_NOW); H2BUGF(infof(data_s, "%zu data received for stream %u " - "(%zu left in buffer %p, total %zu)\n", + "(%zu left in buffer %p, total %zu)", nread, stream_id, stream->len, stream->mem, stream->memlen)); @@ -842,7 +845,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, stream->pausedata = mem + nread; stream->pauselen = len - nread; H2BUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer" - ", stream %u\n", + ", stream %u", len - nread, stream_id)); data_s->conn->proto.httpc.pause_stream_id = stream_id; @@ -880,7 +883,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, decided to reject stream (e.g., PUSH_PROMISE). */ return 0; } - H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n", + H2BUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u", nghttp2_http2_strerror(error_code), error_code, stream_id)); stream = data_s->req.p.http; if(!stream) @@ -895,15 +898,15 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id, /* remove the entry from the hash as the stream is now gone */ rv = nghttp2_session_set_stream_user_data(session, stream_id, 0); if(rv) { - infof(data_s, "http/2: failed to clear user_data for stream %d!\n", + infof(data_s, "http/2: failed to clear user_data for stream %d!", stream_id); DEBUGASSERT(0); } if(stream_id == httpc->pause_stream_id) { - H2BUGF(infof(data_s, "Stopped the pause stream!\n")); + H2BUGF(infof(data_s, "Stopped the pause stream!")); httpc->pause_stream_id = 0; } - H2BUGF(infof(data_s, "Removed stream %u hash!\n", stream_id)); + H2BUGF(infof(data_s, "Removed stream %u hash!", stream_id)); stream->stream_id = 0; /* cleared */ } return 0; @@ -921,7 +924,7 @@ static int on_begin_headers(nghttp2_session *session, return 0; } - H2BUGF(infof(data_s, "on_begin_headers() was called\n")); + H2BUGF(infof(data_s, "on_begin_headers() was called")); if(frame->hd.type != NGHTTP2_HEADERS) { return 0; @@ -1049,7 +1052,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(stream->bodystarted) { /* This is a trailer */ - H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen, + H2BUGF(infof(data_s, "h2 trailer: %.*s: %.*s", namelen, name, valuelen, value)); result = Curl_dyn_addf(&stream->trailer_recvbuf, "%.*s: %.*s\r\n", namelen, name, @@ -1082,7 +1085,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(get_transfer(httpc) != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); - H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n", + H2BUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)", stream->status_code, data_s)); return 0; } @@ -1106,7 +1109,7 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, if(get_transfer(httpc) != data_s) Curl_expire(data_s, 0, EXPIRE_RUN_NOW); - H2BUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen, + H2BUGF(infof(data_s, "h2 header: %.*s: %.*s", namelen, name, valuelen, value)); return 0; /* 0 is successful */ @@ -1156,7 +1159,7 @@ static ssize_t data_source_read_callback(nghttp2_session *session, return NGHTTP2_ERR_DEFERRED; H2BUGF(infof(data_s, "data_source_read_callback: " - "returns %zu bytes stream %u\n", + "returns %zu bytes stream %u", nread, stream_id)); return nread; @@ -1223,7 +1226,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature) (void)nghttp2_session_send(httpc->h2); if(http->stream_id == httpc->pause_stream_id) { - infof(data, "stopped the pause stream!\n"); + infof(data, "stopped the pause stream!"); httpc->pause_stream_id = 0; } } @@ -1236,7 +1239,7 @@ void Curl_http2_done(struct Curl_easy *data, bool premature) int rv = nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0); if(rv) { - infof(data, "http/2: failed to clear user_data for stream %d!\n", + infof(data, "http/2: failed to clear user_data for stream %d!", http->stream_id); DEBUGASSERT(0); } @@ -1383,7 +1386,7 @@ static int h2_process_pending_input(struct Curl_easy *data, if(nread == rv) { H2BUGF(infof(data, "h2_process_pending_input: All data in connection buffer " - "processed\n")); + "processed")); httpc->inbuflen = 0; httpc->nread_inbuf = 0; } @@ -1391,7 +1394,7 @@ static int h2_process_pending_input(struct Curl_easy *data, httpc->nread_inbuf += rv; H2BUGF(infof(data, "h2_process_pending_input: %zu bytes left in connection " - "buffer\n", + "buffer", httpc->inbuflen - httpc->nread_inbuf)); } @@ -1412,7 +1415,7 @@ static int h2_process_pending_input(struct Curl_easy *data, if(should_close_session(httpc)) { struct HTTP *stream = data->req.p.http; H2BUGF(infof(data, - "h2_process_pending_input: nothing to do in this session\n")); + "h2_process_pending_input: nothing to do in this session")); if(stream->error) *err = CURLE_HTTP2; else { @@ -1456,7 +1459,7 @@ CURLcode Curl_http2_done_sending(struct Curl_easy *data, struct SingleRequest *k = &data->req; int rv; - H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)\n", data)); + H2BUGF(infof(data, "HTTP/2 still wants to send data (easy %p)", data)); /* and attempt to send the pending frames */ rv = h2_session_send(data, h2); @@ -1495,7 +1498,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn, /* Reset to FALSE to prevent infinite loop in readwrite_data function. */ stream->closed = FALSE; if(stream->error == NGHTTP2_REFUSED_STREAM) { - H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!\n", + H2BUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!", stream->stream_id)); connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */ data->state.refused_stream = TRUE; @@ -1544,7 +1547,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn, stream->close_handled = TRUE; - H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n")); + H2BUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close")); return 0; } @@ -1587,7 +1590,7 @@ static int h2_session_send(struct Curl_easy *data, h2_pri_spec(data, &pri_spec); - H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n", + H2BUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)", stream->stream_id, data)); DEBUGASSERT(stream->stream_id != -1); rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id, @@ -1611,7 +1614,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, if(should_close_session(httpc)) { H2BUGF(infof(data, - "http2_recv: nothing to do in this session\n")); + "http2_recv: nothing to do in this session")); if(conn->bits.close) { /* already marked for closure, return OK and we're done */ *err = CURLE_OK; @@ -1645,12 +1648,12 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, stream->nread_header_recvbuf, ncopy); stream->nread_header_recvbuf += ncopy; - H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n", + H2BUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf", (int)ncopy)); return ncopy; } - H2BUGF(infof(data, "http2_recv: easy %p (stream %u) win %u/%u\n", + H2BUGF(infof(data, "http2_recv: easy %p (stream %u) win %u/%u", data, stream->stream_id, nghttp2_session_get_local_window_size(httpc->h2), nghttp2_session_get_stream_local_window_size(httpc->h2, @@ -1658,7 +1661,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, )); if((data->state.drain) && stream->memlen) { - H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n", + H2BUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)", stream->memlen, stream->stream_id, stream->mem, mem)); if(mem != stream->mem) { @@ -1686,7 +1689,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, stream->pauselen -= nread; if(stream->pauselen == 0) { - H2BUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id)); + H2BUGF(infof(data, "Unpaused by stream %u", stream->stream_id)); DEBUGASSERT(httpc->pause_stream_id == stream->stream_id); httpc->pause_stream_id = 0; @@ -1704,7 +1707,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, return -1; } } - H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n", + H2BUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u", nread, stream->stream_id)); return nread; } @@ -1720,7 +1723,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, if(stream->closed) /* closed overrides paused */ return 0; - H2BUGF(infof(data, "stream %x is paused, pause id: %x\n", + H2BUGF(infof(data, "stream %x is paused, pause id: %x", stream->stream_id, httpc->pause_stream_id)); *err = CURLE_AGAIN; return -1; @@ -1758,12 +1761,12 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, return -1; } - H2BUGF(infof(data, "end of stream\n")); + H2BUGF(infof(data, "end of stream")); *err = CURLE_OK; return 0; } - H2BUGF(infof(data, "nread=%zd\n", nread)); + H2BUGF(infof(data, "nread=%zd", nread)); httpc->inbuflen = nread; @@ -1772,7 +1775,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, else { nread = httpc->inbuflen - httpc->nread_inbuf; (void)nread; /* silence warning, used in debug */ - H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n", + H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd", nread)); } @@ -1781,14 +1784,14 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, } if(stream->memlen) { ssize_t retlen = stream->memlen; - H2BUGF(infof(data, "http2_recv: returns %zd for stream %u\n", + H2BUGF(infof(data, "http2_recv: returns %zd for stream %u", retlen, stream->stream_id)); stream->memlen = 0; if(httpc->pause_stream_id == stream->stream_id) { /* data for this stream is returned now, but this stream caused a pause already so we need it called again asap */ - H2BUGF(infof(data, "Data returned for PAUSED stream %u\n", + H2BUGF(infof(data, "Data returned for PAUSED stream %u", stream->stream_id)); } else if(!stream->closed) { @@ -1803,7 +1806,7 @@ static ssize_t http2_recv(struct Curl_easy *data, int sockindex, if(stream->closed) return http2_handle_stream_close(conn, data, stream, err); *err = CURLE_AGAIN; - H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u\n", + H2BUGF(infof(data, "http2_recv returns AGAIN for stream %u", stream->stream_id)); return -1; } @@ -1907,11 +1910,11 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, (void)sockindex; - H2BUGF(infof(data, "http2_send len=%zu\n", len)); + H2BUGF(infof(data, "http2_send len=%zu", len)); if(stream->stream_id != -1) { if(stream->close_handled) { - infof(data, "stream %d closed\n", stream->stream_id); + infof(data, "stream %d closed", stream->stream_id); *err = CURLE_HTTP2_STREAM; return -1; } @@ -1940,7 +1943,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, stream->upload_len = 0; if(should_close_session(httpc)) { - H2BUGF(infof(data, "http2_send: nothing to do in this session\n")); + H2BUGF(infof(data, "http2_send: nothing to do in this session")); *err = CURLE_HTTP2; return -1; } @@ -1953,7 +1956,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, nghttp2_session_resume_data(h2, stream->stream_id); } - H2BUGF(infof(data, "http2_send returns %zu for stream %u\n", len, + H2BUGF(infof(data, "http2_send returns %zu for stream %u", len, stream->stream_id)); return len; } @@ -2116,7 +2119,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, for(i = 0; i < nheader; ++i) { acc += nva[i].namelen + nva[i].valuelen; - H2BUGF(infof(data, "h2 header: %.*s:%.*s\n", + H2BUGF(infof(data, "h2 header: %.*s:%.*s", nva[i].namelen, nva[i].name, nva[i].valuelen, nva[i].value)); } @@ -2124,13 +2127,13 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, if(acc > MAX_ACC) { infof(data, "http2_send: Warning: The cumulative length of all " "headers exceeds %d bytes and that could cause the " - "stream to be rejected.\n", MAX_ACC); + "stream to be rejected.", MAX_ACC); } } h2_pri_spec(data, &pri_spec); - H2BUGF(infof(data, "http2_send request allowed %d (easy handle %p)\n", + H2BUGF(infof(data, "http2_send request allowed %d (easy handle %p)", nghttp2_session_check_request_allowed(h2), (void *)data)); switch(data->state.httpreq) { @@ -2158,20 +2161,20 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, if(stream_id < 0) { H2BUGF(infof(data, - "http2_send() nghttp2_submit_request error (%s)%d\n", + "http2_send() nghttp2_submit_request error (%s)%d", nghttp2_strerror(stream_id), stream_id)); *err = CURLE_SEND_ERROR; return -1; } - infof(data, "Using Stream ID: %x (easy handle %p)\n", + infof(data, "Using Stream ID: %x (easy handle %p)", stream_id, (void *)data); stream->stream_id = stream_id; rv = h2_session_send(data, h2); if(rv) { H2BUGF(infof(data, - "http2_send() nghttp2_session_send error (%s)%d\n", + "http2_send() nghttp2_session_send error (%s)%d", nghttp2_strerror(rv), rv)); *err = CURLE_SEND_ERROR; @@ -2179,7 +2182,7 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex, } if(should_close_session(httpc)) { - H2BUGF(infof(data, "http2_send: nothing to do in this session\n")); + H2BUGF(infof(data, "http2_send: nothing to do in this session")); *err = CURLE_HTTP2; return -1; } @@ -2230,7 +2233,7 @@ CURLcode Curl_http2_setup(struct Curl_easy *data, return result; } - infof(data, "Using HTTP2, server supports multi-use\n"); + infof(data, "Using HTTP2, server supports multiplexing"); stream->upload_left = 0; stream->upload_mem = NULL; stream->upload_len = 0; @@ -2247,7 +2250,7 @@ CURLcode Curl_http2_setup(struct Curl_easy *data, conn->httpversion = 20; conn->bundle->multiuse = BUNDLE_MULTIPLEX; - infof(data, "Connection state changed (HTTP/2 confirmed)\n"); + infof(data, "Connection state changed (HTTP/2 confirmed)"); multi_connchanged(data->multi); return CURLE_OK; @@ -2287,7 +2290,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data, stream->stream_id, data); if(rv) { - infof(data, "http/2: failed to set user_data for stream %d!\n", + infof(data, "http/2: failed to set user_data for stream %d!", stream->stream_id); DEBUGASSERT(0); } @@ -2327,7 +2330,7 @@ CURLcode Curl_http2_switched(struct Curl_easy *data, } infof(data, "Copying HTTP/2 data in stream buffer to connection buffer" - " after upgrade: len=%zu\n", + " after upgrade: len=%zu", nread); if(nread) @@ -2378,7 +2381,7 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause) if(rv) return CURLE_SEND_ERROR; - DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u\n", + DEBUGF(infof(data, "Set HTTP/2 window size to %u for stream %u", window, stream->stream_id)); #ifdef DEBUGBUILD @@ -2387,7 +2390,7 @@ CURLcode Curl_http2_stream_pause(struct Curl_easy *data, bool pause) uint32_t window2 = nghttp2_session_get_stream_local_window_size(httpc->h2, stream->stream_id); - DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u\n", + DEBUGF(infof(data, "HTTP/2 window size is now %u for stream %u", window2, stream->stream_id)); } #endif diff --git a/contrib/libs/curl/lib/http2.h b/contrib/libs/curl/lib/http2.h index 21e2c086a3..d6986d97fa 100644 --- a/contrib/libs/curl/lib/http2.h +++ b/contrib/libs/curl/lib/http2.h @@ -32,10 +32,9 @@ #define DEFAULT_MAX_CONCURRENT_STREAMS 100 /* - * Store nghttp2 version info in this buffer, Prefix with a space. Return - * total length written. + * Store nghttp2 version info in this buffer. */ -int Curl_http2_ver(char *p, size_t len); +void Curl_http2_ver(char *p, size_t len); const char *Curl_http2_strerror(uint32_t err); diff --git a/contrib/libs/curl/lib/http_aws_sigv4.c b/contrib/libs/curl/lib/http_aws_sigv4.c index a04b46a351..02663abd63 100644 --- a/contrib/libs/curl/lib/http_aws_sigv4.c +++ b/contrib/libs/curl/lib/http_aws_sigv4.c @@ -126,7 +126,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) tmp1 = strchr(tmp0, ':'); len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0); if(len < 1) { - infof(data, "first provider can't be empty\n"); + infof(data, "first provider can't be empty"); ret = CURLE_BAD_FUNCTION_ARGUMENT; goto fail; } @@ -145,7 +145,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) tmp1 = strchr(tmp0, ':'); len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0); if(len < 1) { - infof(data, "second provider can't be empty\n"); + infof(data, "second provider can't be empty"); ret = CURLE_BAD_FUNCTION_ARGUMENT; goto fail; } @@ -165,7 +165,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) tmp1 = strchr(tmp0, ':'); len = tmp1 ? (size_t)(tmp1 - tmp0) : strlen(tmp0); if(len < 1) { - infof(data, "region can't be empty\n"); + infof(data, "region can't be empty"); ret = CURLE_BAD_FUNCTION_ARGUMENT; goto fail; } @@ -182,7 +182,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) goto fail; } if(strlen(service) < 1) { - infof(data, "service can't be empty\n"); + infof(data, "service can't be empty"); ret = CURLE_BAD_FUNCTION_ARGUMENT; goto fail; } @@ -203,7 +203,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) tmp1 = strchr(tmp0, '.'); len = tmp1 - tmp0; if(!tmp1 || len < 1) { - infof(data, "service missing in parameters or hostname\n"); + infof(data, "service missing in parameters or hostname"); ret = CURLE_URL_MALFORMAT; goto fail; } @@ -218,7 +218,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) tmp1 = strchr(tmp0, '.'); len = tmp1 - tmp0; if(!tmp1 || len < 1) { - infof(data, "region missing in parameters or hostname\n"); + infof(data, "region missing in parameters or hostname"); ret = CURLE_URL_MALFORMAT; goto fail; } diff --git a/contrib/libs/curl/lib/http_digest.c b/contrib/libs/curl/lib/http_digest.c index 049b232e01..34bb5a8e08 100644 --- a/contrib/libs/curl/lib/http_digest.c +++ b/contrib/libs/curl/lib/http_digest.c @@ -146,7 +146,8 @@ CURLcode Curl_output_digest(struct Curl_easy *data, tmp = strchr((char *)uripath, '?'); if(tmp) { size_t urilen = tmp - (char *)uripath; - path = (unsigned char *) aprintf("%.*s", urilen, uripath); + /* typecast is fine here since the value is always less than 32 bits */ + path = (unsigned char *) aprintf("%.*s", (int)urilen, uripath); } } if(!tmp) diff --git a/contrib/libs/curl/lib/http_negotiate.c b/contrib/libs/curl/lib/http_negotiate.c index 68cce1bbb2..5f764dc136 100644 --- a/contrib/libs/curl/lib/http_negotiate.c +++ b/contrib/libs/curl/lib/http_negotiate.c @@ -89,7 +89,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, neg_ctx->havenegdata = len != 0; if(!len) { if(state == GSS_AUTHSUCC) { - infof(data, "Negotiate auth restarted\n"); + infof(data, "Negotiate auth restarted"); Curl_http_auth_cleanup_negotiate(conn); } else if(state != GSS_AUTHNONE) { @@ -142,11 +142,11 @@ CURLcode Curl_output_negotiate(struct Curl_easy *data, } if(neg_ctx->noauthpersist || - (*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) { + (*state != GSS_AUTHDONE && *state != GSS_AUTHSUCC)) { if(neg_ctx->noauthpersist && *state == GSS_AUTHSUCC) { infof(data, "Curl_output_negotiate, " - "no persistent authentication: cleanup existing context"); + "no persistent authentication: cleanup existing context"); Curl_http_auth_cleanup_negotiate(conn); } if(!neg_ctx->context) { diff --git a/contrib/libs/curl/lib/http_ntlm.c b/contrib/libs/curl/lib/http_ntlm.c index e200fdb1da..627a11c5af 100644 --- a/contrib/libs/curl/lib/http_ntlm.c +++ b/contrib/libs/curl/lib/http_ntlm.c @@ -100,17 +100,17 @@ CURLcode Curl_input_ntlm(struct Curl_easy *data, } else { if(*state == NTLMSTATE_LAST) { - infof(data, "NTLM auth restarted\n"); + infof(data, "NTLM auth restarted"); Curl_http_auth_cleanup_ntlm(conn); } else if(*state == NTLMSTATE_TYPE3) { - infof(data, "NTLM handshake rejected\n"); + infof(data, "NTLM handshake rejected"); Curl_http_auth_cleanup_ntlm(conn); *state = NTLMSTATE_NONE; return CURLE_REMOTE_ACCESS_DENIED; } else if(*state >= NTLMSTATE_TYPE1) { - infof(data, "NTLM handshake failure (internal error)\n"); + infof(data, "NTLM handshake failure (internal error)"); return CURLE_REMOTE_ACCESS_DENIED; } diff --git a/contrib/libs/curl/lib/http_proxy.c b/contrib/libs/curl/lib/http_proxy.c index 3ac878eaa4..61457094e4 100644 --- a/contrib/libs/curl/lib/http_proxy.c +++ b/contrib/libs/curl/lib/http_proxy.c @@ -61,7 +61,7 @@ static CURLcode https_proxy_connect(struct Curl_easy *data, int sockindex) if(!conn->bits.proxy_ssl_connected[sockindex]) { /* perform SSL initialization for this socket */ result = - Curl_ssl_connect_nonblocking(data, conn, sockindex, + Curl_ssl_connect_nonblocking(data, conn, TRUE, sockindex, &conn->bits.proxy_ssl_connected[sockindex]); if(result) /* a failed connection is marked for closure to prevent (bad) re-use or @@ -129,13 +129,13 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex) bool Curl_connect_complete(struct connectdata *conn) { return !conn->connect_state || - (conn->connect_state->tunnel_state == TUNNEL_COMPLETE); + (conn->connect_state->tunnel_state >= TUNNEL_COMPLETE); } bool Curl_connect_ongoing(struct connectdata *conn) { return conn->connect_state && - (conn->connect_state->tunnel_state != TUNNEL_COMPLETE); + (conn->connect_state->tunnel_state <= TUNNEL_COMPLETE); } /* when we've sent a CONNECT to a proxy, we should rather either wait for the @@ -169,7 +169,7 @@ static CURLcode connect_init(struct Curl_easy *data, bool reinit) s = calloc(1, sizeof(struct http_connect_state)); if(!s) return CURLE_OUT_OF_MEMORY; - infof(data, "allocate connect buffer!\n"); + infof(data, "allocate connect buffer!"); conn->connect_state = s; Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS); @@ -202,13 +202,16 @@ static void connect_done(struct Curl_easy *data) { struct connectdata *conn = data->conn; struct http_connect_state *s = conn->connect_state; - s->tunnel_state = TUNNEL_COMPLETE; - Curl_dyn_free(&s->rcvbuf); - Curl_dyn_free(&s->req); + if(s->tunnel_state != TUNNEL_EXIT) { + s->tunnel_state = TUNNEL_EXIT; + Curl_dyn_free(&s->rcvbuf); + Curl_dyn_free(&s->req); - /* retore the protocol pointer */ - data->req.p.http = s->prot_save; - infof(data, "CONNECT phase completed!\n"); + /* retore the protocol pointer */ + data->req.p.http = s->prot_save; + s->prot_save = NULL; + infof(data, "CONNECT phase completed!"); + } } static CURLcode CONNECT_host(struct Curl_easy *data, @@ -243,11 +246,11 @@ static CURLcode CONNECT_host(struct Curl_easy *data, return CURLE_OK; } +#ifndef USE_HYPER static CURLcode CONNECT(struct Curl_easy *data, int sockindex, const char *hostname, int remote_port) -#ifndef USE_HYPER { int subversion = 0; struct SingleRequest *k = &data->req; @@ -275,7 +278,7 @@ static CURLcode CONNECT(struct Curl_easy *data, char *hostheader = NULL; char *host = NULL; - infof(data, "Establish HTTP proxy tunnel to %s:%d\n", + infof(data, "Establish HTTP proxy tunnel to %s:%d", hostname, remote_port); /* This only happens if we've looped here due to authentication @@ -416,7 +419,7 @@ static CURLcode CONNECT(struct Curl_easy *data, /* proxy auth was requested and there was proxy auth available, then deem this as "mere" proxy disconnect */ conn->bits.proxy_connect_closed = TRUE; - infof(data, "Proxy CONNECT connection closed\n"); + infof(data, "Proxy CONNECT connection closed"); } else { error = SELECT_ERROR; @@ -451,7 +454,7 @@ static CURLcode CONNECT(struct Curl_easy *data, r = Curl_httpchunk_read(data, &byte, 1, &tookcareof, &extra); if(r == CHUNKE_STOP) { /* we're done reading chunks! */ - infof(data, "chunk reading DONE\n"); + infof(data, "chunk reading DONE"); s->keepon = KEEPON_DONE; /* we did the full CONNECT treatment, go COMPLETE */ s->tunnel_state = TUNNEL_COMPLETE; @@ -510,13 +513,13 @@ static CURLcode CONNECT(struct Curl_easy *data, if(s->cl) { infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T - " bytes of response-body\n", s->cl); + " bytes of response-body", s->cl); } else if(s->chunked_encoding) { CHUNKcode r; CURLcode extra; - infof(data, "Ignore chunked response-body\n"); + infof(data, "Ignore chunked response-body"); /* We set ignorebody true here since the chunked decoder function will acknowledge that. Pay attention so that this is @@ -533,7 +536,7 @@ static CURLcode CONNECT(struct Curl_easy *data, &extra); if(r == CHUNKE_STOP) { /* we're done reading chunks! */ - infof(data, "chunk reading DONE\n"); + infof(data, "chunk reading DONE"); s->keepon = KEEPON_DONE; /* we did the full CONNECT treatment, go to COMPLETE */ s->tunnel_state = TUNNEL_COMPLETE; @@ -579,7 +582,7 @@ static CURLcode CONNECT(struct Curl_easy *data, /* A client MUST ignore any Content-Length or Transfer-Encoding header fields received in a successful response to CONNECT. "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ - infof(data, "Ignoring Content-Length in CONNECT %03d response\n", + infof(data, "Ignoring Content-Length in CONNECT %03d response", k->httpcode); } else { @@ -595,11 +598,11 @@ static CURLcode CONNECT(struct Curl_easy *data, header fields received in a successful response to CONNECT. "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ infof(data, "Ignoring Transfer-Encoding in " - "CONNECT %03d response\n", k->httpcode); + "CONNECT %03d response", k->httpcode); } else if(Curl_compareheader(linep, "Transfer-Encoding:", "chunked")) { - infof(data, "CONNECT responded chunked\n"); + infof(data, "CONNECT responded chunked"); s->chunked_encoding = TRUE; /* init our chunky engine */ Curl_httpchunk_init(data); @@ -657,7 +660,7 @@ static CURLcode CONNECT(struct Curl_easy *data, if(data->info.httpproxycode/100 != 2) { if(s->close_connection && data->req.newurl) { conn->bits.proxy_connect_closed = TRUE; - infof(data, "Connect me again please\n"); + infof(data, "Connect me again please"); connect_done(data); } else { @@ -692,7 +695,7 @@ static CURLcode CONNECT(struct Curl_easy *data, data->state.authproxy.done = TRUE; data->state.authproxy.multipass = FALSE; - infof(data, "Proxy replied %d to CONNECT request\n", + infof(data, "Proxy replied %d to CONNECT request", data->info.httpproxycode); data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */ conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the @@ -702,6 +705,10 @@ static CURLcode CONNECT(struct Curl_easy *data, } #else /* The Hyper version of CONNECT */ +static CURLcode CONNECT(struct Curl_easy *data, + int sockindex, + const char *hostname, + int remote_port) { struct connectdata *conn = data->conn; struct hyptransfer *h = &data->hyp; @@ -740,6 +747,8 @@ static CURLcode CONNECT(struct Curl_easy *data, hyper_io_set_write(io, Curl_hyper_send); conn->sockfd = tunnelsocket; + data->state.hconnect = TRUE; + /* create an executor to poll futures */ if(!h->exec) { h->exec = hyper_executor_new(); @@ -875,7 +884,6 @@ static CURLcode CONNECT(struct Curl_easy *data, goto error; if(!done) break; - fprintf(stderr, "done\n"); s->tunnel_state = TUNNEL_COMPLETE; if(h->exec) { hyper_executor_free(h->exec); @@ -897,6 +905,33 @@ static CURLcode CONNECT(struct Curl_easy *data, } while(data->req.newurl); result = CURLE_OK; + if(s->tunnel_state == TUNNEL_COMPLETE) { + data->info.httpproxycode = data->req.httpcode; + if(data->info.httpproxycode/100 != 2) { + if(conn->bits.close && data->req.newurl) { + conn->bits.proxy_connect_closed = TRUE; + infof(data, "Connect me again please"); + connect_done(data); + } + else { + free(data->req.newurl); + data->req.newurl = NULL; + /* failure, close this connection to avoid re-use */ + streamclose(conn, "proxy CONNECT failure"); + Curl_closesocket(data, conn, conn->sock[sockindex]); + conn->sock[sockindex] = CURL_SOCKET_BAD; + } + + /* to back to init state */ + s->tunnel_state = TUNNEL_INIT; + + if(!conn->bits.proxy_connect_closed) { + failf(data, "Received HTTP code %d from proxy after CONNECT", + data->req.httpcode); + result = CURLE_RECV_ERROR; + } + } + } error: free(host); free(hostheader); @@ -917,7 +952,6 @@ static CURLcode CONNECT(struct Curl_easy *data, } return result; } - #endif void Curl_connect_free(struct Curl_easy *data) diff --git a/contrib/libs/curl/lib/http_proxy.h b/contrib/libs/curl/lib/http_proxy.h index f5a4cb07cf..cdf8de4fba 100644 --- a/contrib/libs/curl/lib/http_proxy.h +++ b/contrib/libs/curl/lib/http_proxy.h @@ -65,9 +65,10 @@ struct http_connect_state { } keepon; curl_off_t cl; /* size of content to read and ignore */ enum { - TUNNEL_INIT, /* init/default/no tunnel state */ - TUNNEL_CONNECT, /* CONNECT has been sent off */ - TUNNEL_COMPLETE /* CONNECT response received completely */ + TUNNEL_INIT, /* init/default/no tunnel state */ + TUNNEL_CONNECT, /* CONNECT has been sent off */ + TUNNEL_COMPLETE, /* CONNECT response received completely */ + TUNNEL_EXIT } tunnel_state; BIT(chunked_encoding); BIT(close_connection); diff --git a/contrib/libs/curl/lib/imap.c b/contrib/libs/curl/lib/imap.c index d85bcc391d..ab4d412ee3 100644 --- a/contrib/libs/curl/lib/imap.c +++ b/contrib/libs/curl/lib/imap.c @@ -414,7 +414,7 @@ static void state(struct Curl_easy *data, imapstate newstate) }; if(imapc->state != newstate) - infof(data, "IMAP %p state change from %s to %s\n", + infof(data, "IMAP %p state change from %s to %s", (void *)imapc, names[imapc->state], names[newstate]); #endif @@ -475,8 +475,8 @@ static CURLcode imap_perform_upgrade_tls(struct Curl_easy *data, { /* Start the SSL connection */ struct imap_conn *imapc = &conn->proto.imapc; - CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET, - &imapc->ssldone); + CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FALSE, + FIRSTSOCKET, &imapc->ssldone); if(!result) { if(imapc->state != IMAP_UPGRADETLS) @@ -606,7 +606,7 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data, result = imap_perform_login(data, conn); else { /* Other mechanisms not supported */ - infof(data, "No known authentication mechanisms supported!\n"); + infof(data, "No known authentication mechanisms supported!"); result = CURLE_LOGIN_DENIED; } } @@ -861,7 +861,7 @@ static CURLcode imap_state_servergreet_resp(struct Curl_easy *data, /* PREAUTH */ struct imap_conn *imapc = &conn->proto.imapc; imapc->preauth = TRUE; - infof(data, "PREAUTH connection, already authenticated!\n"); + infof(data, "PREAUTH connection, already authenticated!"); } else if(imapcode != IMAP_RESP_OK) { failf(data, "Got unexpected imap-server response"); @@ -1143,7 +1143,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data, } if(parsed) { - infof(data, "Found %" CURL_FORMAT_CURL_OFF_T " bytes to download\n", + infof(data, "Found %" CURL_FORMAT_CURL_OFF_T " bytes to download", size); Curl_pgrsSetDownloadSize(data, size); @@ -1169,7 +1169,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data, data->req.bytecount += chunk; infof(data, "Written %zu bytes, %" CURL_FORMAT_CURL_OFF_TU - " bytes are left for transfer\n", chunk, size - chunk); + " bytes are left for transfer", chunk, size - chunk); /* Have we used the entire cache or just part of it?*/ if(pp->cache_size > chunk) { @@ -1369,7 +1369,7 @@ static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done) struct imap_conn *imapc = &conn->proto.imapc; if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) { - result = Curl_ssl_connect_nonblocking(data, conn, + result = Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, &imapc->ssldone); if(result || !imapc->ssldone) return result; @@ -1543,7 +1543,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected, struct imap_conn *imapc = &conn->proto.imapc; bool selected = FALSE; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); if(data->set.opt_no_body) { /* Requested no body means no transfer */ @@ -1590,7 +1590,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected, *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); return result; } @@ -1682,11 +1682,11 @@ static CURLcode imap_doing(struct Curl_easy *data, bool *dophase_done) CURLcode result = imap_multi_statemach(data, dophase_done); if(result) - DEBUGF(infof(data, "DO phase failed\n")); + DEBUGF(infof(data, "DO phase failed")); else if(*dophase_done) { result = imap_dophase_done(data, FALSE /* not connected */); - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; @@ -2017,7 +2017,7 @@ static CURLcode imap_parse_url_path(struct Curl_easy *data) return result; } - DEBUGF(infof(data, "IMAP URL parameter '%s' = '%s'\n", name, value)); + DEBUGF(infof(data, "IMAP URL parameter '%s' = '%s'", name, value)); /* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION and PARTIAL) stripping of the trailing slash character if it is present. diff --git a/contrib/libs/curl/lib/inet_ntop.c b/contrib/libs/curl/lib/inet_ntop.c index 4c3e9e4dad..b5f9b808af 100644 --- a/contrib/libs/curl/lib/inet_ntop.c +++ b/contrib/libs/curl/lib/inet_ntop.c @@ -40,7 +40,7 @@ #define INT16SZ 2 /* - * Format an IPv4 address, more or less like inet_ntoa(). + * Format an IPv4 address, more or less like inet_ntop(). * * Returns `dst' (as a const) * Note: diff --git a/contrib/libs/curl/lib/krb5.c b/contrib/libs/curl/lib/krb5.c index b8ecb5e739..b888521990 100644 --- a/contrib/libs/curl/lib/krb5.c +++ b/contrib/libs/curl/lib/krb5.c @@ -263,7 +263,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn) } /* We pass NULL as |output_name_type| to avoid a leak. */ gss_display_name(&min, gssname, &output_buffer, NULL); - Curl_infof(data, "Trying against %s\n", output_buffer.value); + infof(data, "Trying against %s", output_buffer.value); gssresp = GSS_C_NO_BUFFER; *context = GSS_C_NO_CONTEXT; @@ -290,7 +290,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn) } if(GSS_ERROR(maj)) { - Curl_infof(data, "Error creating security context\n"); + infof(data, "Error creating security context"); ret = AUTH_ERROR; break; } @@ -301,8 +301,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn) result = Curl_base64_encode(data, (char *)output_buffer.value, output_buffer.length, &p, &base64_sz); if(result) { - Curl_infof(data, "base64-encoding: %s\n", - curl_easy_strerror(result)); + infof(data, "base64-encoding: %s", curl_easy_strerror(result)); ret = AUTH_ERROR; break; } @@ -327,7 +326,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn) } if(data->state.buffer[0] != '2' && data->state.buffer[0] != '3') { - Curl_infof(data, "Server didn't accept auth data\n"); + infof(data, "Server didn't accept auth data"); ret = AUTH_ERROR; break; } @@ -629,7 +628,7 @@ static void do_sec_send(struct Curl_easy *data, struct connectdata *conn, socket_write(data, fd, cmd_buffer, cmd_size); socket_write(data, fd, "\r\n", 2); - infof(data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic, + infof(data, "Send: %s%s", prot_level == PROT_PRIVATE?enc:mic, cmd_buffer); free(cmd_buffer); } @@ -738,7 +737,7 @@ static int sec_set_protection_level(struct Curl_easy *data) if(!conn->sec_complete) { infof(data, "Trying to change the protection level after the" - " completion of the data exchange.\n"); + " completion of the data exchange."); return -1; } @@ -815,13 +814,13 @@ static CURLcode choose_mech(struct Curl_easy *data, struct connectdata *conn) if(mech->init) { ret = mech->init(conn->app_data); if(ret) { - infof(data, "Failed initialization for %s. Skipping it.\n", + infof(data, "Failed initialization for %s. Skipping it.", mech->name); return CURLE_FAILED_INIT; } } - infof(data, "Trying mechanism %s...\n", mech->name); + infof(data, "Trying mechanism %s...", mech->name); ret = ftp_send_command(data, "AUTH %s", mech->name); if(ret < 0) return CURLE_COULDNT_CONNECT; @@ -830,15 +829,15 @@ static CURLcode choose_mech(struct Curl_easy *data, struct connectdata *conn) switch(ret) { case 504: infof(data, "Mechanism %s is not supported by the server (server " - "returned ftp code: 504).\n", mech->name); + "returned ftp code: 504).", mech->name); break; case 534: infof(data, "Mechanism %s was rejected by the server (server returned " - "ftp code: 534).\n", mech->name); + "ftp code: 534).", mech->name); break; default: if(ret/100 == 5) { - infof(data, "server does not support the security extensions\n"); + infof(data, "server does not support the security extensions"); return CURLE_USE_SSL_FAILED; } break; diff --git a/contrib/libs/curl/lib/ldap.c b/contrib/libs/curl/lib/ldap.c index 9f0e1e607f..1e2253bbf8 100644 --- a/contrib/libs/curl/lib/ldap.c +++ b/contrib/libs/curl/lib/ldap.c @@ -296,9 +296,9 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) char *passwd = NULL; *done = TRUE; /* unconditionally */ - infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n", + infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d", LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION); - infof(data, "LDAP local: %s\n", data->state.url); + infof(data, "LDAP local: %s", data->state.url); #ifdef HAVE_LDAP_URL_PARSE rc = ldap_url_parse(data->state.url, &ludp); @@ -314,7 +314,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) /* Get the URL scheme (either ldap or ldaps) */ if(conn->given->flags & PROTOPT_SSL) ldap_ssl = 1; - infof(data, "LDAP local: trying to establish %s connection\n", + infof(data, "LDAP local: trying to establish %s connection", ldap_ssl ? "encrypted" : "cleartext"); #if defined(USE_WIN32_LDAP) @@ -366,14 +366,14 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) result = CURLE_SSL_CERTPROBLEM; goto quit; } - infof(data, "LDAP local: using %s CA cert '%s'\n", - (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), - ldap_ca); + infof(data, "LDAP local: using %s CA cert '%s'", + (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), + ldap_ca); rc = ldapssl_add_trusted_cert(ldap_ca, cert_type); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ERROR setting %s CA cert: %s", - (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), - ldap_err2string(rc)); + (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), + ldap_err2string(rc)); result = CURLE_SSL_CERTPROBLEM; goto quit; } @@ -409,7 +409,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) result = CURLE_SSL_CERTPROBLEM; goto quit; } - infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca); + infof(data, "LDAP local: using PEM CA cert: %s", ldap_ca); rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ERROR setting PEM CA cert: %s", @@ -718,7 +718,7 @@ quit: LDAP_TRACE(("Received %d entries\n", num)); } if(rc == LDAP_SIZELIMIT_EXCEEDED) - infof(data, "There are more than %d entries\n", num); + infof(data, "There are more than %d entries", num); if(ludp) ldap_free_urldesc(ludp); if(server) diff --git a/contrib/libs/curl/lib/mprintf.c b/contrib/libs/curl/lib/mprintf.c index 5292026861..7a1aec570e 100644 --- a/contrib/libs/curl/lib/mprintf.c +++ b/contrib/libs/curl/lib/mprintf.c @@ -1017,9 +1017,11 @@ int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, retcode = dprintf_formatf(&info, addbyter, format, ap_save); if((retcode != -1) && info.max) { /* we terminate this with a zero byte */ - if(info.max == info.length) + if(info.max == info.length) { /* we're at maximum, scrap the last letter */ info.buffer[-1] = 0; + retcode--; /* don't count the nul byte */ + } else info.buffer[0] = 0; } diff --git a/contrib/libs/curl/lib/mqtt.c b/contrib/libs/curl/lib/mqtt.c index d88fa737df..f077e6c3dc 100644 --- a/contrib/libs/curl/lib/mqtt.c +++ b/contrib/libs/curl/lib/mqtt.c @@ -143,32 +143,197 @@ static int mqtt_getsock(struct Curl_easy *data, return GETSOCK_READSOCK(FIRSTSOCKET); } +static int mqtt_encode_len(char *buf, size_t len) +{ + unsigned char encoded; + int i; + + for(i = 0; (len > 0) && (i<4); i++) { + encoded = len % 0x80; + len /= 0x80; + if(len) + encoded |= 0x80; + buf[i] = encoded; + } + + return i; +} + +/* add the passwd to the CONNECT packet */ +static int add_passwd(const char *passwd, const size_t plen, + char *pkt, const size_t start, int remain_pos) +{ + /* magic number that need to be set properly */ + const size_t conn_flags_pos = remain_pos + 8; + if(plen > 0xffff) + return 1; + + /* set password flag */ + pkt[conn_flags_pos] |= 0x40; + + /* length of password provided */ + pkt[start] = (char)((plen >> 8) & 0xFF); + pkt[start + 1] = (char)(plen & 0xFF); + memcpy(&pkt[start + 2], passwd, plen); + return 0; +} + +/* add user to the CONN packet */ +static int add_user(const char *username, const size_t ulen, + unsigned char *pkt, const size_t start, int remain_pos) +{ + /* magic number that need to be set properly */ + const size_t conn_flags_pos = remain_pos + 8; + if(ulen > 0xffff) + return 1; + + /* set username flag */ + pkt[conn_flags_pos] |= 0x80; + /* length of username provided */ + pkt[start] = (unsigned char)((ulen >> 8) & 0xFF); + pkt[start + 1] = (unsigned char)(ulen & 0xFF); + memcpy(&pkt[start + 2], username, ulen); + return 0; +} + +/* add client ID to the CONN packet */ +static int add_client_id(const char *client_id, const size_t client_id_len, + char *pkt, const size_t start) +{ + if(client_id_len != MQTT_CLIENTID_LEN) + return 1; + pkt[start] = 0x00; + pkt[start + 1] = MQTT_CLIENTID_LEN; + memcpy(&pkt[start + 2], client_id, MQTT_CLIENTID_LEN); + return 0; +} + +/* Set initial values of CONN packet */ +static int init_connpack(char *packet, char *remain, int remain_pos) +{ + /* Fixed header starts */ + /* packet type */ + packet[0] = MQTT_MSG_CONNECT; + /* remaining length field */ + memcpy(&packet[1], remain, remain_pos); + /* Fixed header ends */ + + /* Variable header starts */ + /* protocol length */ + packet[remain_pos + 1] = 0x00; + packet[remain_pos + 2] = 0x04; + /* protocol name */ + packet[remain_pos + 3] = 'M'; + packet[remain_pos + 4] = 'Q'; + packet[remain_pos + 5] = 'T'; + packet[remain_pos + 6] = 'T'; + /* protocol level */ + packet[remain_pos + 7] = 0x04; + /* CONNECT flag: CleanSession */ + packet[remain_pos + 8] = 0x02; + /* keep-alive 0 = disabled */ + packet[remain_pos + 9] = 0x00; + packet[remain_pos + 10] = 0x3c; + /*end of variable header*/ + return remain_pos + 10; +} + static CURLcode mqtt_connect(struct Curl_easy *data) { CURLcode result = CURLE_OK; - const size_t client_id_offset = 14; - const size_t packetlen = client_id_offset + MQTT_CLIENTID_LEN; + int pos = 0; + int rc = 0; + /*remain length*/ + int remain_pos = 0; + char remain[4] = {0}; + size_t packetlen = 0; + size_t payloadlen = 0; + size_t start_user = 0; + size_t start_pwd = 0; char client_id[MQTT_CLIENTID_LEN + 1] = "curl"; const size_t clen = strlen("curl"); - char packet[32] = { - MQTT_MSG_CONNECT, /* packet type */ - 0x00, /* remaining length */ - 0x00, 0x04, /* protocol length */ - 'M','Q','T','T', /* protocol name */ - 0x04, /* protocol level */ - 0x02, /* CONNECT flag: CleanSession */ - 0x00, 0x3c, /* keep-alive 0 = disabled */ - 0x00, 0x00 /* payload1 length */ - }; - packet[1] = (packetlen - 2) & 0x7f; - packet[client_id_offset - 1] = MQTT_CLIENTID_LEN; + char *packet = NULL; + + /* extracting username from request */ + const char *username = data->state.aptr.user ? + data->state.aptr.user : ""; + const size_t ulen = strlen(username); + /* extracting password from request */ + const char *passwd = data->state.aptr.passwd ? + data->state.aptr.passwd : ""; + const size_t plen = strlen(passwd); + + payloadlen = ulen + plen + MQTT_CLIENTID_LEN + 2; + /* The plus 2 are for the MSB and LSB describing the length of the string to + * be added on the payload. Refer to spec 1.5.2 and 1.5.4 */ + if(ulen) + payloadlen += 2; + if(plen) + payloadlen += 2; + + /* getting how much occupy the remain length */ + remain_pos = mqtt_encode_len(remain, payloadlen + 10); + + /* 10 length of variable header and 1 the first byte of the fixed header */ + packetlen = payloadlen + 10 + remain_pos + 1; + + /* allocating packet */ + if(packetlen > 268435455) + return CURLE_WEIRD_SERVER_REPLY; + packet = malloc(packetlen); + if(!packet) + return CURLE_OUT_OF_MEMORY; + memset(packet, 0, packetlen); + + /* set initial values for CONN pack */ + pos = init_connpack(packet, remain, remain_pos); result = Curl_rand_hex(data, (unsigned char *)&client_id[clen], MQTT_CLIENTID_LEN - clen + 1); - memcpy(&packet[client_id_offset], client_id, MQTT_CLIENTID_LEN); - infof(data, "Using client id '%s'\n", client_id); + /* add client id */ + rc = add_client_id(client_id, strlen(client_id), packet, pos + 1); + if(rc) { + failf(data, "Client ID length mismatched: [%lu]", strlen(client_id)); + result = CURLE_WEIRD_SERVER_REPLY; + goto end; + } + infof(data, "Using client id '%s'", client_id); + + /* position where starts the user payload */ + start_user = pos + 3 + MQTT_CLIENTID_LEN; + /* position where starts the password payload */ + start_pwd = start_user + ulen; + /* if user name was provided, add it to the packet */ + if(ulen) { + start_pwd += 2; + + rc = add_user(username, ulen, + (unsigned char *)packet, start_user, remain_pos); + if(rc) { + failf(data, "Username is too large: [%lu]", ulen); + result = CURLE_WEIRD_SERVER_REPLY; + goto end; + } + } + + /* if passwd was provided, add it to the packet */ + if(plen) { + rc = add_passwd(passwd, plen, packet, start_pwd, remain_pos); + if(rc) { + failf(data, "Password is too large: [%lu]", plen); + result = CURLE_WEIRD_SERVER_REPLY; + goto end; + } + } + if(!result) result = mqtt_send(data, packet, packetlen); + +end: + if(packet) + free(packet); + Curl_safefree(data->state.aptr.user); + Curl_safefree(data->state.aptr.passwd); return result; } @@ -213,35 +378,12 @@ fail: static CURLcode mqtt_get_topic(struct Curl_easy *data, char **topic, size_t *topiclen) { - CURLcode result = CURLE_OK; char *path = data->state.up.path; - - if(strlen(path) > 1) { - result = Curl_urldecode(data, path + 1, 0, topic, topiclen, - REJECT_NADA); - } - else { - failf(data, "Error: No topic specified."); - result = CURLE_URL_MALFORMAT; - } - return result; -} - - -static int mqtt_encode_len(char *buf, size_t len) -{ - unsigned char encoded; - int i; - - for(i = 0; (len > 0) && (i<4); i++) { - encoded = len % 0x80; - len /= 0x80; - if(len) - encoded |= 0x80; - buf[i] = encoded; - } - - return i; + if(strlen(path) > 1) + return Curl_urldecode(data, path + 1, 0, topic, topiclen, + REJECT_NADA); + failf(data, "No MQTT topic found. Forgot to URL encode it?"); + return CURLE_URL_MALFORMAT; } static CURLcode mqtt_subscribe(struct Curl_easy *data) @@ -418,7 +560,7 @@ static void mqstate(struct Curl_easy *data, struct connectdata *conn = data->conn; struct mqtt_conn *mqtt = &conn->proto.mqtt; #ifdef CURLDEBUG - infof(data, "%s (from %s) (next is %s)\n", + infof(data, "%s (from %s) (next is %s)", statenames[state], statenames[mqtt->state], (state == MQTT_FIRST)? statenames[nextstate] : ""); @@ -465,7 +607,7 @@ static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done) goto MQTT_SUBACK_COMING; } else if(packet == MQTT_MSG_DISCONNECT) { - infof(data, "Got DISCONNECT\n"); + infof(data, "Got DISCONNECT"); *done = TRUE; goto end; } @@ -476,7 +618,13 @@ static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done) /* -- switched state -- */ remlen = mq->remaining_length; - infof(data, "Remaining length: %zd bytes\n", remlen); + infof(data, "Remaining length: %zd bytes", remlen); + if(data->set.max_filesize && + (curl_off_t)remlen > data->set.max_filesize) { + failf(data, "Maximum file size exceeded"); + result = CURLE_FILESIZE_EXCEEDED; + goto end; + } Curl_pgrsSetDownloadSize(data, remlen); data->req.bytecount = 0; data->req.size = remlen; @@ -491,12 +639,12 @@ static CURLcode mqtt_read_publish(struct Curl_easy *data, bool *done) result = Curl_read(data, sockfd, (char *)pkt, rest, &nread); if(result) { if(CURLE_AGAIN == result) { - infof(data, "EEEE AAAAGAIN\n"); + infof(data, "EEEE AAAAGAIN"); } goto end; } if(!nread) { - infof(data, "server disconnected\n"); + infof(data, "server disconnected"); result = CURLE_PARTIAL_FILE; goto end; } @@ -562,7 +710,7 @@ static CURLcode mqtt_doing(struct Curl_easy *data, bool *done) return result; } - infof(data, "mqtt_doing: state [%d]\n", (int) mqtt->state); + infof(data, "mqtt_doing: state [%d]", (int) mqtt->state); switch(mqtt->state) { case MQTT_FIRST: /* Read the initial byte only */ @@ -582,6 +730,10 @@ static CURLcode mqtt_doing(struct Curl_easy *data, bool *done) Curl_debug(data, CURLINFO_HEADER_IN, (char *)&byte, 1); pkt[mq->npacket++] = byte; } while((byte & 0x80) && (mq->npacket < 4)); + if(nread && (byte & 0x80)) + /* MQTT supports up to 127 * 128^0 + 127 * 128^1 + 127 * 128^2 + + 127 * 128^3 bytes. server tried to send more */ + result = CURLE_WEIRD_SERVER_REPLY; if(result) break; mq->remaining_length = mqtt_decode_len(&pkt[0], mq->npacket, NULL); @@ -593,7 +745,7 @@ static CURLcode mqtt_doing(struct Curl_easy *data, bool *done) mqstate(data, MQTT_FIRST, MQTT_FIRST); if(mq->firstbyte == MQTT_MSG_DISCONNECT) { - infof(data, "Got DISCONNECT\n"); + infof(data, "Got DISCONNECT"); *done = TRUE; } break; diff --git a/contrib/libs/curl/lib/multi.c b/contrib/libs/curl/lib/multi.c index b62b645aea..c31922d262 100644 --- a/contrib/libs/curl/lib/multi.c +++ b/contrib/libs/curl/lib/multi.c @@ -169,7 +169,7 @@ static void mstate(struct Curl_easy *data, CURLMstate state connection_id = data->conn->connection_id; infof(data, - "STATE: %s => %s handle %p; line %d (connection #%ld)\n", + "STATE: %s => %s handle %p; line %d (connection #%ld)", statename[oldstate], statename[data->mstate], (void *)data, lineno, connection_id); } @@ -562,7 +562,7 @@ static CURLcode multi_done(struct Curl_easy *data, struct connectdata *conn = data->conn; unsigned int i; - DEBUGF(infof(data, "multi_done\n")); + DEBUGF(infof(data, "multi_done")); if(data->state.done) /* Stop if multi_done() has already been called */ @@ -612,7 +612,7 @@ static CURLcode multi_done(struct Curl_easy *data, /* Stop if still used. */ CONNCACHE_UNLOCK(data); DEBUGF(infof(data, "Connection still in use %zu, " - "no more multi_done now!\n", + "no more multi_done now!", conn->easyq.size)); return CURLE_OK; } @@ -689,7 +689,7 @@ static CURLcode multi_done(struct Curl_easy *data, if(Curl_conncache_return_conn(data, conn)) { /* remember the most recently used connection */ data->state.lastconnect_id = conn->connection_id; - infof(data, "%s\n", buffer); + infof(data, "%s", buffer); } else data->state.lastconnect_id = -1; @@ -711,7 +711,6 @@ static int close_connect_only(struct Curl_easy *data, return 1; connclose(conn, "Removing connect-only easy handle"); - conn->bits.connect_only = FALSE; return 1; } @@ -1045,7 +1044,12 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi, data = multi->easyp; while(data) { - int bitmap = multi_getsock(data, sockbunch); + int bitmap; +#ifdef __clang_analyzer_ + /* to prevent "The left operand of '>=' is a garbage value" warnings */ + memset(sockbunch, 0, sizeof(sockbunch)); +#endif + bitmap = multi_getsock(data, sockbunch); for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) { curl_socket_t s = CURL_SOCKET_BAD; @@ -1178,7 +1182,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, #ifdef USE_WINSOCK long mask = 0; #endif - if(bitmap & GETSOCK_READSOCK(i)) { + if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) { s = sockbunch[i]; #ifdef USE_WINSOCK mask |= FD_READ|FD_ACCEPT|FD_CLOSE; @@ -1187,7 +1191,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, ufds[nfds].events = POLLIN; ++nfds; } - if(bitmap & GETSOCK_WRITESOCK(i)) { + if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) { s = sockbunch[i]; #ifdef USE_WINSOCK mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; @@ -1542,6 +1546,58 @@ static CURLcode multi_do_more(struct Curl_easy *data, int *complete) } /* + * Check whether a timeout occurred, and handle it if it did + */ +static bool multi_handle_timeout(struct Curl_easy *data, + struct curltime *now, + bool *stream_error, + CURLcode *result, + bool connect_timeout) +{ + timediff_t timeout_ms; + timeout_ms = Curl_timeleft(data, now, connect_timeout); + + if(timeout_ms < 0) { + /* Handle timed out */ + if(data->mstate == MSTATE_RESOLVING) + failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds", + Curl_timediff(*now, data->progress.t_startsingle)); + else if(data->mstate == MSTATE_CONNECTING) + failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds", + Curl_timediff(*now, data->progress.t_startsingle)); + else { + struct SingleRequest *k = &data->req; + if(k->size != -1) { + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" + CURL_FORMAT_CURL_OFF_T " bytes received", + Curl_timediff(*now, data->progress.t_startsingle), + k->bytecount, k->size); + } + else { + failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T + " milliseconds with %" CURL_FORMAT_CURL_OFF_T + " bytes received", + Curl_timediff(*now, data->progress.t_startsingle), + k->bytecount); + } + } + + /* Force connection closed if the connection has indeed been used */ + if(data->mstate > MSTATE_DO) { + streamclose(data->conn, "Disconnected with pending data"); + *stream_error = TRUE; + } + *result = CURLE_OPERATION_TIMEDOUT; + (void)multi_done(data, *result, TRUE); + } + + return (timeout_ms < 0); +} + +/* * We are doing protocol-specific connecting and this is being called over and * over from the multi interface until the connection phase is done on * protocol layer. @@ -1672,7 +1728,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, bool done = FALSE; CURLMcode rc; CURLcode result = CURLE_OK; - timediff_t timeout_ms; timediff_t recv_timeout_ms; timediff_t send_timeout_ms; int control; @@ -1687,7 +1742,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, rc = CURLM_OK; if(multi_ischanged(multi, TRUE)) { - DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n")); + DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!")); process_pending_handles(multi); /* multiplexed */ } @@ -1702,47 +1757,16 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, if(data->conn && (data->mstate >= MSTATE_CONNECT) && (data->mstate < MSTATE_COMPLETED)) { + /* Check for overall operation timeout here but defer handling the + * connection timeout to later, to allow for a connection to be set up + * in the window since we last checked timeout. This prevents us + * tearing down a completed connection in the case where we were slow + * to check the timeout (e.g. process descheduled during this loop). + * We set connect_timeout=FALSE to do this. */ + /* we need to wait for the connect state as only then is the start time stored, but we must not check already completed handles */ - timeout_ms = Curl_timeleft(data, nowp, - (data->mstate <= MSTATE_DO)? - TRUE:FALSE); - - if(timeout_ms < 0) { - /* Handle timed out */ - if(data->mstate == MSTATE_RESOLVING) - failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds", - Curl_timediff(*nowp, data->progress.t_startsingle)); - else if(data->mstate == MSTATE_CONNECTING) - failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds", - Curl_timediff(*nowp, data->progress.t_startsingle)); - else { - struct SingleRequest *k = &data->req; - if(k->size != -1) { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" - CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_timediff(*nowp, data->progress.t_startsingle), - k->bytecount, k->size); - } - else { - failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T - " milliseconds with %" CURL_FORMAT_CURL_OFF_T - " bytes received", - Curl_timediff(*nowp, data->progress.t_startsingle), - k->bytecount); - } - } - - /* Force connection closed if the connection has indeed been used */ - if(data->mstate > MSTATE_DO) { - streamclose(data->conn, "Disconnected with pending data"); - stream_error = TRUE; - } - result = CURLE_OPERATION_TIMEDOUT; - (void)multi_done(data, result, TRUE); + if(multi_handle_timeout(data, nowp, &stream_error, &result, FALSE)) { /* Skip the statemachine and go directly to error handling section. */ goto statemachine_end; } @@ -1794,7 +1818,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } else if(data->state.previouslypending) { /* this transfer comes from the pending queue so try move another */ - infof(data, "Transfer was pending, now try another\n"); + infof(data, "Transfer was pending, now try another"); process_pending_handles(data->multi); } @@ -1849,7 +1873,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->state.async.done = TRUE; #endif result = CURLE_OK; - infof(data, "Hostname '%s' was found in DNS cache\n", hostname); + infof(data, "Hostname '%s' was found in DNS cache", hostname); } if(!dns) @@ -2281,7 +2305,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, CURLcode ret = Curl_retry_request(data, &newurl); if(!ret) { - infof(data, "Downgrades to HTTP/1.1!\n"); + infof(data, "Downgrades to HTTP/1.1!"); streamclose(data->conn, "Disconnect HTTP/2 for HTTP/1"); data->state.httpwant = CURL_HTTP_VERSION_1_1; /* clear the error message bit too as we ignore the one we got */ @@ -2420,6 +2444,21 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, default: return CURLM_INTERNAL_ERROR; } + + if(data->conn && + data->mstate >= MSTATE_CONNECT && + data->mstate < MSTATE_DO && + rc != CURLM_CALL_MULTI_PERFORM && + !multi_ischanged(multi, false)) { + /* We now handle stream timeouts if and only if this will be the last + * loop iteration. We only check this on the last iteration to ensure + * that if we know we have additional work to do immediately + * (i.e. CURLM_CALL_MULTI_PERFORM == TRUE) then we should do that before + * declaring the connection timed out as we may almost have a completed + * connection. */ + multi_handle_timeout(data, nowp, &stream_error, &result, TRUE); + } + statemachine_end: if(data->mstate < MSTATE_COMPLETED) { @@ -3341,7 +3380,7 @@ void Curl_expire(struct Curl_easy *data, timediff_t milli, expire_id id) rc = Curl_splayremove(multi->timetree, &data->state.timenode, &multi->timetree); if(rc) - infof(data, "Internal error removing splay node = %d\n", rc); + infof(data, "Internal error removing splay node = %d", rc); } /* Indicate that we are in the splay tree and insert the new timer expiry @@ -3388,7 +3427,7 @@ void Curl_expire_clear(struct Curl_easy *data) rc = Curl_splayremove(multi->timetree, &data->state.timenode, &multi->timetree); if(rc) - infof(data, "Internal error clearing splay node = %d\n", rc); + infof(data, "Internal error clearing splay node = %d", rc); /* flush the timeout list too */ while(list->size > 0) { @@ -3396,7 +3435,7 @@ void Curl_expire_clear(struct Curl_easy *data) } #ifdef DEBUGBUILD - infof(data, "Expire cleared (transfer %p)\n", data); + infof(data, "Expire cleared (transfer %p)", data); #endif nowp->tv_sec = 0; nowp->tv_usec = 0; diff --git a/contrib/libs/curl/lib/multihandle.h b/contrib/libs/curl/lib/multihandle.h index 96b84749fc..2e4a6ffba5 100644 --- a/contrib/libs/curl/lib/multihandle.h +++ b/contrib/libs/curl/lib/multihandle.h @@ -153,6 +153,9 @@ struct Curl_multi { bool recheckstate; /* see Curl_multi_connchanged */ bool in_callback; /* true while executing a callback */ bool ipv6_works; +#ifdef USE_OPENSSL + bool ssl_seeded; +#endif }; #endif /* HEADER_CURL_MULTIHANDLE_H */ diff --git a/contrib/libs/curl/lib/netrc.c b/contrib/libs/curl/lib/netrc.c index 13610bb070..0a4ae2cdca 100644 --- a/contrib/libs/curl/lib/netrc.c +++ b/contrib/libs/curl/lib/netrc.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -42,7 +42,8 @@ enum host_lookup_state { NOTHING, HOSTFOUND, /* the 'machine' keyword was found */ - HOSTVALID /* this is "our" machine! */ + HOSTVALID, /* this is "our" machine! */ + MACDEF }; #define NETRC_FILE_MISSING 1 @@ -84,12 +85,17 @@ static int parsenetrc(const char *host, int netrcbuffsize = (int)sizeof(netrcbuffer); while(!done && fgets(netrcbuffer, netrcbuffsize, file)) { + if(state == MACDEF) { + if((netrcbuffer[0] == '\n') || (netrcbuffer[0] == '\r')) + state = NOTHING; + else + continue; + } tok = strtok_r(netrcbuffer, " \t\n", &tok_buf); if(tok && *tok == '#') /* treat an initial hash as a comment line */ continue; while(tok) { - if((login && *login) && (password && *password)) { done = TRUE; break; @@ -97,7 +103,13 @@ static int parsenetrc(const char *host, switch(state) { case NOTHING: - if(strcasecompare("machine", tok)) { + if(strcasecompare("macdef", tok)) { + /* Define a macro. A macro is defined with the specified name; its + contents begin with the next .netrc line and continue until a + null line (consecutive new-line characters) is encountered. */ + state = MACDEF; + } + else if(strcasecompare("machine", tok)) { /* the next tok is the machine name, this is in itself the delimiter that starts the stuff entered for this machine, after this we need to search for 'login' and @@ -109,6 +121,11 @@ static int parsenetrc(const char *host, retcode = NETRC_SUCCESS; /* we did find our host */ } break; + case MACDEF: + if(!strlen(tok)) { + state = NOTHING; + } + break; case HOSTFOUND: if(strcasecompare(host, tok)) { /* and yes, this is our host! */ diff --git a/contrib/libs/curl/lib/openldap.c b/contrib/libs/curl/lib/openldap.c index 4269cd386a..06c5aa0202 100644 --- a/contrib/libs/curl/lib/openldap.c +++ b/contrib/libs/curl/lib/openldap.c @@ -247,7 +247,7 @@ static CURLcode oldap_connect(struct Curl_easy *data, bool *done) #ifdef USE_SSL if(conn->handler->flags & PROTOPT_SSL) { CURLcode result; - result = Curl_ssl_connect_nonblocking(data, conn, + result = Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, &li->ssldone); if(result) return result; @@ -270,7 +270,8 @@ static CURLcode oldap_connecting(struct Curl_easy *data, bool *done) if(conn->handler->flags & PROTOPT_SSL) { /* Is the SSL handshake complete yet? */ if(!li->ssldone) { - CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET, + CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FALSE, + FIRSTSOCKET, &li->ssldone); if(result || !li->ssldone) return result; @@ -399,7 +400,7 @@ static CURLcode oldap_do(struct Curl_easy *data, bool *done) connkeep(conn, "OpenLDAP do"); - infof(data, "LDAP local: %s\n", data->state.url); + infof(data, "LDAP local: %s", data->state.url); rc = ldap_url_parse(data->state.url, &ludp); if(rc != LDAP_URL_SUCCESS) { @@ -509,7 +510,7 @@ static ssize_t oldap_recv(struct Curl_easy *data, int sockindex, char *buf, else { /* successful */ if(code == LDAP_SIZELIMIT_EXCEEDED) - infof(data, "There are more than %d entries\n", lr->nument); + infof(data, "There are more than %d entries", lr->nument); data->req.size = data->req.bytecount; *err = CURLE_OK; ret = 0; diff --git a/contrib/libs/curl/lib/pingpong.c b/contrib/libs/curl/lib/pingpong.c index 481173995f..84c7f51de5 100644 --- a/contrib/libs/curl/lib/pingpong.c +++ b/contrib/libs/curl/lib/pingpong.c @@ -402,7 +402,7 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, clipamount = gotbytes - i; restart = TRUE; DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing " - "server response left\n", + "server response left", (int)clipamount)); } else if(keepon) { @@ -412,7 +412,7 @@ CURLcode Curl_pp_readresp(struct Curl_easy *data, with it. We keep the first bytes of the line then we throw away the rest. */ infof(data, "Excessive server response line length received, " - "%zd bytes. Stripping\n", gotbytes); + "%zd bytes. Stripping", gotbytes); restart = TRUE; /* we keep 40 bytes since all our pingpong protocols are only diff --git a/contrib/libs/curl/lib/pop3.c b/contrib/libs/curl/lib/pop3.c index 9b6ea64804..5fdd6f3e05 100644 --- a/contrib/libs/curl/lib/pop3.c +++ b/contrib/libs/curl/lib/pop3.c @@ -308,7 +308,7 @@ static void state(struct Curl_easy *data, pop3state newstate) }; if(pop3c->state != newstate) - infof(data, "POP3 %p state change from %s to %s\n", + infof(data, "POP3 %p state change from %s to %s", (void *)pop3c, names[pop3c->state], names[newstate]); #endif @@ -370,8 +370,9 @@ static CURLcode pop3_perform_upgrade_tls(struct Curl_easy *data, { /* Start the SSL connection */ struct pop3_conn *pop3c = &conn->proto.pop3c; - CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET, - &pop3c->ssldone); + CURLcode result = + Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, + &pop3c->ssldone); if(!result) { if(pop3c->state != POP3_UPGRADETLS) @@ -551,7 +552,7 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data, result = pop3_perform_user(data, conn); else { /* Other mechanisms not supported */ - infof(data, "No known authentication mechanisms supported!\n"); + infof(data, "No known authentication mechanisms supported!"); result = CURLE_LOGIN_DENIED; } } @@ -1031,7 +1032,7 @@ static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done) struct pop3_conn *pop3c = &conn->proto.pop3c; if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) { - result = Curl_ssl_connect_nonblocking(data, conn, + result = Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, &pop3c->ssldone); if(result || !pop3c->ssldone) return result; @@ -1172,7 +1173,7 @@ static CURLcode pop3_perform(struct Curl_easy *data, bool *connected, struct connectdata *conn = data->conn; struct POP3 *pop3 = data->req.p.pop3; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); if(data->set.opt_no_body) { /* Requested no body means no transfer */ @@ -1191,7 +1192,7 @@ static CURLcode pop3_perform(struct Curl_easy *data, bool *connected, *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); return result; } @@ -1274,11 +1275,11 @@ static CURLcode pop3_doing(struct Curl_easy *data, bool *dophase_done) CURLcode result = pop3_multi_statemach(data, dophase_done); if(result) - DEBUGF(infof(data, "DO phase failed\n")); + DEBUGF(infof(data, "DO phase failed")); else if(*dophase_done) { result = pop3_dophase_done(data, FALSE /* not connected */); - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; diff --git a/contrib/libs/curl/lib/quic.h b/contrib/libs/curl/lib/quic.h index 35b500a886..edd65807cc 100644 --- a/contrib/libs/curl/lib/quic.h +++ b/contrib/libs/curl/lib/quic.h @@ -45,7 +45,7 @@ CURLcode Curl_quic_is_connected(struct Curl_easy *data, struct connectdata *conn, int sockindex, bool *connected); -int Curl_quic_ver(char *p, size_t len); +void Curl_quic_ver(char *p, size_t len); CURLcode Curl_quic_done_sending(struct Curl_easy *data); void Curl_quic_done(struct Curl_easy *data, bool premature); bool Curl_quic_data_pending(const struct Curl_easy *data); diff --git a/contrib/libs/curl/lib/rand.c b/contrib/libs/curl/lib/rand.c index 951fedb0a9..8f2c1ba29e 100644 --- a/contrib/libs/curl/lib/rand.c +++ b/contrib/libs/curl/lib/rand.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -87,7 +87,7 @@ static CURLcode randit(struct Curl_easy *data, unsigned int *rnd) if(!seeded) { struct curltime now = Curl_now(); - infof(data, "WARNING: Using weak random seed\n"); + infof(data, "WARNING: Using weak random seed"); randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec; randseed = randseed * 1103515245 + 12345; randseed = randseed * 1103515245 + 12345; diff --git a/contrib/libs/curl/lib/rtsp.c b/contrib/libs/curl/lib/rtsp.c index 007d5c50b6..30fefb9b82 100644 --- a/contrib/libs/curl/lib/rtsp.c +++ b/contrib/libs/curl/lib/rtsp.c @@ -231,7 +231,7 @@ static CURLcode rtsp_done(struct Curl_easy *data, } if(data->set.rtspreq == RTSPREQ_RECEIVE && (data->conn->proto.rtspc.rtp_channel == -1)) { - infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv); + infof(data, "Got an RTP Receive with a CSeq of %ld", CSeq_recv); } } @@ -651,7 +651,7 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data, } /* We have the full RTP interleaved packet * Write out the header including the leading '$' */ - DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n", + DEBUGF(infof(data, "RTP write channel %d rtp_length %d", rtspc->rtp_channel, rtp_length)); result = rtp_client_write(data, &rtp[0], rtp_length + 4); if(result) { @@ -682,7 +682,7 @@ static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data, } if(rtp_dataleft && rtp[0] == '$') { - DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft, + DEBUGF(infof(data, "RTP Rewinding %zd %s", rtp_dataleft, *readmore ? "(READMORE)" : "")); /* Store the incomplete RTP packet for a "rewind" */ diff --git a/contrib/libs/curl/lib/rtsp.h b/contrib/libs/curl/lib/rtsp.h index 1e9cb7d2c9..da11ade043 100644 --- a/contrib/libs/curl/lib/rtsp.h +++ b/contrib/libs/curl/lib/rtsp.h @@ -22,7 +22,7 @@ * ***************************************************************************/ #ifdef USE_HYPER -#define CURL_DISABLE_RTSP +#define CURL_DISABLE_RTSP 1 #endif #ifndef CURL_DISABLE_RTSP diff --git a/contrib/libs/curl/lib/select.h b/contrib/libs/curl/lib/select.h index 4db64877bb..19da1e774b 100644 --- a/contrib/libs/curl/lib/select.h +++ b/contrib/libs/curl/lib/select.h @@ -106,7 +106,11 @@ int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, } \ } while(0) #else +#ifdef HAVE_POLL_FINE +#define VALID_SOCK(s) ((s) >= 0) /* FD_SETSIZE is irrelevant for poll */ +#else #define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE)) +#endif #define VERIFY_SOCK(x) do { \ if(!VALID_SOCK(x)) { \ SET_SOCKERRNO(EINVAL); \ diff --git a/contrib/libs/curl/lib/sendf.c b/contrib/libs/curl/lib/sendf.c index e41bb805f5..14ca84bfe5 100644 --- a/contrib/libs/curl/lib/sendf.c +++ b/contrib/libs/curl/lib/sendf.c @@ -236,29 +236,21 @@ bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex) #endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ /* Curl_infof() is for info message along the way */ +#define MAXINFO 2048 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; - char print_buffer[2048 + 1]; + char buffer[MAXINFO + 2]; va_start(ap, fmt); - len = mvsnprintf(print_buffer, sizeof(print_buffer), fmt, ap); - /* - * Indicate truncation of the input by replacing the last 3 characters - * with "...", and transfer the newline over in case the format had one. - */ - if(len >= sizeof(print_buffer)) { - len = strlen(fmt); - if(fmt[--len] == '\n') - msnprintf(print_buffer + (sizeof(print_buffer) - 5), 5, "...\n"); - else - msnprintf(print_buffer + (sizeof(print_buffer) - 4), 4, "..."); - } + len = mvsnprintf(buffer, MAXINFO, fmt, ap); va_end(ap); - len = strlen(print_buffer); - Curl_debug(data, CURLINFO_TEXT, print_buffer, len); + buffer[len++] = '\n'; + buffer[len] = '\0'; + Curl_debug(data, CURLINFO_TEXT, buffer, len); } } @@ -274,14 +266,14 @@ void Curl_failf(struct Curl_easy *data, const char *fmt, ...) size_t len; char error[CURL_ERROR_SIZE + 2]; va_start(ap, fmt); - (void)mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap); - len = strlen(error); + len = mvsnprintf(error, CURL_ERROR_SIZE, fmt, ap); if(data->set.errorbuffer && !data->state.errorbuf) { strcpy(data->set.errorbuffer, error); data->state.errorbuf = TRUE; /* wrote error string */ } error[len++] = '\n'; + error[len] = '\0'; Curl_debug(data, CURLINFO_TEXT, error, len); va_end(ap); } diff --git a/contrib/libs/curl/lib/setopt.c b/contrib/libs/curl/lib/setopt.c index fb8b86d474..076fe5f59c 100644 --- a/contrib/libs/curl/lib/setopt.c +++ b/contrib/libs/curl/lib/setopt.c @@ -1689,7 +1689,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_SSLCERT_BLOB: /* - * Blob that holds file name of the SSL certificate to use + * Blob that holds file content of the SSL certificate to use */ result = Curl_setblobopt(&data->set.blobs[BLOB_CERT], va_arg(param, struct curl_blob *)); @@ -1704,7 +1704,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_PROXY_SSLCERT_BLOB: /* - * Blob that holds file name of the SSL certificate to use for proxy + * Blob that holds file content of the SSL certificate to use for proxy */ result = Curl_setblobopt(&data->set.blobs[BLOB_CERT_PROXY], va_arg(param, struct curl_blob *)); @@ -1735,7 +1735,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_SSLKEY_BLOB: /* - * Blob that holds file name of the SSL key to use + * Blob that holds file content of the SSL key to use */ result = Curl_setblobopt(&data->set.blobs[BLOB_KEY], va_arg(param, struct curl_blob *)); @@ -1750,7 +1750,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_PROXY_SSLKEY_BLOB: /* - * Blob that holds file name of the SSL key to use for proxy + * Blob that holds file content of the SSL key to use for proxy */ result = Curl_setblobopt(&data->set.blobs[BLOB_KEY_PROXY], va_arg(param, struct curl_blob *)); @@ -1872,7 +1872,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_DOH_SSL_VERIFYPEER: /* - * Enable peer SSL verifying for DOH. + * Enable peer SSL verifying for DoH. */ data->set.doh_verifypeer = (0 != va_arg(param, long)) ? TRUE : FALSE; @@ -1911,7 +1911,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_DOH_SSL_VERIFYHOST: /* - * Enable verification of the host name in the peer certificate for DOH + * Enable verification of the host name in the peer certificate for DoH */ arg = va_arg(param, long); @@ -1955,7 +1955,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_DOH_SSL_VERIFYSTATUS: /* - * Enable certificate status verifying for DOH. + * Enable certificate status verifying for DoH. */ if(!Curl_ssl_cert_status_request()) { result = CURLE_NOT_BUILT_IN; @@ -2370,8 +2370,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) break; case CURLOPT_IGNORE_CONTENT_LENGTH: +#ifndef USE_HYPER data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE; break; +#else + return CURLE_NOT_BUILT_IN; +#endif case CURLOPT_CONNECT_ONLY: /* diff --git a/contrib/libs/curl/lib/smb.c b/contrib/libs/curl/lib/smb.c index 39facb267d..fd49cf6aaf 100644 --- a/contrib/libs/curl/lib/smb.c +++ b/contrib/libs/curl/lib/smb.c @@ -204,7 +204,7 @@ static void conn_state(struct Curl_easy *data, enum smb_conn_state newstate) }; if(smbc->state != newstate) - infof(data, "SMB conn %p state change from %s to %s\n", + infof(data, "SMB conn %p state change from %s to %s", (void *)smbc, names[smbc->state], names[newstate]); #endif @@ -230,7 +230,7 @@ static void request_state(struct Curl_easy *data, }; if(req->state != newstate) - infof(data, "SMB request %p state change from %s to %s\n", + infof(data, "SMB request %p state change from %s to %s", (void *)req, names[req->state], names[newstate]); #endif @@ -670,7 +670,7 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done) #ifdef USE_SSL if((conn->handler->flags & PROTOPT_SSL)) { bool ssl_done = FALSE; - result = Curl_ssl_connect_nonblocking(data, conn, + result = Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, &ssl_done); if(result && result != CURLE_AGAIN) return result; diff --git a/contrib/libs/curl/lib/smtp.c b/contrib/libs/curl/lib/smtp.c index feffc05bc9..1a3da15599 100644 --- a/contrib/libs/curl/lib/smtp.c +++ b/contrib/libs/curl/lib/smtp.c @@ -308,7 +308,7 @@ static void state(struct Curl_easy *data, smtpstate newstate) }; if(smtpc->state != newstate) - infof(data, "SMTP %p state change from %s to %s\n", + infof(data, "SMTP %p state change from %s to %s", (void *)smtpc, names[smtpc->state], names[newstate]); #endif @@ -397,7 +397,8 @@ static CURLcode smtp_perform_upgrade_tls(struct Curl_easy *data) /* Start the SSL connection */ struct connectdata *conn = data->conn; struct smtp_conn *smtpc = &conn->proto.smtpc; - CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FIRSTSOCKET, + CURLcode result = Curl_ssl_connect_nonblocking(data, conn, FALSE, + FIRSTSOCKET, &smtpc->ssldone); if(!result) { @@ -484,7 +485,7 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data) state(data, SMTP_AUTH); else { /* Other mechanisms not supported */ - infof(data, "No known authentication mechanisms supported!\n"); + infof(data, "No known authentication mechanisms supported!"); result = CURLE_LOGIN_DENIED; } } @@ -1258,7 +1259,7 @@ static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done) struct smtp_conn *smtpc = &conn->proto.smtpc; if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) { - result = Curl_ssl_connect_nonblocking(data, conn, + result = Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, &smtpc->ssldone); if(result || !smtpc->ssldone) return result; @@ -1455,7 +1456,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected, struct connectdata *conn = data->conn; struct SMTP *smtp = data->req.p.smtp; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); if(data->set.opt_no_body) { /* Requested no body means no transfer */ @@ -1495,7 +1496,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected, *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); return result; } @@ -1579,11 +1580,11 @@ static CURLcode smtp_doing(struct Curl_easy *data, bool *dophase_done) CURLcode result = smtp_multi_statemach(data, dophase_done); if(result) - DEBUGF(infof(data, "DO phase failed\n")); + DEBUGF(infof(data, "DO phase failed")); else if(*dophase_done) { result = smtp_dophase_done(data, FALSE /* not connected */); - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; diff --git a/contrib/libs/curl/lib/socketpair.c b/contrib/libs/curl/lib/socketpair.c index 2c580ad2de..409d2ad667 100644 --- a/contrib/libs/curl/lib/socketpair.c +++ b/contrib/libs/curl/lib/socketpair.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2019 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2019 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -48,6 +48,10 @@ #endif /* !INADDR_LOOPBACK */ #endif /* !WIN32 */ +#include "nonblock.h" /* for curlx_nonblock */ +#include "timeval.h" /* needed before select.h */ +#include "select.h" /* for Curl_poll */ + /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -59,12 +63,11 @@ int Curl_socketpair(int domain, int type, int protocol, union { struct sockaddr_in inaddr; struct sockaddr addr; - } a; + } a, a2; curl_socket_t listener; curl_socklen_t addrlen = sizeof(a.inaddr); int reuse = 1; - char data[2][12]; - ssize_t dlen; + struct pollfd pfd[1]; (void)domain; (void)type; (void)protocol; @@ -85,7 +88,8 @@ int Curl_socketpair(int domain, int type, int protocol, goto error; if(bind(listener, &a.addr, sizeof(a.inaddr)) == -1) goto error; - if(getsockname(listener, &a.addr, &addrlen) == -1) + if(getsockname(listener, &a.addr, &addrlen) == -1 || + addrlen < (int)sizeof(a.inaddr)) goto error; if(listen(listener, 1) == -1) goto error; @@ -94,18 +98,30 @@ int Curl_socketpair(int domain, int type, int protocol, goto error; if(connect(socks[0], &a.addr, sizeof(a.inaddr)) == -1) goto error; + + /* use non-blocking accept to make sure we don't block forever */ + if(curlx_nonblock(listener, TRUE) < 0) + goto error; + pfd[0].fd = listener; + pfd[0].events = POLLIN; + pfd[0].revents = 0; + (void)Curl_poll(pfd, 1, 10*1000); /* 10 seconds */ socks[1] = accept(listener, NULL, NULL); if(socks[1] == CURL_SOCKET_BAD) goto error; /* verify that nothing else connected */ - msnprintf(data[0], sizeof(data[0]), "%p", socks); - dlen = strlen(data[0]); - if(swrite(socks[0], data[0], dlen) != dlen) + addrlen = sizeof(a.inaddr); + if(getsockname(socks[0], &a.addr, &addrlen) == -1 || + addrlen < (int)sizeof(a.inaddr)) goto error; - if(sread(socks[1], data[1], sizeof(data[1])) != dlen) + addrlen = sizeof(a2.inaddr); + if(getpeername(socks[1], &a2.addr, &addrlen) == -1 || + addrlen < (int)sizeof(a2.inaddr)) goto error; - if(memcmp(data[0], data[1], dlen)) + if(a.inaddr.sin_family != a2.inaddr.sin_family || + a.inaddr.sin_addr.s_addr != a2.inaddr.sin_addr.s_addr || + a.inaddr.sin_port != a2.inaddr.sin_port) goto error; sclose(listener); diff --git a/contrib/libs/curl/lib/socks.c b/contrib/libs/curl/lib/socks.c index 5cde4a46a1..91c4223a5f 100644 --- a/contrib/libs/curl/lib/socks.c +++ b/contrib/libs/curl/lib/socks.c @@ -148,7 +148,7 @@ static void socksstate(struct Curl_easy *data, #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) infof(data, - "SXSTATE: %s => %s conn %p; line %d\n", + "SXSTATE: %s => %s conn %p; line %d", statename[oldstate], statename[conn->cnnct.state], conn, lineno); #endif @@ -214,10 +214,10 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user, /* SOCKS4 can only do IPv4, insist! */ conn->ip_version = CURL_IPRESOLVE_V4; if(conn->bits.httpproxy) - infof(data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n", + infof(data, "SOCKS4%s: connecting to HTTP proxy %s port %d", protocol4a ? "a" : "", hostname, remote_port); - infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port); + infof(data, "SOCKS4 communication to %s:%d", hostname, remote_port); /* * Compose socks4 request @@ -244,7 +244,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user, return CURLPX_RESOLVE_HOST; else if(rc == CURLRESOLV_PENDING) { sxstate(data, CONNECT_RESOLVING); - infof(data, "SOCKS4 non-blocking resolve of %s\n", hostname); + infof(data, "SOCKS4 non-blocking resolve of %s", hostname); return CURLPX_OK; } sxstate(data, CONNECT_RESOLVED); @@ -264,7 +264,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user, data->state.async.dns = dns; data->state.async.done = TRUE; #endif - infof(data, "Hostname '%s' was found\n", hostname); + infof(data, "Hostname '%s' was found", hostname); sxstate(data, CONNECT_RESOLVED); } else { @@ -279,18 +279,21 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user, CONNECT_RESOLVED: case CONNECT_RESOLVED: { struct Curl_addrinfo *hp = NULL; - char buf[64]; /* * We cannot use 'hostent' as a struct that Curl_resolv() returns. It * returns a Curl_addrinfo pointer that may not always look the same. */ - if(dns) + if(dns) { hp = dns->addr; - if(hp) { - Curl_printable_address(hp, buf, sizeof(buf)); - if(hp->ai_family == AF_INET) { + /* scan for the first IPv4 address */ + while(hp && (hp->ai_family != AF_INET)) + hp = hp->ai_next; + + if(hp) { struct sockaddr_in *saddr_in; + char buf[64]; + Curl_printable_address(hp, buf, sizeof(buf)); saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr; socksreq[4] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[0]; @@ -298,20 +301,19 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user, socksreq[6] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[2]; socksreq[7] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[3]; - infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)\n", buf); - } - else { - hp = NULL; /* fail! */ - failf(data, "SOCKS4 connection to %s not supported", buf); - } + infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)", buf); - Curl_resolv_unlock(data, dns); /* not used anymore from now on */ + Curl_resolv_unlock(data, dns); /* not used anymore from now on */ + } + else + failf(data, "SOCKS4 connection to %s not supported", hostname); } - if(!hp) { + else failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.", hostname); + + if(!hp) return CURLPX_RESOLVE_HOST; - } } /* FALLTHROUGH */ CONNECT_REQ_INIT: @@ -435,7 +437,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user, /* Result */ switch(socksreq[1]) { case 90: - infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":""); + infof(data, "SOCKS4%s request granted.", protocol4a?"a":""); break; case 91: failf(data, @@ -528,19 +530,19 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user, switch(sx->state) { case CONNECT_SOCKS_INIT: if(conn->bits.httpproxy) - infof(data, "SOCKS5: connecting to HTTP proxy %s port %d\n", + infof(data, "SOCKS5: connecting to HTTP proxy %s port %d", hostname, remote_port); /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */ if(!socks5_resolve_local && hostname_len > 255) { infof(data, "SOCKS5: server resolving disabled for hostnames of " - "length > 255 [actual len=%zu]\n", hostname_len); + "length > 255 [actual len=%zu]", hostname_len); socks5_resolve_local = TRUE; } if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) infof(data, - "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n", + "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu", auth); if(!(auth & CURLAUTH_BASIC)) /* disable username/password auth */ @@ -778,7 +780,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user, data->state.async.dns = dns; data->state.async.done = TRUE; #endif - infof(data, "SOCKS5: hostname '%s' found\n", hostname); + infof(data, "SOCKS5: hostname '%s' found", hostname); } if(!dns) { @@ -820,7 +822,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user, socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i]; } - infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", dest); + infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)", dest); } #ifdef ENABLE_IPV6 else if(hp->ai_family == AF_INET6) { @@ -834,7 +836,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user, ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i]; } - infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", dest); + infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)", dest); } #endif else { @@ -858,7 +860,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user, socksreq[len++] = (char) hostname_len; /* one byte address length */ memcpy(&socksreq[len], hostname, hostname_len); /* address w/o NULL */ len += hostname_len; - infof(data, "SOCKS5 connect to %s:%d (remotely resolved)\n", + infof(data, "SOCKS5 connect to %s:%d (remotely resolved)", hostname, remote_port); } /* FALLTHROUGH */ @@ -1022,7 +1024,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user, } sxstate(data, CONNECT_DONE); } - infof(data, "SOCKS5 request granted.\n"); + infof(data, "SOCKS5 request granted."); *done = TRUE; return CURLPX_OK; /* Proxy was successful! */ diff --git a/contrib/libs/curl/lib/socks_gssapi.c b/contrib/libs/curl/lib/socks_gssapi.c index cfb1c2464a..c87244138a 100644 --- a/contrib/libs/curl/lib/socks_gssapi.c +++ b/contrib/libs/curl/lib/socks_gssapi.c @@ -328,7 +328,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, user[gss_send_token.length] = '\0'; gss_release_name(&gss_status, &gss_client_name); gss_release_buffer(&gss_status, &gss_send_token); - infof(data, "SOCKS5 server authenticated user %s with GSS-API.\n",user); + infof(data, "SOCKS5 server authenticated user %s with GSS-API.",user); free(user); user = NULL; @@ -344,7 +344,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, else if(gss_ret_flags & GSS_C_INTEG_FLAG) gss_enc = 1; - infof(data, "SOCKS5 server supports GSS-API %s data protection.\n", + infof(data, "SOCKS5 server supports GSS-API %s data protection.", (gss_enc == 0)?"no":((gss_enc==1)?"integrity":"confidentiality")); /* force for the moment to no data protection */ gss_enc = 0; @@ -518,7 +518,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, (void)curlx_nonblock(sock, TRUE); - infof(data, "SOCKS5 access with%s protection granted.\n", + infof(data, "SOCKS5 access with%s protection granted.", (socksreq[0] == 0)?"out GSS-API data": ((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality")); diff --git a/contrib/libs/curl/lib/socks_sspi.c b/contrib/libs/curl/lib/socks_sspi.c index 813c6be574..cb225b9b5a 100644 --- a/contrib/libs/curl/lib/socks_sspi.c +++ b/contrib/libs/curl/lib/socks_sspi.c @@ -327,7 +327,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, failf(data, "Failed to determine user name."); return CURLE_COULDNT_CONNECT; } - infof(data, "SOCKS5 server authenticated user %s with GSS-API.\n", + infof(data, "SOCKS5 server authenticated user %s with GSS-API.", names.sUserName); s_pSecFn->FreeContextBuffer(names.sUserName); @@ -343,7 +343,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, else if(sspi_ret_flags & ISC_REQ_INTEGRITY) gss_enc = 1; - infof(data, "SOCKS5 server supports GSS-API %s data protection.\n", + infof(data, "SOCKS5 server supports GSS-API %s data protection.", (gss_enc == 0)?"no":((gss_enc == 1)?"integrity":"confidentiality") ); /* force to no data protection, avoid encryption/decryption for now */ gss_enc = 0; @@ -591,7 +591,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, } (void)curlx_nonblock(sock, TRUE); - infof(data, "SOCKS5 access with%s protection granted.\n", + infof(data, "SOCKS5 access with%s protection granted.", (socksreq[0] == 0)?"out GSS-API data": ((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality")); diff --git a/contrib/libs/curl/lib/strerror.c b/contrib/libs/curl/lib/strerror.c index d14525b0d1..ab9deaed00 100644 --- a/contrib/libs/curl/lib/strerror.c +++ b/contrib/libs/curl/lib/strerror.c @@ -188,8 +188,8 @@ curl_easy_strerror(CURLcode error) case CURLE_UNKNOWN_OPTION: return "An unknown option was passed in to libcurl"; - case CURLE_TELNET_OPTION_SYNTAX : - return "Malformed telnet option"; + case CURLE_SETOPT_OPTION_SYNTAX : + return "Malformed option provided in a setopt"; case CURLE_GOT_NOTHING: return "Server returned nothing (no headers, no data)"; diff --git a/contrib/libs/curl/lib/telnet.c b/contrib/libs/curl/lib/telnet.c index fdd137fb0c..a81bb81c36 100644 --- a/contrib/libs/curl/lib/telnet.c +++ b/contrib/libs/curl/lib/telnet.c @@ -268,9 +268,9 @@ static void printoption(struct Curl_easy *data, if(data->set.verbose) { if(cmd == CURL_IAC) { if(CURL_TELCMD_OK(option)) - infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option)); + infof(data, "%s IAC %s", direction, CURL_TELCMD(option)); else - infof(data, "%s IAC %d\n", direction, option); + infof(data, "%s IAC %d", direction, option); } else { const char *fmt = (cmd == CURL_WILL) ? "WILL" : @@ -287,12 +287,12 @@ static void printoption(struct Curl_easy *data, opt = NULL; if(opt) - infof(data, "%s %s %s\n", direction, fmt, opt); + infof(data, "%s %s %s", direction, fmt, opt); else - infof(data, "%s %s %d\n", direction, fmt, option); + infof(data, "%s %s %d", direction, fmt, option); } else - infof(data, "%s %d %d\n", direction, cmd, option); + infof(data, "%s %d %d", direction, cmd, option); } } } @@ -765,8 +765,6 @@ static void printsub(struct Curl_easy *data, break; } } - if(direction) - infof(data, "\n"); } } @@ -834,7 +832,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data) tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES; else { failf(data, "Syntax error in telnet option: %s", head->data); - result = CURLE_TELNET_OPTION_SYNTAX; + result = CURLE_SETOPT_OPTION_SYNTAX; break; } continue; @@ -855,7 +853,7 @@ static CURLcode check_telnet_options(struct Curl_easy *data) break; } failf(data, "Syntax error in telnet option: %s", head->data); - result = CURLE_TELNET_OPTION_SYNTAX; + result = CURLE_SETOPT_OPTION_SYNTAX; break; } @@ -922,12 +920,17 @@ static void suboption(struct Curl_easy *data) size_t tmplen = (strlen(v->data) + 1); /* Add the variable only if it fits */ if(len + tmplen < (int)sizeof(temp)-6) { - if(sscanf(v->data, "%127[^,],%127s", varname, varval) == 2) { - msnprintf((char *)&temp[len], sizeof(temp) - len, - "%c%s%c%s", CURL_NEW_ENV_VAR, varname, - CURL_NEW_ENV_VALUE, varval); - len += tmplen; - } + int rv; + char sep[2] = ""; + varval[0] = 0; + rv = sscanf(v->data, "%127[^,]%1[,]%127s", varname, sep, varval); + if(rv == 1) + len += msnprintf((char *)&temp[len], sizeof(temp) - len, + "%c%s", CURL_NEW_ENV_VAR, varname); + else if(rv >= 2) + len += msnprintf((char *)&temp[len], sizeof(temp) - len, + "%c%s%c%s", CURL_NEW_ENV_VAR, varname, + CURL_NEW_ENV_VALUE, varval); } } msnprintf((char *)&temp[len], sizeof(temp) - len, diff --git a/contrib/libs/curl/lib/tftp.c b/contrib/libs/curl/lib/tftp.c index 11150af361..8aeb14a4f5 100644 --- a/contrib/libs/curl/lib/tftp.c +++ b/contrib/libs/curl/lib/tftp.c @@ -239,7 +239,7 @@ static CURLcode tftp_set_timeouts(struct tftp_state_data *state) infof(state->data, "set timeouts for state %d; Total % " CURL_FORMAT_CURL_OFF_T - ", retry %d maxtry %d\n", + ", retry %d maxtry %d", (int)state->state, timeout_ms, state->retry_time, state->retry_max); /* init RX time */ @@ -325,7 +325,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state, return CURLE_TFTP_ILLEGAL; } - infof(data, "got option=(%s) value=(%s)\n", option, value); + infof(data, "got option=(%s) value=(%s)", option, value); if(checkprefix(option, TFTP_OPTION_BLKSIZE)) { long blksize; @@ -356,14 +356,14 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state, } state->blksize = (int)blksize; - infof(data, "%s (%d) %s (%d)\n", "blksize parsed from OACK", + infof(data, "%s (%d) %s (%d)", "blksize parsed from OACK", state->blksize, "requested", state->requested_blksize); } else if(checkprefix(option, TFTP_OPTION_TSIZE)) { long tsize = 0; tsize = strtol(value, NULL, 10); - infof(data, "%s (%ld)\n", "tsize parsed from OACK", tsize); + infof(data, "%s (%ld)", "tsize parsed from OACK", tsize); /* tsize should be ignored on upload: Who cares about the size of the remote file? */ @@ -397,7 +397,7 @@ static CURLcode tftp_connect_for_tx(struct tftp_state_data *state, #ifndef CURL_DISABLE_VERBOSE_STRINGS struct Curl_easy *data = state->data; - infof(data, "%s\n", "Connected for transmit"); + infof(data, "%s", "Connected for transmit"); #endif state->state = TFTP_STATE_TX; result = tftp_set_timeouts(state); @@ -413,7 +413,7 @@ static CURLcode tftp_connect_for_rx(struct tftp_state_data *state, #ifndef CURL_DISABLE_VERBOSE_STRINGS struct Curl_easy *data = state->data; - infof(data, "%s\n", "Connected for receive"); + infof(data, "%s", "Connected for receive"); #endif state->state = TFTP_STATE_RX; result = tftp_set_timeouts(state); @@ -596,12 +596,12 @@ static CURLcode tftp_rx(struct tftp_state_data *state, else if(state->block == rblock) { /* This is the last recently received block again. Log it and ACK it again. */ - infof(data, "Received last DATA packet block %d again.\n", rblock); + infof(data, "Received last DATA packet block %d again.", rblock); } else { /* totally unexpected, just log it */ infof(data, - "Received unexpected DATA packet block %d, expecting block %d\n", + "Received unexpected DATA packet block %d, expecting block %d", rblock, NEXT_BLOCKNUM(state->block)); break; } @@ -653,7 +653,7 @@ static CURLcode tftp_rx(struct tftp_state_data *state, /* Increment the retry count and fail if over the limit */ state->retries++; infof(data, - "Timeout waiting for block %d ACK. Retries = %d\n", + "Timeout waiting for block %d ACK. Retries = %d", NEXT_BLOCKNUM(state->block), state->retries); if(state->retries > state->retry_max) { state->error = TFTP_ERR_TIMEOUT; @@ -724,7 +724,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event) * */ !(state->block == 0 && rblock == 65535)) { /* This isn't the expected block. Log it and up the retry counter */ - infof(data, "Received ACK for block %d, expecting %d\n", + infof(data, "Received ACK for block %d, expecting %d", rblock, state->block); state->retries++; /* Bail out if over the maximum */ @@ -797,7 +797,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event) /* Increment the retry counter and log the timeout */ state->retries++; infof(data, "Timeout waiting for block %d ACK. " - " Retries = %d\n", NEXT_BLOCKNUM(state->block), state->retries); + " Retries = %d", NEXT_BLOCKNUM(state->block), state->retries); /* Decide if we've had enough */ if(state->retries > state->retry_max) { state->error = TFTP_ERR_TIMEOUT; @@ -906,22 +906,22 @@ static CURLcode tftp_state_machine(struct tftp_state_data *state, switch(state->state) { case TFTP_STATE_START: - DEBUGF(infof(data, "TFTP_STATE_START\n")); + DEBUGF(infof(data, "TFTP_STATE_START")); result = tftp_send_first(state, event); break; case TFTP_STATE_RX: - DEBUGF(infof(data, "TFTP_STATE_RX\n")); + DEBUGF(infof(data, "TFTP_STATE_RX")); result = tftp_rx(state, event); break; case TFTP_STATE_TX: - DEBUGF(infof(data, "TFTP_STATE_TX\n")); + DEBUGF(infof(data, "TFTP_STATE_TX")); result = tftp_tx(state, event); break; case TFTP_STATE_FIN: - infof(data, "%s\n", "TFTP finished"); + infof(data, "%s", "TFTP finished"); break; default: - DEBUGF(infof(data, "STATE: %d\n", state->state)); + DEBUGF(infof(data, "STATE: %d", state->state)); failf(data, "%s", "Internal state machine error"); result = CURLE_TFTP_ILLEGAL; break; @@ -1153,7 +1153,7 @@ static CURLcode tftp_receive_packet(struct Curl_easy *data) size_t strn = state->rbytes - 4; state->error = (tftp_error_t)error; if(tftp_strnlen(str, strn) < strn) - infof(data, "TFTP error: %s\n", str); + infof(data, "TFTP error: %s", str); break; } case TFTP_EVENT_ACK: @@ -1288,7 +1288,7 @@ static CURLcode tftp_doing(struct Curl_easy *data, bool *dophase_done) result = tftp_multi_statemach(data, dophase_done); if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } else if(!result) { /* The multi code doesn't have this logic for the DOING state so we @@ -1325,7 +1325,7 @@ static CURLcode tftp_perform(struct Curl_easy *data, bool *dophase_done) tftp_multi_statemach(data, dophase_done); if(*dophase_done) - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); return result; } diff --git a/contrib/libs/curl/lib/transfer.c b/contrib/libs/curl/lib/transfer.c index bca4e548fa..3e650b5b9e 100644 --- a/contrib/libs/curl/lib/transfer.c +++ b/contrib/libs/curl/lib/transfer.c @@ -188,7 +188,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, /* at this point we already verified that the callback exists so we compile and store the trailers buffer, then proceed */ infof(data, - "Moving trailers state machine from initialized to sending.\n"); + "Moving trailers state machine from initialized to sending."); data->state.trailers_state = TRAILERS_SENDING; Curl_dyn_init(&data->state.trailers_buf, DYN_TRAILERS); @@ -211,7 +211,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, curl_slist_free_all(trailers); return result; } - infof(data, "Successfully compiled trailers.\r\n"); + infof(data, "Successfully compiled trailers."); curl_slist_free_all(trailers); } #endif @@ -376,7 +376,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, data->set.trailer_callback = NULL; /* mark the transfer as done */ data->req.upload_done = TRUE; - infof(data, "Signaling end of chunked upload after trailers.\n"); + infof(data, "Signaling end of chunked upload after trailers."); } else #endif @@ -385,7 +385,7 @@ CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, /* mark this as done once this chunk is transferred */ data->req.upload_done = TRUE; infof(data, - "Signaling end of chunked upload via terminating chunk.\n"); + "Signaling end of chunked upload via terminating chunk."); } if(added_crlf) @@ -463,7 +463,7 @@ CURLcode Curl_readrewind(struct Curl_easy *data) err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD, data->set.ioctl_client); Curl_set_in_callback(data, false); - infof(data, "the ioctl callback returned %d\n", (int)err); + infof(data, "the ioctl callback returned %d", (int)err); if(err) { failf(data, "ioctl callback returned error %d", (int)err); @@ -530,7 +530,7 @@ bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) default: if(timeofdoc <= data->set.timevalue) { infof(data, - "The requested document is not new enough\n"); + "The requested document is not new enough"); data->info.timecond = TRUE; return FALSE; } @@ -538,7 +538,7 @@ bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) case CURL_TIMECOND_IFUNMODSINCE: if(timeofdoc >= data->set.timevalue) { infof(data, - "The requested document is not old enough\n"); + "The requested document is not old enough"); data->info.timecond = TRUE; return FALSE; } @@ -615,7 +615,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, else { /* read nothing but since we wanted nothing we consider this an OK situation to proceed from */ - DEBUGF(infof(data, "readwrite_data: we're done!\n")); + DEBUGF(infof(data, "readwrite_data: we're done!")); nread = 0; } @@ -638,10 +638,10 @@ static CURLcode readwrite_data(struct Curl_easy *data, server closed the connection and we bail out from this! */ #ifdef USE_NGHTTP2 if(is_http2 && !nread) - DEBUGF(infof(data, "nread == 0, stream closed, bailing\n")); + DEBUGF(infof(data, "nread == 0, stream closed, bailing")); else #endif - DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n")); + DEBUGF(infof(data, "nread <= 0, server closed connection, bailing")); k->keepon &= ~KEEP_RECV; break; } @@ -684,7 +684,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, infof(data, "Excess found:" " excess = %zd" - " url = %s (zero-length body)\n", + " url = %s (zero-length body)", nread, data->state.up.path); } @@ -764,7 +764,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, written to the client. */ if(conn->chunk.datasize) { infof(data, "Leftovers after chunking: % " - CURL_FORMAT_CURL_OFF_T "u bytes\n", + CURL_FORMAT_CURL_OFF_T "u bytes", conn->chunk.datasize); } } @@ -775,7 +775,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* Account for body content stored in the header buffer */ if((k->badheader == HEADER_PARTHEADER) && !k->ignorebody) { size_t headlen = Curl_dyn_len(&data->state.headerb); - DEBUGF(infof(data, "Increasing bytecount by %zu\n", headlen)); + DEBUGF(infof(data, "Increasing bytecount by %zu", headlen)); k->bytecount += headlen; } @@ -789,7 +789,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, " excess = %zu" ", size = %" CURL_FORMAT_CURL_OFF_T ", maxdownload = %" CURL_FORMAT_CURL_OFF_T - ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n", + ", bytecount = %" CURL_FORMAT_CURL_OFF_T, excess, k->size, k->maxdownload, k->bytecount); connclose(conn, "excess found in a read"); } @@ -898,7 +898,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, /* When we've read the entire thing and the close bit is set, the server may now close the connection. If there's now any kind of sending going on from our side, we need to stop that immediately. */ - infof(data, "we are done reading and this is set to close, stop send\n"); + infof(data, "we are done reading and this is set to close, stop send"); k->keepon &= ~KEEP_SEND; /* no writing anymore either */ } @@ -923,7 +923,7 @@ CURLcode Curl_done_sending(struct Curl_easy *data, return CURLE_OK; } -#if defined(WIN32) && !defined(USE_LWIPSOCK) +#if defined(WIN32) && defined(USE_WINSOCK) #ifndef SIO_IDEAL_SEND_BACKLOG_QUERY #define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B #endif @@ -1128,7 +1128,7 @@ static CURLcode readwrite_upload(struct Curl_easy *data, (k->writebytecount == data->state.infilesize)) { /* we have sent all data we were supposed to */ k->upload_done = TRUE; - infof(data, "We are completely uploaded and fine\n"); + infof(data, "We are completely uploaded and fine"); } if(k->upload_present != bytes_written) { @@ -1199,7 +1199,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(data->state.drain) { select_res |= CURL_CSELECT_IN; - DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n")); + DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data")); } if(!select_res) /* Call for select()/poll() only, if read/write/error @@ -1212,8 +1212,12 @@ CURLcode Curl_readwrite(struct connectdata *conn, } #ifdef USE_HYPER - if(conn->datastream) - return conn->datastream(data, conn, &didwhat, done, select_res); + if(conn->datastream) { + result = conn->datastream(data, conn, &didwhat, done, select_res); + if(result || *done) + return result; + } + else { #endif /* We go ahead and do a read if we have a readable socket or if the stream was rewound (in which case we have data in a @@ -1232,6 +1236,9 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(result) return result; } +#ifdef USE_HYPER + } +#endif k->now = Curl_now(); if(!didwhat) { @@ -1256,7 +1263,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, k->exp100 = EXP100_SEND_DATA; k->keepon |= KEEP_SEND; Curl_expire_done(data, EXPIRE_100_TIMEOUT); - infof(data, "Done waiting for 100-continue\n"); + infof(data, "Done waiting for 100-continue"); } } } @@ -1632,7 +1639,8 @@ CURLcode Curl_follow(struct Curl_easy *data, DEBUGASSERT(data->state.uh); uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, (type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME : - ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) ); + ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) | + CURLU_ALLOW_SPACE); if(uc) { if(type != FOLLOW_FAKE) return Curl_uc_to_curlcode(uc); @@ -1671,7 +1679,7 @@ CURLcode Curl_follow(struct Curl_easy *data, data->state.url = newurl; data->state.url_alloc = TRUE; - infof(data, "Issue another request to this URL: '%s'\n", data->state.url); + infof(data, "Issue another request to this URL: '%s'", data->state.url); /* * We get here when the HTTP code is 300-399 (and 401). We need to perform @@ -1714,7 +1722,7 @@ CURLcode Curl_follow(struct Curl_easy *data, || data->state.httpreq == HTTPREQ_POST_FORM || data->state.httpreq == HTTPREQ_POST_MIME) && !(data->set.keep_post & CURL_REDIR_POST_301)) { - infof(data, "Switch from POST to GET\n"); + infof(data, "Switch from POST to GET"); data->state.httpreq = HTTPREQ_GET; } break; @@ -1739,7 +1747,7 @@ CURLcode Curl_follow(struct Curl_easy *data, || data->state.httpreq == HTTPREQ_POST_FORM || data->state.httpreq == HTTPREQ_POST_MIME) && !(data->set.keep_post & CURL_REDIR_POST_302)) { - infof(data, "Switch from POST to GET\n"); + infof(data, "Switch from POST to GET"); data->state.httpreq = HTTPREQ_GET; } break; @@ -1757,7 +1765,7 @@ CURLcode Curl_follow(struct Curl_easy *data, !(data->set.keep_post & CURL_REDIR_POST_303))) { data->state.httpreq = HTTPREQ_GET; data->set.upload = false; - infof(data, "Switch to %s\n", + infof(data, "Switch to %s", data->set.opt_no_body?"HEAD":"GET"); } break; @@ -1818,7 +1826,7 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url) to issue again, but the nghttp2 API can deliver the message to other streams as well, which is why this adds the check the data counters too. */ - infof(data, "REFUSED_STREAM, retrying a fresh connect\n"); + infof(data, "REFUSED_STREAM, retrying a fresh connect"); data->state.refused_stream = FALSE; /* clear again */ retry = TRUE; } @@ -1830,8 +1838,8 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url) data->state.retrycount = 0; return CURLE_SEND_ERROR; } - infof(data, "Connection died, retrying a fresh connect\ -(retry count: %d)\n", data->state.retrycount); + infof(data, "Connection died, retrying a fresh connect (retry count: %d)", + data->state.retrycount); *url = strdup(data->state.url); if(!*url) return CURLE_OUT_OF_MEMORY; diff --git a/contrib/libs/curl/lib/url.c b/contrib/libs/curl/lib/url.c index b91986036f..bbe8b48728 100644 --- a/contrib/libs/curl/lib/url.c +++ b/contrib/libs/curl/lib/url.c @@ -62,6 +62,14 @@ #ifdef USE_LIBIDN2 #error #include <idn2.h> +#if defined(WIN32) && defined(UNICODE) +#define IDN2_LOOKUP(name, host, flags) \ + idn2_lookup_u8((const uint8_t *)name, (uint8_t **)host, flags) +#else +#define IDN2_LOOKUP(name, host, flags) \ + idn2_lookup_ul((const char *)name, (char **)host, flags) +#endif + #elif defined(USE_WIN32_IDN) /* prototype for curl_win32_idn_to_ascii() */ bool curl_win32_idn_to_ascii(const char *in, char **out); @@ -92,7 +100,6 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "speedcheck.h" #include "warnless.h" #include "non-ascii.h" -#include "inet_pton.h" #include "getinfo.h" #include "urlapi-int.h" #include "system_win32.h" @@ -726,7 +733,16 @@ static void conn_shutdown(struct Curl_easy *data, struct connectdata *conn) { DEBUGASSERT(conn); DEBUGASSERT(data); - infof(data, "Closing connection %ld\n", conn->connection_id); + 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); @@ -824,7 +840,7 @@ CURLcode Curl_disconnect(struct Curl_easy *data, * are other users of it */ if(CONN_INUSE(conn) && !dead_connection) { - DEBUGF(infof(data, "Curl_disconnect when inuse: %zu\n", CONN_INUSE(conn))); + DEBUGF(infof(data, "Curl_disconnect when inuse: %zu", CONN_INUSE(conn))); return CURLE_OK; } @@ -957,7 +973,7 @@ static bool conn_maxage(struct Curl_easy *data, idletime /= 1000; /* integer seconds is fine */ if(idletime > data->set.maxage_conn) { - infof(data, "Too old connection (%ld seconds), disconnect it\n", + infof(data, "Too old connection (%ld seconds), disconnect it", idletime); return TRUE; } @@ -1006,7 +1022,7 @@ static bool extract_if_dead(struct connectdata *conn, } if(dead) { - infof(data, "Connection %ld seems to be dead!\n", conn->connection_id); + infof(data, "Connection %ld seems to be dead!", conn->connection_id); Curl_conncache_remove_conn(data, conn, FALSE); return TRUE; } @@ -1122,7 +1138,7 @@ ConnectionExists(struct Curl_easy *data, /* Max pipe length is zero (unlimited) for multiplexed connections */ struct Curl_llist_element *curr; - infof(data, "Found bundle for host %s: %p [%s]\n", + infof(data, "Found bundle for host %s: %p [%s]", hostbundle, (void *)bundle, (bundle->multiuse == BUNDLE_MULTIPLEX ? "can multiplex" : "serially")); @@ -1130,22 +1146,22 @@ ConnectionExists(struct Curl_easy *data, if(canmultiplex) { if(bundle->multiuse == BUNDLE_UNKNOWN) { if(data->set.pipewait) { - infof(data, "Server doesn't support multiplex yet, wait\n"); + infof(data, "Server doesn't support multiplex yet, wait"); *waitpipe = TRUE; CONNCACHE_UNLOCK(data); return FALSE; /* no re-use */ } - infof(data, "Server doesn't support multiplex (yet)\n"); + infof(data, "Server doesn't support multiplex (yet)"); canmultiplex = FALSE; } if((bundle->multiuse == BUNDLE_MULTIPLEX) && !Curl_multiplex_wanted(data->multi)) { - infof(data, "Could multiplex, but not asked to!\n"); + infof(data, "Could multiplex, but not asked to!"); canmultiplex = FALSE; } if(bundle->multiuse == BUNDLE_NO_MULTIUSE) { - infof(data, "Can not multiplex, even if we wanted to!\n"); + infof(data, "Can not multiplex, even if we wanted to!"); canmultiplex = FALSE; } } @@ -1193,7 +1209,7 @@ ConnectionExists(struct Curl_easy *data, completed yet and until then we don't re-use this connection */ if(!check->primary_ip[0]) { infof(data, - "Connection #%ld is still name resolving, can't reuse\n", + "Connection #%ld is still name resolving, can't reuse", check->connection_id); continue; } @@ -1202,7 +1218,7 @@ ConnectionExists(struct Curl_easy *data, if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) { foundPendingCandidate = TRUE; /* Don't pick a connection that hasn't connected yet */ - infof(data, "Connection #%ld isn't open enough, can't reuse\n", + infof(data, "Connection #%ld isn't open enough, can't reuse", check->connection_id); continue; } @@ -1357,7 +1373,7 @@ ConnectionExists(struct Curl_easy *data, &check->ssl_config)) { DEBUGF(infof(data, "Connection #%ld has different SSL parameters, " - "can't reuse\n", + "can't reuse", check->connection_id)); continue; } @@ -1365,7 +1381,7 @@ ConnectionExists(struct Curl_easy *data, foundPendingCandidate = TRUE; DEBUGF(infof(data, "Connection #%ld has not started SSL connect, " - "can't reuse\n", + "can't reuse", check->connection_id)); continue; } @@ -1452,14 +1468,14 @@ ConnectionExists(struct Curl_easy *data, /* Multiplexed connections can only be HTTP/2 for now */ struct http_conn *httpc = &check->proto.httpc; if(multiplexed >= httpc->settings.max_concurrent_streams) { - infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n", + infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)", multiplexed); continue; } else if(multiplexed >= Curl_multi_max_concurrent_streams(data->multi)) { infof(data, "client side MAX_CONCURRENT_STREAMS reached" - ", skip (%zu)\n", + ", skip (%zu)", multiplexed); continue; } @@ -1467,7 +1483,7 @@ ConnectionExists(struct Curl_easy *data, #endif /* When not multiplexed, we have a match here! */ chosen = check; - infof(data, "Multiplexed connection found!\n"); + infof(data, "Multiplexed connection found!"); break; } else { @@ -1490,7 +1506,7 @@ ConnectionExists(struct Curl_easy *data, if(foundPendingCandidate && data->set.pipewait) { infof(data, - "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n"); + "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set"); *waitpipe = TRUE; } @@ -1505,7 +1521,7 @@ void Curl_verboseconnect(struct Curl_easy *data, struct connectdata *conn) { if(data->set.verbose) - infof(data, "Connected to %s (%s) port %ld (#%ld)\n", + infof(data, "Connected to %s (%s) port %u (#%ld)", #ifndef CURL_DISABLE_PROXY conn->bits.socksproxy ? conn->socks_proxy.host.dispname : conn->bits.httpproxy ? conn->http_proxy.host.dispname : @@ -1577,12 +1593,12 @@ CURLcode Curl_idnconvert_hostname(struct Curl_easy *data, #else int flags = IDN2_NFC_INPUT; #endif - int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, flags); + int rc = IDN2_LOOKUP(host->name, &ace_hostname, flags); if(rc != IDN2_OK) /* fallback to TR46 Transitional mode for better IDNA2003 compatibility */ - rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, - IDN2_TRANSITIONAL); + rc = IDN2_LOOKUP(host->name, &ace_hostname, + IDN2_TRANSITIONAL); if(rc == IDN2_OK) { host->encalloc = (char *)ace_hostname; /* change the name pointer to point to the encoded hostname */ @@ -1609,7 +1625,7 @@ CURLcode Curl_idnconvert_hostname(struct Curl_easy *data, return CURLE_URL_MALFORMAT; } #else - infof(data, "IDN support not present, can't parse Unicode domains\n"); + infof(data, "IDN support not present, can't parse Unicode domains"); #endif } return CURLE_OK; @@ -1877,7 +1893,7 @@ static void zonefrom_url(CURLU *uh, struct Curl_easy *data, scopeidx = if_nametoindex(zoneid); #endif if(!scopeidx) - infof(data, "Invalid zoneid: %s; %s\n", zoneid, + infof(data, "Invalid zoneid: %s; %s", zoneid, strerror(errno)); else conn->scope_id = scopeidx; @@ -1934,7 +1950,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, CURLU_DISALLOW_USER : 0) | (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)); if(uc) { - DEBUGF(infof(data, "curl_url_set rejected %s\n", data->state.url)); + DEBUGF(infof(data, "curl_url_set rejected %s", data->state.url)); return Curl_uc_to_curlcode(uc); } @@ -1979,7 +1995,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, } data->state.url = url; data->state.url_alloc = TRUE; - infof(data, "Switched from HTTP to HTTPS due to HSTS => %s\n", + infof(data, "Switched from HTTP to HTTPS due to HSTS => %s", data->state.url); } } @@ -2333,7 +2349,7 @@ static char *detect_proxy(struct Curl_easy *data, } } if(proxy) - infof(data, "Uses proxy env variable %s == '%s'\n", envp, proxy); + infof(data, "Uses proxy env variable %s == '%s'", envp, proxy); return proxy; } @@ -2448,7 +2464,7 @@ static CURLcode parse_proxy(struct Curl_easy *data, conn->bits.proxy_user_passwd = TRUE; /* enable it */ } - curl_url_get(uhp, CURLUPART_PORT, &portptr, 0); + (void)curl_url_get(uhp, CURLUPART_PORT, &portptr, 0); if(portptr) { port = (int)strtol(portptr, NULL, 10); @@ -2576,7 +2592,7 @@ static CURLcode create_conn_helper_init_proxy(struct Curl_easy *data, no_proxy = curl_getenv(p); } if(no_proxy) { - infof(data, "Uses proxy env variable %s == '%s'\n", p, no_proxy); + infof(data, "Uses proxy env variable %s == '%s'", p, no_proxy); } } @@ -2871,11 +2887,13 @@ 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 && conn->bits.user_passwd) { Curl_safefree(*userp); Curl_safefree(*passwdp); conn->bits.user_passwd = FALSE; /* disable user+password */ } +#endif if(data->set.str[STRING_OPTIONS]) { free(*optionsp); @@ -2884,6 +2902,7 @@ static CURLcode override_login(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; } +#ifndef CURL_DISABLE_NETRC conn->bits.netrc = FALSE; if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) { bool netrc_user_changed = FALSE; @@ -2895,7 +2914,7 @@ static CURLcode override_login(struct Curl_easy *data, &netrc_user_changed, &netrc_passwd_changed, data->set.str[STRING_NETRC_FILE]); if(ret > 0) { - infof(data, "Couldn't find host %s in the %s file; using defaults\n", + infof(data, "Couldn't find host %s in the %s file; using defaults", conn->host.name, data->set.str[STRING_NETRC_FILE]); } else if(ret < 0) { @@ -2909,6 +2928,7 @@ static CURLcode override_login(struct Curl_easy *data, conn->bits.user_passwd = TRUE; /* enable user+password */ } } +#endif /* for updated strings, we update them in the URL */ if(*userp) { @@ -2996,6 +3016,7 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data, char *host_portno; char *portptr; int port = -1; + CURLcode result = CURLE_OK; #if defined(CURL_DISABLE_VERBOSE_STRINGS) (void) data; @@ -3025,7 +3046,7 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data, if(*ptr == '%') { /* There might be a zone identifier */ if(strncmp("%25", ptr, 3)) - infof(data, "Please URL encode %% as %%25, see RFC 6874.\n"); + infof(data, "Please URL encode %% as %%25, see RFC 6874."); ptr++; /* Allow unreserved characters as defined in RFC 3986 */ while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') || @@ -3036,7 +3057,7 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data, /* yeps, it ended nicely with a bracket as well */ *ptr++ = '\0'; else - infof(data, "Invalid IPv6 address format\n"); + infof(data, "Invalid IPv6 address format"); portptr = ptr; /* Note that if this didn't end with a bracket, we still advanced the * hostptr first, but I can't see anything wrong with that as no host @@ -3044,8 +3065,8 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data, */ #else failf(data, "Use of IPv6 in *_CONNECT_TO without IPv6 support built-in!"); - free(host_dup); - return CURLE_NOT_BUILT_IN; + result = CURLE_NOT_BUILT_IN; + goto error; #endif } @@ -3058,10 +3079,10 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data, if(*host_portno) { long portparse = strtol(host_portno, &endp, 10); if((endp && *endp) || (portparse < 0) || (portparse > 65535)) { - infof(data, "No valid port number in connect to host string (%s)\n", + failf(data, "No valid port number in connect to host string (%s)", host_portno); - hostptr = NULL; - port = -1; + result = CURLE_SETOPT_OPTION_SYNTAX; + goto error; } else port = (int)portparse; /* we know it will fit */ @@ -3072,15 +3093,16 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data, if(hostptr) { *hostname_result = strdup(hostptr); if(!*hostname_result) { - free(host_dup); - return CURLE_OUT_OF_MEMORY; + result = CURLE_OUT_OF_MEMORY; + goto error; } } *port_result = port; + error: free(host_dup); - return CURLE_OK; + return result; } /* @@ -3176,7 +3198,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, conn->conn_to_host.name = host; conn->bits.conn_to_host = TRUE; - infof(data, "Connecting to hostname: %s\n", host); + infof(data, "Connecting to hostname: %s", host); } else { /* no "connect to host" */ @@ -3187,7 +3209,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, if(port >= 0) { conn->conn_to_port = port; conn->bits.conn_to_port = TRUE; - infof(data, "Connecting to port: %d\n", port); + infof(data, "Connecting to port: %d", port); } else { /* no "connect to port" */ @@ -3248,7 +3270,7 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, conn->conn_to_port = as->dst.port; conn->bits.conn_to_port = TRUE; conn->bits.altused = TRUE; - infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d\n", + infof(data, "Alt-svc connecting from [%s]%s:%d to [%s]%s:%d", Curl_alpnid2str(srcalpnid), host, conn->remote_port, Curl_alpnid2str(as->dst.alpnid), hostd, as->dst.port); if(srcalpnid != as->dst.alpnid) { @@ -3356,9 +3378,12 @@ static CURLcode resolve_server(struct Curl_easy *data, if(rc == CURLRESOLV_PENDING) *async = TRUE; - else if(rc == CURLRESOLV_TIMEDOUT) + 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; @@ -3600,7 +3625,7 @@ static CURLcode create_conn(struct Curl_easy *data, if(result) goto out; - /* Check for overridden login details and set them accordingly so they + /* Check for overridden login details and set them accordingly so that they are known when protocol->setup_connection is called! */ result = override_login(data, conn); if(result) @@ -3736,6 +3761,8 @@ static CURLcode create_conn(struct Curl_easy *data, */ data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH]; data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE]; + data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; + data->set.ssl.primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; data->set.ssl.primary.cipher_list = @@ -3763,8 +3790,11 @@ static CURLcode create_conn(struct Curl_easy *data, data->set.proxy_ssl.primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; data->set.proxy_ssl.primary.ca_info_blob = data->set.blobs[BLOB_CAINFO_PROXY]; + data->set.proxy_ssl.primary.issuercert = + data->set.str[STRING_SSL_ISSUERCERT_PROXY]; + data->set.proxy_ssl.primary.issuercert_blob = + data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; - data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; @@ -3773,7 +3803,6 @@ static CURLcode create_conn(struct Curl_easy *data, data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY]; #endif data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; - data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE]; data->set.ssl.key = data->set.str[STRING_KEY]; data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE]; @@ -3787,9 +3816,7 @@ static CURLcode create_conn(struct Curl_easy *data, data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; #endif #endif - data->set.ssl.key_blob = data->set.blobs[BLOB_KEY]; - data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary, &conn->ssl_config)) { @@ -3841,14 +3868,14 @@ static CURLcode create_conn(struct Curl_easy *data, *in_connect = conn; #ifndef CURL_DISABLE_PROXY - infof(data, "Re-using existing connection! (#%ld) with %s %s\n", + infof(data, "Re-using existing connection! (#%ld) with %s %s", conn->connection_id, conn->bits.proxy?"proxy":"host", conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname : conn->http_proxy.host.name ? conn->http_proxy.host.dispname : conn->host.dispname); #else - infof(data, "Re-using existing connection! (#%ld) with host %s\n", + infof(data, "Re-using existing connection! (#%ld) with host %s", conn->connection_id, conn->host.dispname); #endif } @@ -3888,7 +3915,7 @@ static CURLcode create_conn(struct Curl_easy *data, if(conn_candidate) (void)Curl_disconnect(data, conn_candidate, FALSE); else { - infof(data, "No more connections allowed to host %s: %zu\n", + infof(data, "No more connections allowed to host %s: %zu", bundlehost, max_host_connections); connections_available = FALSE; } @@ -3908,13 +3935,13 @@ static CURLcode create_conn(struct Curl_easy *data, if(conn_candidate) (void)Curl_disconnect(data, conn_candidate, FALSE); else { - infof(data, "No connections available in cache\n"); + infof(data, "No connections available in cache"); connections_available = FALSE; } } if(!connections_available) { - infof(data, "No connections available.\n"); + infof(data, "No connections available."); conn_free(conn); *in_connect = NULL; @@ -3939,14 +3966,14 @@ static CURLcode create_conn(struct Curl_easy *data, connection based. */ if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && data->state.authhost.done) { - infof(data, "NTLM picked AND auth done set, clear picked!\n"); + infof(data, "NTLM picked AND auth done set, clear picked!"); data->state.authhost.picked = CURLAUTH_NONE; data->state.authhost.done = FALSE; } if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && data->state.authproxy.done) { - infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n"); + infof(data, "NTLM-proxy picked AND auth done set, clear picked!"); data->state.authproxy.picked = CURLAUTH_NONE; data->state.authproxy.done = FALSE; } diff --git a/contrib/libs/curl/lib/urlapi.c b/contrib/libs/curl/lib/urlapi.c index 6483208ec7..905c499d99 100644 --- a/contrib/libs/curl/lib/urlapi.c +++ b/contrib/libs/curl/lib/urlapi.c @@ -131,7 +131,7 @@ static const char *find_host_sep(const char *url) */ static bool urlchar_needs_escaping(int c) { - return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)); + return !(ISCNTRL(c) || ISSPACE(c) || ISGRAPH(c)); } /* @@ -580,7 +580,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, char *hostname, } /* scan for byte values < 31 or 127 */ -static CURLUcode junkscan(const char *part) +static bool junkscan(const char *part, unsigned int flags) { if(part) { static const char badbytes[]={ @@ -588,17 +588,18 @@ static CURLUcode junkscan(const char *part) 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x7f, - 0x00 /* null-terminate */ + 0x7f, 0x00 /* null-terminate */ }; size_t n = strlen(part); size_t nfine = strcspn(part, badbytes); if(nfine != n) /* since we don't know which part is scanned, return a generic error code */ - return CURLUE_MALFORMED_INPUT; + return TRUE; + if(!(flags & CURLU_ALLOW_SPACE) && strchr(part, ' ')) + return TRUE; } - return CURLUE_OK; + return FALSE; } static CURLUcode hostname_check(struct Curl_URL *u, char *hostname) @@ -884,9 +885,8 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) !(flags & CURLU_NON_SUPPORT_SCHEME)) return CURLUE_UNSUPPORTED_SCHEME; - if(junkscan(schemep)) + if(junkscan(schemep, flags)) return CURLUE_MALFORMED_INPUT; - } else { /* no scheme! */ @@ -927,7 +927,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) } } - if(junkscan(path)) + if(junkscan(path, flags)) return CURLUE_MALFORMED_INPUT; if((flags & CURLU_URLENCODE) && path[0]) { @@ -991,7 +991,7 @@ static CURLUcode seturl(const char *url, CURLU *u, unsigned int flags) /* * Parse the login details and strip them out of the host name. */ - if(junkscan(hostname)) + if(junkscan(hostname, flags)) return CURLUE_MALFORMED_INPUT; result = parse_hostname_login(u, &hostname, flags); @@ -1155,7 +1155,7 @@ CURLUcode curl_url_get(CURLU *u, CURLUPart what, const struct Curl_handler *h = Curl_builtin_scheme(u->scheme); if(h) { - msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport); + msnprintf(portbuf, sizeof(portbuf), "%u", h->defport); ptr = portbuf; } } @@ -1214,7 +1214,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 */ if(h) { - msnprintf(portbuf, sizeof(portbuf), "%ld", h->defport); + msnprintf(portbuf, sizeof(portbuf), "%u", h->defport); port = portbuf; } } diff --git a/contrib/libs/curl/lib/urldata.h b/contrib/libs/curl/lib/urldata.h index aacdc75718..c409d2afed 100644 --- a/contrib/libs/curl/lib/urldata.h +++ b/contrib/libs/curl/lib/urldata.h @@ -246,6 +246,7 @@ struct ssl_primary_config { long version_max; /* max supported version the client wants to use*/ char *CApath; /* certificate dir (doesn't work on windows) */ char *CAfile; /* certificate to verify peer against */ + char *issuercert; /* optional issuer certificate filename */ char *clientcert; char *random_file; /* path to file containing "random" data */ char *egdsocket; /* path to file containing the EGD daemon socket */ @@ -254,6 +255,7 @@ struct ssl_primary_config { char *pinned_key; struct curl_blob *cert_blob; struct curl_blob *ca_info_blob; + struct curl_blob *issuercert_blob; char *curves; /* list of curves to use */ BIT(verifypeer); /* set TRUE if this is desired */ BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */ @@ -265,8 +267,6 @@ struct ssl_config_data { struct ssl_primary_config primary; long certverifyresult; /* result from the certificate verification */ char *CRLfile; /* CRL to check certificate revocation */ - char *issuercert;/* optional issuer certificate filename */ - struct curl_blob *issuercert_blob; curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ void *fsslctxp; /* parameter for call back */ char *cert_type; /* format for certificate (default: PEM)*/ @@ -508,7 +508,9 @@ struct ConnectBits { BIT(ftp_use_data_ssl); /* Enabled SSL for the data connection */ BIT(ftp_use_control_ssl); /* Enabled SSL for the control connection */ #endif +#ifndef CURL_DISABLE_NETRC BIT(netrc); /* name+password provided by netrc */ +#endif BIT(bound); /* set true if bind() has already been done on this socket/ connection */ BIT(multiplex); /* connection is multiplexed */ @@ -1411,6 +1413,7 @@ struct UrlState { trailers_state trailers_state; /* whether we are sending trailers and what stage are we at */ #ifdef USE_HYPER + bool hconnect; /* set if a CONNECT request */ CURLcode hresult; /* used to pass return codes back from hyper callbacks */ #endif @@ -1726,8 +1729,10 @@ 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 */ +#endif curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or IMAP or POP3 or others! */ long new_file_perms; /* Permissions to use when creating remote files */ @@ -1847,9 +1852,9 @@ struct UserDefined { BIT(disallow_username_in_url); /* disallow username in url */ BIT(doh); /* DNS-over-HTTPS enabled */ BIT(doh_get); /* use GET for DoH requests, instead of POST */ - BIT(doh_verifypeer); /* DOH certificate peer verification */ - BIT(doh_verifyhost); /* DOH certificate hostname verification */ - BIT(doh_verifystatus); /* DOH certificate status verification */ + BIT(doh_verifypeer); /* DoH certificate peer verification */ + BIT(doh_verifyhost); /* DoH certificate hostname verification */ + BIT(doh_verifystatus); /* DoH certificate status verification */ BIT(http09_allowed); /* allow HTTP/0.9 responses */ BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some recipients */ diff --git a/contrib/libs/curl/lib/vauth/digest_sspi.c b/contrib/libs/curl/lib/vauth/digest_sspi.c index 2602ffd363..94f8f8c0df 100644 --- a/contrib/libs/curl/lib/vauth/digest_sspi.c +++ b/contrib/libs/curl/lib/vauth/digest_sspi.c @@ -112,7 +112,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, /* Ensure we have a valid challenge message */ if(!Curl_bufref_len(chlg)) { - infof(data, "DIGEST-MD5 handshake failure (empty challenge message)\n"); + infof(data, "DIGEST-MD5 handshake failure (empty challenge message)"); return CURLE_BAD_CONTENT_ENCODING; } @@ -197,7 +197,9 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, status == SEC_I_COMPLETE_AND_CONTINUE) s_pSecFn->CompleteAuthToken(&credentials, &resp_desc); else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) char buffer[STRERROR_LEN]; +#endif s_pSecFn->FreeCredentialsHandle(&credentials); Curl_sspi_free_identity(p_identity); @@ -207,7 +209,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, if(status == SEC_E_INSUFFICIENT_MEMORY) return CURLE_OUT_OF_MEMORY; - infof(data, "schannel: InitializeSecurityContext failed: %s\n", + infof(data, "schannel: InitializeSecurityContext failed: %s", Curl_sspi_strerror(status, buffer, sizeof(buffer))); return CURLE_AUTH_ERROR; @@ -461,7 +463,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, if(status == SEC_E_OK) output_token_len = chlg_buf[4].cbBuffer; else { /* delete the context so a new one can be made */ - infof(data, "digest_sspi: MakeSignature failed, error 0x%08lx\n", + infof(data, "digest_sspi: MakeSignature failed, error 0x%08lx", (long)status); s_pSecFn->DeleteSecurityContext(digest->http_context); Curl_safefree(digest->http_context); @@ -585,7 +587,9 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, status == SEC_I_COMPLETE_AND_CONTINUE) s_pSecFn->CompleteAuthToken(&credentials, &resp_desc); else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { +#if !defined(CURL_DISABLE_VERBOSE_STRINGS) char buffer[STRERROR_LEN]; +#endif s_pSecFn->FreeCredentialsHandle(&credentials); @@ -597,7 +601,7 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, if(status == SEC_E_INSUFFICIENT_MEMORY) return CURLE_OUT_OF_MEMORY; - infof(data, "schannel: InitializeSecurityContext failed: %s\n", + infof(data, "schannel: InitializeSecurityContext failed: %s", Curl_sspi_strerror(status, buffer, sizeof(buffer))); return CURLE_AUTH_ERROR; diff --git a/contrib/libs/curl/lib/vauth/krb5_gssapi.c b/contrib/libs/curl/lib/vauth/krb5_gssapi.c index 15aa0a24e2..d1c5ffd215 100644 --- a/contrib/libs/curl/lib/vauth/krb5_gssapi.c +++ b/contrib/libs/curl/lib/vauth/krb5_gssapi.c @@ -123,7 +123,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, if(chlg) { if(!Curl_bufref_len(chlg)) { - infof(data, "GSSAPI handshake failure (empty challenge message)\n"); + infof(data, "GSSAPI handshake failure (empty challenge message)"); return CURLE_BAD_CONTENT_ENCODING; } input_token.value = (void *) Curl_bufref_ptr(chlg); @@ -199,7 +199,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, /* Ensure we have a valid challenge message */ if(!Curl_bufref_len(chlg)) { - infof(data, "GSSAPI handshake failure (empty security message)\n"); + infof(data, "GSSAPI handshake failure (empty security message)"); return CURLE_BAD_CONTENT_ENCODING; } @@ -238,7 +238,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ if(output_token.length != 4) { - infof(data, "GSSAPI handshake failure (invalid security data)\n"); + infof(data, "GSSAPI handshake failure (invalid security data)"); gss_release_buffer(&unused_status, &username_token); return CURLE_BAD_CONTENT_ENCODING; } @@ -250,7 +250,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, /* Extract the security layer */ sec_layer = indata & 0x000000FF; if(!(sec_layer & GSSAUTH_P_NONE)) { - infof(data, "GSSAPI handshake failure (invalid security layer)\n"); + infof(data, "GSSAPI handshake failure (invalid security layer)"); gss_release_buffer(&unused_status, &username_token); return CURLE_BAD_CONTENT_ENCODING; diff --git a/contrib/libs/curl/lib/vauth/krb5_sspi.c b/contrib/libs/curl/lib/vauth/krb5_sspi.c index e110644225..8f7a2b02de 100644 --- a/contrib/libs/curl/lib/vauth/krb5_sspi.c +++ b/contrib/libs/curl/lib/vauth/krb5_sspi.c @@ -173,7 +173,7 @@ CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data, if(chlg) { if(!Curl_bufref_len(chlg)) { - infof(data, "GSSAPI handshake failure (empty challenge message)\n"); + infof(data, "GSSAPI handshake failure (empty challenge message)"); return CURLE_BAD_CONTENT_ENCODING; } @@ -270,9 +270,13 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, SECURITY_STATUS status; char *user_name; +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) data; +#endif + /* Ensure we have a valid challenge message */ if(!Curl_bufref_len(chlg)) { - infof(data, "GSSAPI handshake failure (empty security message)\n"); + infof(data, "GSSAPI handshake failure (empty security message)"); return CURLE_BAD_CONTENT_ENCODING; } @@ -312,13 +316,13 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, /* Decrypt the inbound challenge and obtain the qop */ status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop); if(status != SEC_E_OK) { - infof(data, "GSSAPI handshake failure (empty security message)\n"); + infof(data, "GSSAPI handshake failure (empty security message)"); return CURLE_BAD_CONTENT_ENCODING; } /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ if(input_buf[1].cbBuffer != 4) { - infof(data, "GSSAPI handshake failure (invalid security data)\n"); + infof(data, "GSSAPI handshake failure (invalid security data)"); return CURLE_BAD_CONTENT_ENCODING; } @@ -329,7 +333,7 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, /* Extract the security layer */ sec_layer = indata & 0x000000FF; if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) { - infof(data, "GSSAPI handshake failure (invalid security layer)\n"); + infof(data, "GSSAPI handshake failure (invalid security layer)"); return CURLE_BAD_CONTENT_ENCODING; } diff --git a/contrib/libs/curl/lib/vauth/ntlm.c b/contrib/libs/curl/lib/vauth/ntlm.c index 47e53572cb..0aa3f1c8ca 100644 --- a/contrib/libs/curl/lib/vauth/ntlm.c +++ b/contrib/libs/curl/lib/vauth/ntlm.c @@ -182,7 +182,7 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, (target_info_offset + target_info_len) > type2len || target_info_offset < 48) { infof(data, "NTLM handshake failure (bad type-2 message). " - "Target Info Offset Len is set incorrect by the peer\n"); + "Target Info Offset Len is set incorrect by the peer"); return CURLE_BAD_CONTENT_ENCODING; } @@ -286,7 +286,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) || (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) { /* This was not a good enough type-2 message */ - infof(data, "NTLM handshake failure (bad type-2 message)\n"); + infof(data, "NTLM handshake failure (bad type-2 message)"); return CURLE_BAD_CONTENT_ENCODING; } @@ -296,7 +296,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) { result = ntlm_decode_type2_target(data, type2ref, ntlm); if(result) { - infof(data, "NTLM handshake failure (bad type-2 message)\n"); + infof(data, "NTLM handshake failure (bad type-2 message)"); return result; } } @@ -533,7 +533,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, /* Get the machine's un-qualified host name as NTLM doesn't like the fully qualified domain name */ if(Curl_gethostname(host, sizeof(host))) { - infof(data, "gethostname() failed, continuing without!\n"); + infof(data, "gethostname() failed, continuing without!"); hostlen = 0; } else { diff --git a/contrib/libs/curl/lib/vauth/ntlm_sspi.c b/contrib/libs/curl/lib/vauth/ntlm_sspi.c index 1b1a176301..3e39dad315 100644 --- a/contrib/libs/curl/lib/vauth/ntlm_sspi.c +++ b/contrib/libs/curl/lib/vauth/ntlm_sspi.c @@ -206,7 +206,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, /* Ensure we have a valid type-2 message */ if(!Curl_bufref_len(type2)) { - infof(data, "NTLM handshake failure (empty type-2 message)\n"); + infof(data, "NTLM handshake failure (empty type-2 message)"); return CURLE_BAD_CONTENT_ENCODING; } @@ -253,6 +253,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, unsigned long attrs; TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ +#if defined(CURL_DISABLE_VERBOSE_STRINGS) + (void) data; +#endif (void) passwdp; (void) userp; @@ -309,7 +312,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, &type_3_desc, &attrs, &expiry); if(status != SEC_E_OK) { - infof(data, "NTLM handshake failure (type-3 message): Status=%x\n", + infof(data, "NTLM handshake failure (type-3 message): Status=%x", status); if(status == SEC_E_INSUFFICIENT_MEMORY) diff --git a/contrib/libs/curl/lib/vauth/spnego_gssapi.c b/contrib/libs/curl/lib/vauth/spnego_gssapi.c index 0911670739..360f3cb4a9 100644 --- a/contrib/libs/curl/lib/vauth/spnego_gssapi.c +++ b/contrib/libs/curl/lib/vauth/spnego_gssapi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -137,8 +137,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, /* Ensure we have a valid challenge message */ if(!chlg) { - infof(data, "SPNEGO handshake failure (empty challenge message)\n"); - + infof(data, "SPNEGO handshake failure (empty challenge message)"); return CURLE_BAD_CONTENT_ENCODING; } diff --git a/contrib/libs/curl/lib/vauth/spnego_sspi.c b/contrib/libs/curl/lib/vauth/spnego_sspi.c index 4aa1ba9572..68bb17da59 100644 --- a/contrib/libs/curl/lib/vauth/spnego_sspi.c +++ b/contrib/libs/curl/lib/vauth/spnego_sspi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -191,8 +191,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data, /* Ensure we have a valid challenge message */ if(!chlg) { - infof(data, "SPNEGO handshake failure (empty challenge message)\n"); - + infof(data, "SPNEGO handshake failure (empty challenge message)"); return CURLE_BAD_CONTENT_ENCODING; } diff --git a/contrib/libs/curl/lib/version.c b/contrib/libs/curl/lib/version.c index 4944dac618..9fb16c5444 100644 --- a/contrib/libs/curl/lib/version.c +++ b/contrib/libs/curl/lib/version.c @@ -75,28 +75,26 @@ #endif #ifdef HAVE_BROTLI -static size_t brotli_version(char *buf, size_t bufsz) +static void brotli_version(char *buf, size_t bufsz) { uint32_t brotli_version = BrotliDecoderVersion(); unsigned int major = brotli_version >> 24; unsigned int minor = (brotli_version & 0x00FFFFFF) >> 12; unsigned int patch = brotli_version & 0x00000FFF; - - return msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch); + (void)msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch); } #endif #ifdef HAVE_ZSTD -static size_t zstd_version(char *buf, size_t bufsz) +static void zstd_version(char *buf, size_t bufsz) { unsigned long zstd_version = (unsigned long)ZSTD_versionNumber(); unsigned int major = (unsigned int)(zstd_version / (100 * 100)); unsigned int minor = (unsigned int)((zstd_version - - (major * 100 * 100)) / 100); + (major * 100 * 100)) / 100); unsigned int patch = (unsigned int)(zstd_version - - (major * 100 * 100) - (minor * 100)); - - return msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch); + (major * 100 * 100) - (minor * 100)); + (void)msnprintf(buf, bufsz, "%u.%u.%u", major, minor, patch); } #endif diff --git a/contrib/libs/curl/lib/vquic/ngtcp2.c b/contrib/libs/curl/lib/vquic/ngtcp2.c index 901498fbeb..20810274e0 100644 --- a/contrib/libs/curl/lib/vquic/ngtcp2.c +++ b/contrib/libs/curl/lib/vquic/ngtcp2.c @@ -86,7 +86,8 @@ struct h3out { #define QUIC_PRIORITY \ "NORMAL:-VERS-ALL:+VERS-TLS1.3:-CIPHER-ALL:+AES-128-GCM:+AES-256-GCM:" \ "+CHACHA20-POLY1305:+AES-128-CCM:-GROUP-ALL:+GROUP-SECP256R1:" \ - "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1" + "+GROUP-X25519:+GROUP-SECP384R1:+GROUP-SECP521R1:" \ + "%DISABLE_TLS13_COMPAT_MODE" #endif static CURLcode ng_process_ingress(struct Curl_easy *data, @@ -778,7 +779,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, return CURLE_BAD_FUNCTION_ARGUMENT; } - infof(data, "Connect socket %d over QUIC to %s:%d\n", + infof(data, "Connect socket %d over QUIC to %s:%d", sockfd, ipbuf, port); qs->version = NGTCP2_PROTO_VER_MAX; @@ -827,15 +828,14 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, } /* - * Store ngtp2 version info in this buffer, Prefix with a space. Return total - * length written. + * Store ngtcp2 version info in this buffer. */ -int Curl_quic_ver(char *p, size_t len) +void Curl_quic_ver(char *p, size_t len) { const ngtcp2_info *ng2 = ngtcp2_version(0); nghttp3_info *ht3 = nghttp3_version(0); - return msnprintf(p, len, "ngtcp2/%s nghttp3/%s", - ng2->version_str, ht3->version_str); + (void)msnprintf(p, len, "ngtcp2/%s nghttp3/%s", + ng2->version_str, ht3->version_str); } static int ng_getsock(struct Curl_easy *data, struct connectdata *conn, @@ -951,7 +951,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id, (void)stream_id; (void)app_error_code; (void)user_data; - H3BUGF(infof(data, "cb_h3_stream_close CALLED\n")); + H3BUGF(infof(data, "cb_h3_stream_close CALLED")); stream->closed = TRUE; Curl_expire(data, 0, EXPIRE_QUIC); @@ -1287,7 +1287,7 @@ static ssize_t ngh3_stream_recv(struct Curl_easy *data, return 0; } - infof(data, "ngh3_stream_recv returns 0 bytes and EAGAIN\n"); + infof(data, "ngh3_stream_recv returns 0 bytes and EAGAIN"); *curlcode = CURLE_AGAIN; return -1; } @@ -1304,7 +1304,7 @@ static int cb_h3_acked_stream_data(nghttp3_conn *conn, int64_t stream_id, if(!data->set.postfields) { stream->h3out->used -= datalen; H3BUGF(infof(data, - "cb_h3_acked_stream_data, %zd bytes, %zd left unacked\n", + "cb_h3_acked_stream_data, %zd bytes, %zd left unacked", datalen, stream->h3out->used)); DEBUGASSERT(stream->h3out->used < H3_SEND_SIZE); @@ -1366,13 +1366,13 @@ static ssize_t cb_h3_readfunction(nghttp3_conn *conn, int64_t stream_id, if(!stream->upload_left) *pflags = NGHTTP3_DATA_FLAG_EOF; } - H3BUGF(infof(data, "cb_h3_readfunction %zd bytes%s (at %zd unacked)\n", + H3BUGF(infof(data, "cb_h3_readfunction %zd bytes%s (at %zd unacked)", nread, *pflags == NGHTTP3_DATA_FLAG_EOF?" EOF":"", out->used)); } if(stream->upload_done && !stream->upload_len && (stream->upload_left <= 0)) { - H3BUGF(infof(data, "!!!!!!!!! cb_h3_readfunction sets EOF\n")); + H3BUGF(infof(data, "!!!!!!!!! cb_h3_readfunction sets EOF")); *pflags = NGHTTP3_DATA_FLAG_EOF; return nread ? 1 : 0; } @@ -1565,7 +1565,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, if(acc > MAX_ACC) { infof(data, "http_request: Warning: The cumulative length of all " "headers exceeds %d bytes and that could cause the " - "stream to be rejected.\n", MAX_ACC); + "stream to be rejected.", MAX_ACC); } } @@ -1611,7 +1611,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, Curl_safefree(nva); - infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)\n", + infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)", stream3_id, (void *)data); return CURLE_OK; @@ -1641,7 +1641,7 @@ static ssize_t ngh3_stream_send(struct Curl_easy *data, sent = len; } else { - H3BUGF(infof(data, "ngh3_stream_send() wants to send %zd bytes\n", + H3BUGF(infof(data, "ngh3_stream_send() wants to send %zd bytes", len)); if(!stream->upload_len) { stream->upload_mem = mem; diff --git a/contrib/libs/curl/lib/vquic/quiche.c b/contrib/libs/curl/lib/vquic/quiche.c index fdef85687f..1762c77b13 100644 --- a/contrib/libs/curl/lib/vquic/quiche.c +++ b/contrib/libs/curl/lib/vquic/quiche.c @@ -258,7 +258,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, return CURLE_BAD_FUNCTION_ARGUMENT; } - infof(data, "Connect socket %d over QUIC to %s:%ld\n", + infof(data, "Connect socket %d over QUIC to %s:%ld", sockfd, ipbuf, port); Curl_persistconninfo(data, conn, NULL, -1); @@ -277,7 +277,7 @@ CURLcode Curl_quic_connect(struct Curl_easy *data, offset += 1 + alpn_len; } - infof(data, "Sent QUIC client Initial, ALPN: %s\n", + infof(data, "Sent QUIC client Initial, ALPN: %s", alpn_protocols + 1); } @@ -345,7 +345,7 @@ CURLcode Curl_quic_is_connected(struct Curl_easy *data, if(quiche_conn_is_established(qs->conn)) { *done = TRUE; result = quiche_has_connected(conn, 0, sockindex); - DEBUGF(infof(data, "quiche established connection!\n")); + DEBUGF(infof(data, "quiche established connection!")); } return result; @@ -422,10 +422,9 @@ static CURLcode flush_egress(struct Curl_easy *data, int sockfd, return CURLE_SEND_ERROR; } - sent = sendto(sockfd, out, sent, 0, - (struct sockaddr *)&send_info.to, send_info.to_len); + sent = send(sockfd, out, sent, 0); if(sent < 0) { - failf(data, "sendto() returned %zd", sent); + failf(data, "send() returned %zd", sent); return CURLE_SEND_ERROR; } } while(1); @@ -492,7 +491,7 @@ static ssize_t h3_stream_recv(struct Curl_easy *data, headers.nlen = 0; if(process_ingress(data, sockfd, qs)) { - infof(data, "h3_stream_recv returns on ingress\n"); + infof(data, "h3_stream_recv returns on ingress"); *curlcode = CURLE_RECV_ERROR; return -1; } @@ -505,7 +504,7 @@ static ssize_t h3_stream_recv(struct Curl_easy *data, if(s != stream->stream3_id) { /* another transfer, ignore for now */ - infof(data, "Got h3 for stream %u, expects %u\n", + infof(data, "Got h3 for stream %u, expects %u", s, stream->stream3_id); continue; } @@ -586,7 +585,7 @@ static ssize_t h3_stream_send(struct Curl_easy *data, sent = len; } else { - H3BUGF(infof(data, "Pass on %zd body bytes to quiche\n", len)); + H3BUGF(infof(data, "Pass on %zd body bytes to quiche", len)); sent = quiche_h3_send_body(qs->h3c, qs->conn, stream->stream3_id, (uint8_t *)mem, len, FALSE); if(sent < 0) { @@ -605,12 +604,11 @@ static ssize_t h3_stream_send(struct Curl_easy *data, } /* - * Store quiche version info in this buffer, Prefix with a space. Return total - * length written. + * Store quiche version info in this buffer. */ -int Curl_quic_ver(char *p, size_t len) +void Curl_quic_ver(char *p, size_t len) { - return msnprintf(p, len, "quiche/%s", quiche_version()); + (void)msnprintf(p, len, "quiche/%s", quiche_version()); } /* Index where :authority header field will appear in request header @@ -780,7 +778,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, for(i = 0; i < nheader; ++i) { acc += nva[i].name_len + nva[i].value_len; - H3BUGF(infof(data, "h3 [%.*s: %.*s]\n", + H3BUGF(infof(data, "h3 [%.*s: %.*s]", nva[i].name_len, nva[i].name, nva[i].value_len, nva[i].value)); } @@ -788,7 +786,7 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, if(acc > MAX_ACC) { infof(data, "http_request: Warning: The cumulative length of all " "headers exceeds %d bytes and that could cause the " - "stream to be rejected.\n", MAX_ACC); + "stream to be rejected.", MAX_ACC); } } @@ -825,13 +823,13 @@ static CURLcode http_request(struct Curl_easy *data, const void *mem, Curl_safefree(nva); if(stream3_id < 0) { - H3BUGF(infof(data, "quiche_h3_send_request returned %d\n", + H3BUGF(infof(data, "quiche_h3_send_request returned %d", stream3_id)); result = CURLE_SEND_ERROR; goto fail; } - infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)\n", + infof(data, "Using HTTP/3 Stream ID: %x (easy handle %p)", stream3_id, (void *)data); stream->stream3_id = stream3_id; diff --git a/contrib/libs/curl/lib/vssh/libssh.c b/contrib/libs/curl/lib/vssh/libssh.c index 843bc504b5..5ec2442a38 100644 --- a/contrib/libs/curl/lib/vssh/libssh.c +++ b/contrib/libs/curl/lib/vssh/libssh.c @@ -303,7 +303,7 @@ static void mystate(struct Curl_easy *data, sshstate nowstate if(sshc->state != nowstate) { - infof(data, "SSH %p state change from %s to %s (line %d)\n", + infof(data, "SSH %p state change from %s to %s (line %d)", (void *) sshc, names[sshc->state], names[nowstate], lineno); } @@ -368,7 +368,7 @@ static int myssh_is_known(struct Curl_easy *data) for(i = 0; i < 16; i++) msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char)hash[i]); - infof(data, "SSH MD5 fingerprint: %s\n", md5buffer); + infof(data, "SSH MD5 fingerprint: %s", md5buffer); if(!strcasecompare(md5buffer, pubkey_md5)) { failf(data, @@ -732,7 +732,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == SSH_AUTH_SUCCESS) { sshc->authed = TRUE; - infof(data, "Authenticated with none\n"); + infof(data, "Authenticated with none"); state(data, SSH_AUTH_DONE); break; } @@ -744,7 +744,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL); if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) { state(data, SSH_AUTH_PKEY_INIT); - infof(data, "Authentication using SSH public key file\n"); + infof(data, "Authentication using SSH public key file"); } else if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { state(data, SSH_AUTH_GSSAPI); @@ -810,7 +810,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == SSH_AUTH_SUCCESS) { rc = SSH_OK; sshc->authed = TRUE; - infof(data, "Completed public key authentication\n"); + infof(data, "Completed public key authentication"); state(data, SSH_AUTH_DONE); break; } @@ -827,12 +827,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == SSH_AUTH_SUCCESS) { sshc->authed = TRUE; - infof(data, "Completed public key authentication\n"); + infof(data, "Completed public key authentication"); state(data, SSH_AUTH_DONE); break; } else { - infof(data, "Failed public key authentication (rc: %d)\n", rc); + infof(data, "Failed public key authentication (rc: %d)", rc); MOVE_TO_SECONDARY_AUTH; } break; @@ -852,7 +852,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == SSH_AUTH_SUCCESS) { rc = SSH_OK; sshc->authed = TRUE; - infof(data, "Completed gssapi authentication\n"); + infof(data, "Completed gssapi authentication"); state(data, SSH_AUTH_DONE); break; } @@ -878,7 +878,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } if(rc == SSH_OK) { sshc->authed = TRUE; - infof(data, "completed keyboard interactive authentication\n"); + infof(data, "completed keyboard interactive authentication"); } state(data, SSH_AUTH_DONE); break; @@ -901,7 +901,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == SSH_AUTH_SUCCESS) { sshc->authed = TRUE; - infof(data, "Completed password authentication\n"); + infof(data, "Completed password authentication"); state(data, SSH_AUTH_DONE); } else { @@ -919,7 +919,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) /* * At this point we have an authenticated ssh session. */ - infof(data, "Authentication complete\n"); + infof(data, "Authentication complete"); Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ @@ -930,7 +930,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_SFTP_INIT); break; } - infof(data, "SSH CONNECT phase done\n"); + infof(data, "SSH CONNECT phase done"); state(data, SSH_STOP); break; @@ -970,7 +970,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) we get the homedir here, we get the "workingpath" in the DO action since the homedir will remain the same between request but the working path will not. */ - DEBUGF(infof(data, "SSH CONNECT phase done\n")); + DEBUGF(infof(data, "SSH CONNECT phase done")); state(data, SSH_STOP); break; @@ -983,7 +983,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } if(data->set.quote) { - infof(data, "Sending quote commands\n"); + infof(data, "Sending quote commands"); sshc->quote_item = data->set.quote; state(data, SSH_SFTP_QUOTE); } @@ -994,7 +994,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_POSTQUOTE_INIT: if(data->set.postquote) { - infof(data, "Sending quote commands\n"); + infof(data, "Sending quote commands"); sshc->quote_item = data->set.postquote; state(data, SSH_SFTP_QUOTE); } @@ -1367,7 +1367,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(sshc->slash_pos) { *sshc->slash_pos = 0; - infof(data, "Creating directory '%s'\n", protop->path); + infof(data, "Creating directory '%s'", protop->path); state(data, SSH_SFTP_CREATE_DIRS_MKDIR); break; } @@ -1731,7 +1731,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) if(data->req.size == 0) { /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); - infof(data, "File already completely downloaded\n"); + infof(data, "File already completely downloaded"); state(data, SSH_STOP); break; } @@ -1764,7 +1764,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) } Curl_safefree(protop->path); - DEBUGF(infof(data, "SFTP DONE done\n")); + DEBUGF(infof(data, "SFTP DONE done")); /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT After nextstate is executed, the control should come back to @@ -1933,7 +1933,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) break; } if(rc != SSH_OK) { - infof(data, "Failed to close libssh scp channel: %s\n", + infof(data, "Failed to close libssh scp channel: %s", ssh_get_error(sshc->ssh_session)); } } @@ -1946,7 +1946,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) ssh_scp_free(sshc->scp_session); sshc->scp_session = NULL; } - DEBUGF(infof(data, "SCP DONE phase complete\n")); + DEBUGF(infof(data, "SCP DONE phase complete")); ssh_set_blocking(sshc->ssh_session, 0); @@ -2213,7 +2213,7 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done) } if(conn->user && conn->user[0] != '\0') { - infof(data, "User: %s\n", conn->user); + infof(data, "User: %s", conn->user); rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_USER, conn->user); if(rc != SSH_OK) { failf(data, "Could not set user"); @@ -2222,7 +2222,7 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done) } if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - infof(data, "Known hosts: %s\n", data->set.str[STRING_SSH_KNOWNHOSTS]); + infof(data, "Known hosts: %s", data->set.str[STRING_SSH_KNOWNHOSTS]); rc = ssh_options_set(ssh->ssh_session, SSH_OPTIONS_KNOWNHOSTS, data->set.str[STRING_SSH_KNOWNHOSTS]); if(rc != SSH_OK) { @@ -2279,7 +2279,7 @@ static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done) result = myssh_multi_statemach(data, dophase_done); if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; } @@ -2300,7 +2300,7 @@ CURLcode scp_perform(struct Curl_easy *data, CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); *dophase_done = FALSE; /* not done yet */ @@ -2312,7 +2312,7 @@ CURLcode scp_perform(struct Curl_easy *data, *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; @@ -2481,7 +2481,7 @@ CURLcode sftp_perform(struct Curl_easy *data, CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); *dophase_done = FALSE; /* not done yet */ @@ -2494,7 +2494,7 @@ CURLcode sftp_perform(struct Curl_easy *data, *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; @@ -2506,7 +2506,7 @@ static CURLcode sftp_doing(struct Curl_easy *data, { CURLcode result = myssh_multi_statemach(data, dophase_done); if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; } @@ -2521,7 +2521,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, CURLcode result = CURLE_OK; (void) dead_connection; - DEBUGF(infof(data, "SSH DISCONNECT starts now\n")); + DEBUGF(infof(data, "SSH DISCONNECT starts now")); if(conn->proto.sshc.ssh_session) { /* only if there's a session still around to use! */ @@ -2529,7 +2529,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, result = myssh_block_statemach(data, TRUE); } - DEBUGF(infof(data, "SSH DISCONNECT is done\n")); + DEBUGF(infof(data, "SSH DISCONNECT is done")); return result; @@ -2940,9 +2940,9 @@ void Curl_ssh_cleanup(void) (void)ssh_finalize(); } -size_t Curl_ssh_version(char *buffer, size_t buflen) +void Curl_ssh_version(char *buffer, size_t buflen) { - return msnprintf(buffer, buflen, "libssh/%s", CURL_LIBSSH_VERSION); + (void)msnprintf(buffer, buflen, "libssh/%s", CURL_LIBSSH_VERSION); } #endif /* USE_LIBSSH */ diff --git a/contrib/libs/curl/lib/vssh/libssh2.c b/contrib/libs/curl/lib/vssh/libssh2.c index d2117edf1b..bfb498cf42 100644 --- a/contrib/libs/curl/lib/vssh/libssh2.c +++ b/contrib/libs/curl/lib/vssh/libssh2.c @@ -378,7 +378,7 @@ static void state(struct Curl_easy *data, sshstate nowstate) DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST); if(sshc->state != nowstate) { - infof(data, "SFTP %p state change from %s to %s\n", + infof(data, "SFTP %p state change from %s to %s", (void *)sshc, names[sshc->state], names[nowstate]); } #endif @@ -491,7 +491,7 @@ static CURLcode ssh_knownhost(struct Curl_easy *data) break; #endif default: - infof(data, "unsupported key type, can't check knownhosts!\n"); + infof(data, "unsupported key type, can't check knownhosts!"); keybit = 0; break; } @@ -519,7 +519,7 @@ static CURLcode ssh_knownhost(struct Curl_easy *data) &host); #endif - infof(data, "SSH host check: %d, key: %s\n", keycheck, + infof(data, "SSH host check: %d, key: %s", keycheck, (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? host->key:"<none>"); @@ -586,7 +586,7 @@ static CURLcode ssh_knownhost(struct Curl_easy *data) LIBSSH2_KNOWNHOST_KEYENC_RAW| keybit, NULL); if(addrc) - infof(data, "Warning adding the known host %s failed!\n", + infof(data, "Warning adding the known host %s failed!", conn->host.name); else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE || rc == CURLKHSTAT_FINE_REPLACE) { @@ -597,7 +597,7 @@ static CURLcode ssh_knownhost(struct Curl_easy *data) data->set.str[STRING_SSH_KNOWNHOSTS], LIBSSH2_KNOWNHOST_FILE_OPENSSH); if(wrc) { - infof(data, "Warning, writing %s failed!\n", + infof(data, "Warning, writing %s failed!", data->set.str[STRING_SSH_KNOWNHOSTS]); } } @@ -626,7 +626,7 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data) int i; for(i = 0; i < 16; i++) msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]); - infof(data, "SSH MD5 fingerprint: %s\n", md5buffer); + infof(data, "SSH MD5 fingerprint: %s", md5buffer); } /* Before we authenticate we check the hostkey's MD5 fingerprint @@ -645,7 +645,7 @@ static CURLcode ssh_check_fingerprint(struct Curl_easy *data) sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; return sshc->actualcode; } - infof(data, "MD5 checksum match!\n"); + infof(data, "MD5 checksum match!"); /* as we already matched, we skip the check for known hosts */ return CURLE_OK; } @@ -702,7 +702,7 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data) if(store->name[0] == '[') { kh_name_end = strstr(store->name, "]:"); if(!kh_name_end) { - infof(data, "Invalid host pattern %s in %s\n", + infof(data, "Invalid host pattern %s in %s", store->name, data->set.str[STRING_SSH_KNOWNHOSTS]); continue; } @@ -729,7 +729,7 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data) } if(found) { - infof(data, "Found host %s in %s\n", + infof(data, "Found host %s in %s", conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]); switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) { @@ -768,13 +768,13 @@ static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data) return CURLE_SSH; } - infof(data, "Set \"%s\" as SSH hostkey type\n", hostkey_method); + infof(data, "Set \"%s\" as SSH hostkey type", hostkey_method); result = libssh2_session_error_to_CURLE( libssh2_session_method_pref( sshc->ssh_session, LIBSSH2_METHOD_HOSTKEY, hostkey_method)); } else { - infof(data, "Did not find host %s in %s\n", + infof(data, "Did not find host %s in %s", conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]); } } @@ -874,7 +874,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(!sshc->authlist) { if(libssh2_userauth_authenticated(sshc->ssh_session)) { sshc->authed = TRUE; - infof(data, "SSH user accepted with no authentication\n"); + infof(data, "SSH user accepted with no authentication"); state(data, SSH_AUTH_DONE); break; } @@ -887,7 +887,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) } break; } - infof(data, "SSH authentication methods available: %s\n", + infof(data, "SSH authentication methods available: %s", sshc->authlist); state(data, SSH_AUTH_PKEY_INIT); @@ -972,8 +972,8 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) sshc->passphrase = ""; if(sshc->rsa_pub) - infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub); - infof(data, "Using SSH private key file '%s'\n", sshc->rsa); + infof(data, "Using SSH public key file '%s'", sshc->rsa_pub); + infof(data, "Using SSH private key file '%s'", sshc->rsa); state(data, SSH_AUTH_PKEY); } @@ -1000,14 +1000,14 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == 0) { sshc->authed = TRUE; - infof(data, "Initialized SSH public key authentication\n"); + infof(data, "Initialized SSH public key authentication"); state(data, SSH_AUTH_DONE); } else { char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "SSH public key authentication failed: %s\n", err_msg); + infof(data, "SSH public key authentication failed: %s", err_msg); state(data, SSH_AUTH_PASS_INIT); rc = 0; /* clear rc and continue */ } @@ -1035,7 +1035,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) } if(rc == 0) { sshc->authed = TRUE; - infof(data, "Initialized password authentication\n"); + infof(data, "Initialized password authentication"); state(data, SSH_AUTH_DONE); } else { @@ -1069,7 +1069,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(!sshc->ssh_agent) { sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session); if(!sshc->ssh_agent) { - infof(data, "Could not create agent object\n"); + infof(data, "Could not create agent object"); state(data, SSH_AUTH_KEY_INIT); break; @@ -1080,7 +1080,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) break; if(rc < 0) { - infof(data, "Failure connecting to agent\n"); + infof(data, "Failure connecting to agent"); state(data, SSH_AUTH_KEY_INIT); rc = 0; /* clear rc and continue */ } @@ -1100,7 +1100,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(rc == LIBSSH2_ERROR_EAGAIN) break; if(rc < 0) { - infof(data, "Failure requesting identities to agent\n"); + infof(data, "Failure requesting identities to agent"); state(data, SSH_AUTH_KEY_INIT); rc = 0; /* clear rc and continue */ } @@ -1136,13 +1136,13 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) } if(rc < 0) - infof(data, "Failure requesting identities to agent\n"); + infof(data, "Failure requesting identities to agent"); else if(rc == 1) - infof(data, "No identity would match\n"); + infof(data, "No identity would match"); if(rc == LIBSSH2_ERROR_NONE) { sshc->authed = TRUE; - infof(data, "Agent based authentication successful\n"); + infof(data, "Agent based authentication successful"); state(data, SSH_AUTH_DONE); } else { @@ -1174,7 +1174,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) } if(rc == 0) { sshc->authed = TRUE; - infof(data, "Initialized keyboard interactive authentication\n"); + infof(data, "Initialized keyboard interactive authentication"); } state(data, SSH_AUTH_DONE); break; @@ -1190,7 +1190,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) /* * At this point we have an authenticated ssh session. */ - infof(data, "Authentication complete\n"); + infof(data, "Authentication complete"); Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ @@ -1201,7 +1201,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_SFTP_INIT); break; } - infof(data, "SSH CONNECT phase done\n"); + infof(data, "SSH CONNECT phase done"); state(data, SSH_STOP); break; @@ -1261,7 +1261,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) a time-out or similar */ result = CURLE_SSH; sshc->actualcode = result; - DEBUGF(infof(data, "error = %lu makes libcurl = %d\n", + DEBUGF(infof(data, "error = %lu makes libcurl = %d", sftperr, (int)result)); state(data, SSH_STOP); break; @@ -1271,7 +1271,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) we get the homedir here, we get the "workingpath" in the DO action since the homedir will remain the same between request but the working path will not. */ - DEBUGF(infof(data, "SSH CONNECT phase done\n")); + DEBUGF(infof(data, "SSH CONNECT phase done")); state(data, SSH_STOP); break; @@ -1285,7 +1285,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) } if(data->set.quote) { - infof(data, "Sending quote commands\n"); + infof(data, "Sending quote commands"); sshc->quote_item = data->set.quote; state(data, SSH_SFTP_QUOTE); } @@ -1296,7 +1296,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) case SSH_SFTP_POSTQUOTE_INIT: if(data->set.postquote) { - infof(data, "Sending quote commands\n"); + infof(data, "Sending quote commands"); sshc->quote_item = data->set.postquote; state(data, SSH_SFTP_QUOTE); } @@ -2048,7 +2048,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(sshc->slash_pos) { *sshc->slash_pos = 0; - infof(data, "Creating directory '%s'\n", sshp->path); + infof(data, "Creating directory '%s'", sshp->path); state(data, SSH_SFTP_CREATE_DIRS_MKDIR); break; } @@ -2411,7 +2411,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) if(data->req.size == 0) { /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); - infof(data, "File already completely downloaded\n"); + infof(data, "File already completely downloaded"); state(data, SSH_STOP); break; } @@ -2446,14 +2446,14 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); + infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg); } sshc->sftp_handle = NULL; } Curl_safefree(sshp->path); - DEBUGF(infof(data, "SFTP DONE done\n")); + DEBUGF(infof(data, "SFTP DONE done")); /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT After nextstate is executed, the control should come back to @@ -2483,7 +2483,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to close libssh2 file: %d %s\n", rc, err_msg); + infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg); } sshc->sftp_handle = NULL; } @@ -2493,7 +2493,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) break; } if(rc < 0) { - infof(data, "Failed to stop libssh2 sftp subsystem\n"); + infof(data, "Failed to stop libssh2 sftp subsystem"); } sshc->sftp_session = NULL; } @@ -2668,7 +2668,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to send libssh2 channel EOF: %d %s\n", + infof(data, "Failed to send libssh2 channel EOF: %d %s", rc, err_msg); } } @@ -2685,7 +2685,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg); + infof(data, "Failed to get channel EOF: %d %s", rc, err_msg); } } state(data, SSH_SCP_WAIT_CLOSE); @@ -2701,7 +2701,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Channel failed to close: %d %s\n", rc, err_msg); + infof(data, "Channel failed to close: %d %s", rc, err_msg); } } state(data, SSH_SCP_CHANNEL_FREE); @@ -2717,12 +2717,12 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", + infof(data, "Failed to free libssh2 scp subsystem: %d %s", rc, err_msg); } sshc->ssh_channel = NULL; } - DEBUGF(infof(data, "SCP DONE phase complete\n")); + DEBUGF(infof(data, "SCP DONE phase complete")); #if 0 /* PREV */ state(data, SSH_SESSION_DISCONNECT); #endif @@ -2743,7 +2743,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 scp subsystem: %d %s\n", + infof(data, "Failed to free libssh2 scp subsystem: %d %s", rc, err_msg); } sshc->ssh_channel = NULL; @@ -2758,7 +2758,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to disconnect libssh2 session: %d %s\n", + infof(data, "Failed to disconnect libssh2 session: %d %s", rc, err_msg); } } @@ -2787,7 +2787,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to disconnect from libssh2 agent: %d %s\n", + infof(data, "Failed to disconnect from libssh2 agent: %d %s", rc, err_msg); } libssh2_agent_free(sshc->ssh_agent); @@ -2809,7 +2809,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); - infof(data, "Failed to free libssh2 session: %d %s\n", rc, err_msg); + infof(data, "Failed to free libssh2 session: %d %s", rc, err_msg); } sshc->ssh_session = NULL; } @@ -2938,6 +2938,7 @@ static CURLcode ssh_block_statemach(struct Curl_easy *data, { struct ssh_conn *sshc = &conn->proto.sshc; CURLcode result = CURLE_OK; + struct curltime dis = Curl_now(); while((sshc->state != SSH_STOP) && !result) { bool block; @@ -2962,6 +2963,12 @@ static CURLcode ssh_block_statemach(struct Curl_easy *data, return CURLE_OPERATION_TIMEDOUT; } } + else if(Curl_timediff(now, dis) > 1000) { + /* disconnect timeout */ + failf(data, "Disconnect timed out"); + result = CURLE_OK; + break; + } if(block) { int dir = libssh2_session_block_directions(sshc->ssh_session); @@ -3078,10 +3085,10 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) #ifdef CURL_LIBSSH2_DEBUG if(conn->user) { - infof(data, "User: %s\n", conn->user); + infof(data, "User: %s", conn->user); } if(conn->passwd) { - infof(data, "Password: %s\n", conn->passwd); + infof(data, "Password: %s", conn->passwd); } sock = conn->sock[FIRSTSOCKET]; #endif /* CURL_LIBSSH2_DEBUG */ @@ -3115,7 +3122,7 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) sshrecv.recvptr = ssh_tls_recv; sshsend.sendptr = ssh_tls_send; - infof(data, "Uses HTTPS proxy!\n"); + infof(data, "Uses HTTPS proxy!"); /* Setup libssh2 callbacks to make it read/write TLS from the socket. @@ -3153,7 +3160,7 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) #if LIBSSH2_VERSION_NUM >= 0x010208 if(libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) #endif - infof(data, "Failed to enable compression for ssh session\n"); + infof(data, "Failed to enable compression for ssh session"); } #ifdef HAVE_LIBSSH2_KNOWNHOST_API @@ -3171,14 +3178,14 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done) data->set.str[STRING_SSH_KNOWNHOSTS], LIBSSH2_KNOWNHOST_FILE_OPENSSH); if(rc < 0) - infof(data, "Failed to read known hosts from %s\n", + infof(data, "Failed to read known hosts from %s", data->set.str[STRING_SSH_KNOWNHOSTS]); } #endif /* HAVE_LIBSSH2_KNOWNHOST_API */ #ifdef CURL_LIBSSH2_DEBUG libssh2_trace(sshc->ssh_session, ~0); - infof(data, "SSH socket: %d\n", (int)sock); + infof(data, "SSH socket: %d", (int)sock); #endif /* CURL_LIBSSH2_DEBUG */ state(data, SSH_INIT); @@ -3205,7 +3212,7 @@ CURLcode scp_perform(struct Curl_easy *data, CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); *dophase_done = FALSE; /* not done yet */ @@ -3218,7 +3225,7 @@ CURLcode scp_perform(struct Curl_easy *data, *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; @@ -3232,7 +3239,7 @@ static CURLcode scp_doing(struct Curl_easy *data, result = ssh_multi_statemach(data, dophase_done); if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; } @@ -3394,7 +3401,7 @@ CURLcode sftp_perform(struct Curl_easy *data, { CURLcode result = CURLE_OK; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); *dophase_done = FALSE; /* not done yet */ @@ -3407,7 +3414,7 @@ CURLcode sftp_perform(struct Curl_easy *data, *connected = data->conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; @@ -3420,7 +3427,7 @@ static CURLcode sftp_doing(struct Curl_easy *data, CURLcode result = ssh_multi_statemach(data, dophase_done); if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; } @@ -3435,7 +3442,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, struct ssh_conn *sshc = &conn->proto.sshc; (void) dead_connection; - DEBUGF(infof(data, "SSH DISCONNECT starts now\n")); + DEBUGF(infof(data, "SSH DISCONNECT starts now")); if(sshc->ssh_session) { /* only if there's a session still around to use! */ @@ -3443,7 +3450,7 @@ static CURLcode sftp_disconnect(struct Curl_easy *data, result = ssh_block_statemach(data, conn, TRUE); } - DEBUGF(infof(data, "SSH DISCONNECT is done\n")); + DEBUGF(infof(data, "SSH DISCONNECT is done")); return result; @@ -3602,9 +3609,9 @@ void Curl_ssh_cleanup(void) #endif } -size_t Curl_ssh_version(char *buffer, size_t buflen) +void Curl_ssh_version(char *buffer, size_t buflen) { - return msnprintf(buffer, buflen, "libssh2/%s", LIBSSH2_VERSION); + (void)msnprintf(buffer, buflen, "libssh2/%s", LIBSSH2_VERSION); } /* The SSH session is associated with the *CONNECTION* but the callback user diff --git a/contrib/libs/curl/lib/vssh/ssh.h b/contrib/libs/curl/lib/vssh/ssh.h index b3eb08cc11..7f50e76b04 100644 --- a/contrib/libs/curl/lib/vssh/ssh.h +++ b/contrib/libs/curl/lib/vssh/ssh.h @@ -262,7 +262,7 @@ extern const struct Curl_handler Curl_handler_sftp; /* generic SSH backend functions */ CURLcode Curl_ssh_init(void); void Curl_ssh_cleanup(void); -size_t Curl_ssh_version(char *buffer, size_t buflen); +void Curl_ssh_version(char *buffer, size_t buflen); void Curl_ssh_attach(struct Curl_easy *data, struct connectdata *conn); #else diff --git a/contrib/libs/curl/lib/vssh/wolfssh.c b/contrib/libs/curl/lib/vssh/wolfssh.c index b0d54f0c40..c5a90487c5 100644 --- a/contrib/libs/curl/lib/vssh/wolfssh.c +++ b/contrib/libs/curl/lib/vssh/wolfssh.c @@ -205,7 +205,7 @@ static void state(struct Curl_easy *data, sshstate nowstate) DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST); if(sshc->state != nowstate) { - infof(data, "wolfssh %p state change from %s to %s\n", + infof(data, "wolfssh %p state change from %s to %s", (void *)sshc, names[sshc->state], names[nowstate]); } #endif @@ -274,7 +274,7 @@ static ssize_t wsftp_send(struct Curl_easy *data, int sockindex, return -1; } DEBUGASSERT(rc == (int)len); - infof(data, "sent %zd bytes SFTP from offset %zd\n", + infof(data, "sent %zd bytes SFTP from offset %zd", len, sshc->offset); sshc->offset += len; return (ssize_t)rc; @@ -348,7 +348,7 @@ static int userauth(byte authtype, void *ctx) { struct Curl_easy *data = ctx; - DEBUGF(infof(data, "wolfssh callback: type %s\n", + DEBUGF(infof(data, "wolfssh callback: type %s", authtype == WOLFSSH_USERAUTH_PASSWORD ? "PASSWORD" : "PUBLICCKEY")); if(authtype == WOLFSSH_USERAUTH_PASSWORD) { @@ -468,7 +468,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) state(data, SSH_STOP); return CURLE_SSH; } - infof(data, "wolfssh connected!\n"); + infof(data, "wolfssh connected!"); state(data, SSH_STOP); break; case SSH_STOP: @@ -489,7 +489,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) return CURLE_OK; } else if(rc == WS_SUCCESS) { - infof(data, "wolfssh SFTP connected!\n"); + infof(data, "wolfssh SFTP connected!"); state(data, SSH_SFTP_REALPATH); } else { @@ -518,7 +518,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) else { memcpy(sshc->homedir, name->fName, name->fSz); sshc->homedir[name->fSz] = 0; - infof(data, "wolfssh SFTP realpath succeeded!\n"); + infof(data, "wolfssh SFTP realpath succeeded!"); } wolfSSH_SFTPNAME_list_free(name); state(data, SSH_STOP); @@ -536,7 +536,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) } if(data->set.quote) { - infof(data, "Sending quote commands\n"); + infof(data, "Sending quote commands"); sshc->quote_item = data->set.quote; state(data, SSH_SFTP_QUOTE); } @@ -616,7 +616,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) return CURLE_OK; } else if(rc == WS_SUCCESS) { - infof(data, "wolfssh SFTP open succeeded!\n"); + infof(data, "wolfssh SFTP open succeeded!"); } else { failf(data, "wolfssh SFTP upload open failed: %d", rc); @@ -727,7 +727,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) return CURLE_OK; } else if(rc == WS_SUCCESS) { - infof(data, "wolfssh SFTP open succeeded!\n"); + infof(data, "wolfssh SFTP open succeeded!"); state(data, SSH_SFTP_DOWNLOAD_STAT); return CURLE_OK; } @@ -753,7 +753,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) return CURLE_OK; } else if(rc == WS_SUCCESS) { - infof(data, "wolfssh STAT succeeded!\n"); + infof(data, "wolfssh STAT succeeded!"); } else { failf(data, "wolfssh SFTP open failed: %d", rc); @@ -769,12 +769,12 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) data->req.maxdownload = size; Curl_pgrsSetDownloadSize(data, size); - infof(data, "SFTP download %" CURL_FORMAT_CURL_OFF_T " bytes\n", size); + infof(data, "SFTP download %" CURL_FORMAT_CURL_OFF_T " bytes", size); /* We cannot seek with wolfSSH so resuming and range requests are not possible */ if(data->state.use_range || data->state.resume_from) { - infof(data, "wolfSSH cannot do range/seek on SFTP\n"); + infof(data, "wolfSSH cannot do range/seek on SFTP"); return CURLE_BAD_DOWNLOAD_RESUME; } @@ -782,7 +782,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) if(data->req.size == 0) { /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); - infof(data, "File already completely downloaded\n"); + infof(data, "File already completely downloaded"); state(data, SSH_STOP); break; } @@ -911,7 +911,7 @@ static CURLcode wssh_multi_statemach(struct Curl_easy *data, bool *done) /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then try again */ if(*done) { - DEBUGF(infof(data, "wssh_statemach_act says DONE\n")); + DEBUGF(infof(data, "wssh_statemach_act says DONE")); } } while(!result && !*done && !block); @@ -937,7 +937,7 @@ CURLcode wsftp_perform(struct Curl_easy *data, CURLcode result = CURLE_OK; struct connectdata *conn = data->conn; - DEBUGF(infof(data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts")); *dophase_done = FALSE; /* not done yet */ @@ -950,7 +950,7 @@ CURLcode wsftp_perform(struct Curl_easy *data, *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; @@ -1107,7 +1107,7 @@ static CURLcode wsftp_doing(struct Curl_easy *data, CURLcode result = wssh_multi_statemach(data, dophase_done); if(*dophase_done) { - DEBUGF(infof(data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete")); } return result; } @@ -1119,7 +1119,7 @@ static CURLcode wsftp_disconnect(struct Curl_easy *data, CURLcode result = CURLE_OK; (void)dead; - DEBUGF(infof(data, "SSH DISCONNECT starts now\n")); + DEBUGF(infof(data, "SSH DISCONNECT starts now")); if(conn->proto.sshc.ssh_session) { /* only if there's a session still around to use! */ @@ -1127,7 +1127,7 @@ static CURLcode wsftp_disconnect(struct Curl_easy *data, result = wssh_block_statemach(data, TRUE); } - DEBUGF(infof(data, "SSH DISCONNECT is done\n")); + DEBUGF(infof(data, "SSH DISCONNECT is done")); return result; } @@ -1148,9 +1148,9 @@ static int wssh_getsock(struct Curl_easy *data, return bitmap; } -size_t Curl_ssh_version(char *buffer, size_t buflen) +void Curl_ssh_version(char *buffer, size_t buflen) { - return msnprintf(buffer, buflen, "wolfssh/%s", LIBWOLFSSH_VERSION_STRING); + (void)msnprintf(buffer, buflen, "wolfssh/%s", LIBWOLFSSH_VERSION_STRING); } CURLcode Curl_ssh_init(void) diff --git a/contrib/libs/curl/lib/vtls/bearssl.c b/contrib/libs/curl/lib/vtls/bearssl.c index 7f729713d8..cbbb3b5deb 100644 --- a/contrib/libs/curl/lib/vtls/bearssl.c +++ b/contrib/libs/curl/lib/vtls/bearssl.c @@ -300,7 +300,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile); - const char * const hostname = SSL_HOST_NAME(); + const char *hostname = SSL_HOST_NAME(); const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const bool verifyhost = SSL_CONN_CONFIG(verifyhost); CURLcode ret; @@ -349,7 +349,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, return ret; } infof(data, "error setting certificate verify locations," - " continuing anyway:\n"); + " continuing anyway:"); } } @@ -373,7 +373,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, if(!Curl_ssl_getsessionid(data, conn, SSL_IS_PROXY() ? TRUE : FALSE, &session, NULL, sockindex)) { br_ssl_engine_set_session_parameters(&backend->ctx.eng, session); - infof(data, "BearSSL: re-using session ID\n"); + infof(data, "BearSSL: re-using session ID"); } Curl_ssl_sessionid_unlock(data); } @@ -392,12 +392,12 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data, #endif ) { backend->protocols[cur++] = ALPN_H2; - infof(data, "ALPN, offering %s\n", ALPN_H2); + infof(data, "ALPN, offering %s", ALPN_H2); } #endif backend->protocols[cur++] = ALPN_HTTP_1_1; - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + infof(data, "ALPN, offering %s", ALPN_HTTP_1_1); br_ssl_engine_set_protocol_names(&backend->ctx.eng, backend->protocols, cur); @@ -538,7 +538,7 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data, protocol = br_ssl_engine_get_selected_protocol(&backend->ctx.eng); if(protocol) { - infof(data, "ALPN, server accepted to use %s\n", protocol); + infof(data, "ALPN, server accepted to use %s", protocol); #ifdef USE_HTTP2 if(!strcmp(protocol, ALPN_H2)) @@ -548,12 +548,12 @@ static CURLcode bearssl_connect_step3(struct Curl_easy *data, if(!strcmp(protocol, ALPN_HTTP_1_1)) conn->negnpn = CURL_HTTP_VERSION_1_1; else - infof(data, "ALPN, unrecognized protocol %s\n", protocol); + infof(data, "ALPN, unrecognized protocol %s", protocol); Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } else - infof(data, "ALPN, server did not agree to a protocol\n"); + infof(data, "ALPN, server did not agree to a protocol"); } if(SSL_SET_OPTION(primary.sessionid)) { @@ -840,30 +840,32 @@ static CURLcode bearssl_sha256sum(const unsigned char *input, } const struct Curl_ssl Curl_ssl_bearssl = { - { CURLSSLBACKEND_BEARSSL, "bearssl" }, + { CURLSSLBACKEND_BEARSSL, "bearssl" }, /* info */ 0, sizeof(struct ssl_backend_data), - Curl_none_init, - Curl_none_cleanup, - bearssl_version, - Curl_none_check_cxn, - Curl_none_shutdown, - bearssl_data_pending, - bearssl_random, - Curl_none_cert_status_request, - bearssl_connect, - bearssl_connect_nonblocking, - Curl_ssl_getsock, - bearssl_get_internals, - bearssl_close, - Curl_none_close_all, - bearssl_session_free, - Curl_none_set_engine, - Curl_none_set_engine_default, - Curl_none_engines_list, - Curl_none_false_start, - bearssl_sha256sum + Curl_none_init, /* init */ + Curl_none_cleanup, /* cleanup */ + bearssl_version, /* version */ + Curl_none_check_cxn, /* check_cxn */ + Curl_none_shutdown, /* shutdown */ + bearssl_data_pending, /* data_pending */ + bearssl_random, /* random */ + Curl_none_cert_status_request, /* cert_status_request */ + bearssl_connect, /* connect */ + bearssl_connect_nonblocking, /* connect_nonblocking */ + Curl_ssl_getsock, /* getsock */ + bearssl_get_internals, /* get_internals */ + bearssl_close, /* close_one */ + Curl_none_close_all, /* close_all */ + bearssl_session_free, /* session_free */ + Curl_none_set_engine, /* set_engine */ + Curl_none_set_engine_default, /* set_engine_default */ + Curl_none_engines_list, /* engines_list */ + Curl_none_false_start, /* false_start */ + bearssl_sha256sum, /* sha256sum */ + NULL, /* associate_connection */ + NULL /* disassociate_connection */ }; #endif /* USE_BEARSSL */ diff --git a/contrib/libs/curl/lib/vtls/gskit.c b/contrib/libs/curl/lib/vtls/gskit.c index ffe944fb8e..c337d6472f 100644 --- a/contrib/libs/curl/lib/vtls/gskit.c +++ b/contrib/libs/curl/lib/vtls/gskit.c @@ -1011,7 +1011,7 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data, CURLE_OK) { int i; - infof(data, "Server certificate:\n"); + infof(data, "Server certificate:"); p = cdev; for(i = 0; i++ < cdec; p++) switch(p->cert_data_id) { @@ -1020,16 +1020,16 @@ static CURLcode gskit_connect_step3(struct Curl_easy *data, certend = cert + cdev->cert_data_l; break; case CERT_DN_PRINTABLE: - infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p); + infof(data, "\t subject: %.*s", p->cert_data_l, p->cert_data_p); break; case CERT_ISSUER_DN_PRINTABLE: - infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p); + infof(data, "\t issuer: %.*s", p->cert_data_l, p->cert_data_p); break; case CERT_VALID_FROM: - infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p); + infof(data, "\t start date: %.*s", p->cert_data_l, p->cert_data_p); break; case CERT_VALID_TO: - infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p); + infof(data, "\t expire date: %.*s", p->cert_data_l, p->cert_data_p); break; } } @@ -1192,6 +1192,7 @@ static int gskit_shutdown(struct Curl_easy *data, int what; int rc; char buf[120]; + int loop = 10; /* don't get stuck */ if(!BACKEND->handle) return 0; @@ -1206,7 +1207,7 @@ static int gskit_shutdown(struct Curl_easy *data, what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT); - for(;;) { + while(loop--) { ssize_t nread; if(what < 0) { diff --git a/contrib/libs/curl/lib/vtls/gtls.c b/contrib/libs/curl/lib/vtls/gtls.c index fb2d522c5f..efba454591 100644 --- a/contrib/libs/curl/lib/vtls/gtls.c +++ b/contrib/libs/curl/lib/vtls/gtls.c @@ -147,7 +147,7 @@ static void showtime(struct Curl_easy *data, msnprintf(str, sizeof(str), - "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT", + " %s: %s, %02d %s %4d %02d:%02d:%02d GMT", text, Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], tm->tm_mday, @@ -156,7 +156,7 @@ static void showtime(struct Curl_easy *data, tm->tm_hour, tm->tm_min, tm->tm_sec); - infof(data, "%s\n", str); + infof(data, "%s", str); } #endif @@ -266,7 +266,7 @@ static CURLcode handshake(struct Curl_easy *data, if(!strerr) strerr = gnutls_strerror(rc); - infof(data, "gnutls_handshake() warning: %s\n", strerr); + infof(data, "gnutls_handshake() warning: %s", strerr); continue; } else if(rc < 0) { @@ -330,6 +330,9 @@ set_ssl_version_min_max(struct Curl_easy *data, ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2; } } + else if(ssl_version_max == CURL_SSLVERSION_MAX_DEFAULT) { + ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_3; + } switch(ssl_version | ssl_version_max) { case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0: @@ -338,11 +341,11 @@ set_ssl_version_min_max(struct Curl_easy *data, return CURLE_OK; case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.0:+VERS-TLS1.1"; + "+VERS-TLS1.1:+VERS-TLS1.0"; return CURLE_OK; case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2"; + "+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0"; return CURLE_OK; case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" @@ -350,7 +353,7 @@ set_ssl_version_min_max(struct Curl_easy *data, return CURLE_OK; case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.1:+VERS-TLS1.2"; + "+VERS-TLS1.2:+VERS-TLS1.1"; return CURLE_OK; case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" @@ -360,25 +363,16 @@ set_ssl_version_min_max(struct Curl_easy *data, *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" "+VERS-TLS1.3"; return CURLE_OK; - case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2" - ":+VERS-TLS1.3"; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT: - *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.1:+VERS-TLS1.2" - ":+VERS-TLS1.3"; + case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_3: + *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0"; return CURLE_OK; - case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT: + case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_3: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.2" - ":+VERS-TLS1.3"; + "+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1"; return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3 | CURL_SSLVERSION_MAX_DEFAULT: + case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_3: *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.2" - ":+VERS-TLS1.3"; + "+VERS-TLS1.3:+VERS-TLS1.2"; return CURLE_OK; } @@ -438,7 +432,7 @@ gtls_connect_step1(struct Curl_easy *data, #ifdef HAVE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { - infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username)); + infof(data, "Using TLS-SRP username: %s", SSL_SET_OPTION(username)); rc = gnutls_srp_allocate_client_credentials( &backend->srp_client_cred); @@ -468,7 +462,7 @@ gtls_connect_step1(struct Curl_easy *data, SSL_CONN_CONFIG(CAfile), GNUTLS_X509_FMT_PEM); if(rc < 0) { - infof(data, "error reading ca cert file %s (%s)\n", + infof(data, "error reading ca cert file %s (%s)", SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc)); if(SSL_CONN_CONFIG(verifypeer)) { *certverifyresult = rc; @@ -476,7 +470,7 @@ gtls_connect_step1(struct Curl_easy *data, } } else - infof(data, "found %d certificates in %s\n", rc, + infof(data, "found %d certificates in %s", rc, SSL_CONN_CONFIG(CAfile)); } @@ -486,7 +480,7 @@ gtls_connect_step1(struct Curl_easy *data, SSL_CONN_CONFIG(CApath), GNUTLS_X509_FMT_PEM); if(rc < 0) { - infof(data, "error reading ca cert file %s (%s)\n", + infof(data, "error reading ca cert file %s (%s)", SSL_CONN_CONFIG(CApath), gnutls_strerror(rc)); if(SSL_CONN_CONFIG(verifypeer)) { *certverifyresult = rc; @@ -494,7 +488,7 @@ gtls_connect_step1(struct Curl_easy *data, } } else - infof(data, "found %d certificates in %s\n", + infof(data, "found %d certificates in %s", rc, SSL_CONN_CONFIG(CApath)); } @@ -517,7 +511,7 @@ gtls_connect_step1(struct Curl_easy *data, return CURLE_SSL_CRL_BADFILE; } else - infof(data, "found %d CRL in %s\n", + infof(data, "found %d CRL in %s", rc, SSL_SET_OPTION(CRLfile)); } @@ -550,7 +544,7 @@ gtls_connect_step1(struct Curl_easy *data, (gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname, strlen(hostname)) < 0)) infof(data, "WARNING: failed to configure server name indication (SNI) " - "TLS extension\n"); + "TLS extension"); /* Use default priorities */ rc = gnutls_set_default_priority(session); @@ -603,11 +597,12 @@ gtls_connect_step1(struct Curl_easy *data, free(prioritysrp); if((rc == GNUTLS_E_INVALID_REQUEST) && err) { - infof(data, "This GnuTLS does not support SRP\n"); + infof(data, "This GnuTLS does not support SRP"); } } else { #endif + infof(data, "GnuTLS ciphers: %s", prioritylist); rc = gnutls_priority_set_direct(session, prioritylist, &err); #ifdef HAVE_GNUTLS_SRP } @@ -632,14 +627,14 @@ gtls_connect_step1(struct Curl_easy *data, protocols[cur].data = (unsigned char *)ALPN_H2; protocols[cur].size = ALPN_H2_LENGTH; cur++; - infof(data, "ALPN, offering %.*s\n", ALPN_H2_LENGTH, ALPN_H2); + infof(data, "ALPN, offering %.*s", ALPN_H2_LENGTH, ALPN_H2); } #endif protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1; protocols[cur].size = ALPN_HTTP_1_1_LENGTH; cur++; - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + infof(data, "ALPN, offering %s", ALPN_HTTP_1_1); gnutls_alpn_set_protocols(session, protocols, cur, 0); } @@ -745,7 +740,7 @@ gtls_connect_step1(struct Curl_easy *data, gnutls_session_set_data(session, ssl_sessionid, ssl_idsize); /* Informational message */ - infof(data, "SSL re-using session ID\n"); + infof(data, "SSL re-using session ID"); } Curl_ssl_sessionid_unlock(data); } @@ -848,7 +843,7 @@ gtls_connect_step3(struct Curl_easy *data, gnutls_cipher_get(session), gnutls_mac_get(session)); - infof(data, "SSL connection using %s / %s\n", + infof(data, "SSL connection using %s / %s", gnutls_protocol_get_name(version), ptr); /* This function will return the peer's raw certificate (chain) as sent by @@ -861,7 +856,7 @@ gtls_connect_step3(struct Curl_easy *data, if(!chainp) { if(SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost) || - SSL_SET_OPTION(issuercert)) { + SSL_CONN_CONFIG(issuercert)) { #ifdef HAVE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP && SSL_SET_OPTION(username) != NULL @@ -879,7 +874,7 @@ gtls_connect_step3(struct Curl_easy *data, } #endif } - infof(data, "\t common name: WARNING couldn't obtain\n"); + infof(data, " common name: WARNING couldn't obtain"); } if(data->set.ssl.certinfo && chainp) { @@ -926,13 +921,13 @@ gtls_connect_step3(struct Curl_easy *data, return CURLE_PEER_FAILED_VERIFICATION; } else - infof(data, "\t server certificate verification FAILED\n"); + infof(data, " server certificate verification FAILED"); } else - infof(data, "\t server certificate verification OK\n"); + infof(data, " server certificate verification OK"); } else - infof(data, "\t server certificate verification SKIPPED\n"); + infof(data, " server certificate verification SKIPPED"); if(SSL_CONN_CONFIG(verifystatus)) { if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) { @@ -944,7 +939,7 @@ gtls_connect_step3(struct Curl_easy *data, rc = gnutls_ocsp_status_request_get(session, &status_request); - infof(data, "\t server certificate status verification FAILED\n"); + infof(data, " server certificate status verification FAILED"); if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { failf(data, "No OCSP response received"); @@ -1032,10 +1027,10 @@ gtls_connect_step3(struct Curl_easy *data, return CURLE_SSL_INVALIDCERTSTATUS; } else - infof(data, "\t server certificate status verification OK\n"); + infof(data, " server certificate status verification OK"); } else - infof(data, "\t server certificate status verification SKIPPED\n"); + infof(data, " server certificate status verification SKIPPED"); /* initialize an X.509 certificate structure. */ gnutls_x509_crt_init(&x509_cert); @@ -1045,21 +1040,21 @@ gtls_connect_step3(struct Curl_easy *data, gnutls_x509_crt_t format */ gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); - if(SSL_SET_OPTION(issuercert)) { + if(SSL_CONN_CONFIG(issuercert)) { gnutls_x509_crt_init(&x509_issuer); - issuerp = load_file(SSL_SET_OPTION(issuercert)); + issuerp = load_file(SSL_CONN_CONFIG(issuercert)); gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); gnutls_x509_crt_deinit(x509_issuer); unload_file(issuerp); if(rc <= 0) { failf(data, "server certificate issuer check failed (IssuerCert: %s)", - SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); + SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); gnutls_x509_crt_deinit(x509_cert); return CURLE_SSL_ISSUER_ERROR; } - infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n", - SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none"); + infof(data, " server certificate issuer check OK (Issuer Cert: %s)", + SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none"); } size = sizeof(certname); @@ -1069,7 +1064,7 @@ gtls_connect_step3(struct Curl_easy *data, certname, &size); if(rc) { - infof(data, "error fetching CN from cert:%s\n", + infof(data, "error fetching CN from cert:%s", gnutls_strerror(rc)); } @@ -1129,11 +1124,11 @@ gtls_connect_step3(struct Curl_easy *data, return CURLE_PEER_FAILED_VERIFICATION; } else - infof(data, "\t common name: %s (does not match '%s')\n", + infof(data, " common name: %s (does not match '%s')", certname, SSL_HOST_DISPNAME()); } else - infof(data, "\t common name: %s (matched)\n", certname); + infof(data, " common name: %s (matched)", certname); /* Check for time-based validity */ certclock = gnutls_x509_crt_get_expiration_time(x509_cert); @@ -1146,7 +1141,7 @@ gtls_connect_step3(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } else - infof(data, "\t server certificate expiration date verify FAILED\n"); + infof(data, " server certificate expiration date verify FAILED"); } else { if(certclock < time(NULL)) { @@ -1157,10 +1152,10 @@ gtls_connect_step3(struct Curl_easy *data, return CURLE_PEER_FAILED_VERIFICATION; } else - infof(data, "\t server certificate expiration date FAILED\n"); + infof(data, " server certificate expiration date FAILED"); } else - infof(data, "\t server certificate expiration date OK\n"); + infof(data, " server certificate expiration date OK"); } certclock = gnutls_x509_crt_get_activation_time(x509_cert); @@ -1173,7 +1168,7 @@ gtls_connect_step3(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } else - infof(data, "\t server certificate activation date verify FAILED\n"); + infof(data, " server certificate activation date verify FAILED"); } else { if(certclock > time(NULL)) { @@ -1184,10 +1179,10 @@ gtls_connect_step3(struct Curl_easy *data, return CURLE_PEER_FAILED_VERIFICATION; } else - infof(data, "\t server certificate activation date FAILED\n"); + infof(data, " server certificate activation date FAILED"); } else - infof(data, "\t server certificate activation date OK\n"); + infof(data, " server certificate activation date OK"); } ptr = SSL_PINNED_PUB_KEY(); @@ -1213,19 +1208,19 @@ gtls_connect_step3(struct Curl_easy *data, #ifndef CURL_DISABLE_VERBOSE_STRINGS /* public key algorithm's parameters */ algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits); - infof(data, "\t certificate public key: %s\n", + infof(data, " certificate public key: %s", gnutls_pk_algorithm_get_name(algo)); /* version of the X.509 certificate. */ - infof(data, "\t certificate version: #%d\n", + infof(data, " certificate version: #%d", gnutls_x509_crt_get_version(x509_cert)); rc = gnutls_x509_crt_get_dn2(x509_cert, &certfields); if(rc) - infof(data, "Failed to get certificate name\n"); + infof(data, "Failed to get certificate name"); else { - infof(data, "\t subject: %s\n", certfields.data); + infof(data, " subject: %s", certfields.data); certclock = gnutls_x509_crt_get_activation_time(x509_cert); showtime(data, "start date", certclock); @@ -1238,9 +1233,9 @@ gtls_connect_step3(struct Curl_easy *data, rc = gnutls_x509_crt_get_issuer_dn2(x509_cert, &certfields); if(rc) - infof(data, "Failed to get certificate issuer\n"); + infof(data, "Failed to get certificate issuer"); else { - infof(data, "\t issuer: %s\n", certfields.data); + infof(data, " issuer: %s", certfields.data); gnutls_free(certfields.data); } @@ -1251,7 +1246,7 @@ gtls_connect_step3(struct Curl_easy *data, if(conn->bits.tls_enable_alpn) { rc = gnutls_alpn_get_selected_protocol(session, &proto); if(rc == 0) { - infof(data, "ALPN, server accepted to use %.*s\n", proto.size, + infof(data, "ALPN, server accepted to use %.*s", proto.size, proto.data); #ifdef USE_HTTP2 @@ -1268,7 +1263,7 @@ gtls_connect_step3(struct Curl_easy *data, } } else - infof(data, "ALPN, server did not agree to a protocol\n"); + infof(data, "ALPN, server did not agree to a protocol"); Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); @@ -1438,6 +1433,10 @@ static void close_one(struct ssl_connect_data *connssl) { struct ssl_backend_data *backend = connssl->backend; if(backend->session) { + char buf[32]; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)gnutls_record_recv(backend->session, buf, sizeof(buf)); gnutls_bye(backend->session, GNUTLS_SHUT_WR); gnutls_deinit(backend->session); backend->session = NULL; @@ -1506,7 +1505,7 @@ static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn, break; case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: - infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n"); + infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED"); break; default: retval = -1; @@ -1620,7 +1619,7 @@ static bool gtls_cert_status_request(void) } static void *gtls_get_internals(struct ssl_connect_data *connssl, - CURLINFO info UNUSED_PARAM) + CURLINFO info UNUSED_PARAM) { struct ssl_backend_data *backend = connssl->backend; (void)info; diff --git a/contrib/libs/curl/lib/vtls/mbedtls.c b/contrib/libs/curl/lib/vtls/mbedtls.c index 4f9a6d2683..e61dcc9c36 100644 --- a/contrib/libs/curl/lib/vtls/mbedtls.c +++ b/contrib/libs/curl/lib/vtls/mbedtls.c @@ -89,6 +89,10 @@ struct ssl_backend_data { #define THREADING_SUPPORT #endif +#ifndef MBEDTLS_ERROR_C +#define mbedtls_strerror(a,b,c) b[0] = 0 +#endif + #if defined(THREADING_SUPPORT) static mbedtls_entropy_context ts_entropy; @@ -250,12 +254,12 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const ssl_capath = SSL_CONN_CONFIG(CApath); char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); + const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); const char * const hostname = SSL_HOST_NAME(); const long int port = SSL_HOST_PORT(); int ret = -1; char errorbuf[128]; - errorbuf[0] = 0; if((SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) || (SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)) { @@ -270,9 +274,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex, &ts_entropy, NULL, 0); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s", -ret, errorbuf); } @@ -283,9 +285,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func, &backend->entropy, NULL, 0); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s", -ret, errorbuf); } @@ -298,9 +298,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile); if(ret<0) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s", ssl_cafile, -ret, errorbuf); @@ -313,9 +311,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath); if(ret<0) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s", ssl_capath, -ret, errorbuf); @@ -331,9 +327,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s", ssl_cert, -ret, errorbuf); @@ -341,27 +335,57 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, } } - /* Load the client private key */ - mbedtls_pk_init(&backend->pk); - - if(SSL_SET_OPTION(key)) { - ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key), - SSL_SET_OPTION(key_passwd)); - if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || - mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) - ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + if(ssl_cert_blob) { + const unsigned char *blob_data = + (const unsigned char *)ssl_cert_blob->data; + ret = mbedtls_x509_crt_parse(&backend->clicert, blob_data, + ssl_cert_blob->len); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s", SSL_SET_OPTION(key), -ret, errorbuf); - return CURLE_SSL_CERTPROBLEM; } } + /* Load the client private key */ + mbedtls_pk_init(&backend->pk); + + if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) { + if(SSL_SET_OPTION(key)) { + ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key), + SSL_SET_OPTION(key_passwd)); + + if(ret) { + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s", + SSL_SET_OPTION(key), -ret, errorbuf); + return CURLE_SSL_CERTPROBLEM; + } + } + else { + const struct curl_blob *ssl_key_blob = SSL_SET_OPTION(key_blob); + const unsigned char *key_data = + (const unsigned char *)ssl_key_blob->data; + const char *passwd = SSL_SET_OPTION(key_passwd); + ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, + (const unsigned char *)passwd, + passwd ? strlen(passwd) : 0); + + if(ret) { + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Error parsing private key - mbedTLS: (-0x%04X) %s", + -ret, errorbuf); + return CURLE_SSL_CERTPROBLEM; + } + } + + if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || + mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) + ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + } + /* Load the CRL */ mbedtls_x509_crl_init(&backend->crl); @@ -369,9 +393,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s", ssl_crlfile, -ret, errorbuf); @@ -379,7 +401,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, } } - infof(data, "mbedTLS: Connecting to %s:%ld\n", hostname, port); + infof(data, "mbedTLS: Connecting to %s:%ld", hostname, port); mbedtls_ssl_config_init(&backend->config); @@ -406,7 +428,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, case CURL_SSLVERSION_TLSv1: mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); - infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n"); + infof(data, "mbedTLS: Set min SSL version to TLS 1.0"); break; case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: @@ -459,7 +481,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret); return CURLE_SSL_CONNECT_ERROR; } - infof(data, "mbedTLS re-using session\n"); + infof(data, "mbedTLS re-using session"); } Curl_ssl_sessionid_unlock(data); } @@ -468,7 +490,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, &backend->cacert, &backend->crl); - if(SSL_SET_OPTION(key)) { + if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) { mbedtls_ssl_conf_own_cert(&backend->config, &backend->clicert, &backend->pk); } @@ -497,7 +519,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } for(p = &backend->protocols[0]; *p; ++p) - infof(data, "ALPN, offering %s\n", *p); + infof(data, "ALPN, offering %s", *p); } #endif @@ -553,18 +575,14 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, } else if(ret) { char errorbuf[128]; - errorbuf[0] = 0; -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s", -ret, errorbuf); return CURLE_SSL_CONNECT_ERROR; } - infof(data, "mbedTLS: Handshake complete, cipher is %s\n", - mbedtls_ssl_get_ciphersuite(&backend->ssl) - ); + infof(data, "mbedTLS: Handshake complete, cipher is %s", + mbedtls_ssl_get_ciphersuite(&backend->ssl)); ret = mbedtls_ssl_get_verify_result(&backend->ssl); @@ -601,9 +619,9 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, return CURLE_OUT_OF_MEMORY; if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0) - infof(data, "Dumping cert info:\n%s\n", buffer); + infof(data, "Dumping cert info: %s", buffer); else - infof(data, "Unable to dump certificate information.\n"); + infof(data, "Unable to dump certificate information"); free(buffer); } @@ -664,7 +682,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&backend->ssl); if(next_protocol) { - infof(data, "ALPN, server accepted to use %s\n", next_protocol); + infof(data, "ALPN, server accepted to use %s", next_protocol); #ifdef USE_NGHTTP2 if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN) && @@ -679,7 +697,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, } } else { - infof(data, "ALPN, server did not agree to a protocol\n"); + infof(data, "ALPN, server did not agree to a protocol"); } Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); @@ -687,7 +705,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, #endif connssl->connecting_state = ssl_connect_3; - infof(data, "SSL connected\n"); + infof(data, "SSL connected"); return CURLE_OK; } @@ -775,8 +793,13 @@ static void mbedtls_close(struct Curl_easy *data, { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - + char buf[32]; (void) data; + + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, sizeof(buf)); + mbedtls_pk_free(&backend->pk); mbedtls_x509_crt_free(&backend->clicert); mbedtls_x509_crt_free(&backend->cacert); @@ -844,15 +867,12 @@ static CURLcode mbedtls_random(struct Curl_easy *data, mbedtls_ctr_drbg_context ctr_drbg; mbedtls_entropy_init(&ctr_entropy); mbedtls_ctr_drbg_init(&ctr_drbg); - errorbuf[0] = 0; ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &ctr_entropy, NULL, 0); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s", -ret, errorbuf); } @@ -860,9 +880,7 @@ static CURLcode mbedtls_random(struct Curl_easy *data, ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s", -ret, errorbuf); } diff --git a/contrib/libs/curl/lib/vtls/mesalink.c b/contrib/libs/curl/lib/vtls/mesalink.c index 80d3d01724..5deaea5f6e 100644 --- a/contrib/libs/curl/lib/vtls/mesalink.c +++ b/contrib/libs/curl/lib/vtls/mesalink.c @@ -167,14 +167,14 @@ mesalink_connect_step1(struct Curl_easy *data, } infof(data, "error setting certificate verify locations," - " continuing anyway:\n"); + " continuing anyway:"); } else { - infof(data, "successfully set certificate verify locations:\n"); + infof(data, "successfully set certificate verify locations:"); } - infof(data, " CAfile: %s\n", + infof(data, " CAfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile): "none"); - infof(data, " CApath: %s\n", + infof(data, " CApath: %s", SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath): "none"); } @@ -196,7 +196,7 @@ mesalink_connect_step1(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } infof(data, - "client cert: %s\n", + "client cert: %s", SSL_CONN_CONFIG(clientcert)? SSL_CONN_CONFIG(clientcert): "none"); } @@ -209,7 +209,7 @@ mesalink_connect_step1(struct Curl_easy *data, return CURLE_SSL_CIPHER; } #endif - infof(data, "Cipher selection: %s\n", ciphers); + infof(data, "Cipher selection: %s", ciphers); } if(BACKEND->handle) @@ -273,7 +273,7 @@ mesalink_connect_step1(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } /* Informational message */ - infof(data, "SSL re-using session ID\n"); + infof(data, "SSL re-using session ID"); } Curl_ssl_sessionid_unlock(data); } @@ -326,7 +326,7 @@ mesalink_connect_step2(struct Curl_easy *data, connssl->connecting_state = ssl_connect_3; infof(data, - "SSL connection using %s / %s\n", + "SSL connection using %s / %s", SSL_get_version(BACKEND->handle), SSL_get_cipher_name(BACKEND->handle)); @@ -356,7 +356,7 @@ mesalink_connect_step3(struct connectdata *conn, int sockindex) sockindex)); if(incache) { if(old_ssl_sessionid != our_ssl_sessionid) { - infof(data, "old SSL session ID is stale, removing\n"); + infof(data, "old SSL session ID is stale, removing"); Curl_ssl_delsessionid(data, old_ssl_sessionid); incache = FALSE; } diff --git a/contrib/libs/curl/lib/vtls/nss.c b/contrib/libs/curl/lib/vtls/nss.c index b5d23bffe0..f274baf05f 100644 --- a/contrib/libs/curl/lib/vtls/nss.c +++ b/contrib/libs/curl/lib/vtls/nss.c @@ -433,7 +433,7 @@ static char *dup_nickname(struct Curl_easy *data, const char *str) n = strchr(str, '/'); if(!n) { infof(data, "warning: certificate file name \"%s\" handled as nickname; " - "please use \"./%s\" to force file name\n", str, str); + "please use \"./%s\" to force file name", str, str); return strdup(str); } @@ -824,7 +824,7 @@ static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig, #endif if(!SSL_CONN_CONFIG(verifypeer)) { - infof(data, "skipping SSL peer certificate verification\n"); + infof(data, "skipping SSL peer certificate verification"); return SECSuccess; } @@ -857,15 +857,15 @@ static void HandshakeCallback(PRFileDesc *sock, void *arg) #endif case SSL_NEXT_PROTO_NO_SUPPORT: case SSL_NEXT_PROTO_NO_OVERLAP: - infof(data, "ALPN/NPN, server did not agree to a protocol\n"); + infof(data, "ALPN/NPN, server did not agree to a protocol"); return; #ifdef SSL_ENABLE_ALPN case SSL_NEXT_PROTO_SELECTED: - infof(data, "ALPN, server accepted to use %.*s\n", buflen, buf); + infof(data, "ALPN, server accepted to use %.*s", buflen, buf); break; #endif case SSL_NEXT_PROTO_NEGOTIATED: - infof(data, "NPN, server accepted to use %.*s\n", buflen, buf); + infof(data, "NPN, server accepted to use %.*s", buflen, buf); break; } @@ -937,7 +937,7 @@ static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data, *canFalseStart = PR_TRUE; - infof(data, "Trying TLS False Start\n"); + infof(data, "Trying TLS False Start"); end: return SECSuccess; @@ -955,17 +955,17 @@ static void display_cert_info(struct Curl_easy *data, subject = CERT_NameToAscii(&cert->subject); issuer = CERT_NameToAscii(&cert->issuer); common_name = CERT_GetCommonName(&cert->subject); - infof(data, "\tsubject: %s\n", subject); + infof(data, "subject: %s\n", subject); CERT_GetCertTimes(cert, ¬Before, ¬After); PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime); PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime); - infof(data, "\tstart date: %s\n", timeString); + infof(data, " start date: %s", timeString); PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime); PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime); - infof(data, "\texpire date: %s\n", timeString); - infof(data, "\tcommon name: %s\n", common_name); - infof(data, "\tissuer: %s\n", issuer); + infof(data, " expire date: %s", timeString); + infof(data, " common name: %s", common_name); + infof(data, " issuer: %s", issuer); PR_Free(subject); PR_Free(issuer); @@ -987,13 +987,13 @@ static CURLcode display_conn_info(struct Curl_easy *data, PRFileDesc *sock) channel.cipherSuite) { if(SSL_GetCipherSuiteInfo(channel.cipherSuite, &suite, sizeof(suite)) == SECSuccess) { - infof(data, "SSL connection using %s\n", suite.cipherSuiteName); + infof(data, "SSL connection using %s", suite.cipherSuiteName); } } cert = SSL_PeerCertificate(sock); if(cert) { - infof(data, "Server certificate:\n"); + infof(data, "Server certificate:"); if(!data->set.ssl.certinfo) { display_cert_info(data, cert); @@ -1058,7 +1058,7 @@ static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) /* print only info about the cert, the error is printed off the callback */ cert = SSL_PeerCertificate(sock); if(cert) { - infof(data, "Server certificate:\n"); + infof(data, "Server certificate:"); display_cert_info(data, cert); CERT_DestroyCertificate(cert); } @@ -1132,7 +1132,7 @@ static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl, /* report the resulting status */ switch(result) { case CURLE_OK: - infof(data, "pinned public key verified successfully!\n"); + infof(data, "pinned public key verified successfully!"); break; case CURLE_SSL_PINNEDPUBKEYNOTMATCH: failf(data, "failed to verify pinned public key"); @@ -1196,7 +1196,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock, return SECFailure; } - infof(data, "NSS: client certificate from file\n"); + infof(data, "NSS: client certificate from file"); display_cert_info(data, cert); *pRetCert = cert; @@ -1234,7 +1234,7 @@ static SECStatus SelectClientCert(void *arg, PRFileDesc *sock, return SECFailure; } - infof(data, "NSS: using client certificate: %s\n", nickname); + infof(data, "NSS: using client certificate: %s", nickname); display_cert_info(data, *pRetCert); return SECSuccess; } @@ -1355,7 +1355,7 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir) if(!certpath) return CURLE_OUT_OF_MEMORY; - infof(data, "Initializing NSS with certpath: %s\n", certpath); + infof(data, "Initializing NSS with certpath: %s", certpath); nss_context = NSS_InitContext(certpath, "", "", "", &initparams, NSS_INIT_READONLY | NSS_INIT_PK11RELOAD); free(certpath); @@ -1365,10 +1365,10 @@ static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir) err = PR_GetError(); err_name = nss_error_to_name(err); - infof(data, "Unable to initialize NSS database: %d (%s)\n", err, err_name); + infof(data, "Unable to initialize NSS database: %d (%s)", err, err_name); } - infof(data, "Initializing NSS with certpath: none\n"); + infof(data, "Initializing NSS with certpath: none"); nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD); @@ -1546,6 +1546,14 @@ static void close_one(struct ssl_connect_data *connssl) const bool client_cert = (backend->client_nickname != NULL) || (backend->obj_clicert != NULL); + if(backend->handle) { + char buf[32]; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)PR_Recv(backend->handle, buf, (int)sizeof(buf), 0, + PR_INTERVAL_NO_WAIT); + } + free(backend->client_nickname); backend->client_nickname = NULL; @@ -1650,8 +1658,8 @@ static CURLcode nss_load_ca_certificates(struct Curl_easy *data, if(capath && !capath[0]) capath = NULL; - infof(data, " CAfile: %s\n", cafile ? cafile : "none"); - infof(data, " CApath: %s\n", capath ? capath : "none"); + infof(data, " CAfile: %s", cafile ? cafile : "none"); + infof(data, " CApath: %s", capath ? capath : "none"); /* load libnssckbi.so if no other trust roots were specified */ use_trust_module = !cafile && !capath; @@ -1660,7 +1668,7 @@ static CURLcode nss_load_ca_certificates(struct Curl_easy *data, if(use_trust_module && !trust_module) { /* libnssckbi.so needed but not yet loaded --> load it! */ result = nss_load_module(&trust_module, trust_library, "trust"); - infof(data, "%s %s\n", (result) ? "failed to load" : "loaded", + infof(data, "%s %s", (result) ? "failed to load" : "loaded", trust_library); if(result == CURLE_FAILED_INIT) /* If libnssckbi.so is not available (or fails to load), one can still @@ -1669,7 +1677,7 @@ static CURLcode nss_load_ca_certificates(struct Curl_easy *data, } else if(!use_trust_module && trust_module) { /* libnssckbi.so not needed but already loaded --> unload it! */ - infof(data, "unloading %s\n", trust_library); + infof(data, "unloading %s", trust_library); nss_unload_module(&trust_module); } PR_Unlock(nss_trustload_lock); @@ -1702,7 +1710,7 @@ static CURLcode nss_load_ca_certificates(struct Curl_easy *data, if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE)) /* This is purposefully tolerant of errors so non-PEM files can * be in the same directory */ - infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath); + infof(data, "failed to load '%s' from CURLOPT_CAPATH", fullpath); free(fullpath); } @@ -1710,7 +1718,7 @@ static CURLcode nss_load_ca_certificates(struct Curl_easy *data, PR_CloseDir(dir); } else - infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath); + infof(data, "warning: CURLOPT_CAPATH not a directory (%s)", capath); } return CURLE_OK; @@ -1813,7 +1821,7 @@ static CURLcode nss_fail_connect(struct ssl_connect_data *connssl, curlerr = CURLE_SSL_CERTPROBLEM; /* print the error number and error string */ - infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err)); + infof(data, "NSS error %d (%s)", err, nss_error_to_name(err)); /* print a human-readable message describing the error if available */ nss_print_error_message(data, err); @@ -1887,7 +1895,7 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, PR_Unlock(nss_initlock); if(result == CURLE_FAILED_INIT) infof(data, "WARNING: failed to load NSS PEM library %s. Using " - "OpenSSL PEM certificates will not work.\n", pem_library); + "OpenSSL PEM certificates will not work.", pem_library); else if(result) goto error; @@ -1922,8 +1930,8 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, sslver_req_str = nss_sslver_to_name(sslver.max); sslver_supp_str = nss_sslver_to_name(sslver_supported.max); if(sslver_req_str && sslver_supp_str) - infof(data, "Falling back from %s to max supported SSL version (%s)\n", - sslver_req_str, sslver_supp_str); + infof(data, "Falling back from %s to max supported SSL version (%s)", + sslver_req_str, sslver_supp_str); free(sslver_req_str); free(sslver_supp_str); sslver.max = sslver_supported.max; @@ -1936,11 +1944,11 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, /* unless the user explicitly asks to allow the protocol vulnerability, we use the work-around */ if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess) - infof(data, "warning: failed to set SSL_CBC_RANDOM_IV = %d\n", + infof(data, "warning: failed to set SSL_CBC_RANDOM_IV = %d", ssl_cbc_random_iv); #else if(ssl_cbc_random_iv) - infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n"); + infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in"); #endif if(SSL_CONN_CONFIG(cipher_list)) { @@ -1951,7 +1959,7 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, } if(!SSL_CONN_CONFIG(verifypeer) && SSL_CONN_CONFIG(verifyhost)) - infof(data, "warning: ignoring value of ssl.verifyhost\n"); + infof(data, "warning: ignoring value of ssl.verifyhost"); /* bypass the default SSL_AuthCertificate() hook in case we do not want to * verify peer */ @@ -1971,7 +1979,7 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, const CURLcode rv = nss_load_ca_certificates(data, conn, sockindex); if((rv == CURLE_SSL_CACERT_BADFILE) && !SSL_CONN_CONFIG(verifypeer)) /* not a fatal error because we are not going to verify the peer */ - infof(data, "warning: CA certificates failed to load\n"); + infof(data, "warning: CA certificates failed to load"); else if(rv) { result = rv; goto error; @@ -1984,7 +1992,7 @@ static CURLcode nss_setup_connect(struct Curl_easy *data, result = rv; goto error; } - infof(data, " CRLfile: %s\n", SSL_SET_OPTION(CRLfile)); + infof(data, " CRLfile: %s", SSL_SET_OPTION(CRLfile)); } if(SSL_SET_OPTION(primary.clientcert)) { @@ -2179,9 +2187,9 @@ static CURLcode nss_do_connect(struct Curl_easy *data, if(result) goto error; - if(SSL_SET_OPTION(issuercert)) { + if(SSL_CONN_CONFIG(issuercert)) { SECStatus ret = SECFailure; - char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert)); + char *nickname = dup_nickname(data, SSL_CONN_CONFIG(issuercert)); if(nickname) { /* we support only nicknames in case of issuercert for now */ ret = check_issuer_cert(backend->handle, nickname); @@ -2189,12 +2197,12 @@ static CURLcode nss_do_connect(struct Curl_easy *data, } if(SECFailure == ret) { - infof(data, "SSL certificate issuer check failed\n"); + infof(data, "SSL certificate issuer check failed"); result = CURLE_SSL_ISSUER_ERROR; goto error; } else { - infof(data, "SSL certificate issuer check ok\n"); + infof(data, "SSL certificate issuer check ok"); } } @@ -2306,7 +2314,7 @@ static ssize_t nss_send(struct Curl_easy *data, /* transfer */ else { /* print the error number and error string */ const char *err_name = nss_error_to_name(err); - infof(data, "SSL write: error %d (%s)\n", err, err_name); + infof(data, "SSL write: error %d (%s)", err, err_name); /* print a human-readable message describing the error if available */ nss_print_error_message(data, err); @@ -2348,7 +2356,7 @@ static ssize_t nss_recv(struct Curl_easy *data, /* transfer */ else { /* print the error number and error string */ const char *err_name = nss_error_to_name(err); - infof(data, "SSL read: errno %d (%s)\n", err, err_name); + infof(data, "SSL read: errno %d (%s)", err, err_name); /* print a human-readable message describing the error if available */ nss_print_error_message(data, err); @@ -2427,7 +2435,7 @@ static bool nss_false_start(void) } static void *nss_get_internals(struct ssl_connect_data *connssl, - CURLINFO info UNUSED_PARAM) + CURLINFO info UNUSED_PARAM) { struct ssl_backend_data *backend = connssl->backend; (void)info; diff --git a/contrib/libs/curl/lib/vtls/openssl.c b/contrib/libs/curl/lib/vtls/openssl.c index ebd7abc3b4..8af23b783a 100644 --- a/contrib/libs/curl/lib/vtls/openssl.c +++ b/contrib/libs/curl/lib/vtls/openssl.c @@ -435,17 +435,16 @@ static bool rand_enough(void) static CURLcode ossl_seed(struct Curl_easy *data) { - /* we have the "SSL is seeded" boolean static to prevent multiple - time-consuming seedings in vain */ - static bool ssl_seeded = FALSE; char fname[256]; - if(ssl_seeded) + /* This might get called before it has been added to a multi handle */ + if(data->multi && data->multi->ssl_seeded) return CURLE_OK; if(rand_enough()) { /* OpenSSL 1.1.0+ will return here */ - ssl_seeded = TRUE; + if(data->multi) + data->multi->ssl_seeded = TRUE; return CURLE_OK; } @@ -518,7 +517,7 @@ static CURLcode ossl_seed(struct Curl_easy *data) return CURLE_OK; } - infof(data, "libcurl is now using a weak random seed!\n"); + infof(data, "libcurl is now using a weak random seed!"); return (rand_enough() ? CURLE_OK : CURLE_SSL_CONNECT_ERROR /* confusing error code */); } @@ -1354,7 +1353,7 @@ static CURLcode ossl_set_engine_default(struct Curl_easy *data) #ifdef USE_OPENSSL_ENGINE if(data->state.engine) { if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) { - infof(data, "set default crypto engine '%s'\n", + infof(data, "set default crypto engine '%s'", ENGINE_get_id(data->state.engine)); } else { @@ -1400,7 +1399,13 @@ static void ossl_closeone(struct Curl_easy *data, { struct ssl_backend_data *backend = connssl->backend; if(backend->handle) { + char buf[32]; set_logger(conn, data); + + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)SSL_read(backend->handle, buf, (int)sizeof(buf)); + (void)SSL_shutdown(backend->handle); SSL_set_connect_state(backend->handle); @@ -1442,6 +1447,7 @@ static int ossl_shutdown(struct Curl_easy *data, int err; bool done = FALSE; struct ssl_backend_data *backend = connssl->backend; + int loop = 10; #ifndef CURL_DISABLE_FTP /* This has only been tested on the proftpd server, and the mod_tls code @@ -1455,7 +1461,7 @@ static int ossl_shutdown(struct Curl_easy *data, if(backend->handle) { buffsize = (int)sizeof(buf); - while(!done) { + while(!done && loop--) { int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT); if(what > 0) { @@ -1475,11 +1481,11 @@ static int ossl_shutdown(struct Curl_easy *data, break; case SSL_ERROR_WANT_READ: /* there's data pending, re-invoke SSL_read() */ - infof(data, "SSL_ERROR_WANT_READ\n"); + infof(data, "SSL_ERROR_WANT_READ"); break; case SSL_ERROR_WANT_WRITE: /* SSL wants a write. Really odd. Let's bail out. */ - infof(data, "SSL_ERROR_WANT_WRITE\n"); + infof(data, "SSL_ERROR_WANT_WRITE"); done = TRUE; break; default: @@ -1511,14 +1517,14 @@ static int ossl_shutdown(struct Curl_easy *data, #ifdef HAVE_SSL_GET_SHUTDOWN switch(SSL_get_shutdown(backend->handle)) { case SSL_SENT_SHUTDOWN: - infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n"); + infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN"); break; case SSL_RECEIVED_SHUTDOWN: - infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n"); + infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN"); break; case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN: infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|" - "SSL_RECEIVED__SHUTDOWN\n"); + "SSL_RECEIVED__SHUTDOWN"); break; } #endif @@ -1585,7 +1591,7 @@ static bool subj_alt_hostcheck(struct Curl_easy *data, if(Curl_cert_hostcheck(match_pattern2, hostname)) { res = TRUE; infof(data, - " subjectAltName: host \"%s\" matched cert's \"%s\"\n", + " subjectAltName: host \"%s\" matched cert's \"%s\"", dispname, match_pattern2); } } @@ -1604,7 +1610,7 @@ static bool subj_alt_hostcheck(struct Curl_easy *data, (void)data; #endif if(Curl_cert_hostcheck(match_pattern, hostname)) { - infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"\n", + infof(data, " subjectAltName: host \"%s\" matched cert's \"%s\"", dispname, match_pattern); return TRUE; } @@ -1724,7 +1730,7 @@ static CURLcode verifyhost(struct Curl_easy *data, struct connectdata *conn, if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) { ipmatched = TRUE; infof(data, - " subjectAltName: host \"%s\" matched cert's IP address!\n", + " subjectAltName: host \"%s\" matched cert's IP address!", dispname); } break; @@ -1741,7 +1747,7 @@ static CURLcode verifyhost(struct Curl_easy *data, struct connectdata *conn, /* an alternative name matched */ ; else if(dNSName || iPAddress) { - infof(data, " subjectAltName does not match %s\n", dispname); + infof(data, " subjectAltName does not match %s", dispname); failf(data, "SSL: no alternative certificate subject name matches " "target host name '%s'", dispname); result = CURLE_PEER_FAILED_VERIFICATION; @@ -1823,7 +1829,7 @@ static CURLcode verifyhost(struct Curl_easy *data, struct connectdata *conn, result = CURLE_PEER_FAILED_VERIFICATION; } else { - infof(data, " common name: %s (matched)\n", peer_CN); + infof(data, " common name: %s (matched)", peer_CN); } if(peer_CN) OPENSSL_free(peer_CN); @@ -1959,7 +1965,7 @@ static CURLcode verifystatus(struct Curl_easy *data, goto end; } - infof(data, "SSL certificate status: %s (%d)\n", + infof(data, "SSL certificate status: %s (%d)", OCSP_cert_status_str(cert_status), cert_status); switch(cert_status) { @@ -2263,7 +2269,7 @@ select_next_proto_cb(SSL *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)\n", ALPN_H2); + infof(data, "NPN, negotiated HTTP2 (%s)", ALPN_H2); conn->negnpn = CURL_HTTP_VERSION_2; return SSL_TLSEXT_ERR_OK; } @@ -2271,12 +2277,12 @@ select_next_proto_cb(SSL *ssl, if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) { - infof(data, "NPN, negotiated HTTP1.1\n"); + 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\n"); + 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; @@ -2493,7 +2499,7 @@ static int ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid) &old_ssl_sessionid, NULL, sockindex)); if(incache) { if(old_ssl_sessionid != ssl_sessionid) { - infof(data, "old SSL session ID is stale, removing\n"); + infof(data, "old SSL session ID is stale, removing"); Curl_ssl_delsessionid(data, old_ssl_sessionid); incache = FALSE; } @@ -2787,14 +2793,14 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, memcpy(&protocols[cur], ALPN_H2, ALPN_H2_LENGTH); cur += ALPN_H2_LENGTH; - infof(data, "ALPN, offering %s\n", ALPN_H2); + infof(data, "ALPN, offering %s", ALPN_H2); } #endif protocols[cur++] = ALPN_HTTP_1_1_LENGTH; memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); cur += ALPN_HTTP_1_1_LENGTH; - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + infof(data, "ALPN, offering %s", ALPN_HTTP_1_1); /* expects length prefixed preference ordered list of protocols in wire * format @@ -2826,7 +2832,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, failf(data, "failed setting cipher list: %s", ciphers); return CURLE_SSL_CIPHER; } - infof(data, "Cipher selection: %s\n", ciphers); + infof(data, "Cipher selection: %s", ciphers); } #ifdef HAVE_SSL_CTX_SET_CIPHERSUITES @@ -2837,7 +2843,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers13); return CURLE_SSL_CIPHER; } - infof(data, "TLS 1.3 cipher selection: %s\n", ciphers13); + infof(data, "TLS 1.3 cipher selection: %s", ciphers13); } } #endif @@ -2863,7 +2869,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, if(ssl_authtype == CURL_TLSAUTH_SRP) { char * const ssl_username = SSL_SET_OPTION(username); - infof(data, "Using TLS-SRP username: %s\n", ssl_username); + infof(data, "Using TLS-SRP username: %s", ssl_username); if(!SSL_CTX_set_srp_username(backend->ctx, ssl_username)) { failf(data, "Unable to set SRP user name"); @@ -2874,7 +2880,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, return CURLE_BAD_FUNCTION_ARGUMENT; } if(!SSL_CONN_CONFIG(cipher_list)) { - infof(data, "Setting cipher list SRP\n"); + infof(data, "Setting cipher list SRP"); if(!SSL_CTX_set_cipher_list(backend->ctx, "SRP")) { failf(data, "failed setting SRP cipher list"); @@ -2927,7 +2933,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, NULL, cert_name, sizeof(cert_name))) { strcpy(cert_name, "Unknown"); } - infof(data, "SSL: Checking cert \"%s\"\n", cert_name); + infof(data, "SSL: Checking cert %s\"\n", cert_name); #endif encoded_cert = (const unsigned char *)pContext->pbCertEncoded; @@ -3009,7 +3015,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, OpenSSL. */ if(X509_STORE_add_cert(store, x509) == 1) { #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - infof(data, "SSL: Imported cert \"%s\"\n", cert_name); + infof(data, "SSL: Imported cert \"%s\"", cert_name); #endif imported_native_ca = true; } @@ -3024,9 +3030,9 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, return result; } if(imported_native_ca) - infof(data, "successfully imported windows ca store\n"); + infof(data, "successfully imported windows ca store"); else - infof(data, "error importing windows ca store, continuing anyway\n"); + infof(data, "error importing windows ca store, continuing anyway"); } #endif @@ -3039,7 +3045,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, return result; } /* Only warning if no certificate verification is required. */ - infof(data, "error importing CA certificate blob, continuing anyway\n"); + infof(data, "error importing CA certificate blob, continuing anyway"); } } @@ -3054,9 +3060,9 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, return CURLE_SSL_CACERT_BADFILE; } /* Continue with a warning if no certificate verif is required. */ - infof(data, "error setting certificate file, continuing anyway\n"); + infof(data, "error setting certificate file, continuing anyway"); } - infof(data, " CAfile: %s\n", ssl_cafile); + infof(data, " CAfile: %s", ssl_cafile); } if(ssl_capath) { if(!SSL_CTX_load_verify_dir(backend->ctx, ssl_capath)) { @@ -3066,9 +3072,9 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, return CURLE_SSL_CACERT_BADFILE; } /* Continue with a warning if no certificate verif is required. */ - infof(data, "error setting certificate path, continuing anyway\n"); + infof(data, "error setting certificate path, continuing anyway"); } - infof(data, " CApath: %s\n", ssl_capath); + infof(data, " CApath: %s", ssl_capath); } } #else @@ -3087,14 +3093,14 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, /* Just continue with a warning if no strict certificate verification is required. */ infof(data, "error setting certificate verify locations," - " continuing anyway:\n"); + " continuing anyway:"); } else { /* Everything is fine. */ - infof(data, "successfully set certificate verify locations:\n"); + infof(data, "successfully set certificate verify locations:"); } - infof(data, " CAfile: %s\n", ssl_cafile ? ssl_cafile : "none"); - infof(data, " CApath: %s\n", ssl_capath ? ssl_capath : "none"); + infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none"); + infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none"); } #endif @@ -3118,11 +3124,11 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, return CURLE_SSL_CRL_BADFILE; } /* Everything is fine. */ - infof(data, "successfully load CRL file:\n"); + infof(data, "successfully load CRL file:"); X509_STORE_set_flags(SSL_CTX_get_cert_store(backend->ctx), X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); - infof(data, " CRLfile: %s\n", ssl_crlfile); + infof(data, " CRLfile: %s", ssl_crlfile); } if(verifypeer) { @@ -3226,7 +3232,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, data->state.buffer[nlen] = 0; if(!SSL_set_tlsext_host_name(backend->handle, data->state.buffer)) infof(data, "WARNING: failed to configure server name indication (SNI) " - "TLS extension\n"); + "TLS extension"); } #endif @@ -3244,7 +3250,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } /* Informational message */ - infof(data, "SSL re-using session ID\n"); + infof(data, "SSL re-using session ID"); } Curl_ssl_sessionid_unlock(data); @@ -3399,7 +3405,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, connssl->connecting_state = ssl_connect_3; /* Informational message */ - infof(data, "SSL connection using %s / %s\n", + infof(data, "SSL connection using %s / %s", SSL_get_version(backend->handle), SSL_get_cipher(backend->handle)); @@ -3412,7 +3418,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, unsigned int len; SSL_get0_alpn_selected(backend->handle, &neg_protocol, &len); if(len) { - infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol); + infof(data, "ALPN, server accepted to use %.*s", len, neg_protocol); #ifdef USE_HTTP2 if(len == ALPN_H2_LENGTH && @@ -3427,7 +3433,7 @@ static CURLcode ossl_connect_step2(struct Curl_easy *data, } } else - infof(data, "ALPN, server did not agree to a protocol\n"); + infof(data, "ALPN, server did not agree to a protocol"); Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); @@ -3637,7 +3643,7 @@ static CURLcode get_cert_chain(struct Curl_easy *data, pubkey = X509_get_pubkey(x); if(!pubkey) - infof(data, " Unable to load public key\n"); + infof(data, " Unable to load public key"); else { int pktype; #ifdef HAVE_OPAQUE_EVP_PKEY @@ -3851,23 +3857,23 @@ static CURLcode servercert(struct Curl_easy *data, return CURLE_PEER_FAILED_VERIFICATION; } - infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server"); + infof(data, "%s certificate:", SSL_IS_PROXY() ? "Proxy" : "Server"); rc = x509_name_oneline(X509_get_subject_name(backend->server_cert), buffer, sizeof(buffer)); - infof(data, " subject: %s\n", rc?"[NONE]":buffer); + infof(data, " subject: %s", rc?"[NONE]":buffer); #ifndef CURL_DISABLE_VERBOSE_STRINGS { long len; ASN1_TIME_print(mem, X509_get0_notBefore(backend->server_cert)); len = BIO_get_mem_data(mem, (char **) &ptr); - infof(data, " start date: %.*s\n", len, ptr); + infof(data, " start date: %.*s", (int)len, ptr); (void)BIO_reset(mem); ASN1_TIME_print(mem, X509_get0_notAfter(backend->server_cert)); len = BIO_get_mem_data(mem, (char **) &ptr); - infof(data, " expire date: %.*s\n", len, ptr); + infof(data, " expire date: %.*s", (int)len, ptr); (void)BIO_reset(mem); } #endif @@ -3891,16 +3897,16 @@ static CURLcode servercert(struct Curl_easy *data, result = CURLE_PEER_FAILED_VERIFICATION; } else { - infof(data, " issuer: %s\n", buffer); + infof(data, " issuer: %s", buffer); /* We could do all sorts of certificate verification stuff here before deallocating the certificate. */ /* e.g. match issuer name with provided issuer certificate */ - if(SSL_SET_OPTION(issuercert) || SSL_SET_OPTION(issuercert_blob)) { - if(SSL_SET_OPTION(issuercert_blob)) - fp = BIO_new_mem_buf(SSL_SET_OPTION(issuercert_blob)->data, - (int)SSL_SET_OPTION(issuercert_blob)->len); + if(SSL_CONN_CONFIG(issuercert) || SSL_CONN_CONFIG(issuercert_blob)) { + if(SSL_CONN_CONFIG(issuercert_blob)) + fp = BIO_new_mem_buf(SSL_CONN_CONFIG(issuercert_blob)->data, + (int)SSL_CONN_CONFIG(issuercert_blob)->len); else { fp = BIO_new(BIO_s_file()); if(!fp) { @@ -3914,10 +3920,10 @@ static CURLcode servercert(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; } - if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) { + if(BIO_read_filename(fp, SSL_CONN_CONFIG(issuercert)) <= 0) { if(strict) failf(data, "SSL: Unable to open issuer cert (%s)", - SSL_SET_OPTION(issuercert)); + SSL_CONN_CONFIG(issuercert)); BIO_free(fp); X509_free(backend->server_cert); backend->server_cert = NULL; @@ -3929,7 +3935,7 @@ static CURLcode servercert(struct Curl_easy *data, if(!issuer) { if(strict) failf(data, "SSL: Unable to read issuer cert (%s)", - SSL_SET_OPTION(issuercert)); + SSL_CONN_CONFIG(issuercert)); BIO_free(fp); X509_free(issuer); X509_free(backend->server_cert); @@ -3940,7 +3946,7 @@ static CURLcode servercert(struct Curl_easy *data, if(X509_check_issued(issuer, backend->server_cert) != X509_V_OK) { if(strict) failf(data, "SSL: Certificate issuer check failed (%s)", - SSL_SET_OPTION(issuercert)); + SSL_CONN_CONFIG(issuercert)); BIO_free(fp); X509_free(issuer); X509_free(backend->server_cert); @@ -3948,8 +3954,8 @@ static CURLcode servercert(struct Curl_easy *data, return CURLE_SSL_ISSUER_ERROR; } - infof(data, " SSL certificate issuer check ok (%s)\n", - SSL_SET_OPTION(issuercert)); + infof(data, " SSL certificate issuer check ok (%s)", + SSL_CONN_CONFIG(issuercert)); BIO_free(fp); X509_free(issuer); } @@ -3967,11 +3973,11 @@ static CURLcode servercert(struct Curl_easy *data, } else infof(data, " SSL certificate verify result: %s (%ld)," - " continuing anyway.\n", + " continuing anyway.", X509_verify_cert_error_string(lerr), lerr); } else - infof(data, " SSL certificate verify ok.\n"); + infof(data, " SSL certificate verify ok."); } #if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ @@ -4244,7 +4250,7 @@ static ssize_t ossl_send(struct Curl_easy *data, #endif ) { char ver[120]; - ossl_version(ver, 120); + (void)ossl_version(ver, sizeof(ver)); failf(data, "Error: %s does not support double SSL tunneling.", ver); } else @@ -4534,9 +4540,6 @@ static void ossl_disassociate_connection(struct Curl_easy *data, return; if(SSL_SET_OPTION(primary.sessionid)) { - bool isproxy = FALSE; - bool incache; - void *old_ssl_sessionid = NULL; int data_idx = ossl_get_ssl_data_index(); int connectdata_idx = ossl_get_ssl_conn_index(); int sockindex_idx = ossl_get_ssl_sockindex_index(); @@ -4544,9 +4547,6 @@ static void ossl_disassociate_connection(struct Curl_easy *data, if(data_idx >= 0 && connectdata_idx >= 0 && sockindex_idx >= 0 && proxy_idx >= 0) { - /* Invalidate the session cache entry, if any */ - isproxy = SSL_get_ex_data(backend->handle, proxy_idx) ? TRUE : FALSE; - /* Disable references to data in "new session" callback to avoid * accessing a stale pointer. */ SSL_set_ex_data(backend->handle, data_idx, NULL); @@ -4554,13 +4554,6 @@ static void ossl_disassociate_connection(struct Curl_easy *data, SSL_set_ex_data(backend->handle, sockindex_idx, NULL); SSL_set_ex_data(backend->handle, proxy_idx, NULL); } - - Curl_ssl_sessionid_lock(data); - incache = !(Curl_ssl_getsessionid(data, conn, isproxy, - &old_ssl_sessionid, NULL, sockindex)); - if(incache) - Curl_ssl_delsessionid(data, old_ssl_sessionid); - Curl_ssl_sessionid_unlock(data); } } diff --git a/contrib/libs/curl/lib/vtls/rustls.c b/contrib/libs/curl/lib/vtls/rustls.c index e9b75a5dc5..3d7aaed782 100644 --- a/contrib/libs/curl/lib/vtls/rustls.c +++ b/contrib/libs/curl/lib/vtls/rustls.c @@ -73,7 +73,7 @@ cr_connect(struct Curl_easy *data UNUSED_PARAM, struct connectdata *conn UNUSED_PARAM, int sockindex UNUSED_PARAM) { - infof(data, "rustls_connect: unimplemented\n"); + infof(data, "rustls_connect: unimplemented"); return CURLE_SSL_CONNECT_ERROR; } @@ -129,7 +129,7 @@ cr_recv(struct Curl_easy *data, int sockindex, io_error = rustls_connection_read_tls(rconn, read_cb, &conn->sock[sockindex], &tls_bytes_read); if(io_error == EAGAIN || io_error == EWOULDBLOCK) { - infof(data, "sread: EAGAIN or EWOULDBLOCK\n"); + infof(data, "sread: EAGAIN or EWOULDBLOCK"); } else if(io_error) { failf(data, "reading from socket: %s", strerror(io_error)); @@ -142,7 +142,7 @@ cr_recv(struct Curl_easy *data, int sockindex, return -1; } - infof(data, "cr_recv read %ld bytes from the network\n", tls_bytes_read); + infof(data, "cr_recv read %ld bytes from the network", tls_bytes_read); rresult = rustls_connection_process_new_packets(rconn); if(rresult != RUSTLS_RESULT_OK) { @@ -173,12 +173,12 @@ cr_recv(struct Curl_easy *data, int sockindex, available data has been read." If we bring in more ciphertext with read_tls, more plaintext will become available. So don't tell curl this is an EOF. Instead, say "come back later." */ - infof(data, "cr_recv got 0 bytes of plaintext\n"); + infof(data, "cr_recv got 0 bytes of plaintext"); backend->data_pending = FALSE; break; } else { - infof(data, "cr_recv copied out %ld bytes of plaintext\n", n); + infof(data, "cr_recv copied out %ld bytes of plaintext", n); plain_bytes_copied += n; } } @@ -218,7 +218,7 @@ cr_send(struct Curl_easy *data, int sockindex, rustls_result rresult; rustls_io_result io_error; - infof(data, "cr_send %ld bytes of plaintext\n", plainlen); + infof(data, "cr_send %ld bytes of plaintext", plainlen); if(plainlen > 0) { rresult = rustls_connection_write(rconn, plainbuf, plainlen, @@ -239,7 +239,7 @@ cr_send(struct Curl_easy *data, int sockindex, io_error = rustls_connection_write_tls(rconn, write_cb, &conn->sock[sockindex], &tlswritten); if(io_error == EAGAIN || io_error == EWOULDBLOCK) { - infof(data, "swrite: EAGAIN after %ld bytes\n", tlswritten_total); + infof(data, "swrite: EAGAIN after %ld bytes", tlswritten_total); *err = CURLE_AGAIN; return -1; } @@ -253,7 +253,7 @@ cr_send(struct Curl_easy *data, int sockindex, *err = CURLE_WRITE_ERROR; return -1; } - infof(data, "cr_send wrote %ld bytes to network\n", tlswritten); + infof(data, "cr_send wrote %ld bytes to network", tlswritten); tlswritten_total += tlswritten; } @@ -304,10 +304,10 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, config_builder = rustls_client_config_builder_new(); #ifdef USE_HTTP2 - infof(data, "offering ALPN for HTTP/1.1 and HTTP/2\n"); + infof(data, "offering ALPN for HTTP/1.1 and HTTP/2"); rustls_client_config_builder_set_protocols(config_builder, alpn, 2); #else - infof(data, "offering ALPN for HTTP/1.1 only\n"); + infof(data, "offering ALPN for HTTP/1.1 only"); rustls_client_config_builder_set_protocols(config_builder, alpn, 1); #endif if(!verifypeer) { @@ -332,15 +332,6 @@ cr_init_backend(struct Curl_easy *data, struct connectdata *conn, return CURLE_SSL_CACERT_BADFILE; } } - else { - result = rustls_client_config_builder_load_native_roots(config_builder); - if(result != RUSTLS_RESULT_OK) { - failf(data, "failed to load trusted certificates"); - rustls_client_config_free( - rustls_client_config_builder_build(config_builder)); - return CURLE_SSL_CACERT_BADFILE; - } - } backend->config = rustls_client_config_builder_build(config_builder); DEBUGASSERT(rconn == NULL); @@ -364,24 +355,24 @@ cr_set_negotiated_alpn(struct Curl_easy *data, struct connectdata *conn, rustls_connection_get_alpn_protocol(rconn, &protocol, &len); if(NULL == protocol) { - infof(data, "ALPN, server did not agree to a protocol\n"); + infof(data, "ALPN, server did not agree to a protocol"); return; } #ifdef USE_HTTP2 if(len == ALPN_H2_LENGTH && 0 == memcmp(ALPN_H2, protocol, len)) { - infof(data, "ALPN, negotiated h2\n"); + infof(data, "ALPN, negotiated h2"); conn->negnpn = CURL_HTTP_VERSION_2; } else #endif if(len == ALPN_HTTP_1_1_LENGTH && 0 == memcmp(ALPN_HTTP_1_1, protocol, len)) { - infof(data, "ALPN, negotiated http/1.1\n"); + infof(data, "ALPN, negotiated http/1.1"); conn->negnpn = CURL_HTTP_VERSION_1_1; } else { - infof(data, "ALPN, negotiated an unrecognized protocol\n"); + infof(data, "ALPN, negotiated an unrecognized protocol"); } Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? @@ -424,7 +415,7 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, * once the handshake is done. */ if(!rustls_connection_is_handshaking(rconn)) { - infof(data, "Done handshaking\n"); + infof(data, "Done handshaking"); /* Done with the handshake. Set up callbacks to send/receive data. */ connssl->state = ssl_connection_complete; @@ -449,22 +440,19 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } if(0 == what) { - infof(data, "Curl_socket_check: %s would block\n", - wants_read&&wants_write ? - "writing and reading" : - wants_write ? - "writing" : - "reading"); + infof(data, "Curl_socket_check: %s would block", + wants_read&&wants_write ? "writing and reading" : + wants_write ? "writing" : "reading"); *done = FALSE; return CURLE_OK; } /* socket is readable or writable */ if(wants_write) { - infof(data, "rustls_connection wants us to write_tls.\n"); + infof(data, "rustls_connection wants us to write_tls."); cr_send(data, sockindex, NULL, 0, &tmperr); if(tmperr == CURLE_AGAIN) { - infof(data, "writing would block\n"); + infof(data, "writing would block"); /* fall through */ } else if(tmperr != CURLE_OK) { @@ -473,11 +461,11 @@ cr_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, } if(wants_read) { - infof(data, "rustls_connection wants us to read_tls.\n"); + infof(data, "rustls_connection wants us to read_tls."); cr_recv(data, sockindex, NULL, 0, &tmperr); if(tmperr == CURLE_AGAIN) { - infof(data, "reading would block\n"); + infof(data, "reading would block"); /* fall through */ } else if(tmperr != CURLE_OK) { diff --git a/contrib/libs/curl/lib/vtls/schannel.c b/contrib/libs/curl/lib/vtls/schannel.c index 574af6a005..96b7120474 100644 --- a/contrib/libs/curl/lib/vtls/schannel.c +++ b/contrib/libs/curl/lib/vtls/schannel.c @@ -372,23 +372,23 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, store_name_len = sep - path; - if(_tcsnccmp(path, TEXT("CurrentUser"), store_name_len) == 0) + if(_tcsncmp(path, TEXT("CurrentUser"), store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_CURRENT_USER; - else if(_tcsnccmp(path, TEXT("LocalMachine"), store_name_len) == 0) + else if(_tcsncmp(path, TEXT("LocalMachine"), store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE; - else if(_tcsnccmp(path, TEXT("CurrentService"), store_name_len) == 0) + else if(_tcsncmp(path, TEXT("CurrentService"), store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_CURRENT_SERVICE; - else if(_tcsnccmp(path, TEXT("Services"), store_name_len) == 0) + else if(_tcsncmp(path, TEXT("Services"), store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_SERVICES; - else if(_tcsnccmp(path, TEXT("Users"), store_name_len) == 0) + else if(_tcsncmp(path, TEXT("Users"), store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_USERS; - else if(_tcsnccmp(path, TEXT("CurrentUserGroupPolicy"), + else if(_tcsncmp(path, TEXT("CurrentUserGroupPolicy"), store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY; - else if(_tcsnccmp(path, TEXT("LocalMachineGroupPolicy"), + else if(_tcsncmp(path, TEXT("LocalMachineGroupPolicy"), store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY; - else if(_tcsnccmp(path, TEXT("LocalMachineEnterprise"), + else if(_tcsncmp(path, TEXT("LocalMachineEnterprise"), store_name_len) == 0) *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE; else @@ -413,6 +413,341 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path, return CURLE_OK; } #endif +static CURLcode +schannel_acquire_credential_handle(struct Curl_easy *data, + struct connectdata *conn, + int sockindex) +{ + struct ssl_connect_data *connssl = &conn->ssl[sockindex]; + SCHANNEL_CRED schannel_cred; + PCCERT_CONTEXT client_certs[1] = { NULL }; + SECURITY_STATUS sspi_status = SEC_E_OK; + CURLcode result; + + /* 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; + else +#endif + schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION; + + if(SSL_SET_OPTION(no_revoke)) { + schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | + SCH_CRED_IGNORE_REVOCATION_OFFLINE; + + DEBUGF(infof(data, "schannel: disabled server certificate revocation " + "checks")); + } + else if(SSL_SET_OPTION(revoke_best_effort)) { + schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | + SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN; + + DEBUGF(infof(data, "schannel: ignore revocation offline errors")); + } + else { + schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; + + DEBUGF(infof(data, + "schannel: checking server certificate revocation")); + } + } + else { + schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | + SCH_CRED_IGNORE_NO_REVOCATION_CHECK | + SCH_CRED_IGNORE_REVOCATION_OFFLINE; + DEBUGF(infof(data, + "schannel: disabled server cert revocation checks")); + } + + if(!conn->ssl_config.verifyhost) { + schannel_cred.dwFlags |= 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; + infof(data, "schannel: disabled automatic use of client certificate"); + } + else + infof(data, "schannel: enabled automatic use of client certificate"); + + switch(conn->ssl_config.version) { + case CURL_SSLVERSION_DEFAULT: + case CURL_SSLVERSION_TLSv1: + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + case CURL_SSLVERSION_TLSv1_3: + { + result = set_ssl_version_min_max(&schannel_cred, data, conn); + if(result != CURLE_OK) + return result; + break; + } + case CURL_SSLVERSION_SSLv3: + case CURL_SSLVERSION_SSLv2: + failf(data, "SSL versions not supported"); + return CURLE_NOT_BUILT_IN; + default: + failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); + return CURLE_SSL_CONNECT_ERROR; + } + + if(SSL_CONN_CONFIG(cipher_list)) { + result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list), + BACKEND->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) { + DWORD cert_store_name = 0; + TCHAR *cert_store_path = NULL; + TCHAR *cert_thumbprint_str = NULL; + CRYPT_HASH_BLOB cert_thumbprint; + BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN]; + HCERTSTORE cert_store = NULL; + FILE *fInCert = NULL; + void *certdata = NULL; + size_t certsize = 0; + bool blob = data->set.ssl.primary.cert_blob != NULL; + TCHAR *cert_path = NULL; + if(blob) { + certdata = data->set.ssl.primary.cert_blob->data; + certsize = data->set.ssl.primary.cert_blob->len; + } + else { + cert_path = curlx_convert_UTF8_to_tchar( + data->set.ssl.primary.clientcert); + if(!cert_path) + return CURLE_OUT_OF_MEMORY; + + result = get_cert_location(cert_path, &cert_store_name, + &cert_store_path, &cert_thumbprint_str); + + if(result && (data->set.ssl.primary.clientcert[0]!='\0')) + fInCert = fopen(data->set.ssl.primary.clientcert, "rb"); + + if(result && !fInCert) { + failf(data, "schannel: Failed to get certificate location" + " or file for %s", + data->set.ssl.primary.clientcert); + curlx_unicodefree(cert_path); + return result; + } + } + + if((fInCert || blob) && (data->set.ssl.cert_type) && + (!strcasecompare(data->set.ssl.cert_type, "P12"))) { + failf(data, "schannel: certificate format compatibility error " + " 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 + */ + CRYPT_DATA_BLOB datablob; + WCHAR* pszPassword; + size_t pwd_len = 0; + int str_w_len = 0; + const char *cert_showfilename_error = blob ? + "(memory blob)" : data->set.ssl.primary.clientcert; + curlx_unicodefree(cert_path); + if(fInCert) { + long cert_tell = 0; + bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0; + if(continue_reading) + cert_tell = ftell(fInCert); + if(cert_tell < 0) + continue_reading = FALSE; + else + certsize = (size_t)cert_tell; + if(continue_reading) + continue_reading = fseek(fInCert, 0, SEEK_SET) == 0; + if(continue_reading) + certdata = malloc(certsize + 1); + if((!certdata) || + ((int) fread(certdata, certsize, 1, fInCert) != 1)) + continue_reading = FALSE; + fclose(fInCert); + if(!continue_reading) { + failf(data, "schannel: Failed to read cert file %s", + data->set.ssl.primary.clientcert); + free(certdata); + return CURLE_SSL_CERTPROBLEM; + } + } + + /* Convert key-pair data to the in-memory certificate store */ + datablob.pbData = (BYTE*)certdata; + datablob.cbData = (DWORD)certsize; + + if(data->set.ssl.key_passwd != NULL) + pwd_len = strlen(data->set.ssl.key_passwd); + pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1)); + 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)); + + 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); + free(pszPassword); + } + if(!blob) + free(certdata); + if(!cert_store) { + DWORD errorcode = GetLastError(); + if(errorcode == ERROR_INVALID_PASSWORD) + failf(data, "schannel: Failed to import cert file %s, " + "password is bad", + cert_showfilename_error); + else + failf(data, "schannel: Failed to import cert file %s, " + "last error is 0x%x", + cert_showfilename_error, errorcode); + return CURLE_SSL_CERTPROBLEM; + } + + client_certs[0] = CertFindCertificateInStore( + cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, + CERT_FIND_ANY, NULL, NULL); + + if(!client_certs[0]) { + failf(data, "schannel: Failed to get certificate from file %s" + ", last error is 0x%x", + cert_showfilename_error, GetLastError()); + CertCloseStore(cert_store, 0); + return CURLE_SSL_CERTPROBLEM; + } + + schannel_cred.cCreds = 1; + schannel_cred.paCred = client_certs; + } + else { + cert_store = + CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0, + (HCRYPTPROV)NULL, + CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name, + cert_store_path); + if(!cert_store) { + failf(data, "schannel: Failed to open cert store %x %s, " + "last error is 0x%x", + cert_store_name, cert_store_path, GetLastError()); + free(cert_store_path); + curlx_unicodefree(cert_path); + return CURLE_SSL_CERTPROBLEM; + } + free(cert_store_path); + + cert_thumbprint.pbData = cert_thumbprint_data; + cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN; + + if(!CryptStringToBinary(cert_thumbprint_str, + CERT_THUMBPRINT_STR_LEN, + CRYPT_STRING_HEX, + cert_thumbprint_data, + &cert_thumbprint.cbData, + NULL, NULL)) { + curlx_unicodefree(cert_path); + CertCloseStore(cert_store, 0); + return CURLE_SSL_CERTPROBLEM; + } + + client_certs[0] = CertFindCertificateInStore( + cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, + CERT_FIND_HASH, &cert_thumbprint, NULL); + + curlx_unicodefree(cert_path); + + if(client_certs[0]) { + schannel_cred.cCreds = 1; + schannel_cred.paCred = client_certs; + } + else { + /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ + CertCloseStore(cert_store, 0); + return CURLE_SSL_CERTPROBLEM; + } + } + CertCloseStore(cert_store, 0); + } +#else + if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { + failf(data, "schannel: client cert support not built in"); + return CURLE_NOT_BUILT_IN; + } +#endif + + /* allocate memory for the re-usable credential handle */ + BACKEND->cred = (struct Curl_schannel_cred *) + calloc(1, sizeof(struct Curl_schannel_cred)); + if(!BACKEND->cred) { + failf(data, "schannel: unable to allocate memory"); + + if(client_certs[0]) + CertFreeCertificateContext(client_certs[0]); + + return CURLE_OUT_OF_MEMORY; + } + BACKEND->cred->refcount = 1; + + /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx + */ + 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); + + if(client_certs[0]) + CertFreeCertificateContext(client_certs[0]); + + if(sspi_status != SEC_E_OK) { + char buffer[STRERROR_LEN]; + failf(data, "schannel: AcquireCredentialsHandle failed: %s", + Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); + Curl_safefree(BACKEND->cred); + switch(sspi_status) { + case SEC_E_INSUFFICIENT_MEMORY: + return CURLE_OUT_OF_MEMORY; + case SEC_E_NO_CREDENTIALS: + case SEC_E_SECPKG_NOT_FOUND: + case SEC_E_NOT_OWNER: + case SEC_E_UNKNOWN_CREDENTIALS: + case SEC_E_INTERNAL_ERROR: + default: + return CURLE_SSL_CONNECT_ERROR; + } + } + + return CURLE_OK; +} static CURLcode schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, @@ -427,8 +762,6 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, #ifdef HAS_ALPN unsigned char alpn_buffer[128]; #endif - SCHANNEL_CRED schannel_cred; - PCCERT_CONTEXT client_certs[1] = { NULL }; SECURITY_STATUS sspi_status = SEC_E_OK; struct Curl_schannel_cred *old_cred = NULL; struct in_addr addr; @@ -440,7 +773,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, char * const hostname = SSL_HOST_NAME(); DEBUGF(infof(data, - "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", + "schannel: SSL/TLS connection with %s port %hu (step 1/3)", hostname, conn->remote_port)); if(curlx_verify_windows_version(5, 1, PLATFORM_WINNT, @@ -448,7 +781,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, /* Schannel in Windows XP (OS version 5.1) uses legacy handshakes and algorithms that may not be supported by all servers. */ infof(data, "schannel: Windows version is old and may not be able to " - "connect to some servers due to lack of SNI, algorithms, etc.\n"); + "connect to some servers due to lack of SNI, algorithms, etc."); } #ifdef HAS_ALPN @@ -503,338 +836,21 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, SSL_IS_PROXY() ? TRUE : FALSE, (void **)&old_cred, NULL, sockindex)) { BACKEND->cred = old_cred; - DEBUGF(infof(data, "schannel: re-using existing credential handle\n")); + DEBUGF(infof(data, "schannel: re-using existing credential handle")); /* increment the reference counter of the credential/session handle */ BACKEND->cred->refcount++; DEBUGF(infof(data, - "schannel: incremented credential handle refcount = %d\n", + "schannel: incremented credential handle refcount = %d", BACKEND->cred->refcount)); } Curl_ssl_sessionid_unlock(data); } if(!BACKEND->cred) { - /* 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; - else -#endif - schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION; - - if(SSL_SET_OPTION(no_revoke)) { - schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; - - DEBUGF(infof(data, "schannel: disabled server certificate revocation " - "checks\n")); - } - else if(SSL_SET_OPTION(revoke_best_effort)) { - schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE | SCH_CRED_REVOCATION_CHECK_CHAIN; - - DEBUGF(infof(data, "schannel: ignore revocation offline errors")); - } - else { - schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; - - DEBUGF(infof(data, - "schannel: checking server certificate revocation\n")); - } - } - else { - schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | - SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; - DEBUGF(infof(data, - "schannel: disabled server cert revocation checks\n")); - } - - if(!conn->ssl_config.verifyhost) { - schannel_cred.dwFlags |= 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.\n")); - } - - if(!SSL_SET_OPTION(auto_client_cert)) { - schannel_cred.dwFlags &= ~SCH_CRED_USE_DEFAULT_CREDS; - schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS; - infof(data, "schannel: disabled automatic use of client certificate\n"); - } - else - infof(data, "schannel: enabled automatic use of client certificate\n"); - - switch(conn->ssl_config.version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - { - result = set_ssl_version_min_max(&schannel_cred, data, conn); - if(result != CURLE_OK) - return result; - break; - } - case CURL_SSLVERSION_SSLv3: - case CURL_SSLVERSION_SSLv2: - failf(data, "SSL versions not supported"); - return CURLE_NOT_BUILT_IN; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(SSL_CONN_CONFIG(cipher_list)) { - result = set_ssl_ciphers(&schannel_cred, SSL_CONN_CONFIG(cipher_list), - BACKEND->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) { - DWORD cert_store_name = 0; - TCHAR *cert_store_path = NULL; - TCHAR *cert_thumbprint_str = NULL; - CRYPT_HASH_BLOB cert_thumbprint; - BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN]; - HCERTSTORE cert_store = NULL; - FILE *fInCert = NULL; - void *certdata = NULL; - size_t certsize = 0; - bool blob = data->set.ssl.primary.cert_blob != NULL; - TCHAR *cert_path = NULL; - if(blob) { - certdata = data->set.ssl.primary.cert_blob->data; - certsize = data->set.ssl.primary.cert_blob->len; - } - else { - cert_path = curlx_convert_UTF8_to_tchar( - data->set.ssl.primary.clientcert); - if(!cert_path) - return CURLE_OUT_OF_MEMORY; - - result = get_cert_location(cert_path, &cert_store_name, - &cert_store_path, &cert_thumbprint_str); - - if(result && (data->set.ssl.primary.clientcert[0]!='\0')) - fInCert = fopen(data->set.ssl.primary.clientcert, "rb"); - - if(result && !fInCert) { - failf(data, "schannel: Failed to get certificate location" - " or file for %s", - data->set.ssl.primary.clientcert); - curlx_unicodefree(cert_path); - return result; - } - } - - if((fInCert || blob) && (data->set.ssl.cert_type) && - (!strcasecompare(data->set.ssl.cert_type, "P12"))) { - failf(data, "schannel: certificate format compatibility error " - " 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 - */ - CRYPT_DATA_BLOB datablob; - WCHAR* pszPassword; - size_t pwd_len = 0; - int str_w_len = 0; - const char *cert_showfilename_error = blob ? - "(memory blob)" : data->set.ssl.primary.clientcert; - curlx_unicodefree(cert_path); - if(fInCert) { - long cert_tell = 0; - bool continue_reading = fseek(fInCert, 0, SEEK_END) == 0; - if(continue_reading) - cert_tell = ftell(fInCert); - if(cert_tell < 0) - continue_reading = FALSE; - else - certsize = (size_t)cert_tell; - if(continue_reading) - continue_reading = fseek(fInCert, 0, SEEK_SET) == 0; - if(continue_reading) - certdata = malloc(certsize + 1); - if((!certdata) || - ((int) fread(certdata, certsize, 1, fInCert) != 1)) - continue_reading = FALSE; - fclose(fInCert); - if(!continue_reading) { - failf(data, "schannel: Failed to read cert file %s", - data->set.ssl.primary.clientcert); - free(certdata); - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Convert key-pair data to the in-memory certificate store */ - datablob.pbData = (BYTE*)certdata; - datablob.cbData = (DWORD)certsize; - - if(data->set.ssl.key_passwd != NULL) - pwd_len = strlen(data->set.ssl.key_passwd); - pszPassword = (WCHAR*)malloc(sizeof(WCHAR)*(pwd_len + 1)); - 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)); - - 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); - free(pszPassword); - } - if(!blob) - free(certdata); - if(!cert_store) { - DWORD errorcode = GetLastError(); - if(errorcode == ERROR_INVALID_PASSWORD) - failf(data, "schannel: Failed to import cert file %s, " - "password is bad", - cert_showfilename_error); - else - failf(data, "schannel: Failed to import cert file %s, " - "last error is 0x%x", - cert_showfilename_error, errorcode); - return CURLE_SSL_CERTPROBLEM; - } - - client_certs[0] = CertFindCertificateInStore( - cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, - CERT_FIND_ANY, NULL, NULL); - - if(!client_certs[0]) { - failf(data, "schannel: Failed to get certificate from file %s" - ", last error is 0x%x", - cert_showfilename_error, GetLastError()); - CertCloseStore(cert_store, 0); - return CURLE_SSL_CERTPROBLEM; - } - - schannel_cred.cCreds = 1; - schannel_cred.paCred = client_certs; - } - else { - cert_store = - CertOpenStore(CURL_CERT_STORE_PROV_SYSTEM, 0, - (HCRYPTPROV)NULL, - CERT_STORE_OPEN_EXISTING_FLAG | cert_store_name, - cert_store_path); - if(!cert_store) { - failf(data, "schannel: Failed to open cert store %x %s, " - "last error is 0x%x", - cert_store_name, cert_store_path, GetLastError()); - free(cert_store_path); - curlx_unicodefree(cert_path); - return CURLE_SSL_CERTPROBLEM; - } - free(cert_store_path); - - cert_thumbprint.pbData = cert_thumbprint_data; - cert_thumbprint.cbData = CERT_THUMBPRINT_DATA_LEN; - - if(!CryptStringToBinary(cert_thumbprint_str, - CERT_THUMBPRINT_STR_LEN, - CRYPT_STRING_HEX, - cert_thumbprint_data, - &cert_thumbprint.cbData, - NULL, NULL)) { - curlx_unicodefree(cert_path); - CertCloseStore(cert_store, 0); - return CURLE_SSL_CERTPROBLEM; - } - - client_certs[0] = CertFindCertificateInStore( - cert_store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, - CERT_FIND_HASH, &cert_thumbprint, NULL); - - curlx_unicodefree(cert_path); - - if(client_certs[0]) { - schannel_cred.cCreds = 1; - schannel_cred.paCred = client_certs; - } - else { - /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ - CertCloseStore(cert_store, 0); - return CURLE_SSL_CERTPROBLEM; - } - } - CertCloseStore(cert_store, 0); - } -#else - if(data->set.ssl.primary.clientcert || data->set.ssl.primary.cert_blob) { - failf(data, "schannel: client cert support not built in"); - return CURLE_NOT_BUILT_IN; - } -#endif - - /* allocate memory for the re-usable credential handle */ - BACKEND->cred = (struct Curl_schannel_cred *) - calloc(1, sizeof(struct Curl_schannel_cred)); - if(!BACKEND->cred) { - failf(data, "schannel: unable to allocate memory"); - - if(client_certs[0]) - CertFreeCertificateContext(client_certs[0]); - - return CURLE_OUT_OF_MEMORY; - } - BACKEND->cred->refcount = 1; - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx - */ - 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); - - if(client_certs[0]) - CertFreeCertificateContext(client_certs[0]); - - if(sspi_status != SEC_E_OK) { - char buffer[STRERROR_LEN]; - failf(data, "schannel: AcquireCredentialsHandle failed: %s", - Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); - Curl_safefree(BACKEND->cred); - switch(sspi_status) { - case SEC_E_INSUFFICIENT_MEMORY: - return CURLE_OUT_OF_MEMORY; - case SEC_E_NO_CREDENTIALS: - case SEC_E_SECPKG_NOT_FOUND: - case SEC_E_NOT_OWNER: - case SEC_E_UNKNOWN_CREDENTIALS: - case SEC_E_INTERNAL_ERROR: - default: - return CURLE_SSL_CONNECT_ERROR; - } + result = schannel_acquire_credential_handle(data, conn, sockindex); + if(result != CURLE_OK) { + return result; } } @@ -844,7 +860,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, || Curl_inet_pton(AF_INET6, hostname, &addr6) #endif ) { - infof(data, "schannel: using IP address, SNI is not supported by OS.\n"); + infof(data, "schannel: using IP address, SNI is not supported by OS."); } #ifdef HAS_ALPN @@ -874,16 +890,17 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, #ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2) { + alpn_buffer[cur++] = ALPN_H2_LENGTH; memcpy(&alpn_buffer[cur], ALPN_H2, ALPN_H2_LENGTH); cur += ALPN_H2_LENGTH; - infof(data, "schannel: ALPN, offering %s\n", ALPN_H2); + infof(data, "schannel: ALPN, offering %s", ALPN_H2); } #endif alpn_buffer[cur++] = ALPN_HTTP_1_1_LENGTH; memcpy(&alpn_buffer[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); cur += ALPN_HTTP_1_1_LENGTH; - infof(data, "schannel: ALPN, offering %s\n", ALPN_HTTP_1_1); + infof(data, "schannel: ALPN, offering %s", ALPN_HTTP_1_1); *list_len = curlx_uitous(cur - list_start_index); *extension_len = *list_len + sizeof(unsigned int) + sizeof(unsigned short); @@ -971,7 +988,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, } DEBUGF(infof(data, "schannel: sending initial handshake data: " - "sending %lu bytes...\n", outbuf.cbBuffer)); + "sending %lu bytes.", outbuf.cbBuffer)); /* send initial handshake data which is now stored in output buffer */ result = Curl_write_plain(data, conn->sock[sockindex], outbuf.pvBuffer, @@ -984,7 +1001,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn, } DEBUGF(infof(data, "schannel: sent initial handshake data: " - "sent %zd bytes\n", written)); + "sent %zd bytes", written)); BACKEND->recv_unrecoverable_err = CURLE_OK; BACKEND->recv_sspi_close_notify = false; @@ -1018,7 +1035,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; DEBUGF(infof(data, - "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n", + "schannel: SSL/TLS connection with %s port %hu (step 2/3)", hostname, conn->remote_port)); if(!BACKEND->cred || !BACKEND->ctxt) @@ -1080,7 +1097,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, if(connssl->connecting_state != ssl_connect_2_writing) connssl->connecting_state = ssl_connect_2_reading; DEBUGF(infof(data, "schannel: failed to receive handshake, " - "need more data\n")); + "need more data")); return CURLE_OK; } else if((result != CURLE_OK) || (nread == 0)) { @@ -1092,11 +1109,11 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, /* increase encrypted data buffer offset */ BACKEND->encdata_offset += nread; BACKEND->encdata_is_incomplete = false; - DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); + DEBUGF(infof(data, "schannel: encrypted data got %zd", nread)); } DEBUGF(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu\n", + "schannel: encrypted data buffer: offset %zu length %zu", BACKEND->encdata_offset, BACKEND->encdata_length)); /* setup input buffers */ @@ -1141,7 +1158,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, BACKEND->encdata_is_incomplete = true; connssl->connecting_state = ssl_connect_2_reading; DEBUGF(infof(data, - "schannel: received incomplete message, need more data\n")); + "schannel: received incomplete message, need more data")); return CURLE_OK; } @@ -1153,7 +1170,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; connssl->connecting_state = ssl_connect_2_writing; DEBUGF(infof(data, - "schannel: a client certificate has been requested\n")); + "schannel: a client certificate has been requested")); return CURLE_OK; } @@ -1163,7 +1180,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, /* search for handshake tokens that need to be send */ if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) { DEBUGF(infof(data, "schannel: sending next handshake data: " - "sending %lu bytes...\n", outbuf[i].cbBuffer)); + "sending %lu bytes.", outbuf[i].cbBuffer)); /* send handshake token to server */ result = Curl_write_plain(data, conn->sock[sockindex], @@ -1218,7 +1235,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, /* check if there was additional remaining encrypted data */ if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) { - DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", + DEBUGF(infof(data, "schannel: encrypted data length: %lu", inbuf[1].cbBuffer)); /* There are two cases where we could be getting extra data here: @@ -1258,7 +1275,7 @@ schannel_connect_step2(struct Curl_easy *data, struct connectdata *conn, /* check if the handshake is complete */ if(sspi_status == SEC_E_OK) { connssl->connecting_state = ssl_connect_3; - DEBUGF(infof(data, "schannel: SSL/TLS handshake complete\n")); + DEBUGF(infof(data, "schannel: SSL/TLS handshake complete")); } pubkey_ptr = SSL_PINNED_PUB_KEY(); @@ -1357,7 +1374,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); DEBUGF(infof(data, - "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n", + "schannel: SSL/TLS connection with %s port %hu (step 3/3)", hostname, conn->remote_port)); if(!BACKEND->cred) @@ -1393,7 +1410,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, if(alpn_result.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success) { - infof(data, "schannel: ALPN, server accepted to use %.*s\n", + infof(data, "schannel: ALPN, server accepted to use %.*s", alpn_result.ProtocolIdSize, alpn_result.ProtocolId); #ifdef USE_HTTP2 @@ -1410,7 +1427,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, } } else - infof(data, "ALPN, server did not agree to a protocol\n"); + infof(data, "ALPN, server did not agree to a protocol"); Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } @@ -1427,7 +1444,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, if(incache) { if(old_cred != BACKEND->cred) { DEBUGF(infof(data, - "schannel: old credential handle is stale, removing\n")); + "schannel: old credential handle is stale, removing")); /* we're not taking old_cred ownership here, no refcount++ is needed */ Curl_ssl_delsessionid(data, (void *)old_cred); incache = FALSE; @@ -1446,7 +1463,7 @@ schannel_connect_step3(struct Curl_easy *data, struct connectdata *conn, /* this cred session is now also referenced by sessionid cache */ BACKEND->cred->refcount++; DEBUGF(infof(data, - "schannel: stored credential handle in session cache\n")); + "schannel: stored credential handle in session cache")); } } Curl_ssl_sessionid_unlock(data); @@ -1777,21 +1794,21 @@ schannel_recv(struct Curl_easy *data, int sockindex, * handled in the cleanup. */ - DEBUGF(infof(data, "schannel: client wants to read %zu bytes\n", len)); + DEBUGF(infof(data, "schannel: client wants to read %zu bytes", len)); *err = CURLE_OK; if(len && len <= BACKEND->decdata_offset) { - infof(data, "schannel: enough decrypted data is already available\n"); + infof(data, "schannel: enough decrypted data is already available"); goto cleanup; } else if(BACKEND->recv_unrecoverable_err) { *err = BACKEND->recv_unrecoverable_err; - infof(data, "schannel: an unrecoverable error occurred in a prior call\n"); + infof(data, "schannel: an unrecoverable error occurred in a prior call"); goto cleanup; } else if(BACKEND->recv_sspi_close_notify) { /* once a server has indicated shutdown there is no more encrypted data */ - infof(data, "schannel: server indicated shutdown in a prior call\n"); + infof(data, "schannel: server indicated shutdown in a prior call"); goto cleanup; } @@ -1820,12 +1837,12 @@ schannel_recv(struct Curl_easy *data, int sockindex, BACKEND->encdata_buffer = reallocated_buffer; BACKEND->encdata_length = reallocated_length; size = BACKEND->encdata_length - BACKEND->encdata_offset; - DEBUGF(infof(data, "schannel: encdata_buffer resized %zu\n", + DEBUGF(infof(data, "schannel: encdata_buffer resized %zu", BACKEND->encdata_length)); } DEBUGF(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu\n", + "schannel: encrypted data buffer: offset %zu length %zu", BACKEND->encdata_offset, BACKEND->encdata_length)); /* read encrypted data from socket */ @@ -1837,25 +1854,25 @@ schannel_recv(struct Curl_easy *data, int sockindex, nread = -1; if(*err == CURLE_AGAIN) DEBUGF(infof(data, - "schannel: Curl_read_plain returned CURLE_AGAIN\n")); + "schannel: Curl_read_plain returned CURLE_AGAIN")); else if(*err == CURLE_RECV_ERROR) - infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n"); + infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR"); else - infof(data, "schannel: Curl_read_plain returned error %d\n", *err); + infof(data, "schannel: Curl_read_plain returned error %d", *err); } else if(nread == 0) { BACKEND->recv_connection_closed = true; - DEBUGF(infof(data, "schannel: server closed the connection\n")); + DEBUGF(infof(data, "schannel: server closed the connection")); } else if(nread > 0) { BACKEND->encdata_offset += (size_t)nread; BACKEND->encdata_is_incomplete = false; - DEBUGF(infof(data, "schannel: encrypted data got %zd\n", nread)); + DEBUGF(infof(data, "schannel: encrypted data got %zd", nread)); } } DEBUGF(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu\n", + "schannel: encrypted data buffer: offset %zu length %zu", BACKEND->encdata_offset, BACKEND->encdata_length)); /* decrypt loop */ @@ -1884,7 +1901,7 @@ schannel_recv(struct Curl_easy *data, int sockindex, /* check for successfully decrypted data, even before actual renegotiation or shutdown of the connection context */ if(inbuf[1].BufferType == SECBUFFER_DATA) { - DEBUGF(infof(data, "schannel: decrypted data length: %lu\n", + DEBUGF(infof(data, "schannel: decrypted data length: %lu", inbuf[1].cbBuffer)); /* increase buffer in order to fit the received amount of data */ @@ -1917,15 +1934,15 @@ schannel_recv(struct Curl_easy *data, int sockindex, BACKEND->decdata_offset += size; } - DEBUGF(infof(data, "schannel: decrypted data added: %zu\n", size)); + DEBUGF(infof(data, "schannel: decrypted data added: %zu", size)); DEBUGF(infof(data, - "schannel: decrypted cached: offset %zu length %zu\n", + "schannel: decrypted cached: offset %zu length %zu", BACKEND->decdata_offset, BACKEND->decdata_length)); } /* check for remaining encrypted data */ if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) { - DEBUGF(infof(data, "schannel: encrypted data length: %lu\n", + DEBUGF(infof(data, "schannel: encrypted data length: %lu", inbuf[3].cbBuffer)); /* check if the remaining data is less than the total amount @@ -1941,7 +1958,7 @@ schannel_recv(struct Curl_easy *data, int sockindex, } DEBUGF(infof(data, - "schannel: encrypted cached: offset %zu length %zu\n", + "schannel: encrypted cached: offset %zu length %zu", BACKEND->encdata_offset, BACKEND->encdata_length)); } else { @@ -1951,29 +1968,29 @@ schannel_recv(struct Curl_easy *data, int sockindex, /* check if server wants to renegotiate the connection context */ if(sspi_status == SEC_I_RENEGOTIATE) { - infof(data, "schannel: remote party requests renegotiation\n"); + infof(data, "schannel: remote party requests renegotiation"); if(*err && *err != CURLE_AGAIN) { - infof(data, "schannel: can't renogotiate, an error is pending\n"); + infof(data, "schannel: can't renogotiate, an error is pending"); goto cleanup; } if(BACKEND->encdata_offset) { *err = CURLE_RECV_ERROR; infof(data, "schannel: can't renogotiate, " - "encrypted data available\n"); + "encrypted data available"); goto cleanup; } /* begin renegotiation */ - infof(data, "schannel: renegotiating SSL/TLS connection\n"); + infof(data, "schannel: renegotiating SSL/TLS connection"); connssl->state = ssl_connection_negotiating; connssl->connecting_state = ssl_connect_2_writing; *err = schannel_connect_common(data, conn, sockindex, FALSE, &done); if(*err) { - infof(data, "schannel: renegotiation failed\n"); + infof(data, "schannel: renegotiation failed"); goto cleanup; } /* now retry receiving data */ sspi_status = SEC_E_OK; - infof(data, "schannel: SSL/TLS connection renegotiated\n"); + infof(data, "schannel: SSL/TLS connection renegotiated"); continue; } /* check if the server closed the connection */ @@ -1983,7 +2000,7 @@ schannel_recv(struct Curl_easy *data, int sockindex, BACKEND->recv_sspi_close_notify = true; if(!BACKEND->recv_connection_closed) { BACKEND->recv_connection_closed = true; - infof(data, "schannel: server closed the connection\n"); + infof(data, "schannel: server closed the connection"); } goto cleanup; } @@ -1992,7 +2009,7 @@ schannel_recv(struct Curl_easy *data, int sockindex, BACKEND->encdata_is_incomplete = true; if(!*err) *err = CURLE_AGAIN; - infof(data, "schannel: failed to decrypt data, need more data\n"); + infof(data, "schannel: failed to decrypt data, need more data"); goto cleanup; } else { @@ -2000,23 +2017,23 @@ schannel_recv(struct Curl_easy *data, int sockindex, char buffer[STRERROR_LEN]; #endif *err = CURLE_RECV_ERROR; - infof(data, "schannel: failed to read data from server: %s\n", + infof(data, "schannel: failed to read data from server: %s", Curl_sspi_strerror(sspi_status, buffer, sizeof(buffer))); goto cleanup; } } DEBUGF(infof(data, - "schannel: encrypted data buffer: offset %zu length %zu\n", + "schannel: encrypted data buffer: offset %zu length %zu", BACKEND->encdata_offset, BACKEND->encdata_length)); DEBUGF(infof(data, - "schannel: decrypted data buffer: offset %zu length %zu\n", + "schannel: decrypted data buffer: offset %zu length %zu", BACKEND->decdata_offset, BACKEND->decdata_length)); cleanup: /* Warning- there is no guarantee the encdata state is valid at this point */ - DEBUGF(infof(data, "schannel: schannel_recv cleanup\n")); + DEBUGF(infof(data, "schannel: schannel_recv cleanup")); /* Error if the connection has closed without a close_notify. @@ -2038,7 +2055,7 @@ schannel_recv(struct Curl_easy *data, int sockindex, BACKEND->recv_sspi_close_notify = true; else { *err = CURLE_RECV_ERROR; - infof(data, "schannel: server closed abruptly (missing close_notify)\n"); + infof(data, "schannel: server closed abruptly (missing close_notify)"); } } @@ -2052,9 +2069,9 @@ schannel_recv(struct Curl_easy *data, int sockindex, memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size, BACKEND->decdata_offset - size); BACKEND->decdata_offset -= size; - DEBUGF(infof(data, "schannel: decrypted data returned %zu\n", size)); + DEBUGF(infof(data, "schannel: decrypted data returned %zu", size)); DEBUGF(infof(data, - "schannel: decrypted data buffer: offset %zu length %zu\n", + "schannel: decrypted data buffer: offset %zu length %zu", BACKEND->decdata_offset, BACKEND->decdata_length)); *err = CURLE_OK; return (ssize_t)size; @@ -2138,7 +2155,7 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn, DEBUGASSERT(data); - infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n", + infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu", hostname, conn->remote_port); if(BACKEND->cred && BACKEND->ctxt) { @@ -2196,14 +2213,14 @@ static int schannel_shutdown(struct Curl_easy *data, struct connectdata *conn, s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) { infof(data, "schannel: failed to send close msg: %s" - " (bytes written: %zd)\n", curl_easy_strerror(result), written); + " (bytes written: %zd)", curl_easy_strerror(result), written); } } } /* free SSPI Schannel API security context handle */ if(BACKEND->ctxt) { - DEBUGF(infof(data, "schannel: clear security context handle\n")); + DEBUGF(infof(data, "schannel: clear security context handle")); s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle); Curl_safefree(BACKEND->ctxt); } diff --git a/contrib/libs/curl/lib/vtls/schannel_verify.c b/contrib/libs/curl/lib/vtls/schannel_verify.c index 25d47b8087..12fccaa8ee 100644 --- a/contrib/libs/curl/lib/vtls/schannel_verify.c +++ b/contrib/libs/curl/lib/vtls/schannel_verify.c @@ -204,12 +204,12 @@ static CURLcode add_certs_data_to_store(HCERTSTORE trust_store, if(result == CURLE_OK) { if(!num_certs) { infof(data, - "schannel: did not add any certificates from CA file '%s'\n", + "schannel: did not add any certificates from CA file '%s'", ca_file_text); } else { infof(data, - "schannel: added %d certificate(s) from CA file '%s'\n", + "schannel: added %d certificate(s) from CA file '%s'", num_certs, ca_file_text); } } @@ -526,7 +526,7 @@ static CURLcode verify_host(struct Curl_easy *data, if(match_result == CURL_HOST_MATCH) { infof(data, "schannel: connection hostname (%s) validated " - "against certificate name (%s)\n", + "against certificate name (%s)", conn_hostname, cert_hostname); result = CURLE_OK; } @@ -535,7 +535,7 @@ static CURLcode verify_host(struct Curl_easy *data, infof(data, "schannel: connection hostname (%s) did not match " - "against certificate name (%s)\n", + "against certificate name (%s)", conn_hostname, cert_hostname); cert_hostname_len = diff --git a/contrib/libs/curl/lib/vtls/sectransp.c b/contrib/libs/curl/lib/vtls/sectransp.c index edd375ea7d..26b833dd2a 100644 --- a/contrib/libs/curl/lib/vtls/sectransp.c +++ b/contrib/libs/curl/lib/vtls/sectransp.c @@ -32,6 +32,7 @@ #include "curl_base64.h" #include "strtok.h" #include "multiif.h" +#include "strcase.h" #ifdef USE_SECTRANSP @@ -1644,7 +1645,7 @@ static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data, } } /* All cipher suites in the list are found. Report to logs as-is */ - infof(data, "SSL: Setting cipher suites list \"%s\"\n", ciphers); + infof(data, "SSL: Setting cipher suites list \"%s\"", ciphers); err = SSLSetEnabledCiphers(ssl_ctx, selected_ciphers, ciphers_count); if(err != noErr) { @@ -1840,19 +1841,19 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, #endif ) { CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2)); - infof(data, "ALPN, offering %s\n", ALPN_H2); + infof(data, "ALPN, offering %s", ALPN_H2); } #endif CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1)); - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + infof(data, "ALPN, offering %s", ALPN_HTTP_1_1); /* expects length prefixed preference ordered list of protocols in wire * format */ err = SSLSetALPNProtocols(backend->ssl_ctx, alpnArr); if(err != noErr) - infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d\n", + infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d", err); CFRelease(alpnArr); } @@ -1861,7 +1862,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, if(SSL_SET_OPTION(key)) { infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure " - "Transport. The private key must be in the Keychain.\n"); + "Transport. The private key must be in the Keychain."); } if(ssl_cert || ssl_cert_blob) { @@ -1869,24 +1870,28 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, bool is_cert_file = (!is_cert_data) && is_file(ssl_cert); SecIdentityRef cert_and_key = NULL; - /* User wants to authenticate with a client cert. Look for it: - If we detect that this is a file on disk, then let's load it. - Otherwise, assume that the user wants to use an identity loaded - from the Keychain. */ - if(is_cert_file || is_cert_data) { + /* User wants to authenticate with a client cert. Look for it. Assume that + the user wants to use an identity loaded from the Keychain. If not, try + it as a file on disk */ + + if(!is_cert_data) + err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); + else + err = !noErr; + if((err != noErr) && (is_cert_file || is_cert_data)) { if(!SSL_SET_OPTION(cert_type)) - infof(data, "WARNING: SSL: Certificate type not set, assuming " - "PKCS#12 format.\n"); - else if(strncmp(SSL_SET_OPTION(cert_type), "P12", - strlen(SSL_SET_OPTION(cert_type))) != 0) - infof(data, "WARNING: SSL: The Security framework only supports " - "loading identities that are in PKCS#12 format.\n"); + infof(data, "SSL: Certificate type not set, assuming " + "PKCS#12 format."); + else if(!strcasecompare(SSL_SET_OPTION(cert_type), "P12")) { + failf(data, "SSL: The Security framework only supports " + "loading identities that are in PKCS#12 format."); + return CURLE_SSL_CERTPROBLEM; + } err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob, - SSL_SET_OPTION(key_passwd), &cert_and_key); + SSL_SET_OPTION(key_passwd), + &cert_and_key); } - else - err = CopyIdentityWithLabel(ssl_cert, &cert_and_key); if(err == noErr && cert_and_key) { SecCertificateRef cert = NULL; @@ -1899,7 +1904,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, char *certp; CURLcode result = CopyCertSubject(data, cert, &certp); if(!result) { - infof(data, "Client certificate: %s\n", certp); + infof(data, "Client certificate: %s", certp); free(certp); } @@ -2025,7 +2030,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, strlen(hostname)); if(err != noErr) { - infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n", + infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d", err); } @@ -2035,11 +2040,11 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, #endif ) { infof(data, "WARNING: using IP address, SNI is being disabled by " - "the OS.\n"); + "the OS."); } } else { - infof(data, "WARNING: disabling hostname validation also disables SNI.\n"); + infof(data, "WARNING: disabling hostname validation also disables SNI."); } ciphers = SSL_CONN_CONFIG(cipher_list); @@ -2082,7 +2087,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } /* Informational message */ - infof(data, "SSL re-using session ID\n"); + infof(data, "SSL re-using session ID"); } /* If there isn't one, then let's make one up! This has to be done prior to starting the handshake. */ @@ -2487,7 +2492,7 @@ static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, spkiHeaderLength = 23; break; default: - infof(data, "SSL: unhandled public key length: %d\n", pubkeylen); + infof(data, "SSL: unhandled public key length: %d", pubkeylen); #elif SECTRANSP_PINNEDPUBKEY_V2 default: /* ecDSA secp256r1 pubkeylen == 91 header already included? @@ -2778,35 +2783,35 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, (void)SSLGetNegotiatedProtocolVersion(backend->ssl_ctx, &protocol); switch(protocol) { case kSSLProtocol2: - infof(data, "SSL 2.0 connection using %s\n", + infof(data, "SSL 2.0 connection using %s", TLSCipherNameForNumber(cipher)); break; case kSSLProtocol3: - infof(data, "SSL 3.0 connection using %s\n", + infof(data, "SSL 3.0 connection using %s", TLSCipherNameForNumber(cipher)); break; case kTLSProtocol1: - infof(data, "TLS 1.0 connection using %s\n", + infof(data, "TLS 1.0 connection using %s", TLSCipherNameForNumber(cipher)); break; #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS case kTLSProtocol11: - infof(data, "TLS 1.1 connection using %s\n", + infof(data, "TLS 1.1 connection using %s", TLSCipherNameForNumber(cipher)); break; case kTLSProtocol12: - infof(data, "TLS 1.2 connection using %s\n", + infof(data, "TLS 1.2 connection using %s", TLSCipherNameForNumber(cipher)); break; #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 case kTLSProtocol13: - infof(data, "TLS 1.3 connection using %s\n", + infof(data, "TLS 1.3 connection using %s", TLSCipherNameForNumber(cipher)); break; #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */ default: - infof(data, "Unknown protocol connection\n"); + infof(data, "Unknown protocol connection"); break; } @@ -2832,7 +2837,7 @@ sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn, conn->negnpn = CURL_HTTP_VERSION_1_1; } else - infof(data, "ALPN, server did not agree to a protocol\n"); + infof(data, "ALPN, server did not agree to a protocol"); Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); @@ -2881,7 +2886,7 @@ show_verbose_server_cert(struct Curl_easy *data, server_cert = SecTrustGetCertificateAtIndex(trust, i); result = CopyCertSubject(data, server_cert, &certp); if(!result) { - infof(data, "Server certificate: %s\n", certp); + infof(data, "Server certificate: %s", certp); free(certp); } } @@ -2907,7 +2912,7 @@ show_verbose_server_cert(struct Curl_easy *data, server_cert = SecTrustGetCertificateAtIndex(trust, i); result = CopyCertSubject(data, server_cert, &certp); if(!result) { - infof(data, "Server certificate: %s\n", certp); + infof(data, "Server certificate: %s", certp); free(certp); } } @@ -2927,7 +2932,7 @@ show_verbose_server_cert(struct Curl_easy *data, i); result = CopyCertSubject(data, server_cert, &certp); if(!result) { - infof(data, "Server certificate: %s\n", certp); + infof(data, "Server certificate: %s", certp); free(certp); } } @@ -2947,7 +2952,7 @@ show_verbose_server_cert(struct Curl_easy *data, server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i); result = CopyCertSubject(data, server_cert, &certp); if(!result) { - infof(data, "Server certificate: %s\n", certp); + infof(data, "Server certificate: %s", certp); free(certp); } } @@ -3148,6 +3153,7 @@ static int sectransp_shutdown(struct Curl_easy *data, int what; int rc; char buf[120]; + int loop = 10; /* avoid getting stuck */ if(!backend->ssl_ctx) return 0; @@ -3163,7 +3169,7 @@ static int sectransp_shutdown(struct Curl_easy *data, what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT); - for(;;) { + while(loop--) { if(what < 0) { /* anything that gets here is fatally bad */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); diff --git a/contrib/libs/curl/lib/vtls/vtls.c b/contrib/libs/curl/lib/vtls/vtls.c index 65f4f773dd..e5bbe1f5f0 100644 --- a/contrib/libs/curl/lib/vtls/vtls.c +++ b/contrib/libs/curl/lib/vtls/vtls.c @@ -125,6 +125,16 @@ static bool blobcmp(struct curl_blob *first, struct curl_blob *second) return !memcmp(first->data, second->data, first->len); /* same data */ } +static bool safecmp(char *a, char *b) +{ + if(a && b) + return !strcmp(a, b); + else if(!a && !b) + return TRUE; /* match */ + return FALSE; /* no match */ +} + + bool Curl_ssl_config_matches(struct ssl_primary_config *data, struct ssl_primary_config *needle) @@ -136,11 +146,13 @@ Curl_ssl_config_matches(struct ssl_primary_config *data, (data->verifystatus == needle->verifystatus) && blobcmp(data->cert_blob, needle->cert_blob) && blobcmp(data->ca_info_blob, needle->ca_info_blob) && - Curl_safe_strcasecompare(data->CApath, needle->CApath) && - Curl_safe_strcasecompare(data->CAfile, needle->CAfile) && - Curl_safe_strcasecompare(data->clientcert, needle->clientcert) && - Curl_safe_strcasecompare(data->random_file, needle->random_file) && - Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) && + blobcmp(data->issuercert_blob, needle->issuercert_blob) && + safecmp(data->CApath, needle->CApath) && + safecmp(data->CAfile, needle->CAfile) && + safecmp(data->issuercert, needle->issuercert) && + safecmp(data->clientcert, needle->clientcert) && + safecmp(data->random_file, needle->random_file) && + safecmp(data->egdsocket, needle->egdsocket) && Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) && Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) && Curl_safe_strcasecompare(data->curves, needle->curves) && @@ -163,8 +175,10 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source, CLONE_BLOB(cert_blob); CLONE_BLOB(ca_info_blob); + CLONE_BLOB(issuercert_blob); CLONE_STRING(CApath); CLONE_STRING(CAfile); + CLONE_STRING(issuercert); CLONE_STRING(clientcert); CLONE_STRING(random_file); CLONE_STRING(egdsocket); @@ -180,6 +194,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) { Curl_safefree(sslc->CApath); Curl_safefree(sslc->CAfile); + Curl_safefree(sslc->issuercert); Curl_safefree(sslc->clientcert); Curl_safefree(sslc->random_file); Curl_safefree(sslc->egdsocket); @@ -188,6 +203,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config *sslc) Curl_safefree(sslc->pinned_key); Curl_safefree(sslc->cert_blob); Curl_safefree(sslc->ca_info_blob); + Curl_safefree(sslc->issuercert_blob); Curl_safefree(sslc->curves); } @@ -326,7 +342,7 @@ Curl_ssl_connect(struct Curl_easy *data, struct connectdata *conn, CURLcode Curl_ssl_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, - int sockindex, bool *done) + bool isproxy, int sockindex, bool *done) { CURLcode result; @@ -345,7 +361,7 @@ Curl_ssl_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, result = Curl_ssl->connect_nonblocking(data, conn, sockindex, done); if(result) conn->ssl[sockindex].use = FALSE; - else if(*done) + else if(*done && !isproxy) Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSL is connected */ return result; } @@ -407,8 +423,9 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data, DEBUGASSERT(SSL_SET_OPTION(primary.sessionid)); - if(!SSL_SET_OPTION(primary.sessionid)) - /* session ID re-use is disabled */ + if(!SSL_SET_OPTION(primary.sessionid) || !data->state.session) + /* session ID re-use is disabled or the session cache has not been + setup */ return TRUE; /* Lock if shared */ @@ -443,6 +460,10 @@ bool Curl_ssl_getsessionid(struct Curl_easy *data, } } + DEBUGF(infof(data, "%s Session ID in cache for %s %s://%s:%d", + no_match? "Didn't find": "Found", + isProxy ? "proxy" : "host", + conn->handler->scheme, name, port)); return no_match; } @@ -492,14 +513,14 @@ void Curl_ssl_delsessionid(struct Curl_easy *data, void *ssl_sessionid) */ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, struct connectdata *conn, - bool isProxy, + const bool isProxy, void *ssl_sessionid, size_t idsize, int sockindex) { size_t i; - struct Curl_ssl_session *store = &data->state.session[0]; - long oldest_age = data->state.session[0].age; /* zero if unused */ + struct Curl_ssl_session *store; + long oldest_age; char *clone_host; char *clone_conn_to_host; int conn_to_port; @@ -515,6 +536,11 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, const char *hostname = conn->host.name; #endif (void)sockindex; + if(!data->state.session) + return CURLE_OK; + + store = &data->state.session[0]; + oldest_age = data->state.session[0].age; /* zero if unused */ DEBUGASSERT(SSL_SET_OPTION(primary.sessionid)); clone_host = strdup(hostname); @@ -583,6 +609,9 @@ CURLcode Curl_ssl_addsessionid(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; } + DEBUGF(infof(data, "Added Session ID to cache for %s://%s:%d [%s]", + store->scheme, store->name, store->remote_port, + isProxy ? "PROXY" : "server")); return CURLE_OK; } @@ -708,12 +737,12 @@ CURLcode Curl_ssl_initsessions(struct Curl_easy *data, size_t amount) static size_t multissl_version(char *buffer, size_t size); -size_t Curl_ssl_version(char *buffer, size_t size) +void Curl_ssl_version(char *buffer, size_t size) { #ifdef CURL_WITH_MULTI_SSL - return multissl_version(buffer, size); + (void)multissl_version(buffer, size); #else - return Curl_ssl->version(buffer, size); + (void)Curl_ssl->version(buffer, size); #endif } @@ -940,7 +969,7 @@ CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data, if(encode) return encode; - infof(data, "\t public key hash: sha256//%s\n", encoded); + infof(data, " public key hash: sha256//%s", encoded); /* it starts with sha256//, copy so we can modify it */ pinkeylen = strlen(pinnedpubkey) + 1; @@ -1374,7 +1403,7 @@ static int multissl_setup(const struct Curl_ssl *backend) for(i = 0; available_backends[i]; i++) { if(strcasecompare(env, available_backends[i]->info.name)) { Curl_ssl = available_backends[i]; - curl_free(env_tmp); + free(env_tmp); return 0; } } @@ -1382,7 +1411,7 @@ static int multissl_setup(const struct Curl_ssl *backend) /* Fall back to first available backend */ Curl_ssl = available_backends[0]; - curl_free(env_tmp); + free(env_tmp); return 0; } diff --git a/contrib/libs/curl/lib/vtls/vtls.h b/contrib/libs/curl/lib/vtls/vtls.h index 7f93e7aedb..beaa83d9e3 100644 --- a/contrib/libs/curl/lib/vtls/vtls.h +++ b/contrib/libs/curl/lib/vtls/vtls.h @@ -193,6 +193,7 @@ CURLcode Curl_ssl_connect(struct Curl_easy *data, struct connectdata *conn, int sockindex); CURLcode Curl_ssl_connect_nonblocking(struct Curl_easy *data, struct connectdata *conn, + bool isproxy, int sockindex, bool *done); /* tell the SSL stuff to close down all open information regarding @@ -209,7 +210,7 @@ struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data); /* init the SSL session ID cache */ CURLcode Curl_ssl_initsessions(struct Curl_easy *, size_t); -size_t Curl_ssl_version(char *buffer, size_t size); +void Curl_ssl_version(char *buffer, size_t size); bool Curl_ssl_data_pending(const struct connectdata *conn, int connindex); int Curl_ssl_check_cxn(struct connectdata *conn); @@ -246,7 +247,7 @@ void Curl_ssl_sessionid_unlock(struct Curl_easy *data); */ bool Curl_ssl_getsessionid(struct Curl_easy *data, struct connectdata *conn, - const bool isproxy, + const bool isProxy, void **ssl_sessionid, size_t *idsize, /* set 0 if unknown */ int sockindex); @@ -313,7 +314,7 @@ void Curl_ssl_detach_conn(struct Curl_easy *data, #define Curl_ssl_data_pending(x,y) 0 #define Curl_ssl_check_cxn(x) 0 #define Curl_ssl_free_certinfo(x) Curl_nop_stmt -#define Curl_ssl_connect_nonblocking(x,y,z,w) CURLE_NOT_BUILT_IN +#define Curl_ssl_connect_nonblocking(x,y,z,w,a) CURLE_NOT_BUILT_IN #define Curl_ssl_kill_session(x) Curl_nop_stmt #define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN) #define Curl_ssl_cert_status_request() FALSE diff --git a/contrib/libs/curl/lib/vtls/wolfssl.c b/contrib/libs/curl/lib/vtls/wolfssl.c index 4fa8cb8a27..3bc45c4956 100644 --- a/contrib/libs/curl/lib/vtls/wolfssl.c +++ b/contrib/libs/curl/lib/vtls/wolfssl.c @@ -239,7 +239,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, req_method = SSLv23_client_method(); #else infof(data, "wolfSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, " - "TLS 1.0 is used exclusively\n"); + "TLS 1.0 is used exclusively"); req_method = TLSv1_client_method(); #endif use_sni(TRUE); @@ -324,7 +324,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, failf(data, "failed setting cipher list: %s", ciphers); return CURLE_SSL_CIPHER; } - infof(data, "Cipher selection: %s\n", ciphers); + infof(data, "Cipher selection: %s", ciphers); } #ifndef NO_FILESYSTEM @@ -347,16 +347,16 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, /* Just continue with a warning if no strict certificate verification is required. */ infof(data, "error setting certificate verify locations," - " continuing anyway:\n"); + " continuing anyway:"); } } else { /* Everything is fine. */ - infof(data, "successfully set certificate verify locations:\n"); + infof(data, "successfully set certificate verify locations:"); } - infof(data, " CAfile: %s\n", + infof(data, " CAfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile) : "none"); - infof(data, " CApath: %s\n", + infof(data, " CApath: %s", SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath) : "none"); } @@ -406,7 +406,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, (wolfSSL_CTX_UseSNI(backend->ctx, WOLFSSL_SNI_HOST_NAME, hostname, (unsigned short)hostname_len) != 1)) { infof(data, "WARNING: failed to configure server name indication (SNI) " - "TLS extension\n"); + "TLS extension"); } } #endif @@ -450,12 +450,12 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, #ifdef USE_HTTP2 if(data->state.httpwant >= CURL_HTTP_VERSION_2) { strcpy(protocols + strlen(protocols), ALPN_H2 ","); - infof(data, "ALPN, offering %s\n", ALPN_H2); + infof(data, "ALPN, offering %s", ALPN_H2); } #endif strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1); - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); + infof(data, "ALPN, offering %s", ALPN_HTTP_1_1); if(wolfSSL_UseALPN(backend->handle, protocols, (unsigned)strlen(protocols), @@ -494,15 +494,11 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn, &ssl_sessionid, NULL, sockindex)) { /* we got a session id, use it! */ if(!SSL_set_session(backend->handle, ssl_sessionid)) { - char error_buffer[WOLFSSL_MAX_ERROR_SZ]; - Curl_ssl_sessionid_unlock(data); - failf(data, "SSL: SSL_set_session failed: %s", - ERR_error_string(SSL_get_error(backend->handle, 0), - error_buffer)); - return CURLE_SSL_CONNECT_ERROR; + Curl_ssl_delsessionid(data, ssl_sessionid); + infof(data, "Can't use session ID, going on without\n"); } - /* Informational message */ - infof(data, "SSL re-using session ID\n"); + else + infof(data, "SSL re-using session ID"); } Curl_ssl_sessionid_unlock(data); } @@ -582,7 +578,7 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, * as also mismatching CN fields */ else if(DOMAIN_NAME_MISMATCH == detail) { #if 1 - failf(data, "\tsubject alt name(s) or common name do not match \"%s\"", + failf(data, " subject alt name(s) or common name do not match \"%s\"", dispname); return CURLE_PEER_FAILED_VERIFICATION; #else @@ -594,13 +590,13 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, * 'conn->ssl_config.verifyhost' value. */ if(SSL_CONN_CONFIG(verifyhost)) { failf(data, - "\tsubject alt name(s) or common name do not match \"%s\"\n", + " subject alt name(s) or common name do not match \"%s\"\n", dispname); return CURLE_PEER_FAILED_VERIFICATION; } else { infof(data, - "\tsubject alt name(s) and/or common name do not match \"%s\"\n", + " subject alt name(s) and/or common name do not match \"%s\"", dispname); return CURLE_OK; } @@ -609,14 +605,14 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, #if LIBWOLFSSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */ else if(ASN_NO_SIGNER_E == detail) { if(SSL_CONN_CONFIG(verifypeer)) { - failf(data, "\tCA signer not available for verification"); + failf(data, " CA signer not available for verification"); return CURLE_SSL_CACERT_BADFILE; } else { /* Just continue with a warning if no strict certificate verification is required. */ infof(data, "CA signer not available for verification, " - "continuing anyway\n"); + "continuing anyway"); } } #endif @@ -681,7 +677,7 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, rc = wolfSSL_ALPN_GetProtocol(backend->handle, &protocol, &protocol_len); if(rc == SSL_SUCCESS) { - infof(data, "ALPN, server accepted to use %.*s\n", protocol_len, + infof(data, "ALPN, server accepted to use %.*s", protocol_len, protocol); if(protocol_len == ALPN_HTTP_1_1_LENGTH && @@ -694,13 +690,13 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, conn->negnpn = CURL_HTTP_VERSION_2; #endif else - infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len, + infof(data, "ALPN, unrecognized protocol %.*s", protocol_len, protocol); Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); } else if(rc == SSL_ALPN_NOT_FOUND) - infof(data, "ALPN, server did not agree to a protocol\n"); + infof(data, "ALPN, server did not agree to a protocol"); else { failf(data, "ALPN, failure getting protocol, error %d", rc); return CURLE_SSL_CONNECT_ERROR; @@ -710,11 +706,11 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn, connssl->connecting_state = ssl_connect_3; #if (LIBWOLFSSL_VERSION_HEX >= 0x03009010) - infof(data, "SSL connection using %s / %s\n", + infof(data, "SSL connection using %s / %s", wolfSSL_get_version(backend->handle), wolfSSL_get_cipher_name(backend->handle)); #else - infof(data, "SSL connected\n"); + infof(data, "SSL connected"); #endif return CURLE_OK; @@ -743,7 +739,7 @@ wolfssl_connect_step3(struct Curl_easy *data, struct connectdata *conn, &old_ssl_sessionid, NULL, sockindex)); if(incache) { if(old_ssl_sessionid != our_ssl_sessionid) { - infof(data, "old SSL session ID is stale, removing\n"); + infof(data, "old SSL session ID is stale, removing"); Curl_ssl_delsessionid(data, old_ssl_sessionid); incache = FALSE; } @@ -810,6 +806,10 @@ static void wolfssl_close(struct Curl_easy *data, struct connectdata *conn, (void) data; if(backend->handle) { + char buf[32]; + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)SSL_read(backend->handle, buf, (int)sizeof(buf)); (void)SSL_shutdown(backend->handle); SSL_free(backend->handle); backend->handle = NULL; @@ -1089,7 +1089,7 @@ static CURLcode wolfssl_sha256sum(const unsigned char *tmp, /* input */ } static void *wolfssl_get_internals(struct ssl_connect_data *connssl, - CURLINFO info UNUSED_PARAM) + CURLINFO info UNUSED_PARAM) { struct ssl_backend_data *backend = connssl->backend; (void)info; diff --git a/contrib/libs/curl/lib/warnless.c b/contrib/libs/curl/lib/warnless.c index c0764c42d0..15c8156d1c 100644 --- a/contrib/libs/curl/lib/warnless.c +++ b/contrib/libs/curl/lib/warnless.c @@ -37,85 +37,23 @@ #include "warnless.h" -#define CURL_MASK_SCHAR 0x7F -#define CURL_MASK_UCHAR 0xFF - -#if (SIZEOF_SHORT == 2) -# define CURL_MASK_SSHORT 0x7FFF -# define CURL_MASK_USHORT 0xFFFF -#elif (SIZEOF_SHORT == 4) -# define CURL_MASK_SSHORT 0x7FFFFFFF -# define CURL_MASK_USHORT 0xFFFFFFFF -#elif (SIZEOF_SHORT == 8) -# define CURL_MASK_SSHORT 0x7FFFFFFFFFFFFFFF -# define CURL_MASK_USHORT 0xFFFFFFFFFFFFFFFF -#else -# error "SIZEOF_SHORT not defined" -#endif - -#if (SIZEOF_INT == 2) -# define CURL_MASK_SINT 0x7FFF -# define CURL_MASK_UINT 0xFFFF -#elif (SIZEOF_INT == 4) -# define CURL_MASK_SINT 0x7FFFFFFF -# define CURL_MASK_UINT 0xFFFFFFFF -#elif (SIZEOF_INT == 8) -# define CURL_MASK_SINT 0x7FFFFFFFFFFFFFFF -# define CURL_MASK_UINT 0xFFFFFFFFFFFFFFFF -#elif (SIZEOF_INT == 16) -# define CURL_MASK_SINT 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -# define CURL_MASK_UINT 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -#else -# error "SIZEOF_INT not defined" -#endif - -#if (SIZEOF_LONG == 2) -# define CURL_MASK_SLONG 0x7FFFL -# define CURL_MASK_ULONG 0xFFFFUL -#elif (SIZEOF_LONG == 4) -# define CURL_MASK_SLONG 0x7FFFFFFFL -# define CURL_MASK_ULONG 0xFFFFFFFFUL -#elif (SIZEOF_LONG == 8) -# define CURL_MASK_SLONG 0x7FFFFFFFFFFFFFFFL -# define CURL_MASK_ULONG 0xFFFFFFFFFFFFFFFFUL -#elif (SIZEOF_LONG == 16) -# define CURL_MASK_SLONG 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL -# define CURL_MASK_ULONG 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUL -#else -# error "SIZEOF_LONG not defined" -#endif - -#if (SIZEOF_CURL_OFF_T == 2) -# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFF) -# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFF) -#elif (SIZEOF_CURL_OFF_T == 4) -# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFF) -# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFF) -#elif (SIZEOF_CURL_OFF_T == 8) -# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) -# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFF) -#elif (SIZEOF_CURL_OFF_T == 16) -# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -#else -# error "SIZEOF_CURL_OFF_T not defined" -#endif - -#if (SIZEOF_SIZE_T == SIZEOF_SHORT) -# define CURL_MASK_SSIZE_T CURL_MASK_SSHORT -# define CURL_MASK_USIZE_T CURL_MASK_USHORT -#elif (SIZEOF_SIZE_T == SIZEOF_INT) -# define CURL_MASK_SSIZE_T CURL_MASK_SINT -# define CURL_MASK_USIZE_T CURL_MASK_UINT -#elif (SIZEOF_SIZE_T == SIZEOF_LONG) -# define CURL_MASK_SSIZE_T CURL_MASK_SLONG -# define CURL_MASK_USIZE_T CURL_MASK_ULONG -#elif (SIZEOF_SIZE_T == SIZEOF_CURL_OFF_T) -# define CURL_MASK_SSIZE_T CURL_MASK_SCOFFT -# define CURL_MASK_USIZE_T CURL_MASK_UCOFFT -#else -# error "SIZEOF_SIZE_T not defined" -#endif +#define CURL_MASK_UCHAR ((unsigned char)~0) +#define CURL_MASK_SCHAR (CURL_MASK_UCHAR >> 1) + +#define CURL_MASK_USHORT ((unsigned short)~0) +#define CURL_MASK_SSHORT (CURL_MASK_USHORT >> 1) + +#define CURL_MASK_UINT ((unsigned int)~0) +#define CURL_MASK_SINT (CURL_MASK_UINT >> 1) + +#define CURL_MASK_ULONG ((unsigned long)~0) +#define CURL_MASK_SLONG (CURL_MASK_ULONG >> 1) + +#define CURL_MASK_UCOFFT ((unsigned CURL_TYPEOF_CURL_OFF_T)~0) +#define CURL_MASK_SCOFFT (CURL_MASK_UCOFFT >> 1) + +#define CURL_MASK_USIZE_T ((size_t)~0) +#define CURL_MASK_SSIZE_T (CURL_MASK_USIZE_T >> 1) /* ** unsigned long to unsigned short @@ -207,7 +145,7 @@ unsigned long curlx_uztoul(size_t uznum) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif -#if (SIZEOF_LONG < SIZEOF_SIZE_T) +#if ULONG_MAX < SIZE_T_MAX DEBUGASSERT(uznum <= (size_t) CURL_MASK_ULONG); #endif return (unsigned long)(uznum & (size_t) CURL_MASK_ULONG); @@ -228,7 +166,7 @@ unsigned int curlx_uztoui(size_t uznum) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif -#if (SIZEOF_INT < SIZEOF_SIZE_T) +#if UINT_MAX < SIZE_T_MAX DEBUGASSERT(uznum <= (size_t) CURL_MASK_UINT); #endif return (unsigned int)(uznum & (size_t) CURL_MASK_UINT); @@ -250,7 +188,7 @@ int curlx_sltosi(long slnum) #endif DEBUGASSERT(slnum >= 0); -#if (SIZEOF_INT < SIZEOF_LONG) +#if INT_MAX < LONG_MAX DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_SINT); #endif return (int)(slnum & (long) CURL_MASK_SINT); @@ -272,7 +210,7 @@ unsigned int curlx_sltoui(long slnum) #endif DEBUGASSERT(slnum >= 0); -#if (SIZEOF_INT < SIZEOF_LONG) +#if UINT_MAX < LONG_MAX DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_UINT); #endif return (unsigned int)(slnum & (long) CURL_MASK_UINT); @@ -352,7 +290,7 @@ int curlx_sztosi(ssize_t sznum) #endif DEBUGASSERT(sznum >= 0); -#if (SIZEOF_INT < SIZEOF_SIZE_T) +#if INT_MAX < SSIZE_T_MAX DEBUGASSERT((size_t) sznum <= (size_t) CURL_MASK_SINT); #endif return (int)(sznum & (ssize_t) CURL_MASK_SINT); diff --git a/contrib/libs/curl/lib/x509asn1.c b/contrib/libs/curl/lib/x509asn1.c index 71eed68490..df54438b36 100644 --- a/contrib/libs/curl/lib/x509asn1.c +++ b/contrib/libs/curl/lib/x509asn1.c @@ -517,8 +517,8 @@ static const char *GTime2str(const char *beg, const char *end) return curl_maprintf("%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s", beg, beg + 4, beg + 6, beg + 8, beg + 10, sec1, sec2, - fracl? ".": "", fracl, fracp, - sep, tzl, tzp); + fracl? ".": "", (int)fracl, fracp, + sep, (int)tzl, tzp); } /* @@ -558,7 +558,7 @@ static const char *UTime2str(const char *beg, const char *end) return curl_maprintf("%u%.2s-%.2s-%.2s %.2s:%.2s:%.2s %.*s", 20 - (*beg >= '5'), beg, beg + 2, beg + 4, beg + 6, beg + 8, sec, - tzl, tzp); + (int)tzl, tzp); } /* @@ -866,7 +866,7 @@ static void do_pubkey_field(struct Curl_easy *data, int certnum, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, label, output); if(!certnum) - infof(data, " %s: %s\n", label, output); + infof(data, " %s: %s", label, output); free((char *) output); } } @@ -905,7 +905,7 @@ static void do_pubkey(struct Curl_easy *data, int certnum, if(len > 32) elem.beg = q; /* Strip leading zero bytes. */ if(!certnum) - infof(data, " RSA Public Key (%lu bits)\n", len); + infof(data, " RSA Public Key (%lu bits)", len); if(data->set.ssl.certinfo) { q = curl_maprintf("%lu", len); if(q) { @@ -978,7 +978,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, "Subject", ccp); if(!certnum) - infof(data, "%2d Subject: %s\n", certnum, ccp); + infof(data, "%2d Subject: %s", certnum, ccp); free((char *) ccp); /* Issuer. */ @@ -988,7 +988,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp); if(!certnum) - infof(data, " Issuer: %s\n", ccp); + infof(data, " Issuer: %s", ccp); free((char *) ccp); /* Version (always fits in less than 32 bits). */ @@ -1003,7 +1003,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, free((char *) ccp); } if(!certnum) - infof(data, " Version: %lu (0x%lx)\n", version + 1, version); + infof(data, " Version: %lu (0x%lx)", version + 1, version); /* Serial number. */ ccp = ASN1tostr(&cert.serialNumber, 0); @@ -1012,7 +1012,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp); if(!certnum) - infof(data, " Serial Number: %s\n", ccp); + infof(data, " Serial Number: %s", ccp); free((char *) ccp); /* Signature algorithm .*/ @@ -1023,7 +1023,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp); if(!certnum) - infof(data, " Signature Algorithm: %s\n", ccp); + infof(data, " Signature Algorithm: %s", ccp); free((char *) ccp); /* Start Date. */ @@ -1033,7 +1033,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp); if(!certnum) - infof(data, " Start Date: %s\n", ccp); + infof(data, " Start Date: %s", ccp); free((char *) ccp); /* Expire Date. */ @@ -1043,7 +1043,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp); if(!certnum) - infof(data, " Expire Date: %s\n", ccp); + infof(data, " Expire Date: %s", ccp); free((char *) ccp); /* Public Key Algorithm. */ @@ -1054,7 +1054,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp); if(!certnum) - infof(data, " Public Key Algorithm: %s\n", ccp); + infof(data, " Public Key Algorithm: %s", ccp); do_pubkey(data, certnum, ccp, ¶m, &cert.subjectPublicKey); free((char *) ccp); @@ -1065,7 +1065,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, "Signature", ccp); if(!certnum) - infof(data, " Signature: %s\n", ccp); + infof(data, " Signature: %s", ccp); free((char *) ccp); /* Generate PEM certificate. */ @@ -1098,7 +1098,7 @@ CURLcode Curl_extract_certinfo(struct Curl_easy *data, if(data->set.ssl.certinfo) Curl_ssl_push_certinfo(data, certnum, "Cert", cp2); if(!certnum) - infof(data, "%s\n", cp2); + infof(data, "%s", cp2); free(cp2); return CURLE_OK; } @@ -1220,12 +1220,12 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn, switch(matched) { case 1: /* an alternative name matched the server hostname */ - infof(data, "\t subjectAltName: %s matched\n", dispname); + infof(data, " subjectAltName: %s matched", dispname); return CURLE_OK; case 0: /* an alternative name field existed, but didn't match and then we MUST fail */ - infof(data, "\t subjectAltName does not match %s\n", dispname); + infof(data, " subjectAltName does not match %s", dispname); return CURLE_PEER_FAILED_VERIFICATION; } @@ -1262,7 +1262,7 @@ CURLcode Curl_verifyhost(struct Curl_easy *data, struct connectdata *conn, if(strlen(dnsname) != (size_t) len) /* Nul byte in string ? */ failf(data, "SSL: illegal cert name field"); else if(Curl_cert_hostcheck((const char *) dnsname, hostname)) { - infof(data, "\t common name: %s (matched)\n", dnsname); + infof(data, " common name: %s (matched)", dnsname); free(dnsname); return CURLE_OK; } |